wmpop3lb: Add version 2.4.2 to repository.
[dockapps.git] / wmpop3lb / wmpop3 / wmpop3.c
bloba7f4649b35976ee1f19d92aeef27abfdb6808d06
1 /*
2 * wmpop3.c
3 * multi pop3 mail checker.
4 * written by Louis-Benoit JOURDAIN (lb@jourdain.org)
5 * based on the original work by Scott Holden (scotth@thezone.net)
7 */
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <ctype.h>
13 #include <string.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include <time.h>
18 #include <sys/socket.h>
19 #include <sys/stat.h>
20 #include <sys/param.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <sys/ioctl.h>
25 #include <X11/xpm.h>
26 #include <X11/Xlib.h>
27 #include <X11/extensions/shape.h>
29 #include <dirent.h>
31 #include "../wmgeneral/misc.h"
32 #include "../wmgeneral/wmgeneral.h"
33 #include "Pop3Client.h"
35 #include "wmpop3.xpm"
37 char wminet_mask_bits[64*64];
38 int wminet_mask_width = 64;
39 int wminet_mask_height = 64;
41 char *ProgName;
43 char mailclient[32] = "pine";
44 char password[32];
45 char username[32];
46 char popserver[128];
47 int serverport = 110;
48 int mailCheckDelay = 10; /* default */
49 int autoChecking = YES; /* default */
50 int newMessagesOnly = YES; /* default */
51 int displaydelay = 1;
52 char tempdir[1024];
53 char config_file[256] = "not-defined";
54 int scrollspeed = 100;
56 Pop3 conf[6];
57 int nb_conf; /* number of configured pop servers */
58 int summess; /* total number of messages */
59 int color;
61 #ifdef _DEBUG
62 int haspassed = 0;
63 #endif
65 t_scrollbar scrollbar;
67 void usage(void);
68 void printversion(void);
69 void wmCheckMail_routine(int, char **);
70 int readConfigFile( char *filename );
72 void BlitString(char *name, int x, int y, int fragment);
73 void BlitNum(int num, int x, int y, int todelete);
75 int pop3DeleteMail(int num, Pop3 pc);
76 int pop3VerifStats(Pop3 pc);
78 /********************************
79 * Main Program
80 ********************************/
81 void deleteoldtmpfiles()
83 char buf[1024];
84 DIR *dir;
85 struct dirent *dp;
87 if (tempdir) {
88 if ((dir = opendir(tempdir))) {
89 chdir(tempdir);
90 while((dp = readdir(dir))) {
91 if (!strncmp(dp->d_name, TMPPREFIX, TMPPREFIXLEN)) {
92 sprintf(buf, "%s/%s", tempdir, dp->d_name);
93 #ifdef _DEBUG
94 printf(" delete old tmp file: %s\n", buf);
95 #endif
96 unlink(buf);
99 closedir(dir);
104 int main(int argc, char *argv[]) {
106 int i;
108 ProgName = argv[0];
109 if (strlen(ProgName) >= 5)
110 ProgName += (strlen(ProgName) - 5);
112 for (i=1; i<argc; i++) {
113 char *arg = argv[i];
115 if (*arg=='-') {
116 switch (arg[1]) {
117 case 'd' :
118 if (strcmp(arg+1, "display")) {
119 usage();
120 exit(1);
122 break;
123 case 'g' :
124 if (strcmp(arg+1, "geometry")) {
125 usage();
126 exit(1);
128 break;
129 case 'v' :
130 printversion();
131 exit(0);
132 break;
133 case 'c' :
134 if (argc > (i+1))
136 strcpy(config_file, argv[i+1]);
137 i++;
139 break;
140 default:
141 usage();
142 exit(0);
143 break;
147 wmCheckMail_routine(argc, argv);
149 return 0;
152 void build_line(char *buf, int num, int index, Pop3 pc)
154 int len;
155 int pos;
156 char tmp[256];
158 /* display spaces in case alias is less than 3 char long */
159 memset(tmp, ' ', sizeof(char) * 3);
160 memset(tmp + 3, 0, sizeof(char) * (256 - 3));
161 memcpy(tmp, pc->alias, strlen(pc->alias));
162 tmp[3] = ':';
163 pos = 4;
164 for (len = 0; len < MAIL_BUFLEN && pc->mails[num].from[len]; len++);
165 memcpy(tmp + pos, pc->mails[num].from, len);
166 tmp[pos + len] = '/';
167 pos += len + 1;
168 for (len = 0; len < MAIL_BUFLEN && pc->mails[num].subject[len]; len++);
169 memcpy(tmp + pos, pc->mails[num].subject, len);
170 len += pos;
171 tmp[len++] = ' ';
172 tmp[len++] = '*';
173 tmp[len++] = ' ';
174 tmp[len] = '\0';
175 pos = index % len;
176 if (len - pos < (NB_DISP + EXTRA)) { /* We are at the end of the string */
177 memcpy(buf, tmp + pos, len - pos);
178 memcpy(buf + len - pos, tmp, (NB_DISP + EXTRA) - len + pos);
180 else {
181 memcpy(buf, tmp + pos, NB_DISP + EXTRA);
185 void display_index(int mail_index, int line, Pop3 pc)
187 #ifdef _DEBUG
188 if (haspassed) {
189 printf(" mail_index: %d, line: %d, todelete: %d\n",
190 mail_index, line, pc->mails[mail_index].todelete);
192 #endif
193 if (pc->mails[mail_index].todelete) {
194 copyXPMArea(67, 12, 2, 5, 7, (line * 6) + TOP_MARGIN);
196 else {
197 copyXPMArea(69, 11, 2, 6, 7, (line * 6) + TOP_MARGIN - 1);
201 void ClearDisplay() {
202 int i;
204 copyXPMArea(72, 4, 3, 42, LEFT_MARGIN, 4);
205 copyXPMArea(72, 4, 50, 42, 9, 4 );
206 for (i = 0; i < NB_LINE; i++) {
207 copyXPMArea(69, 11, 2, 6, 7, (i * 6) + TOP_MARGIN - 1);
211 /* return < 0 if error
212 0 if no pb
213 else nb of mails which couldn't be deleted */
214 int DeleteMail(Pop3 pc)
216 int etat = 0;
217 int old_sizeOfAllMessages;
218 int i;
220 old_sizeOfAllMessages = pc->sizeOfAllMessages;
221 BlitString(pc->alias, 10, TOP_MARGIN, 0);
222 BlitString("connect", 10, 6*2 + TOP_MARGIN, 0);
223 RedrawWindow();
224 etat = pop3MakeConnection(pc, pc->popserver, pc->serverport);
225 if (-1 != etat) {
226 BlitString("login", 10, (6*3) + TOP_MARGIN, 0);
227 RedrawWindow();
228 etat = pop3Login(pc, pc->username, pc->password);
230 if (-1 != etat) {
231 BlitString("chk cont", 10, (6*4) + TOP_MARGIN, 0);
232 RedrawWindow();
233 etat = pop3VerifStats(pc);
235 if (-1 != etat) {
236 if (etat != old_sizeOfAllMessages) {
237 BlitString("mailbox", 10, TOP_MARGIN, 0);
238 BlitString("content", 10, 6 + TOP_MARGIN, 0);
239 BlitString("changed", 10, 6*2 + TOP_MARGIN, 0);
240 BlitString("between", 10, 6*3 + TOP_MARGIN, 0);
241 BlitString("updates", 10, 6*4 + TOP_MARGIN, 0);
242 BlitString("del can.", 10, 6*6 + TOP_MARGIN, 0);
243 RedrawWindow();
244 sleep(displaydelay);
245 for (i = 0, etat = 0; i < pc->numOfMessages; i++) {
246 etat += pc->mails[i].todelete;
249 else {
250 etat = 0;
251 for (i = 0; i < pc->numOfMessages; i++) {
252 if (pc->mails[i].todelete) {
253 etat += pop3DeleteMail(i + 1, pc);
258 pop3Quit(pc);
259 return (etat);
263 void launch_mail_client(int iS)
265 int i;
266 int j;
267 char str[16];
268 char **args;
270 ClearDisplay();
271 if ((args = conf[iS]->mailclient)) {
272 BlitString("starting", 10, TOP_MARGIN, 0);
273 for (i = 0; i < 5 && args[i]; i++) {
274 for (j = 0; j < 8 && args[i][j]; j++);
275 memcpy(str, args[i], j);
276 str[j] = '\0';
277 BlitString(str, 10, (i + 2)*6 + TOP_MARGIN, 0);
279 if (0 == fork()) {
280 if (execvp(args[0], args)) {
281 perror("execvp");
282 copyXPMArea(72, 4, 3, 42, LEFT_MARGIN, 4);
283 copyXPMArea(72, 4, 50, 6, 9, 4 );
284 copyXPMArea(69, 11, 2, 6, 7, TOP_MARGIN - 1);
285 BlitString("Error", 10, TOP_MARGIN, 0);
288 else {
289 conf[iS]->nextCheckTime = time(0) + 30;
292 else {
293 BlitString(" mail", 10, TOP_MARGIN, 0);
294 BlitString(" client", 10, 6 + TOP_MARGIN, 0);
295 BlitString("not set", 10, 6*2 + TOP_MARGIN, 0);
296 BlitString(" check", 15, 6*5 + TOP_MARGIN, 0);
297 BlitString("wmpop3rc", 10, 6*6 + TOP_MARGIN, 0);
299 RedrawWindow();
300 sleep(displaydelay);
304 void display_scrollbar(int index, int totalmessages,
305 int maxlines, int scrollmode)
307 int delta;
308 int scrollen;
309 int vertpos;
311 if (totalmessages <= maxlines) {
312 #ifdef _DEBUG
313 if (haspassed)
314 printf(" full scrollbar\n");
315 #endif
316 copyXPMArea((scrollmode) ? 68 : 65, 18, SCROLL_W,
317 SCROLL_H + (2 * SCROLL_EXT), SCROLL_LX, SCROLL_TY);
318 scrollbar.top = SCROLL_TY;
319 scrollbar.bottom = SCROLL_TY + SCROLL_H;
320 scrollbar.allowedspace = SCROLL_H;
322 else {
323 delta = totalmessages - maxlines;
324 /* determine the size of the scrollbar */
325 if (0 >= (scrollen = SCROLL_H - ((SCROLL_H / maxlines) * delta)))
326 scrollen = 1;
327 /* determine the position */
328 scrollbar.allowedspace = SCROLL_H - scrollen;
329 vertpos = scrollbar.allowedspace * index / delta;
330 copyXPMArea((scrollmode) ? 68 : 65, 18, SCROLL_W, SCROLL_EXT,
331 SCROLL_LX, vertpos + SCROLL_TY);
332 copyXPMArea((scrollmode) ? 68 : 65, 18 + SCROLL_EXT, SCROLL_W, scrollen,
333 SCROLL_LX, vertpos + SCROLL_TY + SCROLL_EXT);
334 copyXPMArea((scrollmode) ? 68 : 65, 18 + SCROLL_EXT + SCROLL_H,
335 SCROLL_W, SCROLL_EXT,
336 SCROLL_LX, vertpos + SCROLL_TY + SCROLL_EXT + scrollen);
337 scrollbar.top = vertpos + SCROLL_TY;
338 scrollbar.bottom = vertpos + SCROLL_TY + (SCROLL_EXT * 2) + scrollen;
340 #ifdef _DEBUG
341 if (haspassed) {
342 printf(" index: %d, totalmess:%d, mxli: %d, delta: %d, vertpos: %d, allowedspace: %d, sl:%d\n",
343 index, totalmessages, maxlines, delta, vertpos,
344 scrollbar.allowedspace, scrollen);
346 #endif
348 /* RedrawWindow(); */
351 int is_for_each_mail(char **command)
353 int i;
355 if (command) {
356 for (i = 0; command[i]; i++) {
357 if ('%' == command[i][0]) {
358 if (('f' == command[i][1]) ||
359 ('s' == command[i][1]) ||
360 ('m' == command[i][1]) ||
361 ('n' == command[i][1]))
362 return (1);
366 return (0);
369 char *quotify(char *str)
371 char *retour;
372 int len;
374 len = strlen(str);
375 if (NULL != (retour = (char *) malloc(sizeof(char) * len + 3))) {
376 retour[0] = '\'';
377 memcpy(retour + 1, str, len);
378 retour[len + 1] = '\'';
379 retour[len + 2] = '\0';
381 return (retour);
384 /* nb: number of the mail on the server - 1 (if -1: for all mails)
385 path: allocated buffer to store path of tmp file
386 newonly: only for new messages
387 onlyselected: only for selected messages
388 pc: main struct.
389 on success return 0 */
390 int writemailstofile(int nb, char *path, int newonly,
391 int onlyselected, Pop3 pc)
393 int fd;
394 int len;
395 int i;
396 int retour = 0;
397 int goforwritemail = 0;
398 int mustdisconnect = 0;
400 len = strlen(tempdir);
401 if (len) {
402 path[0] = '\0';
403 strcat(path, tempdir);
404 if ('/' != tempdir[len - 1])
405 strcat(path, "/");
406 strcat(path, TMPPREFIX);
407 strcat(path, "XXXXXX");
408 #ifdef _DEBUG
409 printf(" creating temporary file [%s]\n", path);
410 printf(" nb=%d, newonly=%d, onlyselected=%d\n",
411 nb, newonly, onlyselected);
412 #endif
413 if (-1 == (fd = mkstemp(path))) {
414 fprintf(stderr, "Error: writing mail to file\n");
415 perror(path);
416 retour++;
418 else {
419 /* to prevent connecting many times, do it now. */
420 if (NOT_CONNECTED == pc->connected) {
421 #ifdef _DEBUG
422 printf(" writemailstofile not connected, connecting\n");
423 #endif
424 if (pop3MakeConnection(pc,pc->popserver,pc->serverport) == -1){
425 return (1);
427 if (pop3Login(pc, pc->username, pc->password) == -1) {
428 return (1);
430 mustdisconnect = 1;
433 if (nb < 0) {
434 /* concatenate all the mails into 1 file */
435 for (i = 0; i < pc->numOfMessages; i++) {
436 goforwritemail = 0;
437 #ifdef _DEBUG
438 printf(" mail %d:", i);
439 #endif
440 if (!newonly && !onlyselected) {
441 #ifdef _DEBUG
442 printf(" !newonly && !onlyselected\n");
443 #endif
444 goforwritemail = 1;
446 else if (newonly) {
447 if (pc->mails[i].new &&
448 (!onlyselected || (onlyselected && pc->mails[i].todelete))) {
449 #ifdef _DEBUG
450 printf(" newonly\n");
451 #endif
452 goforwritemail = 1;
455 else if (onlyselected && pc->mails[i].todelete) {
456 #ifdef _DEBUG
457 printf(" onlyselected\n");
458 #endif
459 goforwritemail = 1;
461 if (goforwritemail) {
462 /* put the mail separator */
463 if (strlen(pc->mailseparator)) {
464 #ifdef _DEBUG
465 printf(" pc->mailseparator: [%s]\n", pc->mailseparator);
466 #endif
467 write(fd, pc->mailseparator, strlen(pc->mailseparator));
469 else {
470 #ifdef _DEBUG
471 printf(" TXT_SEPARATOR: [%s]\n", TXT_SEPARATOR);
472 #endif
473 write(fd, TXT_SEPARATOR, strlen(TXT_SEPARATOR));
475 if (pop3WriteOneMail(i + 1, fd, pc)) {
476 retour++;
482 else {
483 if (pop3WriteOneMail(nb + 1, fd, pc))
484 retour++;
486 close(fd);
487 /* close the connection if we've opened it */
488 if (mustdisconnect) {
489 #ifdef _DEBUG
490 printf(" writemailstofile disconnecting\n");
491 #endif
492 pop3Quit(pc);
496 else {
497 fprintf(stderr, "no tempdir configured, can't create file\n");
498 retour++;
500 return (retour);
504 * do_command_completion
505 * returned array should be freed by calling function
506 * if nbnewmail == 0, for %c option concatenate _all_ the messages
508 char **do_command_completion(int num, char **command,
509 int nbnewmail, Pop3 pc)
511 char **retour;
512 int i;
513 int yaerreur = 0;
514 char path[1024];
516 for (i = 0; command[i]; i++);
517 #ifdef _DEBUG
518 printf(" %d args to the command, mail num %d\n", i, num);
519 #endif
520 if (NULL == (retour = (char **) malloc (sizeof(char *) * i + 1))) {
521 return (NULL);
523 memset(retour, 0, sizeof(char *) * i + 1);
524 for (i = 0; command[i]; i++) {
525 #ifdef _DEBUG
526 printf(" arg %d: [%s]\n", i, command[i]);
527 #endif
528 if ('%' == command[i][0]) {
529 switch (command[i][1]) {
530 case 'T': /* total nb of mails */
531 if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
532 sprintf(retour[i], "%d", pc->numOfMessages);
533 else
534 yaerreur = 1;
535 break;
536 case 't': /* total nb of new mails */
537 if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
538 sprintf(retour[i], "%d", (nbnewmail < 0) ? 0 : 1);
539 else
540 yaerreur = 1;
541 break;
542 case 'C': /* concatenate all the selected mails in 1 file */
543 if (writemailstofile(-1, path, 0, SELECTONLY, pc))
544 yaerreur = 1;
545 else
546 if (NULL == (retour[i] = strdup(path))) {
547 yaerreur = 1;
549 break;
550 case 'c': /* concatenate all the mails in 1 file */
551 if (writemailstofile(-1, path, (nbnewmail > 0), NOSELECTONLY, pc))
552 yaerreur = 1;
553 else
554 if (NULL == (retour[i] = strdup(path))) {
555 yaerreur = 1;
557 break;
558 case 'f': /* from field */
559 #ifdef _DEBUG
560 printf(" from field: [%s]\n", pc->mails[num].from);
561 #endif
562 if (NULL == (retour[i] = quotify(pc->mails[num].from)))
563 yaerreur = 1;
564 break;
565 case 's': /* subject of the mail */
566 #ifdef _DEBUG
567 printf(" subject field: [%s]\n", pc->mails[num].subject);
568 #endif
569 if (NULL == (retour[i] = quotify(pc->mails[num].subject)))
570 yaerreur = 1;
571 break;
572 case 'm': /* copy the mail to tmp file */
573 if (0 <= num) {
574 if (writemailstofile(num, path, (nbnewmail > 0), NOSELECTONLY, pc))
575 yaerreur = 1;
576 else
577 if (NULL == (retour[i] = strdup(path))) {
578 yaerreur = 1;
581 break;
582 case 'n': /* number of the message on the mail server */
583 if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
584 sprintf(retour[i], "%d", num + 1);
585 else
586 yaerreur = 1;
587 break;
588 case 'S': /* server name */
589 if (NULL == (retour[i] = strdup(pc->popserver)))
590 yaerreur = 1;
591 break;
592 case 'a': /* server alias */
593 if (NULL == (retour[i] = strdup(pc->alias)))
594 yaerreur = 1;
595 break;
596 case 'u': /* user name */
597 if (NULL == (retour[i] = strdup(pc->username)))
598 yaerreur = 1;
599 break;
600 case 'w': /* user password */
601 if (NULL == (retour[i] = strdup(pc->password)))
602 yaerreur = 1;
603 break;
604 case 'P': /* server port */
605 if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
606 sprintf(retour[i], "%d", pc->serverport);
607 else
608 yaerreur = 1;
609 break;
610 case '%': /* % character, leave in place */
611 if (NULL == (retour[i] = strdup(command[i])))
612 yaerreur = 1;
613 break;
614 default:
615 break;
618 else {
619 #ifdef _DEBUG
620 printf(" just copying arg [%s]\n", command[i]);
621 #endif
622 if (NULL == (retour[i] = strdup(command[i])))
623 yaerreur = 1;
626 retour[i] = NULL;
627 #ifdef _DEBUG
628 printf(" retour: %ld\n", (long) retour);
629 #endif
630 if (!yaerreur)
631 return (retour);
632 else
633 return (NULL);
636 /* num is the index of the mail in the mail array
637 if num == -1, means that the command isn't for each mail */
640 void spawn_command(int num, char **command, int nbnewmail,
641 char *display, Pop3 pc)
643 char **tmpcommand;
644 char str[16];
645 int i, j;
647 if (display) {
648 ClearDisplay();
649 if (!command) {
650 BlitString(display, 10, 6 + TOP_MARGIN, 0);
651 BlitString("not set", 10, 6*2 + TOP_MARGIN, 0);
652 BlitString(" check", 15, 6*5 + TOP_MARGIN, 0);
653 BlitString("wmpop3rc", 10, 6*6 + TOP_MARGIN, 0);
655 else {
656 BlitString("starting", 10, TOP_MARGIN, 0);
657 for (i = 0; i < 5 && command[i]; i++) {
658 for (j = 0; j < 8 && command[i][j]; j++);
659 memcpy(str, command[i], j);
660 str[j] = '\0';
661 BlitString(str, 10, (i + 2)*6 + TOP_MARGIN, 0);
663 RedrawWindow();
666 if (command) {
667 /* check for any '%' sign in the command and complete it */
668 tmpcommand = do_command_completion(num, command, nbnewmail, pc);
669 if (tmpcommand) {
670 /* launch the command in a new process */
671 if (0 == fork()) {
672 #ifdef _DEBUG
673 printf(" spawning command: [");
674 for (i = 0; tmpcommand[i]; i++) {
675 printf(" %s ", tmpcommand[i]);
677 printf("]\n");
678 #endif
679 if (execvp(tmpcommand[0], tmpcommand)) {
680 perror("execvp");
683 else {
684 if (display) {
685 /* set the check delay to 30 seconds */
686 pc->nextCheckTime = time(0) + 30;
688 /* free the memory (in the parent process...) */
689 for (i = 0; tmpcommand[i]; i++) {
690 free (tmpcommand[i]);
692 free (tmpcommand);
695 else {
696 if (display) {
697 ClearDisplay();
698 BlitString(" Error", 15, TOP_MARGIN, 0);
699 BlitString(" While", 15, 6*2 + TOP_MARGIN, 0);
700 BlitString("parsing", 15, 6*3 + TOP_MARGIN, 0);
701 BlitString("command", 15, 6*4 +TOP_MARGIN, 0);
702 BlitString(display, 10, 6*6 + TOP_MARGIN, 0);
703 fprintf(stderr, "Error while parsing %s\n", display);
705 else
706 fprintf(stderr, "Error while parsing command\n");
709 if (display) {
710 RedrawWindow();
711 sleep(displaydelay);
716 * wmCheckMail_routine : This function is used to set up the X display
717 * for wmpop3 and check for mail every n number of minutes.
720 void wmCheckMail_routine(int argc, char **argv){
722 int buttonStatus = -1;
723 int iS;
724 Pop3 pc;
725 int i, j, k;
726 XEvent Event;
727 char str[256];
728 int index = 0;
729 int fragment = 0;
730 int index_vert = 0;
731 int oldnbmess = 0;
732 int nbsel;
733 int selectedmess;
734 int justreloaded;
735 long thistime;
736 char *linestodel[7];
737 int unreachable;
738 long sleeplenght;
739 int scrollmode = 0;
740 int nbnewmail;
741 char separ;
743 if( !strcmp( config_file, "not-defined") )
744 sprintf(config_file, "%s/.wmpop3rc", getenv("HOME"));
746 if( readConfigFile(config_file) == -1){
747 exit(0);
749 /* Set up timer for checking mail */
750 createXBMfromXPM(wminet_mask_bits, wmpop3_xpm
751 , wminet_mask_width, wminet_mask_height);
753 openXwindow(argc, argv, wmpop3_xpm, wminet_mask_bits
754 , wminet_mask_width, wminet_mask_height);
756 AddMouseRegion(0, 19, 49, 30, 58); /* check button */
757 AddMouseRegion(1, 46, 49, 50, 58 ); /* autocheck button */
758 AddMouseRegion(2, 53, 49, 57, 58 ); /* switch display button */
759 AddMouseRegion(3, 5, 49, 16, 58 ); /* delete button */
760 AddMouseRegion(4, 33, 49, 44, 53); /* top arrow */
761 AddMouseRegion(5, 33, 54, 44, 58); /* botton arrow */
762 /* add the mouse regions for each line */
763 for (i = 0; i < NB_LINE; i++) {
764 AddMouseRegion(6 + i, 9, (i*6) + TOP_MARGIN,
765 58, (i*6) + TOP_MARGIN + CHAR_HEIGHT);
769 /* Check if Autochecking is on or off */
770 if(autoChecking == NO ){
771 copyXPMArea(142, 38, 7, 11, 45, 48);
773 else {
774 copyXPMArea(142, 49, 7, 11, 45, 48);
777 RedrawWindow();
779 summess = 0;
781 deleteoldtmpfiles();
783 sleeplenght = (long) 20000L + (20000L - (20000L * scrollspeed / 100));
784 while (1) {
785 RSET_COLOR;
786 for (iS = 0; iS < nb_conf; iS++) {
787 pc = conf[iS];
788 if( (((time(0) > pc->nextCheckTime) ||
789 (pc->nextCheckTime == 0)) && ( autoChecking == YES))
790 || (pc->forcedCheck == YES)){
791 justreloaded = 1;
792 ClearDisplay();
793 BlitString(pc->alias, 10, TOP_MARGIN, 0);
794 BlitString("connect", 10, (6*2) + TOP_MARGIN, 0);
795 RedrawWindow();
796 pc->status = 0;
797 if(pop3MakeConnection(pc,pc->popserver,pc->serverport) == -1){
798 pc->status = 1;
800 if (!pc->status) {
801 BlitString("login", 10, (6*3) + TOP_MARGIN, 0);
802 RedrawWindow();
803 if (pop3Login(pc, pc->username, pc->password) == -1 )
804 pc->status = 2;
806 if (!pc->status) {
807 BlitString("get mail", 10, (6*4) + TOP_MARGIN, 0);
808 RedrawWindow();
809 if (pop3CheckMail(pc) == -1)
810 pc->status = 3;
812 pc->nextCheckTime = time(0) + (pc->mailCheckDelay * SEC_IN_MIN);
813 index = 0;
814 pc->forcedCheck = NO;
815 /* check if new mail has arrived */
816 for (i = 0, nbnewmail = 0; i < pc->numOfMessages; i++)
817 if (pc->mails[i].new)
818 nbnewmail++;
819 /* launch the new mail command */
820 if (pc->newmailcommand && (-1 != pc->sizechanged)) {
821 if (nbnewmail) {
822 #ifdef _DEBUG
823 printf(" %d New mail(s) ha(s)(ve) arrived!\n", nbnewmail);
824 #endif
825 if (is_for_each_mail(pc->newmailcommand)) {
826 for (i = 0; i < pc->numOfMessages; i++)
827 if (pc->mails[i].new)
828 spawn_command(i, pc->newmailcommand, nbnewmail, NULL, pc);
830 else {
831 spawn_command(-1, pc->newmailcommand, nbnewmail, NULL, pc);
835 /* close the connection */
836 pop3Quit(pc);
837 pc->sizechanged = 0;
840 waitpid(0, NULL, WNOHANG);
841 /* reset the number of messages */
842 unreachable = 1;
843 for (summess = 0, iS = 0; iS < nb_conf; iS++) {
844 pc = conf[iS];
845 if (!pc->status) {
846 unreachable = 0;
847 summess += pc->numOfMessages;
850 /* set the offset from the beginning of the list */
851 if (summess != oldnbmess) {
852 oldnbmess = summess;
853 if (summess < NB_LINE)
854 index_vert = 0;
855 else {
856 index_vert = summess - NB_LINE;
859 memset(str, 0, 128);
860 /* clear the display */
861 ClearDisplay();
862 nbsel = 0;
863 for (iS = 0; iS < nb_conf; iS++) {
864 pc = conf[iS];
865 for (i = 0; i < summess && i < pc->numOfMessages; i++) {
866 #ifdef _DEBUG
867 if (haspassed) {
868 printf(" %s, mails[%d], todelete=%d\n",
869 pc->alias, i, pc->mails[i].todelete);
871 #endif
872 nbsel += pc->mails[i].todelete;
875 if (justreloaded) {
876 /* make sure we display the correct buttons */
877 justreloaded = 0;
878 if ((NO == newMessagesOnly) && nbsel)
879 copyXPMArea(128,49 ,14 ,11 ,18 ,48 );
880 else
881 copyXPMArea(128,27 ,14 ,11 ,18 ,48 );
883 if (newMessagesOnly == YES ){
884 /* Show messages waiting */
885 RSET_COLOR;
886 for (color = 0, iS = 0; iS < nb_conf; iS++) {
887 pc = conf[iS];
888 if (pc->countunreadonly)
889 separ = '-';
890 else
891 separ = ':';
892 switch(pc->status) {
893 case 1:
894 sprintf(str, "%-3s%cC*ER", pc->alias, separ);
895 break;
896 case 2:
897 sprintf(str, "%-3s%cL*ER", pc->alias, separ);
898 break;
899 case 3:
900 sprintf(str, "%-3s%cM*ER", pc->alias, separ);
901 break;
902 default:
903 sprintf(str, "%-3s%c %3d", pc->alias, separ,
904 (pc->countunreadonly) ? pc->numOfUnreadMessages :
905 pc->numOfMessages);
906 break;
908 BlitString(str, 10, (int) (6*iS) + TOP_MARGIN, 0);
909 SWAP_COLOR;
911 RSET_COLOR;
912 sprintf(str, "sel.: %2d", nbsel);
913 BlitString(str, 10, (int) (6*6) + TOP_MARGIN, 0);
915 else {
916 RSET_COLOR;
917 if (0 == summess) {
918 if (unreachable) {
919 BlitString(" error", 10, TOP_MARGIN, 0);
921 else {
922 BlitString("No Mesg", 10, TOP_MARGIN, 0);
924 if (autoChecking == YES) {
925 BlitString(" next", 10, 6*2 + TOP_MARGIN, 0);
926 BlitString(" update", 10, 6*3 + TOP_MARGIN, 0);
927 j = SEC_IN_MIN * 1000;
928 thistime = time(0);
929 for (i = 0, k = 0; i < nb_conf; i++) {
930 if ((conf[i]->nextCheckTime - thistime) < j) {
931 j = conf[i]->nextCheckTime - thistime;
932 k = i;
935 sprintf(str, " is:%s", conf[k]->alias);
936 BlitString(str, 10, 6*4 + TOP_MARGIN, 0);
937 BlitString(" in", 10, 6*5 + TOP_MARGIN, 0);
938 sprintf(str, "%-5d s.", j);
939 BlitString(str, 10, 6*6 + TOP_MARGIN, 0);
942 else {
943 RSET_COLOR;
944 /* iS = index in the conf struct
945 i = index of the mail
946 j = line nb on display */
947 memset(linestodel, 0, sizeof(char *));
948 for (iS = 0, j = 0; iS < nb_conf && j < NB_LINE + index_vert; iS++) {
949 pc = conf[iS];
950 for (i = 0; (j < NB_LINE + index_vert) && i < pc->numOfMessages;
951 j++, i++) {
952 if (j >= index_vert) {
953 build_line(str, i, index, pc);
954 BlitString(str, 10, ((j - index_vert) * 6) + TOP_MARGIN,
955 fragment);
956 display_index(i, (j - index_vert), pc);
957 /* store the address of the delete flag, so that it will */
958 /* be easier to modify it afterwards */
959 linestodel[j - index_vert] = &(pc->mails[i].todelete);
962 SWAP_COLOR;
964 display_scrollbar(index_vert, summess, NB_LINE, scrollmode);
966 fragment++;
967 if (0 == (fragment % (CHAR_WIDTH + 1))) {
968 index++;
969 fragment = 0;
970 /* printf("index=%d, fragment=%d\n", index, fragment); */
973 #ifdef _DEBUG
974 haspassed = 0;
975 #endif
977 RedrawWindow();
979 RSET_COLOR;
980 /* X Events */
981 while (XPending(display)){
982 XNextEvent(display, &Event);
983 switch (Event.type) {
984 case Expose:
985 RedrawWindow();
986 break;
987 case DestroyNotify:
988 XCloseDisplay(display);
989 exit(0);
990 break;
991 case MotionNotify:
992 if (scrollmode) {
993 #ifdef _DEBUG
994 printf(" ca bouge... index_vert before = %d, %d x %d, allowedspace: %d, summess: %d\n",
995 index_vert,
996 Event.xbutton.x, Event.xbutton.y,
997 scrollbar.allowedspace,
998 summess);
1000 #endif
1001 if (summess > NB_LINE) {
1002 index_vert = scrollbar.orig_index_vert +
1003 ((Event.xbutton.y - scrollbar.orig_y) * (summess - NB_LINE) /
1004 scrollbar.allowedspace);
1005 if (0 > index_vert)
1006 index_vert = 0;
1007 if (index_vert + NB_LINE > summess)
1008 index_vert = summess - NB_LINE;
1010 #ifdef _DEBUG
1011 printf(" deplacement de %d pixels --> index_vert = %d\n",
1012 Event.xbutton.y - scrollbar.orig_y, index_vert);
1013 #endif
1015 break;
1016 case ButtonPress:
1017 buttonStatus = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
1018 if (buttonStatus >= 0){
1019 switch (buttonStatus){
1020 case 0 : /* check / open button pressed */
1021 if ((NO == newMessagesOnly) && nbsel)
1022 copyXPMArea(128, 60 ,14 ,11 ,18 ,48 );
1023 else
1024 copyXPMArea(128,38 ,14 ,11 ,18 ,48 );
1025 break;
1026 case 1 : /* autocheck button pressed */
1027 break;
1028 case 2: /* switch display button pressed */
1029 break;
1030 case 3: /* delete button pressed */
1031 copyXPMArea(127, 15, 14, 11, 4, 48);
1032 break;
1033 case 4: /* top arrow button pressed */
1034 break;
1035 case 5: /* bottom arrow button pressed */
1036 break;
1037 default:
1038 break;
1040 RedrawWindow();
1042 else if (SCROLL_LX <= Event.xbutton.x && SCROLL_RX >= Event.xbutton.x
1043 && scrollbar.top <= Event.xbutton.y &&
1044 scrollbar.bottom >= Event.xbutton.y) {
1045 scrollbar.orig_y = Event.xbutton.y;
1046 scrollbar.orig_index_vert = index_vert;
1047 scrollmode = 1;
1049 break;
1050 case ButtonRelease:
1051 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
1053 if (buttonStatus == i && buttonStatus >= 0){
1054 switch (buttonStatus){
1055 case 0 : /* check button */
1056 if (nbsel && !newMessagesOnly) {
1057 copyXPMArea(128,49 ,14 ,11 ,18 ,48 );
1058 /* this is where you launch the open mail command */
1059 for (iS = 0; iS < nb_conf; iS++) {
1060 pc = conf[iS];
1061 for (i = 0, selectedmess = 0; i < pc->numOfMessages; i++) {
1062 if (pc->mails[i].todelete) {
1063 selectedmess = 1;
1064 break;
1067 if (selectedmess) {
1068 #ifdef _DEBUG
1069 printf(" launching selectedmesgcommand command for conf %d\n",
1070 iS);
1071 #endif
1073 if (is_for_each_mail(pc->selectedmesgcommand)) {
1074 #ifdef _DEBUG
1075 if (!pc->numOfMessages) {
1076 printf(" command is for each mail but there's no mail\n");
1078 else
1079 printf(" command is for each mail\n");
1080 #endif
1081 for (i = 0; i < pc->numOfMessages; i++)
1082 spawn_command(i, pc->selectedmesgcommand, 0,
1083 "selectm.", pc);
1085 else {
1086 spawn_command(-1, pc->selectedmesgcommand, 0,
1087 "selectm.", pc);
1092 else {
1093 copyXPMArea(128,27 ,14 ,11 ,18 ,48 );
1094 for (iS = 0; iS < nb_conf; iS++)
1095 conf[iS]->forcedCheck = YES;
1097 break;
1098 case 1 : /* autocheck Button */
1099 if (autoChecking == YES){
1100 autoChecking = NO;
1101 copyXPMArea(142, 38, 7, 11, 45, 48);
1103 else {
1104 autoChecking = YES;
1105 for (iS = 0; iS < nb_conf; iS++)
1106 conf[iS]->nextCheckTime = time(0) +
1107 (conf[iS]->mailCheckDelay * SEC_IN_MIN);
1108 copyXPMArea(142, 49, 7, 11, 45, 48);
1110 break;
1111 case 2: /* switch display Button */
1112 index = 0;
1113 /* change view on # of messages */
1114 if( newMessagesOnly == YES ) {
1115 newMessagesOnly = NO;
1116 copyXPMArea(149,38 , 7 , 11, 52, 48);
1117 if (nbsel) {
1118 copyXPMArea(128,49,14,11,18,48);
1120 else {
1121 copyXPMArea(128,27,14,11,18,48);
1124 else {
1125 newMessagesOnly = YES;
1126 copyXPMArea(149,49 , 7 , 11, 52, 48);
1127 copyXPMArea(128,27,14,11,18,48);
1129 #ifdef _DEBUG
1130 haspassed = 1;
1131 #endif
1132 break;
1133 case 3: /* delete button */
1134 copyXPMArea(143, 15, 14, 11, 4, 48);
1135 j = 0;
1136 RSET_COLOR;
1137 for (iS = 0; iS < nb_conf; iS++) {
1138 pc = conf[iS];
1139 for (i = 0, k = 0; i < pc->numOfMessages; i++)
1140 k += pc->mails[i].todelete;
1141 if (k) {
1142 /* clear the display */
1143 ClearDisplay();
1144 k = DeleteMail(pc);
1145 if (k < 0) {
1146 sprintf(pc->delstatus, "%-3s: Err", pc->alias);
1148 else if (k > 0) {
1149 sprintf(pc->delstatus, "%-3s/D:%2d", pc->alias, k);
1151 else
1152 sprintf(pc->delstatus, "%-3s: ok", pc->alias);
1153 pc->forcedCheck = YES;
1155 else {
1156 sprintf(pc->delstatus, "%-3s:none", pc->alias);
1159 /* clear the display */
1160 ClearDisplay();
1161 RSET_COLOR;
1162 for (iS = 0; iS < nb_conf; iS++) {
1163 BlitString(conf[iS]->delstatus, 10, 6*iS + TOP_MARGIN, 0);
1164 SWAP_COLOR;
1166 RedrawWindow();
1167 sleep(displaydelay);
1168 break;
1169 case 4: /* top arrow button pressed */
1170 index_vert--;
1171 if (0 > index_vert)
1172 index_vert = 0;
1173 #ifdef _DEBUG
1174 haspassed = 1;
1175 #endif
1176 break;
1177 case 5: /* bottom arrow button pressed */
1178 if (summess > NB_LINE) {
1179 index_vert++;
1180 if (index_vert + NB_LINE > summess)
1181 index_vert = summess - NB_LINE;
1183 #ifdef _DEBUG
1184 haspassed = 1;
1185 #endif
1186 break;
1187 default:
1188 if (newMessagesOnly == NO) { /* message view mode */
1189 if ((5 < buttonStatus) && (buttonStatus <= 5 + NB_LINE)) {
1190 if ((buttonStatus - 6 + index_vert) < summess) {
1191 /* first update lines to del */
1192 *(linestodel[buttonStatus - 6]) =
1193 1 - *(linestodel[buttonStatus - 6]);
1194 #ifdef _DEBUG
1195 printf(" button %d pressed, j'update lines to del\n",
1196 buttonStatus - 6);
1197 haspassed = 1;
1198 #endif
1199 nbsel = 0;
1200 for (iS = 0; iS < nb_conf; iS++) {
1201 pc = conf[iS];
1202 for (i = 0; i < pc->numOfMessages; i++) {
1203 nbsel += pc->mails[i].todelete;
1204 #ifdef _DEBUG
1205 printf(" conf %d, mail %d, todelete = %d\n",
1206 iS, i, pc->mails[i].todelete);
1207 #endif
1210 /* display open or reload buttons */
1211 if (nbsel) {
1212 copyXPMArea(128,49,14,11,18,48);
1214 else {
1215 copyXPMArea(128,27,14,11,18,48);
1220 else { /* summary view mode */
1221 if ((5 < buttonStatus) && (buttonStatus <= 5 + nb_conf)) {
1222 if ((Event.xbutton.x > 10) &&
1223 (Event.xbutton.x < (10 + (4 * (CHAR_WIDTH + 1))))) {
1224 #ifdef _DEBUG
1225 printf(" launching command for conf %d\n",
1226 buttonStatus - 6);
1227 #endif
1228 pc = conf[buttonStatus - 6];
1229 if (is_for_each_mail(pc->mailclient)) {
1230 #ifdef _DEBUG
1231 if (!pc->numOfMessages) {
1232 printf(" command is for each mail but there's no mail\n");
1234 #endif
1235 for (i = 0; i < pc->numOfMessages; i++)
1236 spawn_command(i, pc->mailclient, nbnewmail,
1237 "mailcli.", pc);
1239 else {
1240 spawn_command(-1, pc->mailclient, nbnewmail,
1241 "mailcli.", pc);
1244 else if ((Event.xbutton.x > (10 + (4 * (CHAR_WIDTH + 1)))) &&
1245 (Event.xbutton.x < (10 + (8 * (CHAR_WIDTH + 1))))) {
1246 /* swap view mode */
1247 conf[buttonStatus - 6]->countunreadonly =
1248 1 - conf[buttonStatus - 6]->countunreadonly;
1249 #ifdef _DEBUG
1250 printf(" swapping view mode for conf %d: %s\n",
1251 buttonStatus - 6,
1252 (conf[buttonStatus - 6]->countunreadonly) ?
1253 "UnreadMessages" : "TotalMessages");
1255 #endif
1258 else if ((5 + NB_LINE) == buttonStatus) {
1259 /* status summary line pressed */
1260 if ((Event.xbutton.x > 10) &&
1261 (Event.xbutton.x < (10 + (4 * (CHAR_WIDTH + 1))))) {
1262 /* select all messages */
1263 for (iS = 0; iS < nb_conf; iS++) {
1264 for (pc = conf[iS], i = 0; i < pc->numOfMessages; i++) {
1265 pc->mails[i].todelete = 1;
1269 else if ((Event.xbutton.x > (10 + (4 * (CHAR_WIDTH + 1)))) &&
1270 (Event.xbutton.x < (10 + (8 * (CHAR_WIDTH + 1))))) {
1271 /* unselect all messages */
1272 for (iS = 0; iS < nb_conf; iS++) {
1273 for (pc = conf[iS], i = 0; i < pc->numOfMessages; i++) {
1274 pc->mails[i].todelete = 0;
1280 break;
1283 else {
1284 if (buttonStatus >= 0) {
1285 /* button has been pressed correctly but released somewhere else */
1286 switch(buttonStatus) {
1287 case 0: /* check button was pressed */
1288 if ((NO == newMessagesOnly) && nbsel)
1289 copyXPMArea(128,49 ,14 ,11 ,18 ,48 );
1290 else
1291 copyXPMArea(128,27 ,14 ,11 ,18 ,48 );
1292 break;
1293 case 3: /* delete button was pressed */
1294 copyXPMArea(143, 15, 14, 11, 4, 48);
1295 break;
1299 RedrawWindow();
1300 buttonStatus = -1;
1301 scrollmode = 0;
1302 break;
1305 usleep(sleeplenght);
1311 * usage : Prints proper command parameters of wmpop3.
1313 void usage(void)
1315 fprintf(stdout, "\nWMPop3LB - Louis-Benoit JOURDAIN (wmpop3lb@jourdain.org)\n");
1316 fprintf(stdout, "based on the work by Scott Holden <scotth@thezone.net>\n\n");
1317 fprintf(stdout, "usage:\n");
1318 fprintf(stdout, " -display <display name>\n");
1319 fprintf(stdout, " -geometry +XPOS+YPOS initial window position\n");
1320 fprintf(stdout, " -c <filename> use specified config file\n");
1321 fprintf(stdout, " -h this help screen\n");
1322 fprintf(stdout, " -v print the version number\n");
1323 fprintf(stdout, "\n");
1326 void printversion(void)
1328 fprintf(stdout, "wmpop3 v%s\n", WMPOP3_VERSION);
1331 // Blits a string at given co-ordinates
1332 void BlitString(char *name, int x, int y, int fragment)
1334 int i;
1335 int c;
1336 int k;
1337 int row;
1339 /* printf("--name: [%s] \n", name); */
1340 for (i = 0, k = x; name[i]; i++) {
1341 c = toupper(name[i]);
1342 if (c >= 'A' && c <= 'Z') { /* its a letter */
1343 c -= 'A';
1344 row = LETTERS;
1346 else if (c >= '0' && c <= '9') { /* its a number */
1347 c -= '0';
1348 row = NUMBERS;
1350 else switch(c) {
1351 case '-':
1352 c = 26;
1353 row = LETTERS;
1354 break;
1355 case '*':
1356 c = 27;
1357 row = LETTERS;
1358 break;
1359 case ':':
1360 c = 10;
1361 row = NUMBERS;
1362 break;
1363 case '/':
1364 c = 11;
1365 row = NUMBERS;
1366 break;
1367 case '@':
1368 c = 12;
1369 row = NUMBERS;
1370 break;
1371 case '%':
1372 c = 15;
1373 row = NUMBERS;
1374 break;
1375 case ' ':
1376 c = 13;
1377 row = NUMBERS;
1378 break;
1379 case '.':
1380 c = 28;
1381 row = LETTERS;
1382 break;
1383 default:
1384 c = 14;
1385 row = NUMBERS;
1386 break;
1388 /* printf("c:%2d (%c), fragment: %d, i:%d, k=%d ",
1389 c, name[i], fragment, i, k); */
1390 if (i > 0 && i < NB_DISP) {
1391 copyXPMArea(c * CHAR_WIDTH, CH_COLOR(row), CHAR_WIDTH + 1, CHAR_HEIGHT,
1392 k, y);
1393 /* printf(" - k1: %d += %d + 1", k, CHAR_WIDTH); */
1394 k += CHAR_WIDTH + 1;
1396 else if (0 == i) {
1397 copyXPMArea(c * CHAR_WIDTH + fragment, CH_COLOR(row),
1398 CHAR_WIDTH + 1 - fragment, CHAR_HEIGHT,
1399 k, y);
1400 /* printf(" - k2: %d += %d + 1 - %d", k, CHAR_WIDTH, fragment); */
1401 k += CHAR_WIDTH + 1 - fragment;
1403 else if (fragment && (NB_DISP == i)) {
1404 copyXPMArea(c * CHAR_WIDTH, CH_COLOR(row), fragment + 1, CHAR_HEIGHT,
1405 k, y);
1406 /* printf(" - k3: %d += %d ", k, fragment); */
1407 k += fragment;
1409 /* printf(" -- apres k=%d\n", k); */
1414 /* Blits number to given coordinates...*/
1416 void BlitNum(int num, int x, int y, int todelete)
1418 if (todelete)
1419 num += 19;
1420 copyXPMArea(((num - 1) * (SN_CHAR_W + 1)) + 1, CH_COLOR(SMALL_NUM),
1421 SN_CHAR_W, CHAR_HEIGHT + 1, x, y);
1424 int parsestring(char *buf, char *data, int max, FILE *fp)
1426 char *deb;
1427 char *end;
1428 char *bal;
1429 int go = 1;
1430 int linelen = 0;
1432 /* trim the leading spaces */
1433 memset(data, 0, max);
1434 for (deb = buf; *deb && isspace(*deb); deb++);
1435 if (!*deb)
1436 return (-1);
1437 if ('"' == *deb) {
1438 ++deb;
1439 bal = data;
1440 while (go) {
1441 #ifdef _DEBUG
1442 printf(" line to parse: [%s]\n", deb);
1443 #endif
1444 /* get to the end of the line */
1445 for (end = deb; *end && ('"' != *end); end++);
1446 if (!*end) { /* this is a multiline entry */
1447 linelen += (int) (end - deb);
1448 if (linelen > max) {
1449 #ifdef _DEBUG
1450 printf(" maximum line length reached\n");
1451 #endif
1452 return (-1);
1454 memcpy(bal, deb, (int) (end - deb));
1455 bal = data + linelen;
1456 if (fgets(buf, CONF_BUFLEN, fp)) {
1457 deb = buf;
1459 else { /* end of file reached */
1460 return (-1);
1463 else {
1464 memcpy(bal, deb, end - deb);
1465 go = 0;
1469 else {
1470 for (end = deb; *end && !isspace(*end); end++);
1471 memcpy(data, deb, ((end - deb) > max) ? max : end - deb);
1473 #ifdef _DEBUG
1474 printf(" parsed string (len=%d) : [%s]\n", strlen(data), data);
1475 #endif
1476 return (0);
1479 int parsenum(char *buf, int *data)
1481 char *deb;
1482 char *end;
1483 char temp[32];
1485 memset(temp, 0, 32);
1486 for (deb = buf; *deb && isspace(*deb); deb++);
1487 if (!*deb)
1488 return (-1);
1489 if ('"' == *deb) {
1490 for (end = ++deb; *end && ('"' != *end); end++);
1491 if (!*end)
1492 return (-1);
1493 memcpy(temp, deb, end - deb);
1494 *data = atoi(temp);
1496 else {
1497 for (end = deb; *end && !isspace(*end); end++);
1498 memcpy(temp, deb, end - deb);
1499 *data = atoi(temp);
1501 return (0);
1504 char **build_arg_list(char *buf, int len)
1506 int espaces;
1507 int i, j;
1508 char **retour;
1510 /* count number of args */
1511 for (espaces = 0, i = 0; buf[i] && i < len; i++)
1512 if (isspace(buf[i]))
1513 espaces++;
1514 /* allocate space for the structure */
1515 if (NULL == (retour = (char **) malloc(sizeof(char *) * espaces + 2)))
1516 return (NULL);
1517 /* get each arg one by one */
1518 for (i = 0, j = 0; j < len && i < 256; i++) {
1519 /* get the end of the arg */
1520 for (espaces = j; espaces < len && !isspace(buf[espaces]); espaces++);
1521 /* allocate space for the arg */
1522 if (0 == (retour[i] = malloc(sizeof(char) * (espaces - j) + 1))) {
1523 /* free what has been allocated */
1524 for (j = 0; j < i; j++)
1525 free(retour[j]);
1526 return (NULL);
1528 memcpy(retour[i], buf + j, espaces - j);
1529 retour[i][espaces - j] = '\0';
1530 j = espaces + 1;
1532 retour[i] = 0;
1533 return (retour);
1537 int readConfigFile( char *filename ){
1538 char buf[CONF_BUFLEN];
1539 char tmp[CONF_BUFLEN];
1540 FILE *fp;
1541 char *bal;
1543 if( (fp = fopen( filename, "r")) == 0 ){
1544 sprintf(config_file, "%s/.wmpop3rc", getenv("HOME"));
1545 fprintf(stderr, "-Config file does not exit : %s\n",config_file);
1546 fprintf(stderr, "+Trying to create new config file.\n");
1547 if((fp = fopen(config_file,"w")) == 0){
1548 fprintf(stderr, "-Error creating new config file\n");
1549 return -1;
1551 fprintf(fp, "#####################################################\n");
1552 fprintf(fp, "# wmpop3lb configuration file #\n");
1553 fprintf(fp, "# #\n");
1554 fprintf(fp, "# for more information about wmpop3lb, please see: #\n");
1555 fprintf(fp, "# http://wmpop3lb.jourdain.org #\n");
1556 fprintf(fp, "# or send a mail to #\n");
1557 fprintf(fp, "# wmpop3lb@jourdain.org #\n");
1558 fprintf(fp, "#####################################################\n");
1559 fprintf(fp, "autochecking 0 # 1 enables, 0 disables\n");
1560 fprintf(fp, "displaydelay 2 # nb of seconds error info is displayed\n");
1561 fprintf(fp, "scrollspeed 100 # percentage of original scrool speed\n");
1562 fprintf(fp, "tempdir /tmp # directory for tmp files\n");
1563 fprintf(fp, "viewallmessages 0 # 0 Shows the from and subject\n");
1564 fprintf(fp, "# 1 Shows the number of messages\n");
1565 fprintf(fp, "#\n# Replace all values with appropriate data\n#\n");
1566 fprintf(fp, "[Server] # server section\n");
1567 fprintf(fp, "alias \"3 alphanum. char. long alias\"\n");
1568 fprintf(fp, "popserver \" pop3 server name \"\n");
1569 fprintf(fp, "port 110 # default port\n");
1570 fprintf(fp, "username \" pop3 login name \"\n");
1571 fprintf(fp, "password \" pop3 password \"\n");
1572 fprintf(fp, "mailcheckdelay 10 # default mail check time in minutes\n");
1573 fprintf(fp, "countUnreadOnly 0 # count unread messages only\n");
1574 fprintf(fp, "mailclient \"netscape -mail\" # for example...\n");
1575 fprintf(fp, "newmailcommand \" specify new mail command \"\n");
1576 fprintf(fp, "selectedmesgcommand \"specify command for selected mess\"\n");
1577 fprintf(fp, "mailseparator \" separator when concatening messages\"\n");
1578 fprintf(fp, "maxdlsize -1 # (no limit)\n");
1579 fprintf(fp, "#\n# start new [server] section below (up to a total of 6)\n");
1580 fprintf(stderr, "+New config file created : ~/.wmpop3rc\n\n");
1581 fprintf(stderr, "+ ~/.wmpop3rc must be configured before running wmpop3.\n");
1582 fclose(fp);
1583 return -1;
1586 nb_conf = 0;
1587 tempdir[0] = '\0';
1589 while ((nb_conf < 7) && fgets(buf, CONF_BUFLEN, fp) != 0) {
1590 if (buf[0] != '#') {
1591 if (!nb_conf && !strncasecmp( buf, "autochecking", 12) ){
1592 if (parsenum(buf + 12, &autoChecking))
1593 fprintf(stderr, "syntax error for parameter autochecking\n");
1595 else if (!nb_conf && !strncasecmp( buf, "scrollspeed", 11) ){
1596 if (parsenum(buf + 11, &scrollspeed))
1597 fprintf(stderr, "syntax error for parameter scrollspeed\n");
1599 else if (!nb_conf && !strncasecmp( buf, "displaydelay", 12) ){
1600 if (parsenum(buf + 12, &displaydelay))
1601 fprintf(stderr, "syntax error for parameter displaydelay\n");
1603 else if (!nb_conf && !strncasecmp(buf, "tempdir", 7)) {
1604 if (parsestring(buf + 7, tempdir, 1024, fp))
1605 fprintf(stderr, "syntax error for parameter tempdir\n");
1607 else if (!strncasecmp(buf, "[server]", 8)) {
1608 nb_conf++;
1609 if (!(conf[nb_conf - 1] = pop3Create(nb_conf))) {
1610 fprintf(stderr, "Can't allocate memory for config structure\n");
1611 fclose(fp);
1612 return (-1);
1615 else if (nb_conf && !strncasecmp(buf, "username", 8) ) {
1616 if (parsestring(buf + 8, conf[nb_conf -1]->username, 256, fp))
1617 fprintf(stderr, "section %d: invalid syntax for username\n",
1618 nb_conf);
1620 else if (nb_conf && !strncasecmp( buf, "password", 8) ){
1621 if (parsestring(buf + 8, conf[nb_conf - 1]->password, 256, fp))
1622 fprintf(stderr, "section %d: invalid syntax for password\n",
1623 nb_conf);
1625 else if (nb_conf && !strncasecmp(buf, "alias", 5) ) {
1626 if (parsestring(buf + 5, conf[nb_conf -1]->alias, 3, fp))
1627 fprintf(stderr, "section %d: invalid syntax for alias\n", nb_conf);
1629 else if (nb_conf && !strncasecmp( buf, "popserver", 9) ){
1630 if (parsestring(buf + 9, conf[nb_conf - 1]->popserver, 128, fp))
1631 fprintf(stderr, "section %d: invalid syntax for popserver\n",
1632 nb_conf);
1634 else if (nb_conf && !strncasecmp( buf, "port", 4) ){
1635 if (parsenum(buf + 4, &(conf[nb_conf - 1]->serverport)))
1636 fprintf(stderr, "section %d: Invalid popserver port number.\n",
1637 nb_conf);
1639 else if (!nb_conf && !strncasecmp( buf, "viewallmessages", 15) ){
1640 if (parsenum(buf + 15, &newMessagesOnly))
1641 fprintf(stderr, "section %d: Invalid number ( viewallmessages )\n",
1642 nb_conf);
1644 else if (nb_conf && !strncasecmp(buf, "countunreadonly", 15)) {
1645 if (parsenum(buf + 15, &(conf[nb_conf - 1]->countunreadonly)))
1646 fprintf(stderr, "section %d: Invalid number ( countunreadonly )\n",
1647 nb_conf);
1649 else if (nb_conf && !strncasecmp( buf, "mailcheckdelay", 14) ){
1650 if (parsenum(buf + 14, &(conf[nb_conf -1]->mailCheckDelay)))
1651 fprintf(stderr, "section %d: Invalid delay time.\n", nb_conf);
1653 else if (nb_conf && !strncasecmp(buf, "mailclient", 10)) {
1654 if (parsestring(buf + 10, tmp, 256, fp))
1655 fprintf(stderr, "section %d: Invalid syntax for mailclient.\n",
1656 nb_conf);
1657 else
1658 conf[nb_conf - 1]->mailclient = build_arg_list(tmp, strlen(tmp));
1660 else if (nb_conf && !strncasecmp(buf, "newmailcommand", 14)) {
1661 if (parsestring(buf + 14, tmp, 256, fp))
1662 fprintf(stderr,"section %d: Invalid syntax for newmailcommand.\n",
1663 nb_conf);
1664 else
1665 conf[nb_conf - 1]->newmailcommand =
1666 build_arg_list(tmp, strlen(tmp));
1668 else if (nb_conf && !strncasecmp(buf, "selectedmesgcommand", 19)) {
1669 if (parsestring(buf + 19, tmp, 256, fp))
1670 fprintf(stderr,
1671 "section %d: Invalid syntax for selectedmesgcommand.\n",
1672 nb_conf);
1673 else
1674 conf[nb_conf - 1]->selectedmesgcommand =
1675 build_arg_list(tmp, strlen(tmp));
1677 else if (nb_conf && !strncasecmp(buf, "mailseparator", 13)) {
1678 if (parsestring(buf + 13, conf[nb_conf - 1]->mailseparator, 256, fp))
1679 fprintf(stderr, "section %d: Invalid syntax for mailseparator\n",
1680 nb_conf);
1682 else if (nb_conf && !strncasecmp( buf, "maxdlsize", 9) ){
1683 if (parsenum(buf + 9, &(conf[nb_conf -1]->maxdlsize)))
1684 fprintf(stderr, "section %d: Invalid maxdlsize.\n", nb_conf);
1686 else if (nb_conf) {
1687 if (*buf && (isalpha(*buf) || isalnum(*buf)))
1688 fprintf(stderr, "section %d: Unknown indentifier : [%s]\n",
1689 nb_conf, buf);
1691 else {
1692 for (bal = buf; *bal && !isalnum(*bal); bal++);
1693 if (*bal)
1694 fprintf(stderr, "identifier outside Server section: [%s]\n", buf);
1698 fclose(fp);
1699 return 0;