summaryrefslogtreecommitdiff
path: root/protocols/YAMN/docs/YAMN-Readme.developers.txt
blob: fdb338707c4c5af96327bbf533991a740744dec4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
==================================================================================
= YAMN plugin for Miranda (short readme for developers)                          =
==================================================================================
Hello developer! :)
I hope YAMN will give you what you find, but you can also improve YAMN.

This readme gives you some info about YAMN. Please read it first before you are 
going to look at YAMN sources.

YAMN provides two types of plugins now: protocol plugins and filter plugins.


1.	What do you need to make your protocol plugin cooperating with YAMN
	-------------------------------------------------------------------

	If you want to cooperate with YAMN, you have to do some things. YAMN offers you some services,
	so your work is easier, but YAMN needs some things to be done for proper work. These limits go
	according thread synchronization and memory mutual exclusion.

	YAMN  offers  you  two  types  of services. Exported functions and Miranda services. Miranda
	services  are  described in header files, exported functions are described in cpp files. All
	exported  functions  in  YAMN  have  the  suffix Fcn, so you can easy get if the function is
	exported.  Using exported functions is more difficult than using miranda services, but after
	solving some definitions, the work with exported functions is more clear and easier. Miranda
	services  from  YAMN  are for miscellaneus functions. The fact Miranda service uses only two
	parameters  and  therefore is sometimes very unsuitable leads us to make exported functions.
	Exported  functions  are  divided in several parts: synchronizing functions (used for thread
	and account synchronization) and MIME functions (used to work with MIME 
	messages).

	Miranda services are used through Miranda CallService function. YAMN exported functions are avialable
	when registering plugin. Then YAMN gives you its table of exported functions.

	How  to  write  write  your  protocol  plugin  for  YAMN? The best way for you is to look at
	internal POP3 protocol, where all info about this is written. At start, you need to register
	plugin  (it  is  done in two steps- registering and inserting to YAMN), then get pointers to
	YAMN's  exported  functions  (using  Miranda's service MS_YAMN_GETFCN) you will need in your
	protocol  plugin.  These  are the first steps you should do when implementing some plugin to
	YAMN.  Next,  you  should  know  how  YAMN is stuctured. Structures of YAMN are described in
	chapter  2.  And, at the end, you should know something about account synchronizing and some
	limitations you have to achieve, if you want your plugin works well.


2.	YAMN structures and memory organization
	---------------------------------------

	YAMN  uses  its  own  structures, that can change in the future. The problem with change is,
	that  there  can occur some incomapatibilities between YAMN and plugins written for old YAMN
	versions.  To  avoid  problems,  YAMN  defines  versions  for  services or exported/imported
	functions, where strucutre version information is passed to/from plugins.


2.1.	Structures of protcol plugin queue

        (PYAMN_PROTOPLUGINQUEUE)FirstPlugin---> =(HYAMNPROTOPLUGIN)=  ---> =(HYAMNPROTOPLUGIN)=  ---> =(HYAMNPROTOPLUGIN)=  ---> NULL
                                                |                  |  |    |                  |  |    |                  |  |
                                                |         .        |  |    |         .        |  |    |         .        |  |
                                                |         .        |  |    |         .        |  |    |         .        |  |
                                                |         .        |  |    |         .        |  |    |         .        |  |
                                                --------------------  |    |------------------|  |    |------------------|  |
                                                |             Next |--|    |             Next |--|    |             Next |--|
                                                ====================       ====================       ====================

        This  structure  is not needed if you only create protocol plugin for YAMN. YAMN plugin does
        not see and it is not important for it how YAMN works with plugins and how it stores plugins
        data.   For   plugin   is   important   only  handle  for  its  own  plugin,  returned  from
        MS_YAMN_REGISTERPLUGIN service.


2.2.	Structure of accounts

	Every  account  in  YAMN  belongs  to  exact  plugin  and  its  members  are  allocated with
	MS_YAMN_CREATEPLUGINACCOUNT  service.  This  service cooperates with your function, which is
	defined in your function import table. In your function (if you have defined it), you should
	create  the whole account. It is because YAMN cannot know which members in structure did you
	add.  So  you  create  the  whole derived structure. If your fcn is not implemented (NULL in
	import table), YAMN creates standard account structure.

	This  structure contains information (members) related to YAMN, to plugin and members shared
	between both (plugin and YAMN). Therefore it is needed to synchronize access to members (see
	Ch.  3).  Standard  YAMN  account  is  defined  in  m_account.h  header  file.  There's also
	description  for every member how it is synchronised. YAMN creates two synchronizing objects
	(SO)  to  synchronise access to members. In m_synchro.h file, there are definitions for easy
	work with these SO.

	Accounts are queued in plugin:

        =(HYAMNPLUGIN)=  ---> ===(HACCOUNT)===  ---> ===(HACCOUNT)===  ---> ===(HACCOUNT)===  ---> NULL
        |             |  |    |              |  |    |              |  |    |              |  |
        |             |  |    |              |  |    |              |  |    |              |  |
        |      .      |  |    |              |  |    |              |  |    |              |  |
        |      .      |  |    |              |  |    |              |  |    |              |  |
        |      .      |  |    |              |  |    |              |  |    |              |  |
        |             |  |    |--------------|  |    |--------------|  |    |--------------|  |
        | (HACCOUNT)  |  |    |         Next |--|    |         Next |--|    |         Next |--|
        | FirstAccount|--|    ================       ================       ================
        |-------------|
        |             |
        ===============

        Every  account  has  its own back pointer to (HYAMNPLUGIN) in Plugin member, so you can easy
        look at first account, when you have any other account (see m_account.h).


2.3.	Structure of mails

	Account  has a pointer to mails. Account's pointer to mails is pointer to first mail in fact
	and mails are queued too:
        
        ==(HACCOUNT)==  ---> ==(HYAMNMAIL)==  ---> ==(HYAMNMAIL)==  ---> ==(HYAMNMAIL)==  ---> NULL
        |            |  |    |             |  |    |             |  |    |             |  |
        |      .     |  |    |             |  |    |             |  |    |             |  |
        |      .     |  |    |             |  |    |             |  |    |             |  |
        |      .     |  |    |             |  |    |             |  |    |             |  |
        |            |  |    |-------------|  |    |-------------|  |    |-------------|  |
        | (HYAMNMAIL)|  |    |        Next |--|    |        Next |--|    |        Next |--|
        |       Mails|--|    ===============       ===============       ===============
        |------------|
        |            |
	==============

	Standard MIME mail is defined in mails/m_mails.h file. 

	Plugin  can  work with accounts in its own way, but note it is needed to synchronize access.
	For  better  work,  YAMN  offers  you  some  services  and exports functions. Description of
	exported functions is in its declartation; for accounts functions see account.cpp, for mails
	functions see mails/mails.cpp and so on.


3.	YAMN thread synchronization
	---------------------------

	Because  YAMN  is  multithreaded,  more  than one thread can access to any member of account
	structure.  Therefore  access to these members should be synchronised. YAMN offers two types
	of   synchronization  objects  (SO):  SCOUNTER  (Synchronized  Counter)  and  SWMRG  (Single
	Writer/Multiple Readers Guard). To use these objects, you can use exported functions:

	SWMRG: WaitToWriteSO, WaitToWriteSOEx, WriteDoneSO, WaitToReadSO, WaitToReadSOEx, ReadDoneSO
	SCOUNTER: SCGetNumber, SCInc, SCDec

	To  see  description  for these functions, see m_synchro.h header file and synchro.cpp. Note
	that  in HACCOUNT structure, there are 3 synchronizing members, which you have to use if you
	want to access to any member of account structure. All access techniques (writing to members
	and  read  from members) are used in POP3 protocol plugin. Now, it is important what we have
	to  do  when  we  want  to make our plugin be synchronized with YAMN (in POP3 protocol it is
	described too).

	1. We have to use ThreadRunningEV event when YAMN calls our checking/deleting function. This
	parameter  is to stop YAMN called thread until we do not have copied datas from stack. After
	that, we SetEvent(ThreadRunningEvent) to unblock YAMN to continue in its work.

	2.  We  have  to  use  UsingThreads account's member. This is only for YAMN account deleting
	prevention. We use this counter to set number of threads using account. If no thread is just
	using  account,  account  is  signaled, that it can be deleted (and is deleted when needed).
	This leads us to do some things: We use SCInc(UsingThreads) as the first thing we can do. We
	cannot  omit,  that called thread finished before we call this function. UsingThreads should
	have  "continuous"  value  greater than zero when using account. E.g. if YAMN creates thread
	for  plugin  that  checks account for new mail, YAMN waits until we set ThreadRunningEV (see
	point  1).  After  setting  this  event  to  signal,  that YAMN can continue in its work, we
	increase  SCInc(UsingThreads),  so  we  ensure  that another thread uses account before YAMN
	thread,  that uses this account ends. And SCDec(UsingThreads) should be the last thing we do
	in  our  thread.  If  we  run another thread in our thread, we should wait until it does not
	SCInc(UsingThreads)  and after that we should continue (just like YAMN creates and calls our
	thread).

	3.  If  we  use account's SWMRG (AccountAccessSO, MessagesAccessSO), we should test what our
	function  returned.  Use  the same methods as POP3 protocol does while testing and accessing
	critical  section. Note that we cannot use WaitToWriteSO(MyAccount->AccountAccessSO), but in
	easy       way      we      can      WaitToWrite(AccountAccess)      and      for      mails
	WaitToWriteSO(MyAccount->MessagesAccessSO) use MsgsWaitToWrite(AccountAccess) and so on. See
	export.h file for these definitions.

	4. Deleting account is quite easy, but in YAMN, it is very problematic operation. If you use
	MS_YAMN_DELETEACCOUNT service, it is the best way to avoid any problem. These problems raise
	from the facts desribed in the point 2.

	5. You should use ctritical sections only for short time not to block other threads. You can
	imagine that users can't browse through mails, because account is blocked by your thread...

	All  needed  infos  in  POP3  internal  protocol  plugin  (see proto/pop3/pop3comm.cpp), are
	described.


4.	What do you need to make your filter plugin cooperating with YAMN
	-----------------------------------------------------------------

	Filter  plugins  are  very  easy  to write in its own way, it much more easier than protocol
	plugin.  But  some  things  are  common: you have to register your plugin and insert to YAMN
	(these  are  2  steps,  see  sources of some filter plugin), You have to import to YAMN your
	filter function. Filter function can do anything with mails, but the most important is, that
	it  can set Flags member of mail (see mails/m_mails.h file) to one of YAMN_MSG_SPAMLx.
	Note  Mail  is  in  write-access,  so  your  plugin  can do anything with mail and avoid the
	synchronization problem.

	Now YAMN recognizes 4 spam levels:
	1. Notifies about this mail, but shows it in mailbrowser with other color than normally
	2. Does not notify about this mail, shows it in mailbrowser with other color than normally
        3. Deletes mail from server (depends on protocol),  does not notify and shows "this spam was
        deleted"
        4. Deletes  mail  from  server  (depends  on  protocol),  does not notify,  does not show in
        mailbrowser

	Your  plugin  can  set  data for mail in the TranslatedHeader structure, inserting it to the
	queue.  This  information  is  stored, so it is reloaded after protocol read mails from book
	file.