/[pkg-mixmaster]/branches/mixmaster_2_9_STABLE/Mix/Src/mail.c
ViewVC logotype

Contents of /branches/mixmaster_2_9_STABLE/Mix/Src/mail.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 306 - (hide annotations) (download)
Fri Oct 4 23:49:17 2002 UTC (10 years, 7 months ago) by rabbi
File MIME type: text/plain
File size: 18498 byte(s)
I've back-ported most of the important changes since 2.9b38 to the -STABLE branch.
I've only applied the changes I think are unlikely to break anything. This needs to be tested (and the diff'd reviewed) before we proceed.

If anyone feels I've left out anything that should really be in 2.9, please speak up.
1 rabbi 1 /* Mixmaster version 3 -- (C) 1999 Anonymizer Inc.
2    
3     Mixmaster may be redistributed and modified under certain conditions.
4     This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5     ANY KIND, either express or implied. See the file COPYRIGHT for
6     details.
7    
8     Socket-based mail transport services
9 rabbi 306 $Id: mail.c,v 1.7.2.2 2002/10/04 23:49:16 rabbi Exp $ */
10 rabbi 1
11    
12     #include "mix3.h"
13     #include <stdio.h>
14     #include <stdlib.h>
15     #include <string.h>
16    
17     #if defined(UNIX) && defined(USE_SOCK)
18     #include <unistd.h>
19     #include <sys/types.h>
20     #include <sys/socket.h>
21     #include <netinet/in.h>
22     #include <arpa/inet.h>
23     #include <netdb.h>
24 rabbi 306 #endif
25 rabbi 1 #include <fcntl.h>
26 rabbi 306 #include <time.h>
27     #include <sys/stat.h>
28     #include <errno.h>
29 rabbi 1
30 rabbi 306
31 rabbi 1 int sendinfofile(char *name, char *logname, BUFFER *address, BUFFER *header)
32     {
33 weaselp 122 FILE *f = NULL, *log = NULL;
34 rabbi 1 BUFFER *msg, *addr;
35     char line[LINELEN];
36     int ret = -1;
37    
38     if (bufeq(address, ANONNAME))
39     return (0); /* don't reply to our own anon messages */
40     f = mix_openfile(name, "r");
41     if (f == NULL)
42     return (-1);
43    
44     addr = buf_new();
45     rfc822_addr(address, addr);
46     if (addr->length == 0)
47     buf_set(addr, address), buf_nl(addr);
48    
49     if (logname != NULL) {
50     if ((log = mix_openfile(logname, "r+")) != NULL) {
51     /* log recipients to prevent mail loop */
52     while (fgets(line, sizeof(line), log) != NULL)
53     if (strieq(line, addr->data))
54     goto end;
55     } else if ((log = mix_openfile(logname, "w")) == NULL) {
56     errlog(ERRORMSG, "Can't create %s.\n", logname);
57     ret = -1;
58     goto end;
59     }
60     fprintf(log, "%s", addr->data);
61     }
62     msg = buf_new();
63     if (header)
64     buf_cat(msg, header), buf_nl(msg);
65     while (fgets(line, sizeof(line), f) != NULL) {
66     if (streq(line, "DESTINATION-BLOCK\n"))
67     buf_appendf(msg, "destination-block %b", addr);
68     else
69     buf_appends(msg, line);
70     }
71     ret = sendmail(msg, REMAILERNAME, address);
72     buf_free(msg);
73     end:
74 weaselp 122 if (f)
75     fclose(f);
76 rabbi 1 if (log)
77     fclose(log);
78     buf_free(addr);
79     return (ret);
80     }
81    
82     int smtpsend(BUFFER *head, BUFFER *message, char *from);
83    
84 weaselp 116
85     int sendmail_loop(BUFFER *message, char *from, BUFFER *address)
86     {
87     BUFFER *msg;
88     int err;
89    
90     msg = buf_new();
91     buf_appendf(msg, "X-Loop: %s\n", REMAILERADDR);
92     buf_cat(msg, message);
93     err = sendmail(msg, from, address);
94     buf_free(msg);
95    
96     return(err);
97 weaselp 121 }
98 weaselp 116
99 rabbi 1 int sendmail(BUFFER *message, char *from, BUFFER *address)
100     {
101     /* returns: 0: ok 1: problem, try again -1: failed */
102    
103     BUFFER *head, *block;
104     FILE *f;
105     int err = -1;
106    
107     head = buf_new();
108    
109     block = readdestblk( );
110     if ( !block ) block = buf_new( );
111    
112     if (address != NULL &&
113     (address->length == 0 || doblock(address, block, 1) == -1))
114     goto end;
115    
116     if (from != NULL) {
117     buf_setf(head, "From: %s", from);
118     hdr_encode(head, 255);
119     buf_nl(head);
120     }
121     if (address != NULL)
122     buf_appendf(head, "To: %b\n", address);
123    
124     buf_rewind(message);
125    
126     if (SMTPRELAY[0])
127     err = smtpsend(head, message, from);
128     else if (strieq(SENDMAIL, "outfile")) {
129     char path[PATHMAX];
130     FILE *f = NULL;
131 rabbi 306 #ifdef SHORTNAMES
132 rabbi 1 int i;
133     for (i = 0; i < 10000; i++) {
134 rabbi 11 sprintf(path, "%s%cout%i.txt", POOLDIR, DIRSEP, i);
135 rabbi 1 f = fopen(path, "r");
136     if (f)
137     fclose(f);
138     else
139     break;
140     }
141     f = fopen(path, "w");
142 rabbi 306 #else /* SHORTNAMES */
143     static unsigned long namecounter = 0;
144     struct stat statbuf;
145     int count;
146     char hostname[64];
147    
148     hostname[0] = '\0';
149     gethostname(hostname, 63);
150     hostname[63] = '\0';
151    
152     /* Step 2: Stat the file. Wait for ENOENT as a response. */
153     for (count = 0;; count++) {
154     snprintf(path, PATHMAX, "%s%cout.%lu.%u_%lu.%s,S=%lu.txt",
155     POOLDIR, DIRSEP, time(NULL), getpid(), namecounter++, hostname, head->length + message->length);
156     path[PATHMAX-1] = '\0';
157    
158     if (stat(path, &statbuf) == 0)
159     errno = EEXIST;
160     else if (errno == ENOENT) { /* create the file (at least try) */
161     f = fopen(path, "w");
162     if (f != NULL)
163     break; /* we managed to open the file */
164     }
165     if (count > 5)
166     break; /* Too many retries - give up */
167     #ifdef WIN32
168     Sleep(2000); /* sleep and retry */
169     #else
170     sleep(2); /* sleep and retry */
171     #endif
172     }
173     #endif /* SHORTNAMES */
174 rabbi 1 if (f != NULL) {
175     err = buf_write(head, f);
176     err = buf_write(message, f);
177     fclose(f);
178     } else
179     errlog(ERRORMSG, "Can't create %s!\n", path);
180     } else {
181     if (SENDANONMAIL[0] != '\0' && (from == NULL || streq(from, ANONNAME)))
182     f = openpipe(SENDANONMAIL);
183     else
184     f = openpipe(SENDMAIL);
185     if (f != NULL) {
186     err = buf_write(head, f);
187     err = buf_write(message, f);
188     closepipe(f);
189     }
190     }
191     if (err != 0)
192     err = 1; /* error while sending, retry later */
193     end:
194     buf_free(block);
195     buf_free(head);
196     return (err);
197     }
198    
199     /* socket communication **********************************************/
200    
201     #ifdef USE_SOCK
202     #ifdef WIN32
203     WSADATA w;
204    
205     int sock_init()
206     {
207     if (WSAStartup(MAKEWORD(2, 0), &w) != 0) {
208     errlog(ERRORMSG, "Unable to initialize WINSOCK.\n");
209     return 0;
210     }
211     return 1;
212     }
213    
214     void sock_exit(void)
215     {
216     WSACleanup();
217     }
218     #endif
219    
220     SOCKET opensocket(char *hostname, int port)
221     {
222     struct hostent *hp;
223     struct sockaddr_in server;
224     SOCKET s;
225    
226     if ((hp = gethostbyname(hostname)) == NULL)
227     return (INVALID_SOCKET);
228    
229     memset((char *) &server, 0, sizeof(server));
230     server.sin_family = AF_INET;
231     server.sin_addr.s_addr = *(unsigned long *) hp->h_addr;
232     server.sin_port = htons((unsigned short) port);
233    
234     s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
235     if (s != INVALID_SOCKET)
236     if (connect(s, (struct sockaddr *) &server, sizeof(server)) < 0) {
237     closesocket(s);
238     return (INVALID_SOCKET);
239     }
240     return (s);
241     }
242    
243     #ifndef WIN32
244     int closesocket(SOCKET s)
245     {
246     return (close(s));
247     }
248     #endif
249    
250     int sock_getline(SOCKET s, BUFFER *line)
251     {
252     char c;
253     int ok;
254    
255     buf_clear(line);
256     while ((ok = recv(s, &c, 1, 0)) > 0) {
257     if (c == '\n')
258     break;
259     if (c != '\r')
260     buf_appendc(line, c);
261     }
262     if (ok <= 0)
263     return (-1);
264     if (line->length == 0)
265     return (1);
266     return (0);
267     }
268    
269     int sock_cat(SOCKET s, BUFFER *b)
270     {
271     int p = 0, n;
272    
273     do {
274     n = send(s, b->data, b->length, 0);
275     if (n < 0)
276     return (-1);
277     p += n;
278     } while (p < b->length);
279     return (0);
280     }
281     #else
282     SOCKET opensocket(char *hostname, int port)
283     {
284     return (INVALID_SOCKET);
285     }
286    
287     int closesocket(SOCKET s)
288     {
289     return (INVALID_SOCKET);
290     }
291    
292     int sock_getline(SOCKET s, BUFFER *line)
293     {
294     return (-1);
295     }
296    
297     int sock_cat(SOCKET s, BUFFER *b)
298     {
299     return (-1);
300     }
301     #endif
302    
303     /* send messages by SMTP ************************************************/
304    
305 rabbi 306 static int sock_getsmtp(SOCKET s, BUFFER *response)
306 rabbi 1 {
307     int ret;
308 rabbi 306 BUFFER *line;
309     line = buf_new();
310 rabbi 1
311 rabbi 306 buf_clear(response);
312     do {
313 rabbi 1 ret = sock_getline(s, line);
314 rabbi 306 buf_cat(response, line);
315     } while (line->length >= 4 && line->data[3] == '-');
316     buf_free(line);
317 rabbi 1 return (ret);
318     }
319    
320     SOCKET smtp_open(void)
321     {
322     int s = INVALID_SOCKET;
323 rabbi 306 int esmtp = 0;
324 rabbi 1 BUFFER *line;
325    
326     #ifdef USE_SOCK
327     if (SMTPRELAY[0] != '\0')
328     s = opensocket(SMTPRELAY, 25);
329     if (s != INVALID_SOCKET) {
330     line = buf_new();
331     sock_getsmtp(s, line);
332 rabbi 306 if (bufifind(line, "ESMTP"))
333     esmtp = 1;
334 rabbi 1 if (line->data[0] != '2') {
335     errlog(ERRORMSG, "SMTP relay not ready. %b\n", line);
336     closesocket(s);
337     s = INVALID_SOCKET;
338     } else {
339     errlog(DEBUGINFO, "Opening SMTP connection.\n");
340 rabbi 306 if (esmtp)
341     buf_sets(line, "EHLO ");
342     else
343     buf_sets(line, "HELO ");
344 rabbi 1 if (HELONAME[0])
345     buf_appends(line, HELONAME);
346     else if (strchr(ENVFROM, '@'))
347     buf_appends(line, strchr(ENVFROM, '@') + 1);
348     else {
349     struct sockaddr_in sa;
350     int len = sizeof(sa);
351     struct hostent *hp;
352    
353     if (getsockname(s, (struct sockaddr *) &sa, &len) == 0 &&
354     (hp = gethostbyaddr((char *) &sa.sin_addr, sizeof(sa.sin_addr),
355     AF_INET)) != NULL)
356     buf_appends(line, (char *) hp->h_name);
357     else if (strchr(REMAILERADDR, '@'))
358     buf_appends(line, strchr(REMAILERADDR, '@') + 1);
359     else
360     buf_appends(line, SHORTNAME);
361     }
362 rabbi 306 buf_chop(line);
363 rabbi 1 buf_appends(line, "\r\n");
364     sock_cat(s, line);
365     sock_getsmtp(s, line);
366     if (line->data[0] != '2') {
367     errlog(ERRORMSG, "SMTP relay refuses HELO: %b\n", line);
368     closesocket(s);
369     s = INVALID_SOCKET;
370 rabbi 306 } else if (SMTPUSERNAME[0] && esmtp && bufifind(line, "AUTH") && bufifind(line, "LOGIN")) {
371     buf_sets(line, "AUTH LOGIN\r\n");
372     sock_cat(s, line);
373     sock_getsmtp(s, line);
374     if (!bufleft(line, "334")) {
375     errlog(ERRORMSG, "SMTP AUTH fails: %b\n", line);
376     goto err;
377     }
378     buf_sets(line, SMTPUSERNAME);
379     encode(line, 0);
380     buf_appends(line, "\r\n");
381     sock_cat(s, line);
382     sock_getsmtp(s, line);
383     if (!bufleft(line, "334")) {
384     errlog(ERRORMSG, "SMTP username rejected: %b\n", line);
385     goto err;
386     }
387     buf_sets(line, SMTPPASSWORD);
388     encode(line, 0);
389     buf_appends(line, "\r\n");
390     sock_cat(s, line);
391     sock_getsmtp(s, line);
392     if (!bufleft(line, "235"))
393     errlog(ERRORMSG, "SMTP authentication failed: %b\n", line);
394 rabbi 1 }
395     }
396 rabbi 306 err:
397 rabbi 1 buf_free(line);
398     }
399     #endif
400     return (s);
401     }
402    
403     int smtp_close(SOCKET s)
404     {
405     BUFFER *line;
406     int ret = -1;
407    
408     #ifdef USE_SOCK
409     line = buf_new();
410     buf_sets(line, "QUIT\r\n");
411     sock_cat(s, line);
412     if (sock_getsmtp(s, line) == 0 && line->data[0] == '2') {
413     errlog(DEBUGINFO, "Closing SMTP connection.\n");
414     ret = 0;
415     } else
416     errlog(WARNING, "SMTP quit failed: %b\n", line);
417     closesocket(s);
418     buf_free(line);
419     #endif
420     return (ret);
421     }
422    
423     int smtp_send(SOCKET relay, BUFFER *head, BUFFER *message, char *from)
424     {
425     BUFFER *rcpt, *line, *field, *content;
426     int ret = -1;
427    
428     #ifdef USE_SOCK
429     line = buf_new();
430     field = buf_new();
431     content = buf_new();
432     rcpt = buf_new();
433    
434     while (buf_getheader(head, field, content) == 0)
435     if (bufieq(field, "to"))
436 rabbi 29 #ifdef BROKEN_MTA
437     if (!bufifind(rcpt, content->data))
438     /* Do not add the same recipient twice.
439     Needed for brain-dead MTAs. */
440 rabbi 306 #endif /* BROKEN_MTA */
441 rabbi 29 rfc822_addr(content, rcpt);
442 rabbi 1 buf_rewind(head);
443    
444 weaselp 116 while (buf_isheader(message) && buf_getheader(message, field, content) == 0) {
445 rabbi 1 if (bufieq(field, "to") || bufieq(field, "cc") || bufieq(field, "bcc")) {
446 rabbi 29 #ifdef BROKEN_MTA
447     if (!bufifind(rcpt, content->data))
448     /* Do not add the same recipient twice.
449     Needed for brain-dead MTAs. */
450 rabbi 306 #endif /* BROKEN_MTA */
451 rabbi 29 rfc822_addr(content, rcpt);
452 rabbi 1 }
453     if (!bufieq(field, "bcc"))
454     buf_appendheader(head, field, content);
455     }
456     buf_nl(head);
457    
458     buf_clear(content);
459     if (from) {
460     buf_sets(line, from);
461     rfc822_addr(line, content);
462     buf_chop(content);
463     }
464     if (bufieq(content, REMAILERADDR) || bufieq(content, ANONADDR))
465     buf_clear(content);
466     if (content->length == 0)
467     buf_sets(content, ENVFROM[0] ? ENVFROM : ANONADDR);
468    
469     buf_setf(line, "MAIL FROM:<%b>\r\n", content);
470     sock_cat(relay, line);
471     sock_getsmtp(relay, line);
472     if (!line->data[0] == '2') {
473     errlog(ERRORMSG, "SMTP relay does not accept mail: %b\n", line);
474     goto end;
475     }
476     while (buf_getline(rcpt, content) == 0) {
477     buf_setf(line, "RCPT TO:<%b>\r\n", content);
478     sock_cat(relay, line);
479     sock_getsmtp(relay, line);
480     if (bufleft(line, "421")) {
481     errlog(ERRORMSG, "SMTP relay error: %b\n", line);
482     goto end;
483     }
484 rabbi 306 if (bufleft(line, "530")) {
485     errlog(ERRORMSG, "SMTP authentication required: %b\n", line);
486     goto end;
487     }
488 rabbi 1 }
489    
490     buf_sets(line, "DATA\r\n");
491     sock_cat(relay, line);
492     sock_getsmtp(relay, line);
493     if (!bufleft(line, "354")) {
494     errlog(WARNING, "SMTP relay does not accept message: %b\n", line);
495     goto end;
496     }
497     while (buf_getline(head, line) >= 0) {
498     buf_appends(line, "\r\n");
499     if (bufleft(line, ".")) {
500     buf_setf(content, ".%b", line);
501     buf_move(line, content);
502     }
503     sock_cat(relay, line);
504     }
505     while (buf_getline(message, line) >= 0) {
506     buf_appends(line, "\r\n");
507     if (bufleft(line, ".")) {
508     buf_setf(content, ".%b", line);
509     buf_move(line, content);
510     }
511     sock_cat(relay, line);
512     }
513     buf_sets(line, ".\r\n");
514     sock_cat(relay, line);
515     sock_getsmtp(relay, line);
516     if (bufleft(line, "2"))
517     ret = 0;
518     else
519     errlog(WARNING, "SMTP relay will not send message: %b\n", line);
520     end:
521     buf_free(line);
522     buf_free(field);
523     buf_free(content);
524     buf_free(rcpt);
525     #endif
526     return (ret);
527     }
528    
529     static SOCKET sendmail_state = INVALID_SOCKET;
530    
531     void sendmail_begin(void)
532     {
533     /* begin mail sending session */
534     if (sendmail_state == INVALID_SOCKET)
535     sendmail_state = smtp_open();
536     }
537     void sendmail_end(void)
538     {
539     /* end mail sending session */
540     if (sendmail_state != INVALID_SOCKET) {
541     smtp_close(sendmail_state);
542     sendmail_state = INVALID_SOCKET;
543     }
544     }
545    
546     int smtpsend(BUFFER *head, BUFFER *message, char *from)
547     {
548     SOCKET s;
549     int ret = -1;
550    
551     if (sendmail_state != INVALID_SOCKET)
552     ret = smtp_send(sendmail_state, head, message, from);
553     else {
554     s = smtp_open();
555     if (s != INVALID_SOCKET) {
556     ret = smtp_send(s, head, message, from);
557     smtp_close(s);
558     }
559     }
560     return (ret);
561     }
562    
563     /* retrieve mail with POP3 **********************************************/
564     #ifdef USE_SOCK
565     int pop3_close(SOCKET s);
566    
567     #define POP3_ANY 0
568     #define POP3_APOP 1
569     #define POP3_PASS 2
570    
571     SOCKET pop3_open(char *user, char *host, char *pass, int auth)
572     {
573     SOCKET server = INVALID_SOCKET;
574     BUFFER *line;
575     int authenticated = 0;
576 rabbi 246 char md[33];
577     int c;
578 rabbi 1
579     line = buf_new();
580     server = opensocket(host, 110);
581     if (server == INVALID_SOCKET)
582     errlog(NOTICE, "Can't connect to POP3 server %s.\n", host);
583     else {
584     sock_getline(server, line);
585     if (!bufleft(line, "+")) {
586     errlog(WARNING, "No POP3 service at %s.\n", host);
587     closesocket(server);
588 rabbi 11 server = INVALID_SOCKET;
589 rabbi 1 }
590     }
591     if (server != INVALID_SOCKET) {
592     errlog(DEBUGINFO, "Opening POP3 connection to %s.\n", host);
593     do
594     c = buf_getc(line);
595     while (c != '<' && c != -1);
596     while (c != '>' && c != -1) {
597     buf_appendc(line, c);
598     c = buf_getc(line);
599     }
600     if (c == '>' && (auth == POP3_ANY || auth == POP3_APOP)) {
601     buf_appendc(line, c);
602     buf_appends(line, pass);
603     digest_md5(line, line);
604     id_encode(line->data, md);
605     buf_setf(line, "APOP %s %s\r\n", user, md);
606     sock_cat(server, line);
607     sock_getline(server, line);
608     if (bufleft(line, "+"))
609     authenticated = 1;
610     else {
611     errlog(auth == POP3_APOP ? ERRORMSG : NOTICE,
612     "POP3 APOP auth at %s failed: %b\n", host, line);
613     buf_sets(line, "QUIT\r\n");
614     sock_cat(server, line);
615     closesocket(server);
616     server = pop3_open(user, host, pass, POP3_PASS);
617     goto end;
618     }
619     }
620     if (!authenticated) {
621     buf_setf(line, "USER %s\r\n", user);
622     sock_cat(server, line);
623     sock_getline(server, line);
624     if (!bufleft(line, "+"))
625     errlog(ERRORMSG, "POP3 USER command at %s failed: %b\n", host, line);
626     else {
627     buf_setf(line, "PASS %s\r\n", pass);
628     sock_cat(server, line);
629     sock_getline(server, line);
630     if (bufleft(line, "+"))
631     authenticated = 1;
632     else
633     errlog(ERRORMSG, "POP3 auth at %s failed: %b\n", host, line);
634     }
635     }
636     if (!authenticated) {
637     pop3_close(server);
638 rabbi 11 closesocket(server);
639 rabbi 1 server = INVALID_SOCKET;
640     }
641     }
642     end:
643     buf_free(line);
644     return (server);
645     }
646    
647     int pop3_close(SOCKET s)
648     {
649     BUFFER *line;
650     int ret = -1;
651    
652     line = buf_new();
653     buf_sets(line, "QUIT\r\n");
654     sock_cat(s, line);
655     sock_getline(s, line);
656     if (bufleft(line, "+")) {
657     ret = 0;
658     errlog(DEBUGINFO, "Closing POP3 connection.\n");
659     } else
660     errlog(ERRORMSG, "POP3 QUIT failed:\n", line->data);
661     buf_free(line);
662     return (ret);
663     }
664    
665     int pop3_stat(SOCKET s)
666     {
667     BUFFER *line;
668     int val = -1;
669    
670     line = buf_new();
671     buf_sets(line, "STAT\r\n");
672     sock_cat(s, line);
673     sock_getline(s, line);
674     if (bufleft(line, "+"))
675     sscanf(line->data, "+%*s %d", &val);
676     buf_free(line);
677     return (val);
678     }
679    
680     int pop3_list(SOCKET s, int n)
681     {
682     BUFFER *line;
683     int val = -1;
684    
685     line = buf_new();
686     buf_setf(line, "LIST %d\r\n", n);
687     sock_cat(s, line);
688     sock_getline(s, line);
689     if (bufleft(line, "+"))
690     sscanf(line->data, "+%*s %d", &val);
691     buf_free(line);
692     return (val);
693     }
694    
695     int pop3_dele(SOCKET s, int n)
696     {
697     BUFFER *line;
698     int ret = 0;
699    
700     line = buf_new();
701     buf_setf(line, "DELE %d\r\n", n);
702     sock_cat(s, line);
703     sock_getline(s, line);
704     if (!bufleft(line, "+"))
705     ret = -1;
706     buf_free(line);
707     return (ret);
708     }
709    
710     int pop3_retr(SOCKET s, int n, BUFFER *msg)
711     {
712     BUFFER *line;
713     int ret = -1;
714    
715     line = buf_new();
716     buf_clear(msg);
717     buf_setf(line, "RETR %d\r\n", n);
718     sock_cat(s, line);
719     sock_getline(s, line);
720     if (bufleft(line, "+")) {
721     for (;;) {
722     if (sock_getline(s, line) == -1)
723     break;
724     if (bufeq(line, ".")) {
725     ret = 0;
726     break;
727     } else if (bufleft(line, ".")) {
728     buf_append(msg, line->data + 1, line->length - 1);
729     } else
730     buf_cat(msg, line);
731     buf_nl(msg);
732     }
733     }
734     buf_free(line);
735     return (ret);
736     }
737    
738     void pop3get(void)
739     {
740     FILE *f;
741     char cfg[LINELEN], user[LINELEN], host[LINELEN], pass[LINELEN], auth[5];
742     SOCKET server;
743     BUFFER *line, *msg;
744     int i = 0, num = 0;
745    
746     line = buf_new();
747     msg = buf_new();
748     f = mix_openfile(POP3CONF, "r");
749     if (f != NULL)
750     while (fgets(cfg, sizeof(cfg), f) != NULL) {
751 rabbi 306 if (cfg[0] == '#')
752     continue;
753 rabbi 1 if (strchr(cfg, '@'))
754     strchr(cfg, '@')[0] = ' ';
755     if (sscanf(cfg, "%127s %127s %127s %4s", user, host, pass, auth) < 3)
756     continue;
757     i = POP3_ANY;
758     if (strileft(auth, "apop"))
759     i = POP3_APOP;
760     if (strileft(auth, "pass"))
761     i = POP3_PASS;
762     server = pop3_open(user, host, pass, i);
763     if (server != INVALID_SOCKET) {
764     num = pop3_stat(server);
765     if (num < 0)
766     errlog(WARNING, "POP3 protocol error at %s.\n", host);
767     else if (num == 0)
768     errlog(DEBUGINFO, "No mail at %s.\n", host);
769     else
770     for (i = 1; i <= num; i++) {
771     if (POP3SIZELIMIT > 0 &&
772     pop3_list(server, i) > POP3SIZELIMIT * 1024) {
773     errlog(WARNING, "Over size message on %s.", host);
774     if (POP3DEL == 1)
775     pop3_dele(server, i);
776     } else {
777     if (pop3_retr(server, i, msg) == 0 &&
778     pool_add(msg, "inf") == 0)
779     pop3_dele(server, i);
780     else {
781     errlog(WARNING, "POP3 error while getting mail from %s.",
782     host);
783     closesocket(server);
784     goto end;
785     }
786     }
787     }
788     pop3_close(server);
789 rabbi 11 closesocket(server);
790 rabbi 1 }
791     }
792     end:
793 rabbi 11 if (f != NULL)
794     fclose(f);
795 rabbi 1 buf_free(line);
796     buf_free(msg);
797     }
798     #endif

  ViewVC Help
Powered by ViewVC 1.1.5