comparison src/pop3_in.c @ 10:26e34ae9a3e3

changed indention and line wrapping to a more consistent style
author meillo@marmaro.de
date Mon, 27 Oct 2008 16:23:10 +0100
parents 08114f7dcc23
children f671821d8222
comparison
equal deleted inserted replaced
9:31cc8a89cb74 10:26e34ae9a3e3
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by 4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or 5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version. 6 * (at your option) any later version.
7 * 7 *
8 * This program is distributed in the hope that it will be useful, 8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
34 #ifdef ENABLE_POP3 34 #ifdef ENABLE_POP3
35 35
36 /* experimental feature */ 36 /* experimental feature */
37 #define DO_WRITE_UIDL_EARLY 1 37 #define DO_WRITE_UIDL_EARLY 1
38 38
39 static 39 static gchar*
40 gchar *MD5String (char *string) 40 MD5String(char *string)
41 { 41 {
42 MD5_CTX context; 42 MD5_CTX context;
43 unsigned char digest[16]; 43 unsigned char digest[16];
44 char str_digest[33]; 44 char str_digest[33];
45 int i; 45 int i;
46 46
47 #ifdef USE_LIB_CRYPTO 47 #ifdef USE_LIB_CRYPTO
48 MD5(string, strlen(string), digest); 48 MD5(string, strlen(string), digest);
49 #else 49 #else
50 MD5Init(&context); 50 MD5Init(&context);
51 MD5Update(&context, string, strlen(string)); 51 MD5Update(&context, string, strlen(string));
52 MD5Final(digest, &context); 52 MD5Final(digest, &context);
53 #endif 53 #endif
54 for (i = 0; i < 16; i++) 54 for (i = 0; i < 16; i++)
55 sprintf(str_digest+2*i, "%02x", digest[i]); 55 sprintf(str_digest + 2 * i, "%02x", digest[i]);
56 56
57 return g_strdup(str_digest); 57 return g_strdup(str_digest);
58 } 58 }
59 59
60 static 60 static pop3_base*
61 pop3_base *create_pop3base(gint sock, guint flags) 61 create_pop3base(gint sock, guint flags)
62 { 62 {
63 gint dup_sock; 63 gint dup_sock;
64 64
65 pop3_base *popb = (pop3_base *)g_malloc(sizeof(pop3_base)); 65 pop3_base *popb = (pop3_base *) g_malloc(sizeof(pop3_base));
66 if(popb){ 66 if (popb) {
67 memset(popb, 0, sizeof(pop3_base)); 67 memset(popb, 0, sizeof(pop3_base));
68 68
69 popb->error = pop3_ok; 69 popb->error = pop3_ok;
70 70
71 popb->buffer = (gchar *)g_malloc(POP3_BUF_LEN); 71 popb->buffer = (gchar *) g_malloc(POP3_BUF_LEN);
72 72
73 dup_sock = dup(sock); 73 dup_sock = dup(sock);
74 popb->out = fdopen(sock, "w"); 74 popb->out = fdopen(sock, "w");
75 popb->in = fdopen(dup_sock, "r"); 75 popb->in = fdopen(dup_sock, "r");
76 76
77 popb->flags = flags; 77 popb->flags = flags;
78 } 78 }
79 return popb; 79 return popb;
80 } 80 }
81 81
82 static 82 static void
83 void pop3_printf(FILE *out, gchar *fmt, ...) 83 pop3_printf(FILE * out, gchar * fmt, ...)
84 { 84 {
85 va_list args; 85 va_list args;
86 va_start(args, fmt); 86 va_start(args, fmt);
87 87
88 DEBUG(4){ 88 DEBUG(4) {
89 gchar buf[256]; 89 gchar buf[256];
90 va_list args_copy; 90 va_list args_copy;
91 91
92 va_copy(args_copy, args); 92 va_copy(args_copy, args);
93 vsnprintf(buf, 255, fmt, args_copy); 93 vsnprintf(buf, 255, fmt, args_copy);
94 va_end(args_copy); 94 va_end(args_copy);
95 95
96 debugf(">>>%s", buf); 96 debugf(">>>%s", buf);
97 } 97 }
98 98
99 vfprintf(out, fmt, args); fflush(out); 99 vfprintf(out, fmt, args);
100 100 fflush(out);
101 va_end(args); 101
102 } 102 va_end(args);
103 103 }
104 static 104
105 gboolean find_uid(pop3_base *popb, gchar *str) 105 static gboolean
106 { 106 find_uid(pop3_base * popb, gchar * str)
107 GList *node, *node_next; 107 {
108 108 GList *node, *node_next;
109 for(node = popb->list_uid_old; node; node=node_next){ 109
110 gchar *uid = (gchar *)(node->data); 110 for (node = popb->list_uid_old; node; node = node_next) {
111 node_next = node->next; 111 gchar *uid = (gchar *) (node->data);
112 if(strcmp(uid, str) == 0){ 112 node_next = node->next;
113 if (strcmp(uid, str) == 0) {
113 #if 1 114 #if 1
114 popb->list_uid_old = g_list_remove_link(popb->list_uid_old, node); 115 popb->list_uid_old = g_list_remove_link(popb->list_uid_old, node);
115 g_list_free_1(node); 116 g_list_free_1(node);
116 g_free(uid); 117 g_free(uid);
117 #endif 118 #endif
118 return TRUE; 119 return TRUE;
119 } 120 }
120 } 121 }
121 return FALSE; 122 return FALSE;
122 } 123 }
123 124
124 static 125 static gboolean
125 gboolean write_uidl(pop3_base *popb, gchar *user) 126 write_uidl(pop3_base * popb, gchar * user)
126 { 127 {
127 gboolean ok = FALSE; 128 gboolean ok = FALSE;
128 GList *node; 129 GList *node;
129 gchar *filename = g_strdup_printf("%s/popuidl/%s@%s", 130 gchar *filename = g_strdup_printf("%s/popuidl/%s@%s", conf.spool_dir, user, popb->remote_host);
130 conf.spool_dir, 131 gchar *tmpname = g_strdup_printf("%s.tmp", filename);
131 user, popb->remote_host); 132 FILE *fptr = fopen(tmpname, "wt");
132 gchar *tmpname = g_strdup_printf("%s.tmp", filename); 133
133 FILE *fptr = fopen(tmpname, "wt"); 134 if (fptr) {
134 135 foreach(popb->drop_list, node) {
135 if(fptr){ 136 msg_info *info = (msg_info *) (node->data);
136 foreach(popb->drop_list, node){ 137 if (info->is_fetched || info->is_in_uidl)
137 msg_info *info = (msg_info *)(node->data); 138 fprintf(fptr, "%s\n", info->uid);
138 if(info->is_fetched || info->is_in_uidl) 139 }
139 fprintf(fptr, "%s\n", info->uid); 140 fclose(fptr);
140 } 141 ok = (rename(tmpname, filename) != -1);
141 fclose(fptr); 142 }
142 ok = (rename(tmpname, filename) != -1); 143
143 } 144 g_free(tmpname);
144 145 g_free(filename);
145 g_free(tmpname); 146 return ok;
146 g_free(filename); 147 }
147 return ok; 148
148 } 149 static gboolean
149 150 read_uidl_fname(pop3_base * popb, gchar * filename)
150 static 151 {
151 gboolean read_uidl_fname(pop3_base *popb, gchar *filename) 152 gboolean ok = FALSE;
152 { 153 FILE *fptr = fopen(filename, "rt");
153 gboolean ok = FALSE; 154 gchar buf[256];
154 FILE *fptr = fopen(filename, "rt"); 155
155 gchar buf[256]; 156 if (fptr) {
156 157 popb->list_uid_old = NULL;
157 if(fptr){ 158 while (fgets(buf, 255, fptr)) {
158 popb->list_uid_old = NULL; 159 if (buf[strlen(buf) - 1] == '\n') {
159 while(fgets(buf, 255, fptr)){ 160 g_strchomp(buf);
160 if(buf[strlen(buf)-1] == '\n'){ 161 popb->list_uid_old = g_list_append(popb->list_uid_old, g_strdup(buf));
161 g_strchomp(buf); 162 } else {
162 popb->list_uid_old = 163 logwrite(LOG_ALERT, "broken uid: %s\n", buf);
163 g_list_append(popb->list_uid_old, g_strdup(buf)); 164 break;
164 }else{ 165 }
165 logwrite(LOG_ALERT, "broken uid: %s\n", buf); 166 }
166 break; 167 fclose(fptr);
167 } 168 ok = TRUE;
168 } 169 } else
169 fclose(fptr); 170 logwrite(LOG_ALERT, "opening of %s failed: %s", filename, strerror(errno));
170 ok = TRUE; 171 return ok;
171 }else 172 }
172 logwrite(LOG_ALERT, "opening of %s failed: %s", filename, strerror(errno)); 173
173 return ok; 174 static gboolean
174 } 175 read_uidl(pop3_base * popb, gchar * user)
175 176 {
176 static 177 gboolean ok = FALSE;
177 gboolean read_uidl(pop3_base *popb, gchar *user) 178 struct stat statbuf;
178 { 179 gchar *filename = g_strdup_printf("%s/popuidl/%s@%s", conf.spool_dir, user, popb->remote_host);
179 gboolean ok = FALSE; 180
180 struct stat statbuf; 181 if (stat(filename, &statbuf) == 0) {
181 gchar *filename = g_strdup_printf("%s/popuidl/%s@%s", 182 ok = read_uidl_fname(popb, filename);
182 conf.spool_dir, 183 if (ok) {
183 user, popb->remote_host); 184 GList *drop_node;
184 185 foreach(popb->drop_list, drop_node) {
185 if(stat(filename, &statbuf) == 0){ 186 msg_info *info = (msg_info *) (drop_node->data);
186 ok = read_uidl_fname(popb, filename); 187 if (find_uid(popb, info->uid)) {
187 if(ok){ 188 DEBUG(5) debugf("msg with uid '%s' already known\n", info->uid);
188 GList *drop_node; 189 info->is_in_uidl = TRUE;
189 foreach(popb->drop_list, drop_node){ 190 popb->uidl_known_cnt++;
190 msg_info *info = (msg_info *)(drop_node->data); 191 } else
191 if(find_uid(popb, info->uid)){ 192 DEBUG(5) debugf("msg with uid '%s' not known\n", info->uid);
192 DEBUG(5) debugf("msg with uid '%s' already known\n", info->uid); 193 }
193 info->is_in_uidl = TRUE; 194 }
194 popb->uidl_known_cnt++; 195 } else {
195 }else 196 logwrite(LOG_DEBUG, "no uidl file '%s' found\n", filename);
196 DEBUG(5) debugf("msg with uid '%s' not known\n", info->uid); 197 ok = TRUE;
197 } 198 }
198 } 199
199 }else{ 200 g_free(filename);
200 logwrite(LOG_DEBUG, "no uidl file '%s' found\n", filename); 201 return ok; /* return code is irrelevant, do not check... */
201 ok = TRUE; 202 }
202 } 203
203 204 static gboolean
204 g_free(filename); 205 read_response(pop3_base * popb, int timeout)
205 return ok; /* return code is irrelevant, do not check... */ 206 {
206 } 207 gint len;
207 208
208 static 209 len = read_sockline(popb->in, popb->buffer, POP3_BUF_LEN, timeout, READSOCKL_CHUG);
209 gboolean read_response(pop3_base *popb, int timeout) 210
210 { 211 if (len == -3) {
211 gint len; 212 popb->error = pop3_timeout;
212 213 return FALSE;
213 len = read_sockline(popb->in, popb->buffer, POP3_BUF_LEN, timeout, READSOCKL_CHUG); 214 } else if (len == -2) {
214 215 popb->error = pop3_syntax;
215 if(len == -3){ 216 return FALSE;
216 popb->error = pop3_timeout; 217 } else if (len == -1) {
217 return FALSE; 218 popb->error = pop3_eof;
218 } 219 return FALSE;
219 else if(len == -2){ 220 }
220 popb->error = pop3_syntax; 221
221 return FALSE;
222 }
223 else if(len == -1){
224 popb->error = pop3_eof;
225 return FALSE;
226 }
227
228 return TRUE;
229 }
230
231 static
232 gboolean check_response(pop3_base *popb)
233 {
234 char c = popb->buffer[0];
235
236 if(c == '+'){
237 popb->error = pop3_ok;
238 return TRUE;
239 }else if(c == '-')
240 popb->error = pop3_fail;
241 else
242 popb->error = pop3_syntax;
243 return FALSE;
244 }
245
246 static
247 gboolean strtoi(gchar *p, gchar **pend, gint *val)
248 {
249 gchar buf[12];
250 gint i = 0;
251
252 while(*p && isspace(*p)) p++;
253 if(*p){
254 while((i < 11) && isdigit(*p))
255 buf[i++] = *(p++);
256 buf[i] = 0;
257 *val = atoi(buf);
258 *pend = p;
259 return TRUE;
260 }
261 return FALSE;
262 }
263
264 static
265 gboolean check_response_int_int(pop3_base *popb, gint *arg0, gint *arg1)
266 {
267 if(check_response(popb)){
268 gchar *p = &(popb->buffer[3]);
269 gchar *pe;
270
271 if(strtoi(p, &pe, arg0)){
272 DEBUG(5) debugf("arg0 = %d\n", *arg0);
273 p = pe;
274 if(strtoi(p, &pe, arg1))
275 DEBUG(5) debugf("arg1 = %d\n", *arg1);
276 return TRUE; 222 return TRUE;
277 } 223 }
278 popb->error = pop3_syntax; 224
279 } 225 static gboolean
280 return FALSE; 226 check_response(pop3_base * popb)
281 } 227 {
282 228 char c = popb->buffer[0];
283 static 229
284 gboolean get_drop_listing(pop3_base *popb) 230 if (c == '+') {
285 { 231 popb->error = pop3_ok;
286 gchar buf[64]; 232 return TRUE;
287 233 } else if (c == '-')
288 DEBUG(5) debugf("get_drop_listing() entered\n"); 234 popb->error = pop3_fail;
289 235 else
290 while(1){ 236 popb->error = pop3_syntax;
291 gint len = read_sockline(popb->in, buf, 64, POP3_CMD_TIMEOUT, READSOCKL_CHUG); 237 return FALSE;
292 if(len > 0){ 238 }
293 if(buf[0] == '.') 239
240 static gboolean
241 strtoi(gchar * p, gchar ** pend, gint * val)
242 {
243 gchar buf[12];
244 gint i = 0;
245
246 while (*p && isspace(*p))
247 p++;
248 if (*p) {
249 while ((i < 11) && isdigit(*p))
250 buf[i++] = *(p++);
251 buf[i] = 0;
252 *val = atoi(buf);
253 *pend = p;
254 return TRUE;
255 }
256 return FALSE;
257 }
258
259 static gboolean
260 check_response_int_int(pop3_base * popb, gint * arg0, gint * arg1)
261 {
262 if (check_response(popb)) {
263 gchar *p = &(popb->buffer[3]);
264 gchar *pe;
265
266 if (strtoi(p, &pe, arg0)) {
267 DEBUG(5) debugf("arg0 = %d\n", *arg0);
268 p = pe;
269 if (strtoi(p, &pe, arg1))
270 DEBUG(5) debugf("arg1 = %d\n", *arg1);
271 return TRUE;
272 }
273 popb->error = pop3_syntax;
274 }
275 return FALSE;
276 }
277
278 static gboolean
279 get_drop_listing(pop3_base * popb)
280 {
281 gchar buf[64];
282
283 DEBUG(5) debugf("get_drop_listing() entered\n");
284
285 while (1) {
286 gint len = read_sockline(popb->in, buf, 64, POP3_CMD_TIMEOUT, READSOCKL_CHUG);
287 if (len > 0) {
288 if (buf[0] == '.')
289 return TRUE;
290 else {
291 gint number, msg_size;
292 gchar *p = buf, *pe;
293 if (strtoi(p, &pe, &number)) {
294 p = pe;
295 if (strtoi(p, &pe, &msg_size)) {
296 msg_info *info = g_malloc(sizeof(msg_info));
297 info->number = number;
298 info->size = msg_size;
299
300 DEBUG(5) debugf ("get_drop_listing(), number = %d, msg_size = %d\n", number, msg_size);
301
302 info->uid = NULL;
303 info->is_fetched = FALSE;
304 info->is_in_uidl = FALSE;
305 popb->drop_list = g_list_append(popb->drop_list, info);
306 } else {
307 popb->error = pop3_syntax;
308 break;
309 }
310 } else {
311 popb->error = pop3_syntax;
312 break;
313 }
314 }
315 } else {
316 popb->error = (len == -1) ? pop3_eof : pop3_timeout;
317 return FALSE;
318 }
319 }
320 return FALSE;
321 }
322
323 static gboolean
324 get_uid_listing(pop3_base * popb)
325 {
326 gchar buf[64];
327
328 while (1) {
329 gint len = read_sockline(popb->in, buf, 64, POP3_CMD_TIMEOUT, READSOCKL_CHUG);
330 if (len > 0) {
331 if (buf[0] == '.')
332 return TRUE;
333 else {
334 gint number;
335 gchar *p = buf, *pe;
336 if (strtoi(p, &pe, &number)) {
337 msg_info *info = NULL;
338 GList *drop_node;
339
340 p = pe;
341 while (*p && isspace(*p))
342 p++;
343
344 foreach(popb->drop_list, drop_node) {
345 msg_info *curr_info = (msg_info *) (drop_node->data);
346 if (curr_info->number == number) {
347 info = curr_info;
348 break;
349 }
350 }
351 if (info) {
352 info->uid = g_strdup(p);
353 g_strchomp(info->uid);
354 }
355
356 } else {
357 popb->error = pop3_syntax;
358 break;
359 }
360 }
361 }
362 }
363 return FALSE;
364 }
365
366 static gboolean
367 check_init_response(pop3_base * popb)
368 {
369 if (check_response(popb)) {
370 gchar buf[256];
371 gchar *p = popb->buffer;
372 gint i = 0;
373 if (*p) {
374 while (*p && (*p != '<'))
375 p++;
376 while (*p && (*p != '>') && (i < 254))
377 buf[i++] = *(p++);
378 buf[i++] = '>';
379 buf[i] = 0;
380
381 popb->timestamp = g_strdup(buf);
382
383 return TRUE;
384 }
385 }
386 return FALSE;
387 }
388
389 void
390 pop3_in_close(pop3_base * popb)
391 {
392 GList *node;
393
394 fclose(popb->in);
395 fclose(popb->out);
396
397 close(popb->sock);
398
399 foreach(popb->list_uid_old, node) {
400 gchar *uid = (gchar *) (node->data);
401 g_free(uid);
402 }
403 g_list_free(popb->list_uid_old);
404
405 foreach(popb->drop_list, node) {
406 msg_info *info = (msg_info *) (node->data);
407 if (info->uid)
408 g_free(info->uid);
409 g_free(info);
410 }
411 g_list_free(popb->drop_list);
412
413 if (popb->buffer)
414 g_free(popb->buffer);
415 if (popb->timestamp)
416 g_free(popb->timestamp);
417 }
418
419 pop3_base*
420 pop3_in_open(gchar * host, gint port, GList * resolve_list, guint flags)
421 {
422 pop3_base *popb;
423 gint sock;
424 mxip_addr *addr;
425
426 DEBUG(5) debugf("pop3_in_open entered, host = %s\n", host);
427
428 if ((addr = connect_resolvelist(&sock, host, port, resolve_list))) {
429 /* create structure to hold status data: */
430 popb = create_pop3base(sock, flags);
431 popb->remote_host = addr->name;
432
433 DEBUG(5) {
434 struct sockaddr_in name;
435 int len;
436 getsockname(sock, (struct sockaddr *) (&name), &len);
437 debugf("socket: name.sin_addr = %s\n", inet_ntoa(name.sin_addr));
438 }
439 return popb;
440 }
441 return NULL;
442 }
443
444 pop3_base*
445 pop3_in_open_child(gchar * cmd, guint flags)
446 {
447 pop3_base *popb;
448 gint sock;
449
450 DEBUG(5) debugf("pop3_in_open_child entered, cmd = %s\n", cmd);
451
452 sock = child(cmd);
453
454 if (sock > 0) {
455
456 popb = create_pop3base(sock, flags);
457 popb->remote_host = NULL;
458
459 return popb;
460 }
461 logwrite(LOG_ALERT, "child failed (sock = %d): %s\n", sock, strerror(errno));
462
463 return NULL;
464 }
465
466 gboolean
467 pop3_in_init(pop3_base * popb)
468 {
469 gboolean ok;
470
471 if ((ok = read_response(popb, POP3_INITIAL_TIMEOUT))) {
472 ok = check_init_response(popb);
473 }
474 if (!ok)
475 /* pop3_in_log_failure(popb, NULL); */
476 logwrite(LOG_ALERT, "pop3 failed\n");
477 return ok;
478 }
479
480 gboolean
481 pop3_in_login(pop3_base * popb, gchar * user, gchar * pass)
482 {
483 if (popb->flags & POP3_FLAG_APOP) {
484
485 gchar *string = g_strdup_printf("%s%s", popb->timestamp, pass);
486 gchar *digest = MD5String(string);
487 pop3_printf(popb->out, "APOP %s %s\r\n", user, digest);
488 g_free(string);
489 g_free(digest);
490 if (read_response(popb, POP3_CMD_TIMEOUT)) {
491 if (check_response(popb))
492 return TRUE;
493 else
494 popb->error = pop3_login_failure;
495 }
496
497 } else {
498
499 pop3_printf(popb->out, "USER %s\r\n", user);
500 if (read_response(popb, POP3_CMD_TIMEOUT)) {
501 if (check_response(popb)) {
502 pop3_printf(popb->out, "PASS %s\r\n", pass);
503 if (read_response(popb, POP3_CMD_TIMEOUT)) {
504 if (check_response(popb))
505 return TRUE;
506 else
507 popb->error = pop3_login_failure;
508 }
509 } else {
510 popb->error = pop3_login_failure;
511 }
512 }
513 }
514 return FALSE;
515 }
516
517 gboolean
518 pop3_in_stat(pop3_base * popb)
519 {
520 pop3_printf(popb->out, "STAT\r\n");
521 if (read_response(popb, POP3_CMD_TIMEOUT)) {
522 gint msg_cnt, mbox_size;
523 if (check_response_int_int(popb, &msg_cnt, &mbox_size)) {
524 popb->msg_cnt = msg_cnt;
525 popb->mbox_size = mbox_size;
526
527 return TRUE;
528 }
529 }
530 return FALSE;
531 }
532
533 gboolean
534 pop3_in_list(pop3_base * popb)
535 {
536 pop3_printf(popb->out, "LIST\r\n");
537 if (read_response(popb, POP3_CMD_TIMEOUT)) {
538 if (get_drop_listing(popb)) {
539 return TRUE;
540 }
541 }
542 return FALSE;
543 }
544
545 gboolean
546 pop3_in_dele(pop3_base * popb, gint number)
547 {
548 pop3_printf(popb->out, "DELE %d\r\n", number);
549 if (read_response(popb, POP3_CMD_TIMEOUT)) {
550 return TRUE;
551 }
552 return FALSE;
553 }
554
555 message*
556 pop3_in_retr(pop3_base * popb, gint number, address * rcpt)
557 {
558 accept_error err;
559
560 pop3_printf(popb->out, "RETR %d\r\n", number);
561 if (read_response(popb, POP3_CMD_TIMEOUT)) {
562 message *msg = create_message();
563 msg->received_host = popb->remote_host;
564 msg->received_prot = (popb->flags & POP3_FLAG_APOP) ? PROT_APOP : PROT_POP3;
565 msg->transfer_id = (popb->next_id)++;
566 msg->rcpt_list = g_list_append(NULL, copy_address(rcpt));
567
568 if ((err = accept_message(popb->in, msg, ACC_MAIL_FROM_HEAD
569 | (conf.do_save_envelope_to ? ACC_SAVE_ENVELOPE_TO : 0)))
570 == AERR_OK)
571 return msg;
572
573 destroy_message(msg);
574 }
575 return NULL;
576 }
577
578 gboolean
579 pop3_in_uidl(pop3_base * popb)
580 {
581 pop3_printf(popb->out, "UIDL\r\n");
582 if (read_response(popb, POP3_CMD_TIMEOUT)) {
583 if (get_uid_listing(popb)) {
584 return TRUE;
585 }
586 }
587 return FALSE;
588 }
589
590 gboolean
591 pop3_in_quit(pop3_base * popb)
592 {
593 pop3_printf(popb->out, "QUIT\r\n");
594
595 DEBUG(4) debugf("QUIT\n");
596
597 signal(SIGALRM, SIG_DFL);
598
294 return TRUE; 599 return TRUE;
295 else{
296 gint number, msg_size;
297 gchar *p = buf, *pe;
298 if(strtoi(p, &pe, &number)){
299 p = pe;
300 if(strtoi(p, &pe, &msg_size)){
301 msg_info *info = g_malloc(sizeof(msg_info));
302 info->number = number;
303 info->size = msg_size;
304
305 DEBUG(5) debugf("get_drop_listing(), number = %d, msg_size = %d\n", number, msg_size);
306
307 info->uid = NULL;
308 info->is_fetched = FALSE;
309 info->is_in_uidl = FALSE;
310 popb->drop_list = g_list_append(popb->drop_list, info);
311 }else{
312 popb->error = pop3_syntax;
313 break;
314 }
315 }else{
316 popb->error = pop3_syntax;
317 break;
318 }
319 }
320 }else{
321 popb->error = (len == -1) ? pop3_eof : pop3_timeout;
322 return FALSE;
323 }
324 }
325 return FALSE;
326 }
327
328 static
329 gboolean get_uid_listing(pop3_base *popb)
330 {
331 gchar buf[64];
332
333 while(1){
334 gint len = read_sockline(popb->in, buf, 64, POP3_CMD_TIMEOUT, READSOCKL_CHUG);
335 if(len > 0){
336 if(buf[0] == '.')
337 return TRUE;
338 else{
339 gint number;
340 gchar *p = buf, *pe;
341 if(strtoi(p, &pe, &number)){
342 msg_info *info = NULL;
343 GList *drop_node;
344
345 p = pe;
346 while(*p && isspace(*p)) p++;
347
348 foreach(popb->drop_list, drop_node){
349 msg_info *curr_info = (msg_info *)(drop_node->data);
350 if(curr_info->number == number){
351 info = curr_info;
352 break;
353 }
354 }
355 if(info){
356 info->uid = g_strdup(p);
357 g_strchomp(info->uid);
358 }
359
360 }else{
361 popb->error = pop3_syntax;
362 break;
363 }
364 }
365 }
366 }
367 return FALSE;
368 }
369
370 static
371 gboolean check_init_response(pop3_base *popb)
372 {
373 if(check_response(popb)){
374 gchar buf[256];
375 gchar *p = popb->buffer;
376 gint i = 0;
377 if(*p){
378 while(*p && (*p != '<')) p++;
379 while(*p && (*p != '>') && (i < 254))
380 buf[i++] = *(p++);
381 buf[i++] = '>';
382 buf[i] = 0;
383
384 popb->timestamp = g_strdup(buf);
385
386 return TRUE;
387 }
388 }
389 return FALSE;
390 }
391
392 void pop3_in_close(pop3_base *popb)
393 {
394 GList *node;
395
396 fclose(popb->in);
397 fclose(popb->out);
398
399 close(popb->sock);
400
401 foreach(popb->list_uid_old, node){
402 gchar *uid = (gchar *)(node->data);
403 g_free(uid);
404 }
405 g_list_free(popb->list_uid_old);
406
407 foreach(popb->drop_list, node){
408 msg_info *info = (msg_info *)(node->data);
409 if(info->uid) g_free(info->uid);
410 g_free(info);
411 }
412 g_list_free(popb->drop_list);
413
414 if(popb->buffer) g_free(popb->buffer);
415 if(popb->timestamp) g_free(popb->timestamp);
416 }
417
418 pop3_base *pop3_in_open(gchar *host, gint port, GList *resolve_list, guint flags)
419 {
420 pop3_base *popb;
421 gint sock;
422 mxip_addr *addr;
423
424 DEBUG(5) debugf("pop3_in_open entered, host = %s\n", host);
425
426 if((addr = connect_resolvelist(&sock, host, port, resolve_list))){
427 /* create structure to hold status data: */
428 popb = create_pop3base(sock, flags);
429 popb->remote_host = addr->name;
430
431 DEBUG(5){
432 struct sockaddr_in name;
433 int len;
434 getsockname(sock, (struct sockaddr *)(&name), &len);
435 debugf("socket: name.sin_addr = %s\n", inet_ntoa(name.sin_addr));
436 }
437 return popb;
438 }
439 return NULL;
440 }
441
442 pop3_base *pop3_in_open_child(gchar *cmd, guint flags)
443 {
444 pop3_base *popb;
445 gint sock;
446
447 DEBUG(5) debugf("pop3_in_open_child entered, cmd = %s\n", cmd);
448
449 sock = child(cmd);
450
451 if(sock > 0){
452
453 popb = create_pop3base(sock, flags);
454 popb->remote_host = NULL;
455
456 return popb;
457 }
458 logwrite(LOG_ALERT, "child failed (sock = %d): %s\n", sock, strerror(errno));
459
460 return NULL;
461 }
462
463 gboolean pop3_in_init(pop3_base *popb)
464 {
465 gboolean ok;
466
467 if((ok = read_response(popb, POP3_INITIAL_TIMEOUT))){
468 ok = check_init_response(popb);
469 }
470 if(!ok)
471 /* pop3_in_log_failure(popb, NULL);*/
472 logwrite(LOG_ALERT, "pop3 failed\n");
473 return ok;
474 }
475
476 gboolean pop3_in_login(pop3_base *popb, gchar *user, gchar *pass)
477 {
478 if(popb->flags & POP3_FLAG_APOP){
479
480 gchar *string = g_strdup_printf("%s%s", popb->timestamp, pass);
481 gchar *digest = MD5String(string);
482 pop3_printf(popb->out, "APOP %s %s\r\n", user, digest);
483 g_free(string);
484 g_free(digest);
485 if(read_response(popb, POP3_CMD_TIMEOUT)){
486 if(check_response(popb))
487 return TRUE;
488 else
489 popb->error = pop3_login_failure;
490 }
491
492 }else{
493
494 pop3_printf(popb->out, "USER %s\r\n", user);
495 if(read_response(popb, POP3_CMD_TIMEOUT)){
496 if(check_response(popb)){
497 pop3_printf(popb->out, "PASS %s\r\n", pass);
498 if(read_response(popb, POP3_CMD_TIMEOUT)){
499 if(check_response(popb))
500 return TRUE;
501 else
502 popb->error = pop3_login_failure;
503 }
504 }else{
505 popb->error = pop3_login_failure;
506 }
507 }
508 }
509 return FALSE;
510 }
511
512 gboolean pop3_in_stat(pop3_base *popb)
513 {
514 pop3_printf(popb->out, "STAT\r\n");
515 if(read_response(popb, POP3_CMD_TIMEOUT)){
516 gint msg_cnt, mbox_size;
517 if(check_response_int_int(popb, &msg_cnt, &mbox_size)){
518 popb->msg_cnt = msg_cnt;
519 popb->mbox_size = mbox_size;
520
521 return TRUE;
522 }
523 }
524 return FALSE;
525 }
526
527 gboolean pop3_in_list(pop3_base *popb)
528 {
529 pop3_printf(popb->out, "LIST\r\n");
530 if(read_response(popb, POP3_CMD_TIMEOUT)){
531 if(get_drop_listing(popb)){
532 return TRUE;
533 }
534 }
535 return FALSE;
536 }
537
538 gboolean pop3_in_dele(pop3_base *popb, gint number)
539 {
540 pop3_printf(popb->out, "DELE %d\r\n", number);
541 if(read_response(popb, POP3_CMD_TIMEOUT)){
542 return TRUE;
543 }
544 return FALSE;
545 }
546
547 message *pop3_in_retr(pop3_base *popb, gint number, address *rcpt)
548 {
549 accept_error err;
550
551 pop3_printf(popb->out, "RETR %d\r\n", number);
552 if(read_response(popb, POP3_CMD_TIMEOUT)){
553 message *msg = create_message();
554 msg->received_host = popb->remote_host;
555 msg->received_prot = (popb->flags & POP3_FLAG_APOP) ? PROT_APOP : PROT_POP3;
556 msg->transfer_id = (popb->next_id)++;
557 msg->rcpt_list = g_list_append(NULL, copy_address(rcpt));
558
559 if((err = accept_message(popb->in, msg,
560 ACC_MAIL_FROM_HEAD|(conf.do_save_envelope_to ? ACC_SAVE_ENVELOPE_TO : 0)))
561 == AERR_OK)
562 return msg;
563
564 destroy_message(msg);
565 }
566 return NULL;
567 }
568
569 gboolean pop3_in_uidl(pop3_base *popb)
570 {
571 pop3_printf(popb->out, "UIDL\r\n");
572 if(read_response(popb, POP3_CMD_TIMEOUT)){
573 if(get_uid_listing(popb)){
574 return TRUE;
575 }
576 }
577 return FALSE;
578 }
579
580 gboolean pop3_in_quit(pop3_base *popb)
581 {
582 pop3_printf(popb->out, "QUIT\r\n");
583
584 DEBUG(4) debugf("QUIT\n");
585
586 signal(SIGALRM, SIG_DFL);
587
588 return TRUE;
589 } 600 }
590 601
591 /* Send a DELE command for each message in (the old) uid listing. 602 /* Send a DELE command for each message in (the old) uid listing.
592 This is to prevent mail from to be kept on server, if a previous 603 This is to prevent mail from to be kept on server, if a previous
593 transaction was interupted. */ 604 transaction was interupted. */
594 gboolean pop3_in_uidl_dele(pop3_base *popb) 605 gboolean
595 { 606 pop3_in_uidl_dele(pop3_base * popb)
596 GList *drop_node; 607 {
597 608 GList *drop_node;
598 foreach(popb->drop_list, drop_node){ 609
599 msg_info *info = (msg_info *)(drop_node->data); 610 foreach(popb->drop_list, drop_node) {
600 /* if(find_uid(popb, info->uid)){*/ 611 msg_info *info = (msg_info *) (drop_node->data);
601 if(info->is_in_uidl){ 612 /* if(find_uid(popb, info->uid)){ */
602 if(!pop3_in_dele(popb, info->number)) 613 if (info->is_in_uidl) {
603 return FALSE; 614 if (!pop3_in_dele(popb, info->number))
604 /* TODO: it probably makes sense to also 615 return FALSE;
605 delete this uid from the listing */ 616 /* TODO: it probably makes sense to also delete this uid from the listing */
606 } 617 }
607 } 618 }
608 return TRUE; 619 return TRUE;
609 } 620 }
610 621
611 gboolean pop3_get(pop3_base *popb, 622 gboolean
612 gchar *user, gchar *pass, address *rcpt, address *return_path, 623 pop3_get(pop3_base * popb, gchar * user, gchar * pass, address * rcpt, address * return_path, gint max_count, gint max_size, gboolean max_size_delete)
613 gint max_count, gint max_size, gboolean max_size_delete) 624 {
614 { 625 gboolean ok = FALSE;
615 gboolean ok = FALSE; 626 gint num_children = 0;
616 gint num_children = 0; 627
617 628 DEBUG(5) debugf("rcpt = %s@%s\n", rcpt->local_part, rcpt->domain);
618 DEBUG(5) debugf("rcpt = %s@%s\n", rcpt->local_part, rcpt->domain); 629
619 630 signal(SIGCHLD, SIG_DFL);
620 signal(SIGCHLD, SIG_DFL); 631
621 632 if (pop3_in_init(popb)) {
622 if(pop3_in_init(popb)){ 633 if (pop3_in_login(popb, user, pass)) {
623 if(pop3_in_login(popb, user, pass)){ 634 if (pop3_in_stat(popb)) {
624 if(pop3_in_stat(popb)){ 635 if (popb->msg_cnt > 0) {
625 if(popb->msg_cnt > 0){ 636
626 637 logwrite(LOG_NOTICE | LOG_VERBOSE, "%d message(s) for user %s at %s\n", popb->msg_cnt, user, popb->remote_host);
627 logwrite(LOG_NOTICE|LOG_VERBOSE, "%d message(s) for user %s at %s\n", 638
628 popb->msg_cnt, user, popb->remote_host); 639 if (pop3_in_list(popb)) {
629 640 gboolean do_get = !(popb->flags & POP3_FLAG_UIDL);
630 if(pop3_in_list(popb)){ 641 if (!do_get)
631 gboolean do_get = !(popb->flags & POP3_FLAG_UIDL); 642 do_get = pop3_in_uidl(popb);
632 if(!do_get) do_get = pop3_in_uidl(popb); 643 if (do_get) {
633 if(do_get){ 644 gint count = 0;
634 gint count = 0; 645 GList *drop_node;
635 GList *drop_node; 646
636 647 if (popb->flags & POP3_FLAG_UIDL) {
637 if(popb->flags & POP3_FLAG_UIDL){ 648 read_uidl(popb, user);
638 read_uidl(popb, user); 649 logwrite(LOG_VERBOSE | LOG_NOTICE, "%d message(s) already in uidl.\n", popb->uidl_known_cnt);
639 logwrite(LOG_VERBOSE|LOG_NOTICE, "%d message(s) already in uidl.\n", 650 }
640 popb->uidl_known_cnt); 651 if ((popb->flags & POP3_FLAG_UIDL) && (popb->flags & POP3_FLAG_UIDL_DELE))
641 } 652 pop3_in_uidl_dele(popb);
642 if((popb->flags & POP3_FLAG_UIDL) && (popb->flags & POP3_FLAG_UIDL_DELE)) 653
643 pop3_in_uidl_dele(popb); 654 foreach(popb->drop_list, drop_node) {
644 655
645 foreach(popb->drop_list, drop_node){ 656 msg_info *info = (msg_info *) (drop_node->data);
646 657 gboolean do_get_this = !(popb->flags & POP3_FLAG_UIDL);
647 msg_info *info = (msg_info *)(drop_node->data); 658 /* if(!do_get_this) do_get_this = !find_uid(popb, info->uid); */
648 gboolean do_get_this = !(popb->flags & POP3_FLAG_UIDL); 659 if (!do_get_this)
649 /* if(!do_get_this) do_get_this = !find_uid(popb, info->uid);*/ 660 do_get_this = !(info->is_in_uidl);
650 if(!do_get_this) do_get_this = !(info->is_in_uidl); 661 if (do_get_this) {
651 if(do_get_this){ 662
652 663 if ((info->size < max_size) || (max_size == 0)) {
653 if((info->size < max_size) || (max_size == 0)){ 664 message *msg;
654 message *msg; 665
655 666 logwrite(LOG_VERBOSE | LOG_NOTICE, "receiving message %d\n", info->number);
656 logwrite(LOG_VERBOSE|LOG_NOTICE, "receiving message %d\n", info->number); 667 msg = pop3_in_retr(popb, info->number, rcpt);
657 msg = pop3_in_retr(popb, info->number, rcpt); 668
658 669 if (msg) {
659 if(msg){ 670 if (return_path)
660 if(return_path) 671 msg->return_path = copy_address(return_path);
661 msg->return_path = copy_address(return_path); 672 if (spool_write(msg, TRUE)) {
662 if(spool_write(msg, TRUE)){ 673 pid_t pid;
663 pid_t pid; 674 logwrite(LOG_NOTICE, "%s <= %s host=%s with %s\n", msg->uid,
664 logwrite(LOG_NOTICE, "%s <= %s host=%s with %s\n", 675 addr_string(msg->return_path), popb->remote_host,
665 msg->uid, 676 (popb->flags & POP3_FLAG_APOP) ? prot_names [PROT_APOP] : prot_names [PROT_POP3]);
666 addr_string(msg->return_path), 677 info->is_fetched = TRUE;
667 popb->remote_host, 678 count++;
668 (popb->flags & POP3_FLAG_APOP) ?
669 prot_names[PROT_APOP] : prot_names[PROT_POP3]
670 );
671 info->is_fetched = TRUE;
672 count++;
673 #if DO_WRITE_UIDL_EARLY 679 #if DO_WRITE_UIDL_EARLY
674 if(popb->flags & POP3_FLAG_UIDL) write_uidl(popb, user); 680 if (popb->flags & POP3_FLAG_UIDL)
681 write_uidl(popb, user);
675 #endif 682 #endif
676 if(!conf.do_queue){ 683 if (!conf.do_queue) {
677 684
678 /* wait for child processes. If there are too many, 685 /* wait for child processes. If there are too many, we wait blocking, before we fork another one */
679 we wait blocking, before we fork another one */ 686 while (num_children > 0) {
680 while(num_children > 0){ 687 int status, options = WNOHANG;
681 int status, options = WNOHANG; 688 pid_t pid;
682 pid_t pid; 689
683 690 if (num_children >= POP3_MAX_CHILDREN) {
684 if(num_children >= POP3_MAX_CHILDREN){ 691 logwrite(LOG_NOTICE, "too many children - waiting\n");
685 logwrite(LOG_NOTICE, "too many children - waiting\n"); 692 options = 0;
686 options = 0; 693 }
687 } 694 if ((pid = waitpid(0, &status, options)) > 0) {
688 if((pid = waitpid(0, &status, options)) > 0){ 695 num_children--;
689 num_children--; 696 if (WEXITSTATUS(status) != EXIT_SUCCESS)
690 if(WEXITSTATUS(status) != EXIT_SUCCESS) 697 logwrite(LOG_WARNING, "delivery process with pid %d returned %d\n", pid, WEXITSTATUS (status));
691 logwrite(LOG_WARNING, 698 if (WIFSIGNALED(status))
692 "delivery process with pid %d returned %d\n", 699 logwrite(LOG_WARNING, "delivery process with pid %d got signal: %d\n", pid, WTERMSIG (status));
693 pid, WEXITSTATUS(status)); 700 } else if (pid < 0) {
694 if(WIFSIGNALED(status)) 701 logwrite(LOG_WARNING, "wait got error: %s\n", strerror(errno));
695 logwrite(LOG_WARNING, 702 }
696 "delivery process with pid %d got signal: %d\n", 703 }
697 pid, WTERMSIG(status)); 704
698 }else if(pid < 0){ 705 if ((pid = fork()) == 0) {
699 logwrite(LOG_WARNING, "wait got error: %s\n", strerror(errno)); 706 deliver(msg);
700 } 707 _exit(EXIT_SUCCESS);
701 } 708 } else if (pid < 0) {
702 709 logwrite(LOG_ALERT | LOG_VERBOSE, "could not fork for delivery, id = %s: %s\n", msg->uid, strerror(errno));
703 if((pid = fork()) == 0){ 710 } else
704 deliver(msg); 711 num_children++;
705 _exit(EXIT_SUCCESS); 712 } else {
706 }else if(pid < 0){ 713 DEBUG(1) debugf("queuing forced by configuration or option.\n");
707 logwrite(LOG_ALERT|LOG_VERBOSE, 714 }
708 "could not fork for delivery, id = %s: %s\n", 715 if (popb->flags & POP3_FLAG_DELETE)
709 msg->uid, strerror(errno)); 716 pop3_in_dele(popb, info->number);
710 }else 717
711 num_children++; 718 destroy_message(msg);
712 }else{ 719 } /* if(spool_write(msg, TRUE)) */
713 DEBUG(1) debugf("queuing forced by configuration or option.\n"); 720 } else {
714 } 721 logwrite(LOG_ALERT, "retrieving of message %d failed: %d\n", info->number, popb->error);
715 if(popb->flags & POP3_FLAG_DELETE) 722 }
716 pop3_in_dele(popb, info->number); 723 } /* if((info->size > max_size) ... */
717 724 else {
718 destroy_message(msg); 725 logwrite(LOG_NOTICE | LOG_VERBOSE, "size of message #%d (%d) > max_size (%d)\n", info->number, info->size, max_size);
719 }/* if(spool_write(msg, TRUE)) */ 726 if (max_size_delete)
720 }else{ 727 if (popb->flags & POP3_FLAG_DELETE)
721 logwrite(LOG_ALERT, 728 pop3_in_dele(popb, info->number);
722 "retrieving of message %d failed: %d\n", 729 }
723 info->number, popb->error); 730 } /* if(do_get_this) ... */
724 } 731 else {
725 }/* if((info->size > max_size) ... */ 732 if (popb->flags & POP3_FLAG_UIDL) {
726 else{ 733 info->is_fetched = TRUE; /* obsolete? */
727 logwrite(LOG_NOTICE|LOG_VERBOSE, "size of message #%d (%d) > max_size (%d)\n", 734 logwrite(LOG_VERBOSE, "message %d already known\n", info->number);
728 info->number, info->size, max_size); 735 DEBUG(1) debugf("message %d (uid = %s) not fetched\n", info->number, info->uid);
729 if(max_size_delete)
730 if(popb->flags & POP3_FLAG_DELETE)
731 pop3_in_dele(popb, info->number);
732 }
733 }/* if(do_get_this) ... */
734 else{
735 if(popb->flags & POP3_FLAG_UIDL){
736 info->is_fetched = TRUE; /* obsolete? */
737 logwrite(LOG_VERBOSE, "message %d already known\n",
738 info->number);
739 DEBUG(1) debugf("message %d (uid = %s) not fetched\n",
740 info->number, info->uid);
741 #if 0 736 #if 0
742 #if DO_WRITE_UIDL_EARLY 737 #if DO_WRITE_UIDL_EARLY
743 write_uidl(popb, user); /* obsolete? */ 738 write_uidl(popb, user); /* obsolete? */
744 #endif 739 #endif
745 #endif 740 #endif
746 } 741 }
747 } 742 }
748 if((max_count != 0) && (count >= max_count)) 743 if ((max_count != 0) && (count >= max_count))
749 break; 744 break;
750 }/* foreach() */ 745 } /* foreach() */
751 #if DO_WRITE_UIDL_EARLY 746 #if DO_WRITE_UIDL_EARLY
752 #else 747 #else
753 if(popb->flags & POP3_FLAG_UIDL) write_uidl(popb, user); 748 if (popb->flags & POP3_FLAG_UIDL)
749 write_uidl(popb, user);
754 #endif 750 #endif
755 }/* if(pop3_in_uidl(popb) ... */ 751 } /* if(pop3_in_uidl(popb) ... */
756 }/* if(pop3_in_list(popb)) */ 752 } /* if(pop3_in_list(popb)) */
757 }/* if(popb->msg_cnt > 0) */ 753 } /* if(popb->msg_cnt > 0) */
758 else{ 754 else {
759 logwrite(LOG_NOTICE|LOG_VERBOSE, 755 logwrite(LOG_NOTICE | LOG_VERBOSE, "no messages for user %s at %s\n", user, popb->remote_host);
760 "no messages for user %s at %s\n", user, popb->remote_host); 756 }
761 } 757 ok = TRUE;
762 ok = TRUE; 758 }
763 } 759 pop3_in_quit(popb);
764 pop3_in_quit(popb); 760 } else {
765 }else{ 761 logwrite(LOG_ALERT | LOG_VERBOSE, "pop3 login failed for user %s, host = %s\n", user, popb->remote_host);
766 logwrite(LOG_ALERT|LOG_VERBOSE, 762 }
767 "pop3 login failed for user %s, host = %s\n", user, popb->remote_host); 763 }
768 } 764 if (!ok) {
769 } 765 logwrite(LOG_ALERT | LOG_VERBOSE, "pop3 failed, error = %d\n", popb->error);
770 if(!ok){ 766 }
771 logwrite(LOG_ALERT|LOG_VERBOSE, "pop3 failed, error = %d\n", popb->error); 767
772 } 768 while (num_children > 0) {
773 769 int status;
774 while(num_children > 0){ 770 pid_t pid;
775 int status; 771 if ((pid = wait(&status)) > 0) {
776 pid_t pid; 772 num_children--;
777 if((pid = wait(&status)) > 0){ 773 if (WEXITSTATUS(status) != EXIT_SUCCESS)
778 num_children--; 774 logwrite(LOG_WARNING, "delivery process with pid %d returned %d\n", pid, WEXITSTATUS(status));
779 if(WEXITSTATUS(status) != EXIT_SUCCESS) 775 if (WIFSIGNALED(status))
780 logwrite(LOG_WARNING, 776 logwrite(LOG_WARNING, "delivery process with pid %d got signal: %d\n", pid, WTERMSIG(status));
781 "delivery process with pid %d returned %d\n", 777 } else {
782 pid, WEXITSTATUS(status)); 778 logwrite(LOG_WARNING, "wait got error: %s\n", strerror(errno));
783 if(WIFSIGNALED(status)) 779 }
784 logwrite(LOG_WARNING, 780 }
785 "delivery process with pid %d got signal: %d\n", 781
786 pid, WTERMSIG(status)); 782 return ok;
787 }else{
788 logwrite(LOG_WARNING, "wait got error: %s\n", strerror(errno));
789 }
790 }
791
792 return ok;
793 } 783 }
794 784
795 /* function just to log into a pop server, 785 /* function just to log into a pop server,
796 for pop_before_smtp (or is it smtp_after_pop?) 786 for pop_before_smtp (or is it smtp_after_pop?)
797 */ 787 */
798 788
799 gboolean pop3_login(gchar *host, gint port, GList *resolve_list, 789 gboolean
800 gchar *user, gchar *pass, guint flags) 790 pop3_login(gchar * host, gint port, GList * resolve_list, gchar * user, gchar * pass, guint flags)
801 { 791 {
802 gboolean ok = FALSE; 792 gboolean ok = FALSE;
803 pop3_base *popb; 793 pop3_base *popb;
804 794
805 signal(SIGCHLD, SIG_IGN); 795 signal(SIGCHLD, SIG_IGN);
806 796
807 if((popb = pop3_in_open(host, port, resolve_list, flags))){ 797 if ((popb = pop3_in_open(host, port, resolve_list, flags))) {
808 if(pop3_in_init(popb)){ 798 if (pop3_in_init(popb)) {
809 if(pop3_in_login(popb, user, pass)) 799 if (pop3_in_login(popb, user, pass))
810 ok = TRUE; 800 ok = TRUE;
811 else 801 else
812 logwrite(LOG_ALERT|LOG_VERBOSE, 802 logwrite(LOG_ALERT | LOG_VERBOSE, "pop3 login failed for user %s, host = %s\n", user, host);
813 "pop3 login failed for user %s, host = %s\n", user, host); 803 }
814 } 804 pop3_in_close(popb);
815 pop3_in_close(popb); 805 }
816 } 806 return ok;
817 return ok;
818 } 807 }
819 808
820 #endif 809 #endif