initial commit
[rofl0r-KOL.git] / units / indy / IdIMAP4Server.pas
blob277755299245122093e95cec1095f344138fe58b
1 // 26-nov-2002
2 unit IdIMAP4Server;
4 interface
6 uses KOL { ,
7 Classes } ,
8 IdGlobal,
9 IdTCPServer;
11 const
12 IMAPCommands: array[1..25] of string =
13 ({ Client Commands - Any State}
14 'CAPABILITY',
15 'NOOP',
16 'LOGOUT',
17 { Client Commands - Non Authenticated State}
18 'AUTHENTICATE',
19 'LOGIN',
20 { Client Commands - Authenticated State}
21 'SELECT',
22 'EXAMINE',
23 'CREATE',
24 'DELETE',
25 'RENAME',
26 'SUBSCRIBE',
27 'UNSUBSCRIBE',
28 'LIST',
29 'LSUB',
30 'STATUS',
31 'APPEND',
32 { Client Commands - Selected State}
33 'CHECK',
34 'CLOSE',
35 'EXPUNGE',
36 'SEARCH',
37 'FETCH',
38 'STORE',
39 'COPY',
40 'UID',
41 { Client Commands - Experimental/ Expansion}
42 'X');
44 type
45 TCommandEvent = procedure(Thread: TIdPeerThread; const Tag, CmdStr: string;
46 var Handled: Boolean) of object;
48 TIdIMAP4Server = object(TIdTCPServer)
49 protected
50 fOnCommandCAPABILITY: TCommandEvent;
51 fONCommandNOOP: TCommandEvent;
52 fONCommandLOGOUT: TCommandEvent;
53 fONCommandAUTHENTICATE: TCommandEvent;
54 fONCommandLOGIN: TCommandEvent;
55 fONCommandSELECT: TCommandEvent;
56 fONCommandEXAMINE: TCommandEvent;
57 fONCommandCREATE: TCommandEvent;
58 fONCommandDELETE: TCommandEvent;
59 fONCommandRENAME: TCommandEvent;
60 fONCommandSUBSCRIBE: TCommandEvent;
61 fONCommandUNSUBSCRIBE: TCommandEvent;
62 fONCommandLIST: TCommandEvent;
63 fONCommandLSUB: TCommandEvent;
64 fONCommandSTATUS: TCommandEvent;
65 fONCommandAPPEND: TCommandEvent;
66 fONCommandCHECK: TCommandEvent;
67 fONCommandCLOSE: TCommandEvent;
68 fONCommandEXPUNGE: TCommandEvent;
69 fONCommandSEARCH: TCommandEvent;
70 fONCommandFETCH: TCommandEvent;
71 fONCommandSTORE: TCommandEvent;
72 fONCommandCOPY: TCommandEvent;
73 fONCommandUID: TCommandEvent;
74 fONCommandX: TCommandEvent;
75 fOnCommandError: TCommandEvent;
76 procedure DoCommandCAPABILITY(Thread: TIdPeerThread; const Tag, CmdStr:
77 string; var Handled: Boolean);
78 procedure DoCommandNOOP(Thread: TIdPeerThread; const Tag, CmdStr: string; var
79 Handled: Boolean);
80 procedure DoCommandLOGOUT(Thread: TIdPeerThread; const Tag, CmdStr: string;
81 var Handled: Boolean);
82 procedure DoCommandAUTHENTICATE(Thread: TIdPeerThread; const Tag, CmdStr:
83 string; var Handled: Boolean);
84 procedure DoCommandLOGIN(Thread: TIdPeerThread; const Tag, CmdStr: string;
85 var Handled: Boolean);
86 procedure DoCommandSELECT(Thread: TIdPeerThread; const Tag, CmdStr: string;
87 var Handled: Boolean);
88 procedure DoCommandEXAMINE(Thread: TIdPeerThread; const Tag, CmdStr: string;
89 var Handled: Boolean);
90 procedure DoCommandCREATE(Thread: TIdPeerThread; const Tag, CmdStr: string;
91 var Handled: Boolean);
92 procedure DoCommandDELETE(Thread: TIdPeerThread; const Tag, CmdStr: string;
93 var Handled: Boolean);
94 procedure DoCommandRENAME(Thread: TIdPeerThread; const Tag, CmdStr: string;
95 var Handled: Boolean);
96 procedure DoCommandSUBSCRIBE(Thread: TIdPeerThread; const Tag, CmdStr:
97 string; var Handled: Boolean);
98 procedure DoCommandUNSUBSCRIBE(Thread: TIdPeerThread; const Tag, CmdStr:
99 string; var Handled: Boolean);
100 procedure DoCommandLIST(Thread: TIdPeerThread; const Tag, CmdStr: string; var
101 Handled: Boolean);
102 procedure DoCommandLSUB(Thread: TIdPeerThread; const Tag, CmdStr: string; var
103 Handled: Boolean);
104 procedure DoCommandSTATUS(Thread: TIdPeerThread; const Tag, CmdStr: string;
105 var Handled: Boolean);
106 procedure DoCommandAPPEND(Thread: TIdPeerThread; const Tag, CmdStr: string;
107 var Handled: Boolean);
108 procedure DoCommandCHECK(Thread: TIdPeerThread; const Tag, CmdStr: string;
109 var Handled: Boolean);
110 procedure DoCommandCLOSE(Thread: TIdPeerThread; const Tag, CmdStr: string;
111 var Handled: Boolean);
112 procedure DoCommandEXPUNGE(Thread: TIdPeerThread; const Tag, CmdStr: string;
113 var Handled: Boolean);
114 procedure DoCommandSEARCH(Thread: TIdPeerThread; const Tag, CmdStr: string;
115 var Handled: Boolean);
116 procedure DoCommandFETCH(Thread: TIdPeerThread; const Tag, CmdStr: string;
117 var Handled: Boolean);
118 procedure DoCommandSTORE(Thread: TIdPeerThread; const Tag, CmdStr: string;
119 var Handled: Boolean);
120 procedure DoCommandCOPY(Thread: TIdPeerThread; const Tag, CmdStr: string; var
121 Handled: Boolean);
122 procedure DoCommandUID(Thread: TIdPeerThread; const Tag, CmdStr: string; var
123 Handled: Boolean);
124 procedure DoCommandX(Thread: TIdPeerThread; const Tag, CmdStr: string; var
125 Handled: Boolean);
126 procedure DoCommandError(Thread: TIdPeerThread; const Tag, CmdStr: string;
127 var Handled: Boolean);
128 function DoExecute(Thread: TIdPeerThread): Boolean; override;
129 public
130 // constructor Create(AOwner: TComponent); override;
131 published
132 property ONCommandCAPABILITY: TCommandEvent read fOnCommandCAPABILITY write
133 fOnCommandCAPABILITY;
134 property ONCommandNOOP: TCommandEvent read fONCommandNOOP write
135 fONCommandNOOP;
136 property ONCommandLOGOUT: TCommandEvent read fONCommandLOGOUT write
137 fONCommandLOGOUT;
138 property ONCommandAUTHENTICATE: TCommandEvent read fONCommandAUTHENTICATE
139 write fONCommandAUTHENTICATE;
140 property ONCommandLOGIN: TCommandEvent read fONCommandLOGIN write
141 fONCommandLOGIN;
142 property ONCommandSELECT: TCommandEvent read fONCommandSELECT write
143 fONCommandSELECT;
144 property OnCommandEXAMINE: TCommandEvent read fOnCommandEXAMINE write
145 fOnCommandEXAMINE;
146 property ONCommandCREATE: TCommandEvent read fONCommandCREATE write
147 fONCommandCREATE;
148 property ONCommandDELETE: TCommandEvent read fONCommandDELETE write
149 fONCommandDELETE;
150 property OnCommandRENAME: TCommandEvent read fOnCommandRENAME write
151 fOnCommandRENAME;
152 property ONCommandSUBSCRIBE: TCommandEvent read fONCommandSUBSCRIBE write
153 fONCommandSUBSCRIBE;
154 property ONCommandUNSUBSCRIBE: TCommandEvent read fONCommandUNSUBSCRIBE write
155 fONCommandUNSUBSCRIBE;
156 property ONCommandLIST: TCommandEvent read fONCommandLIST write
157 fONCommandLIST;
158 property OnCommandLSUB: TCommandEvent read fOnCommandLSUB write
159 fOnCommandLSUB;
160 property ONCommandSTATUS: TCommandEvent read fONCommandSTATUS write
161 fONCommandSTATUS;
162 property OnCommandAPPEND: TCommandEvent read fOnCommandAPPEND write
163 fOnCommandAPPEND;
164 property ONCommandCHECK: TCommandEvent read fONCommandCHECK write
165 fONCommandCHECK;
166 property OnCommandCLOSE: TCommandEvent read fOnCommandCLOSE write
167 fOnCommandCLOSE;
168 property ONCommandEXPUNGE: TCommandEvent read fONCommandEXPUNGE write
169 fONCommandEXPUNGE;
170 property OnCommandSEARCH: TCommandEvent read fOnCommandSEARCH write
171 fOnCommandSEARCH;
172 property ONCommandFETCH: TCommandEvent read fONCommandFETCH write
173 fONCommandFETCH;
174 property OnCommandSTORE: TCommandEvent read fOnCommandSTORE write
175 fOnCommandSTORE;
176 property OnCommandCOPY: TCommandEvent read fOnCommandCOPY write
177 fOnCommandCOPY;
178 property ONCommandUID: TCommandEvent read fONCommandUID write fONCommandUID;
179 property OnCommandX: TCommandEvent read fOnCommandX write fOnCommandX;
180 property OnCommandError: TCommandEvent read fOnCommandError write
181 fOnCommandError;
182 property DefaultPort default IdPORT_IMAP4;
183 end;
185 PIdIMAP4Server=^TIdIMAP4Server;
186 // constructor Create(AOwner: TComponent); override;
187 function NewIdIMAP4Server(AOwner:PControl):PIdIMAP4Server;
191 implementation
193 uses KOL,
194 SysUtils;
196 const
197 cCAPABILITY = 1;
198 cNOOP = 2;
199 cLOGOUT = 3;
200 cAUTHENTICATE = 4;
201 cLOGIN = 5;
202 cSELECT = 6;
203 cEXAMINE = 7;
204 cCREATE = 8;
205 cDELETE = 9;
206 cRENAME = 10;
207 cSUBSCRIBE = 11;
208 cUNSUBSCRIBE = 12;
209 cLIST = 13;
210 cLSUB = 14;
211 cSTATUS = 15;
212 cAPPEND = 16;
213 cCHECK = 17;
214 cCLOSE = 18;
215 cEXPUNGE = 19;
216 cSEARCH = 20;
217 cFETCH = 21;
218 cSTORE = 22;
219 cCOPY = 23;
220 cUID = 24;
221 cXCmd = 25;
223 { constructor TIdIMAP4Server.Create(AOwner: TComponent);
226 function NewIdIMAP4Server(AOwner:PControl):PIdIMAP4Server;
227 begin
228 // inherited;
229 New( Result, Create );
230 with Result^ do
231 DefaultPort := IdPORT_IMAP4;
232 end;
234 function TIdIMAP4Server.DoExecute(Thread: TIdPeerThread): Boolean;
236 RcvdStr,
237 ArgStr,
238 sTag,
239 sCmd: string;
240 cmdNum: Integer;
241 Handled: Boolean;
243 function GetFirstTokenDeleteFromArg(var s1: string;
244 const sDelim: string): string;
246 nPos: Integer;
247 begin
248 nPos := IndyPos(sDelim, s1);
249 if nPos = 0 then
250 begin
251 nPos := Length(s1) + 1;
252 end;
253 Result := Copy(s1, 1, nPos - 1);
254 Delete(s1, 1, nPos);
255 S1 := Trim(S1);
256 end;
258 begin
259 result := true;
260 while Thread.Connection.Connected do
261 begin
262 Handled := False;
263 RcvdStr := Thread.Connection.ReadLn;
264 ArgStr := RcvdStr;
265 sTag := UpperCase(GetFirstTokenDeleteFromArg(ArgStr, CHAR32));
266 sCmd := UpperCase(GetFirstTokenDeleteFromArg(ArgStr, CHAR32));
267 CmdNum := Succ(PosInStrArray(Uppercase(sCmd), IMAPCommands));
268 case CmdNum of
269 cCAPABILITY: DoCommandCAPABILITY(Thread, sTag, ArgStr, Handled);
270 cNOOP: DoCommandNOOP(Thread, sTag, ArgStr, Handled);
271 cLOGOUT: DoCommandLOGOUT(Thread, sTag, ArgStr, Handled);
272 cAUTHENTICATE: DoCommandAUTHENTICATE(Thread, sTag, ArgStr, Handled);
273 cLOGIN: DoCommandLOGIN(Thread, sTag, ArgStr, Handled);
274 cSELECT: DoCommandSELECT(Thread, sTag, ArgStr, Handled);
275 cEXAMINE: DoCommandEXAMINE(Thread, sTag, ArgStr, Handled);
276 cCREATE: DoCommandCREATE(Thread, sTag, ArgStr, Handled);
277 cDELETE: DoCommandDELETE(Thread, sTag, ArgStr, Handled);
278 cRENAME: DoCommandRENAME(Thread, sTag, ArgStr, Handled);
279 cSUBSCRIBE: DoCommandSUBSCRIBE(Thread, sTag, ArgStr, Handled);
280 cUNSUBSCRIBE: DoCommandUNSUBSCRIBE(Thread, sTag, ArgStr, Handled);
281 cLIST: DoCommandLIST(Thread, sTag, ArgStr, Handled);
282 cLSUB: DoCommandLSUB(Thread, sTag, ArgStr, Handled);
283 cSTATUS: DoCommandSTATUS(Thread, sTag, ArgStr, Handled);
284 cAPPEND: DoCommandAPPEND(Thread, sTag, ArgStr, Handled);
285 cCHECK: DoCommandCHECK(Thread, sTag, ArgStr, Handled);
286 cCLOSE: DoCommandCLOSE(Thread, sTag, ArgStr, Handled);
287 cEXPUNGE: DoCommandEXPUNGE(Thread, sTag, ArgStr, Handled);
288 cSEARCH: DoCommandSEARCH(Thread, sTag, ArgStr, Handled);
289 cFETCH: DoCommandFETCH(Thread, sTag, ArgStr, Handled);
290 cSTORE: DoCommandSTORE(Thread, sTag, ArgStr, Handled);
291 cCOPY: DoCommandCOPY(Thread, sTag, ArgStr, Handled);
292 cUID: DoCommandUID(Thread, sTag, ArgStr, Handled);
293 else
294 begin
295 if (Length(SCmd) > 0) and (UpCase(SCmd[1]) = 'X') then
296 begin
297 DoCommandX(Thread, sTag, ArgStr, Handled);
299 else
300 begin
301 DoCommandError(Thread, sTag, ArgStr, Handled);
302 end;
303 end;
304 end;
305 end;
306 end;
308 procedure TIdIMAP4Server.DoCommandCapability(Thread: TIdPeerThread; const Tag,
309 CmdStr: string;
310 var Handled: Boolean);
311 begin
312 if Assigned(fOnCommandCAPABILITY) then
313 begin
314 OnCommandCAPABILITY(Thread, Tag, CmdStr, Handled);
315 end;
316 end;
318 procedure TIdIMAP4Server.DoCommandNOOP(Thread: TIdPeerThread;
319 const Tag, CmdStr: string; var Handled: Boolean);
320 begin
321 if Assigned(fONCommandNOOP) then
322 begin
323 OnCommandNOOP(Thread, Tag, CmdStr, Handled);
324 end;
325 end;
327 procedure TIdIMAP4Server.DoCommandLOGOUT(Thread: TIdPeerThread;
328 const Tag, CmdStr: string; var Handled: Boolean);
329 begin
330 if Assigned(fONCommandLOGOUT) then
331 begin
332 OnCommandLOGOUT(Thread, Tag, CmdStr, Handled);
333 end;
334 end;
336 procedure TIdIMAP4Server.DoCommandAUTHENTICATE(Thread: TIdPeerThread;
337 const Tag, CmdStr: string; var Handled: Boolean);
338 begin
339 if Assigned(fONCommandAUTHENTICATE) then
340 begin
341 OnCommandAUTHENTICATE(Thread, Tag, CmdStr, Handled);
342 end;
343 end;
345 procedure TIdIMAP4Server.DoCommandLOGIN(Thread: TIdPeerThread;
346 const Tag, CmdStr: string; var Handled: Boolean);
347 begin
348 if Assigned(fONCommandLOGIN) then
349 begin
350 OnCommandLOGIN(Thread, Tag, CmdStr, Handled);
351 end;
352 end;
354 procedure TIdIMAP4Server.DoCommandSELECT(Thread: TIdPeerThread;
355 const Tag, CmdStr: string; var Handled: Boolean);
356 begin
357 if Assigned(fONCommandSELECT) then
358 begin
359 OnCommandSELECT(Thread, Tag, CmdStr, Handled);
360 end;
361 end;
363 procedure TIdIMAP4Server.DoCommandEXAMINE(Thread: TIdPeerThread;
364 const Tag, CmdStr: string; var Handled: Boolean);
365 begin
366 if Assigned(fONCommandEXAMINE) then
367 begin
368 OnCommandEXAMINE(Thread, Tag, CmdStr, Handled);
369 end;
370 end;
372 procedure TIdIMAP4Server.DoCommandCREATE(Thread: TIdPeerThread;
373 const Tag, CmdStr: string; var Handled: Boolean);
374 begin
375 if Assigned(fONCommandCREATE) then
376 begin
377 OnCommandCREATE(Thread, Tag, CmdStr, Handled);
378 end;
379 end;
381 procedure TIdIMAP4Server.DoCommandDELETE(Thread: TIdPeerThread;
382 const Tag, CmdStr: string; var Handled: Boolean);
383 begin
384 if Assigned(fONCommandDELETE) then
385 begin
386 OnCommandDELETE(Thread, Tag, CmdStr, Handled);
387 end;
388 end;
390 procedure TIdIMAP4Server.DoCommandRENAME(Thread: TIdPeerThread;
391 const Tag, CmdStr: string; var Handled: Boolean);
392 begin
393 if Assigned(fONCommandRENAME) then
394 begin
395 OnCommandRENAME(Thread, Tag, CmdStr, Handled);
396 end;
397 end;
399 procedure TIdIMAP4Server.DoCommandSUBSCRIBE(Thread: TIdPeerThread;
400 const Tag, CmdStr: string; var Handled: Boolean);
401 begin
402 if Assigned(fONCommandSUBSCRIBE) then
403 begin
404 OnCommandSUBSCRIBE(Thread, Tag, CmdStr, Handled);
405 end;
406 end;
408 procedure TIdIMAP4Server.DoCommandUNSUBSCRIBE(Thread: TIdPeerThread;
409 const Tag, CmdStr: string; var Handled: Boolean);
410 begin
411 if Assigned(fONCommandUNSUBSCRIBE) then
412 begin
413 OnCommandUNSUBSCRIBE(Thread, Tag, CmdStr, Handled);
414 end;
415 end;
417 procedure TIdIMAP4Server.DoCommandLIST(Thread: TIdPeerThread;
418 const Tag, CmdStr: string; var Handled: Boolean);
419 begin
420 if Assigned(fONCommandLIST) then
421 begin
422 OnCommandLIST(Thread, Tag, CmdStr, Handled);
423 end;
424 end;
426 procedure TIdIMAP4Server.DoCommandLSUB(Thread: TIdPeerThread;
427 const Tag, CmdStr: string; var Handled: Boolean);
428 begin
429 if Assigned(fONCommandLSUB) then
430 begin
431 OnCommandLSUB(Thread, Tag, CmdStr, Handled);
432 end;
433 end;
435 procedure TIdIMAP4Server.DoCommandSTATUS(Thread: TIdPeerThread;
436 const Tag, CmdStr: string; var Handled: Boolean);
437 begin
438 if Assigned(fONCommandSTATUS) then
439 begin
440 OnCommandSTATUS(Thread, Tag, CmdStr, Handled);
441 end;
442 end;
444 procedure TIdIMAP4Server.DoCommandAPPEND(Thread: TIdPeerThread;
445 const Tag, CmdStr: string; var Handled: Boolean);
446 begin
447 if Assigned(fONCommandAPPEND) then
448 begin
449 OnCommandAPPEND(Thread, Tag, CmdStr, Handled);
450 end;
451 end;
453 procedure TIdIMAP4Server.DoCommandCHECK(Thread: TIdPeerThread;
454 const Tag, CmdStr: string; var Handled: Boolean);
455 begin
456 if Assigned(fONCommandCHECK) then
457 begin
458 OnCommandCHECK(Thread, Tag, CmdStr, Handled);
459 end;
460 end;
462 procedure TIdIMAP4Server.DoCommandCLOSE(Thread: TIdPeerThread;
463 const Tag, CmdStr: string; var Handled: Boolean);
464 begin
465 if Assigned(fONCommandCLOSE) then
466 begin
467 OnCommandCLOSE(Thread, Tag, CmdStr, Handled);
468 end;
469 end;
471 procedure TIdIMAP4Server.DoCommandEXPUNGE(Thread: TIdPeerThread;
472 const Tag, CmdStr: string; var Handled: Boolean);
473 begin
474 if Assigned(fONCommandEXPUNGE) then
475 begin
476 OnCommandEXPUNGE(Thread, Tag, CmdStr, Handled);
477 end;
478 end;
480 procedure TIdIMAP4Server.DoCommandSEARCH(Thread: TIdPeerThread;
481 const Tag, CmdStr: string; var Handled: Boolean);
482 begin
483 if Assigned(fONCommandSEARCH) then
484 begin
485 OnCommandSEARCH(Thread, Tag, CmdStr, Handled);
486 end;
487 end;
489 procedure TIdIMAP4Server.DoCommandFETCH(Thread: TIdPeerThread;
490 const Tag, CmdStr: string; var Handled: Boolean);
491 begin
492 if Assigned(fONCommandFETCH) then
493 begin
494 OnCommandFETCH(Thread, Tag, CmdStr, Handled);
495 end;
496 end;
498 procedure TIdIMAP4Server.DoCommandSTORE(Thread: TIdPeerThread;
499 const Tag, CmdStr: string; var Handled: Boolean);
500 begin
501 if Assigned(fONCommandSTORE) then
502 begin
503 OnCommandSTORE(Thread, Tag, CmdStr, Handled);
504 end;
505 end;
507 procedure TIdIMAP4Server.DoCommandCOPY(Thread: TIdPeerThread;
508 const Tag, CmdStr: string; var Handled: Boolean);
509 begin
510 if Assigned(fONCommandCOPY) then
511 begin
512 OnCommandCOPY(Thread, Tag, CmdStr, Handled);
513 end;
514 end;
516 procedure TIdIMAP4Server.DoCommandUID(Thread: TIdPeerThread; const Tag, CmdStr:
517 string;
518 var Handled: Boolean);
519 begin
520 if Assigned(fONCommandUID) then
521 begin
522 OnCommandUID(Thread, Tag, CmdStr, Handled);
523 end;
524 end;
526 procedure TIdIMAP4Server.DoCommandX(Thread: TIdPeerThread; const Tag, CmdStr:
527 string;
528 var Handled: Boolean);
529 begin
530 if Assigned(fONCommandX) then
531 begin
532 OnCommandX(Thread, Tag, CmdStr, Handled);
533 end;
534 end;
536 procedure TIdIMAP4Server.DoCommandError(Thread: TIdPeerThread; const Tag,
537 CmdStr: string;
538 var Handled: Boolean);
539 begin
540 if Assigned(fONCommandError) then
541 begin
542 OnCommandError(Thread, Tag, CmdStr, Handled);
543 end;
544 end;
546 end.