1 /*******************************************************************************
2
3 Copyright (c) 1994,1995 William Pemberton (wfp5p@virginia.edu)
4
5 The X Consortium, and any party obtaining a copy of these files from
6 the X Consortium, directly or indirectly, is granted, free of charge, a
7 full and unrestricted irrevocable, world-wide, paid up, royalty-free,
8 nonexclusive right and license to deal in this software and
9 documentation files (the "Software"), including without limitation the
10 rights to use, copy, modify, merge, publish, distribute, sublicense,
11 and/or sell copies of the Software, and to permit persons who receive
12 copies from any such party to do so. This license includes without
13 limitation a license to do the foregoing actions under any patents of
14 the party supplying this software to the X Consortium.
15
16 *******************************************************************************/
17
18
19
20 /*
21 xbuffy - Bill's version of the multiple mailbox biff
22
23 Author: Bill Pemberton, wfp5p@virginia.edu
24
25 This is a modified version of xmultibiff 2.0 by:
26
27 John Reardon, Midnight Networks, badger@midnight.com, 1993.
28
29 */
30
31
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <fcntl.h>
36 #include <ctype.h>
37 #include <sys/time.h>
38 #include <sys/resource.h>
39 #include <dirent.h>
40 #include <limits.h>
41 #ifndef SUN
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #endif /* SYSV */
45 #include "xbuffy.h"
46 #ifndef USE_MOTIF
47 #include <X11/Intrinsic.h>
48 #include <X11/StringDefs.h>
49 #include <X11/Shell.h>
50 #include <X11/Xaw/Form.h>
51 #include <X11/Xaw/Box.h>
52 #include <X11/Xaw/Command.h>
53 #include <X11/Xaw/Paned.h>
54 #else
55 #include <Xm/Xm.h>
56 #include <Xm/RowColumn.h>
57 #include <Xm/Text.h>
58 #include <Xm/PushB.h>
59 /*
60 #define XtNbackground XmNbackground
61 #define XtNforeground XmNforeground
62 #define XtNwidth XmNwidth
63 #define XtNheight XmNheight
64 #define XtNlabel XmNvalue
65 */
66 #endif
67
68 #ifdef USE_LED
69 #include <signal.h>
70 #endif
71
72 #include "xbuffy.xbm"
73
74 #ifdef WFP_DEBUG
75 #include "/home/wfp5p/bin/debug_include/malloc.h"
76 #endif
77
78
79
80 void CheckBox();
81 void TimerBreakPopup();
82 int CountUnixMail();
83 void ParseMailPath();
84 int makeBoxTitle();
85 void initBox();
86 Pixel convertColor();
87
88 void ButtonDownHandler();
89 void ButtonUpHandler();
90 void BreakPopup();
91 void ExecuteCommand();
92 void setBoxColor();
93 void PopupHeader();
94 char *EliminatePath();
95 void UpdateBoxNumber();
96
97
98
99 /** globals **/
100 char versionString[MAX_STRING];
101 char *programName;
102 Widget toplevel;
103 Widget *header;
104 ApplicationData_t data;
105 XtAppContext app;
106 DynObject DynBoxObj;
107 BoxInfo_t *boxInfo;
108 int *headerUp;
109 int nBoxes = 0;
110 int envPolltime = 0;
111 int envPriority = 0;
112 int envHeadertime = 0;
113 int NNTPinit = 0;
114 int maxBoxSize = 0;
115 FILE *NNTP_fIn, *NNTP_fOut;
116 extern char **environ;
117
118 XtResource resources[] = {
119 {"mailboxes", "Mailboxes", XtRString, sizeof(String),
120 XtOffset(ApplicationData_t *, mailBoxes), XtRString, 0},
121 {"nobeep", "Nobeep", XtRBoolean, sizeof(int),
122 XtOffset(ApplicationData_t *, nobeep), XtRString, "FALSE"},
123 {"horiz", "Horiz", XtRBoolean, sizeof(int),
124 XtOffset(ApplicationData_t *, horiz), XtRString, "FALSE"},
125 {"command", "Command", XtRString, sizeof(String),
126 XtOffset(ApplicationData_t *, command), XtRString, 0},
127 {"names", "Names", XtRBoolean, sizeof(int),
128 XtOffset(ApplicationData_t *, longNames), XtRString, "FALSE"},
129 {"shortnames", "Shortnames", XtRBoolean, sizeof(int),
130 XtOffset(ApplicationData_t *, shortNames), XtRString, "FALSE"},
131 {"polltime", "Polltime", XtRString, sizeof(String),
132 XtOffset(ApplicationData_t *, pollTime), XtRString, "60"},
133 {"priority", "Priority", XtRString, sizeof(String),
134 XtOffset(ApplicationData_t *, priority), XtRString, "15"},
135 {"headertime", "Headertime", XtRString, sizeof(String),
136 XtOffset(ApplicationData_t *, headerTime), XtRString, 0},
137 {"orig", "Orig", XtRBoolean, sizeof(int),
138 XtOffset(ApplicationData_t *, origMode), XtRString, "FALSE"},
139 {"audiocmd", "Audiocmd", XtRString, sizeof(String),
140 XtOffset(ApplicationData_t *, audioCmd), XtRString, 0},
141 {"boxfile", "Boxfile", XtRString, sizeof(String),
142 XtOffset(ApplicationData_t *, boxFile), XtRString, 0},
143 {"center", "Center", XtRBoolean, sizeof(int),
144 XtOffset(ApplicationData_t *, center), XtRString, "FALSE"},
145 {"fill", "Fill", XtRBoolean, sizeof(int),
146 XtOffset(ApplicationData_t *, fill), XtRString, "FALSE"},
147 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
148 XtOffset(ApplicationData_t *, fg), XtRString, XtDefaultForeground},
149 {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
150 XtOffset(ApplicationData_t *, bg), XtRString, XtDefaultBackground},
151 #ifdef USE_NNTP
152 {"newsboxes", "Newsboxes", XtRString, sizeof(String),
153 XtOffset(ApplicationData_t *, newsBoxes), XtRString, 0},
154 #endif /* USE_NNTP */
155
156 };
157
158 XrmOptionDescRec options[] = {
159 {"-nobeep", "*nobeep", XrmoptionNoArg, "TRUE"},
160 {"-center", "*center", XrmoptionNoArg, "TRUE"},
161 {"-fill", "*fill", XrmoptionNoArg, "TRUE"},
162 {"-horiz", "*horiz", XrmoptionNoArg, "TRUE"},
163 {"-names", "*names", XrmoptionNoArg, "TRUE"},
164 {"-shortnames", "*shortnames", XrmoptionNoArg, "TRUE"},
165 {"-acmd", "*audiocmd", XrmoptionSepArg, 0},
166 {"-poll", "*polltime", XrmoptionSepArg, 0},
167 {"-priority", "*priority", XrmoptionSepArg, 0},
168 {"-header", "*headertime", XrmoptionSepArg, 0},
169 {"-orig", "*orig", XrmoptionNoArg, "TRUE"},
170 {"-boxfile", "*boxfile", XrmoptionSepArg, 0},
171 {"-command", "*command", XrmoptionSepArg, 0},
172 };
173
CheckBox(i)174 void CheckBox(i)
175 int i;
176 {
177 int num = 0;
178 Arg args[5];
179 int nargs;
180 BoxInfo_t *currentBox;
181 Boolean beenTouched;
182 Boolean isIcon = FALSE;
183
184 currentBox = &boxInfo[i];
185
186 #ifdef USE_NNTP
187 if (boxInfo[i].type == NNTPBOX)
188 {
189 num = CountNNTP(currentBox, NULL, &beenTouched);
190 }
191 #endif /* USE_NNTP */
192 if ((boxInfo[i].type == MAILBOX) || (boxInfo[i].type == MAILDIR) ||
193 (boxInfo[i].type == MHDIR))
194 {
195 num = CountUnixMail(currentBox, NULL, &beenTouched);
196 }
197
198 nargs = 0;
199 XtSetArg(args[nargs], XtNiconic, &isIcon);
200
201
202 if ((num > currentBox->n) ||
203 ((!currentBox->origMode) && ((num != currentBox->n) || (beenTouched))))
204 {
205
206 if ((currentBox->headerTime != 0) && (!isIcon) && (num > 0))
207 {
208 PopupHeader(currentBox->w, currentBox->boxNum, 0, 0);
209 }
210
211 if ((!currentBox->nobeep) && (num > 0))
212 {
213 if (currentBox->audioCmd != NULL)
214 {
215 system(currentBox->audioCmd);
216 }
217 else
218 {
219 XBell(XtDisplay(currentBox->w), 0);
220 }
221 }
222 }
223
224 if (currentBox->n != num)
225 {
226 currentBox->n = num;
227 UpdateBoxNumber(currentBox);
228 }
229
230
231 XtAppAddTimeOut(app, (currentBox->pollTime * 1000), CheckBox, (XtPointer) i);
232 }
233
234
setBoxColor(box,status)235 void setBoxColor(box,status)
236 BoxInfo_t *box;
237 int status;
238 {
239 Arg args[5];
240 int nargs;
241
242 nargs = 0;
243 if (status)
244 {
245 XtSetArg(args[nargs], XtNbackground, box->fg);
246 nargs++;
247 XtSetArg(args[nargs], XtNforeground, box->bg);
248 nargs++;
249 }
250 else
251 {
252 XtSetArg(args[nargs], XtNbackground, box->bg);
253 nargs++;
254 XtSetArg(args[nargs], XtNforeground, box->fg);
255 nargs++;
256 }
257
258 XtSetValues(box->w, args, nargs);
259 }
260
261
262
263
UpdateBoxNumber(box)264 void UpdateBoxNumber(box)
265 BoxInfo_t *box;
266 {
267 char amt[MAX_STRING];
268 char fmtString[MAX_STRING];
269 char *ptr;
270 int offset;
271 Arg args[5];
272 int nargs;
273
274 #ifdef USE_MOTIF
275 XmString label;
276 #endif
277
278 #ifdef USE_LED
279 if (box->led != -1)
280 {
281 char l[17];
282
283 if (box->n > 0)
284 {
285 if (box->pid > 1) {
286 if (!kill(box->pid, SIGINT))
287 waitpid(box->pid, NULL, 0);
288 /*
289 else
290 perror("Failing to kill led");
291 */
292 }
293 switch (box->pid = fork()) {
294 case -1:
295 perror("Fork failure");
296 break;
297 case 0:
298 sprintf(amt, "%d", box->n);
299 sprintf(l, "%d", box->led);
300 if (execlp("led", "led", l, amt, (char*)NULL) == -1) {
301 fprintf(stderr, "Error executing led\n");
302 _exit(1);
303 }
304 default:
305 }
306 }
307 else
308 {
309 if (box->pid > 1)
310 if (!kill(box->pid, SIGINT))
311 {
312 waitpid(box->pid, NULL, 0);
313 box->pid = 0;
314 }
315 else
316 perror("Failing to kill led");
317 }
318 }
319 #endif
320
321 if (box->boxTitle != NULL)
322 {
323 sprintf(amt, "%s: %d", box->boxTitle, box->n);
324 }
325 else
326 {
327 sprintf(amt, "%d", box->n);
328 }
329
330 memset(fmtString, ' ',MAX_STRING);
331
332
333 if (data.center) /* center implies fill */
334 {
335 offset = ((maxBoxSize+4) - NEWstrlen(amt))/2;
336 if (offset < 0) offset = 0;
337 if (offset > MAX_STRING) offset = 0;
338 ptr = fmtString+ offset;
339 strcpy(ptr,amt);
340 ptr = fmtString+NEWstrlen(fmtString);
341 *ptr = ' ';
342 *(ptr+offset+1-(offset%2))='\0';
343 }
344 else if (data.fill)
345 {
346
347
348 offset = maxBoxSize+4-NEWstrlen(amt);
349 if (offset < 0) offset = 0;
350 strcpy(fmtString,amt);
351 ptr = fmtString+NEWstrlen(fmtString);
352 while (offset-- >0)
353 *ptr++ = ' ';
354
355 *ptr = '\0';
356 }
357 else
358 {
359 strcpy(fmtString, amt);
360 }
361
362
363 nargs = 0;
364
365 if (!box->origMode)
366 {
367 if (box->n > 0)
368 {
369 setBoxColor(box,1);
370 }
371 else
372 {
373 setBoxColor(box,0);
374
375 }
376 }
377
378
379 #ifdef USE_MOTIF
380 label = XmStringCreateSimple(amt);
381 XtSetArg(args[nargs], XmNlabelString, label);
382 nargs++;
383 #else
384 XtSetArg(args[nargs], XtNlabel, fmtString);
385 nargs++;
386 #endif
387 XtSetValues(box->w, args, nargs);
388
389 #ifdef USE_MOTIF
390 XmStringFree(label);
391 #endif
392 }
393
394
395 #ifdef USE_MOTIF
dimension_text(char * hdrPtr,int * rows,int * cols)396 static void dimension_text(char *hdrPtr, int *rows, int *cols)
397 {
398 int curwidth;
399
400 *rows = 0;
401 *cols = 0;
402 curwidth = 0;
403 while (*hdrPtr != '\0')
404 {
405 if (*hdrPtr == '\n')
406 {
407 (*rows)++;
408 if (curwidth > *cols)
409 *cols = curwidth;
410 curwidth = 0;
411 }
412 else
413 curwidth++;
414 hdrPtr++;
415 }
416
417 }
418
419 #endif
420
421 /* event handlers that decides what to do with button clicks */
ButtonDownHandler(w,i,event,cont)422 void ButtonDownHandler(w, i, event, cont)
423 Widget w;
424 int *i;
425 XEvent *event;
426 Boolean *cont;
427 {
428 if (event->xbutton.button == 1)
429 {
430 PopupHeader(w, *i, event, cont);
431 }
432 /* don't do anything else for other button clicks */
433 }
434
435
436
ButtonUpHandler(w,i,event,cont)437 void ButtonUpHandler(w, i, event, cont)
438 Widget w;
439 int *i;
440 XEvent *event;
441 Boolean *cont;
442 {
443 if (event->xbutton.button == 1)
444 {
445 BreakPopup(w, *i, event, cont);
446 }
447 else if (event->xbutton.button == 2)
448 {
449 ExecuteCommand(w, *i, event, cont);
450 }
451 else if (event->xbutton.button == 3)
452 {
453 BoxInfo_t *currentBox;
454 currentBox = &boxInfo[*i];
455
456 setBoxColor(currentBox,0);
457
458 #ifdef USE_LED
459 if (currentBox->led != -1)
460 if (currentBox->pid > 1)
461 if (!kill(currentBox->pid, SIGINT))
462 {
463 waitpid(currentBox->pid, NULL, 0);
464 currentBox->pid = 0;
465 }
466 else
467 perror("Failing to kill led");
468 #endif
469 }
470 }
471
472
473
PopupHeader(w,i,event,cont)474 void PopupHeader(w, i, event, cont)
475 Widget w;
476 int i;
477 XEvent *event;
478 Boolean *cont;
479 {
480 Arg args[5];
481 int nargs;
482 Widget tmpCommand;
483 Position biff_x, biff_y, root_x, root_y;
484 static XtIntervalId timerID;
485 static int rootH = 0;
486 static int rootW = 0;
487 int number = 0;
488 static Boolean firstTime = TRUE;
489 static DynObject mailHeaders;
490 static char *hdrPtr;
491 Dimension headerW, headerH;
492 BoxInfo_t *currentBox;
493 Boolean beenTouched;
494
495 #ifdef USE_MOTIF
496 int rows, cols;
497
498 #endif
499
500 currentBox = &boxInfo[i];
501
502 if (rootH == 0)
503 {
504 rootH = DisplayHeight(XtDisplay(w), DefaultScreen(XtDisplay(w)));
505 rootW = DisplayWidth(XtDisplay(w), DefaultScreen(XtDisplay(w)));
506 }
507
508
509 if ((!firstTime) && (DynSize(mailHeaders) != 0))
510 {
511 DynDestroy(mailHeaders);
512 }
513
514 firstTime = FALSE;
515 mailHeaders = DynCreate(sizeof(char), MAX_STRING);
516
517 #ifdef DEBUG
518 DynDebug(mailHeaders, 1);
519 DynParanoid(mailHeaders, 1);
520 #endif
521
522 #ifdef USE_NNTP
523 /* check to see if there is any news before proceeding */
524 if (boxInfo[i].type == NNTPBOX)
525 {
526 number = CountNNTP(&boxInfo[i], mailHeaders, &beenTouched);
527 DynAdd(mailHeaders, "\0");
528 hdrPtr = (char *) DynGet(mailHeaders, 0);
529 }
530 #endif
531
532 /* update the number on the box (in case there are new articles) */
533 if ((currentBox->type == MAILBOX) || (currentBox->type == MAILDIR) ||
534 (currentBox->type == MHDIR))
535 {
536 number = CountUnixMail(currentBox, mailHeaders, &beenTouched);
537
538
539 DynAdd(mailHeaders, "\0");
540 hdrPtr = (char *) DynGet(mailHeaders, 0);
541 }
542
543 /* if the number is different, update it */
544 currentBox->n = number;
545 UpdateBoxNumber(&boxInfo[i]);
546
547 /* if the number is zero, there's no header, so leave */
548 if (boxInfo[i].n == 0)
549 {
550 return;
551 }
552
553 /* if its already up, pop it down, because we must update it */
554 if (headerUp[i] == TRUE)
555 {
556 XtRemoveTimeOut(timerID);
557 BreakPopup(0, i, 0, 0);
558 }
559
560 /* Calculate Relative position -> Root absolute position */
561 nargs = 0;
562 XtSetArg(args[nargs], XtNwidth, &biff_x);
563 nargs++;
564 XtSetArg(args[nargs], XtNheight, &biff_y);
565 nargs++;
566 XtGetValues(w, args, nargs);
567 XtTranslateCoords(w, biff_x, biff_y, &root_x, &root_y);
568
569
570 header[i] = XtCreatePopupShell(currentBox->boxTitle, transientShellWidgetClass,
571 currentBox->w, 0, 0);
572
573 nargs = 0;
574 #ifndef USE_MOTIF
575 XtSetArg(args[nargs], XtNlabel, hdrPtr);
576 nargs++;
577 XtSetArg(args[nargs], XtNhighlightThickness, 0);
578 nargs++;
579
580 tmpCommand = XtCreateManagedWidget("popup", commandWidgetClass, header[i], args, nargs);
581
582 XtAddCallback(tmpCommand, XtNcallback, BreakPopup, (XtPointer) i);
583 #else
584 dimension_text((char *) hdrPtr, &rows, &cols);
585 XtSetArg(args[nargs], XmNvalue, hdrPtr);
586 nargs++;
587 XtSetArg(args[nargs], XmNeditMode, XmMULTI_LINE_EDIT);
588 nargs++;
589 XtSetArg(args[nargs], XmNeditable, False);
590 nargs++;
591 XtSetArg(args[nargs], XmNrows, (short) rows);
592 nargs++;
593 XtSetArg(args[nargs], XmNcolumns, (short) cols);
594 nargs++;
595 tmpCommand = XmCreateText(header[i], "popup", args, nargs);
596 XtManageChild(tmpCommand);
597 XtAddCallback(tmpCommand, XmNactivateCallback, BreakPopup, (XtPointer) i);
598 #endif
599
600 if (!XtIsRealized(header[i]))
601 {
602 XtRealizeWidget(header[i]);
603 }
604
605 /* see where we should put this thing so its on the screen */
606 /* i.e. make sure we can see it */
607 nargs = 0;
608 XtSetArg(args[nargs], XtNwidth, &headerW);
609 nargs++;
610 XtSetArg(args[nargs], XtNheight, &headerH);
611 nargs++;
612 XtGetValues(header[i], args, nargs);
613 if (((int) root_x + (int) headerW) >= (rootW - 20))
614 {
615 root_x = (Position) rootW - ((Position) headerW + 5);
616 }
617 if (((int) root_y + (int) headerH) >= (rootH - 20))
618 {
619 root_y = (Position) rootH - ((Position) headerH + 40);
620 }
621 nargs = 0;
622 XtSetArg(args[nargs], XtNx, root_x);
623 nargs++;
624 XtSetArg(args[nargs], XtNy, root_y);
625 nargs++;
626 XtSetValues(header[i], args, nargs);
627
628 XtPopup(header[i], XtGrabNone);
629
630 headerUp[i] = TRUE;
631 /* free alloc'ed string */
632
633 /* register a routine to pop it down if it was invoked from a routine */
634 if (event == 0)
635 {
636 timerID = XtAppAddTimeOut(app, (currentBox->headerTime * 1000),
637 TimerBreakPopup, (XtPointer) i);
638 }
639 }
640
TimerBreakPopup(i)641 void TimerBreakPopup(i)
642 int i;
643 {
644 BreakPopup(0, i, 0, 0);
645 }
646
BreakPopup(w,i,event,cont)647 void BreakPopup(w, i, event, cont)
648 Widget w;
649 int i;
650 XEvent *event;
651 Boolean *cont;
652 {
653 if (headerUp[i] != TRUE)
654 {
655 return;
656 }
657 XtPopdown(header[i]);
658 XtDestroyWidget(header[i]);
659 headerUp[i] = FALSE;
660 }
661
662
ExecuteCommand(w,i,event,cont)663 void ExecuteCommand(w, i, event, cont)
664 Widget w;
665 int i;
666 XEvent *event;
667 Boolean *cont;
668 {
669 BoxInfo_t *currentBox;
670
671 currentBox = &boxInfo[i];
672
673 #ifdef USE_LED
674 if (currentBox->led != -1)
675 if (currentBox->pid > 1)
676 if (!kill(currentBox->pid, SIGINT))
677 {
678 waitpid(currentBox->pid, NULL, 0);
679 currentBox->pid = 0;
680 }
681 else
682 perror("Failing to kill led");
683 #endif
684
685 if (currentBox->command != NULL)
686 {
687 system(currentBox->command);
688 }
689
690 }
691
692
isLocked(mbox)693 int isLocked(mbox)
694 char *mbox;
695 {
696
697 /* right now this is a REAL stupid function, it just looks for a .lock file */
698
699 char *lockfile;
700 int retVal;
701
702 lockfile = (char *) malloc( (NEWstrlen(mbox)+15)*sizeof(char));
703
704 strcpy(lockfile, mbox);
705 strcat(lockfile, ".lock");
706
707 retVal = exists(lockfile);
708 free(lockfile);
709 return(retVal);
710 }
711
CountMBoxMail(mailBox,headerString)712 int CountMBoxMail(mailBox, headerString)
713 BoxInfo_t *mailBox;
714 DynObject headerString;
715 {
716 FILE *fp = 0;
717 char buffer[MAX_STRING];
718 char From[MAX_STRING], Subject[MAX_STRING];
719 register int count = 0;
720 int status = UNKNOWN;
721 register Boolean in_header = FALSE;
722
723 fp = fopen(mailBox->box, "r");
724 if (fp == NULL)
725 return 0;
726
727 From[0] = Subject[0] = '\0';
728
729
730 while (fgets(buffer, MAX_STRING - 2, fp) != 0)
731 {
732 long CL = 0L;
733 int has_CL = FALSE;
734
735 buffer[MAX_STRING - 1] = '\0'; /* just in case */
736 if ((strchr(buffer, '\n') == NULL) && (!feof(fp)))
737 {
738 int c;
739
740 while ((c = getc(fp)) != EOF && c != '\n'); /* keep reading */
741 }
742
743 if ((!in_header) && (real_from(buffer)))
744 {
745 has_CL = FALSE;
746 in_header = TRUE;
747 status = NEW_MSG;
748 }
749 else if (in_header)
750 {
751 if (header_cmp(buffer, "From", NULL))
752 {
753 strcpy(From, buffer);
754 }
755
756
757 if (header_cmp(buffer, "Content-Length", NULL))
758 {
759 has_CL = TRUE;
760 CL = atol(buffer+15);
761 }
762
763 if (header_cmp(buffer, "Subject", NULL))
764 {
765 strcpy(Subject, buffer);
766 }
767
768 if (header_cmp(buffer, "Status", NULL))
769 {
770 remove_header_keyword(buffer);
771 if (*buffer == 'N')
772 status = NEW_MSG;
773 else
774 status = READ_MSG;
775 }
776 else if (buffer[0] == LINEFEED)
777 {
778 #ifdef USE_CONTENT_LENGTH
779 if (has_CL)
780 fseek(fp,CL,SEEK_CUR);
781 #endif
782 in_header = FALSE;
783 if ((status == NEW_MSG) || (mailBox->origMode))
784 {
785 count++;
786 if (headerString != NULL)
787 {
788 if (NEWstrlen(From) != 0)
789 DynInsert(headerString, ((DynHigh(headerString) > 0) ? (DynSize(headerString)) : 0), From, NEWstrlen(From));
790
791 if (NEWstrlen(Subject) != 0)
792 DynInsert(headerString, ((DynHigh(headerString) > 0) ? (DynSize(headerString)) : 0), Subject, NEWstrlen(Subject));
793 }
794 }
795 From[0] = Subject[0] = '\0';
796
797 }
798
799 }
800 }
801 fclose(fp);
802
803 return count;
804 }
805
CountDirMail(mailBox,headerString)806 int CountDirMail(mailBox, headerString)
807 BoxInfo_t *mailBox;
808 DynObject headerString;
809 {
810 DIR *dp = 0;
811 FILE *fp = 0;
812 char buffer[MAX_STRING];
813 char From[MAX_STRING], Subject[MAX_STRING];
814 char path[_POSIX_PATH_MAX];
815 int status;
816 register Boolean found = FALSE;
817 register Boolean mailfile = TRUE;
818 struct dirent *de;
819 register int count = 0;
820
821 if (mailBox->type == MAILDIR) {
822 sprintf(path, "%s/new", mailBox->box);
823 } else {
824 strcpy(path,mailBox->box);
825 }
826 dp = opendir(path);
827 if (dp == NULL)
828 return 0;
829
830 while ((de = readdir (dp)) != NULL)
831 {
832 mailfile = TRUE;
833 if (mailBox->type == MHDIR) {
834 char *p;
835 p = de->d_name;
836 while (*p && mailfile)
837 {
838 if (!isdigit (*p)) mailfile = FALSE;
839 p++;
840 }
841 } else if (mailBox->type == MAILDIR) {
842 if (*de->d_name == '.') mailfile = FALSE;
843 }
844 if (mailfile)
845 {
846 if (mailBox->type == MAILDIR) count++;
847 if (headerString != NULL || mailBox->type == MHDIR) {
848 /* Ok, we need to get the From: and Subject: lines */
849 From[0] = Subject[0] = '\0';
850 found = FALSE;
851 status = NEW_MSG;
852 if (mailBox->type == MAILDIR) {
853 sprintf(path, "%s/new/%s",mailBox->box,de->d_name);
854 } else {
855 sprintf(path, "%s/%s",mailBox->box,de->d_name);
856 }
857 fp = fopen(path, "r");
858 if (fp != NULL) {
859 while (!found && fgets(buffer, MAX_STRING - 2, fp) != 0)
860 {
861 long CL;
862 int has_CL;
863
864 buffer[MAX_STRING - 1] = '\0'; /* just in case */
865 if ((strchr(buffer, '\n') == NULL) && (!feof(fp)))
866 { /* read to end of line */
867 int c;
868 while ((c = getc(fp)) != EOF && c != '\n'); /* keep reading */
869 }
870 if (headerString != NULL &&
871 header_cmp(buffer, "From", NULL))
872 {
873 strcpy(From, buffer);
874 }
875 else if (headerString != NULL &&
876 header_cmp(buffer, "Subject", NULL))
877 {
878 strcpy(Subject, buffer);
879 }
880 else if (mailBox->type == MHDIR &&
881 header_cmp(buffer, "Status", NULL))
882 {
883 remove_header_keyword(buffer);
884 if (*buffer == 'N')
885 status = NEW_MSG;
886 else
887 status = READ_MSG;
888 }
889 else if (buffer[0] == LINEFEED && (mailBox->type == MAILDIR ||
890 status == NEW_MSG))
891 {
892 if (mailBox->type == MHDIR) count++;
893 if (strlen(From) != 0)
894 DynInsert(headerString,
895 ((DynHigh(headerString) > 0) ? (DynSize(headerString)) : 0),
896 From, strlen(From));
897
898 if (strlen(Subject) != 0)
899 DynInsert(headerString,
900 ((DynHigh(headerString) > 0) ? (DynSize(headerString)) : 0),
901 Subject, strlen(Subject));
902 found = TRUE;
903 }
904 }
905 fclose(fp);
906 }
907 }
908 }
909 }
910 closedir(dp);
911
912 return count;
913 }
914
CountUnixMail(mailBox,headerString,beenTouched)915 int CountUnixMail(mailBox, headerString, beenTouched)
916 BoxInfo_t *mailBox;
917 DynObject headerString;
918 Boolean *beenTouched;
919 {
920 struct stat f_stat;
921 struct timeval t[2];
922 register int count = 0;
923 char path[_POSIX_PATH_MAX];
924
925 *beenTouched = FALSE;
926
927 if (mailBox->type == MAILBOX) {
928 if (isLocked(mailBox->box))
929 return (mailBox->n);
930 }
931
932 if (mailBox->type == MAILDIR) {
933 sprintf(path,"%s/new",mailBox->box);
934 } else {
935 strcpy(path,mailBox->box);
936 }
937
938 if (stat(path, &f_stat))
939 {
940 mailBox->st_size = 0;
941 mailBox->box_mtime = 0;
942 return (0);
943 }
944
945 if ((f_stat.st_size != mailBox->st_size) ||
946 (f_stat.st_mtime > mailBox->box_mtime))
947 {
948 mailBox->st_size = f_stat.st_size;
949 mailBox->box_mtime = f_stat.st_mtime;
950 *beenTouched = TRUE;
951 }
952
953 if ((!*beenTouched) && (headerString == NULL))
954 return (mailBox->n);
955
956 switch (mailBox->type) {
957 case MAILBOX:
958 count = CountMBoxMail(mailBox, headerString);
959 break;
960 case MAILDIR:
961 case MHDIR:
962 count = CountDirMail(mailBox, headerString);
963 break;
964 }
965
966 /* Restore access time of mailbox. */
967
968 t[0].tv_sec = f_stat.st_atime;
969 t[0].tv_usec = 0;
970 t[1].tv_sec = f_stat.st_mtime;
971 t[1].tv_usec = 0;
972
973 utimes(mailBox->box, t);
974
975 return count;
976 }
977
978
convertColor(colorname,defValue)979 Pixel convertColor(colorname, defValue)
980 char *colorname;
981 Pixel defValue;
982 {
983 XrmValue namein, pixelout;
984
985 namein.addr = colorname;
986 namein.size = NEWstrlen(colorname) + 1;
987 pixelout.size = 0;
988
989 XtConvert(toplevel, XtRString, &namein, XtRPixel, &pixelout);
990
991 if (pixelout.size == 0) /* it failed */
992 return(defValue);
993 else
994 return(*(Pixel *)pixelout.addr);
995 }
996
997 #ifdef USE_LED
initBox(box,BoxType,pollTime,headerTime,BoxNameType,command,audioCmd,title,origMode,nobeep,bgName,fgName,led)998 void initBox(box, BoxType, pollTime, headerTime, BoxNameType, command, audioCmd,
999 title, origMode, nobeep, bgName, fgName, led)
1000 #else
1001 void initBox(box, BoxType, pollTime, headerTime, BoxNameType, command, audioCmd,
1002 title, origMode, nobeep, bgName, fgName)
1003 #endif
1004 char *box;
1005 BoxType_t BoxType;
1006 int pollTime;
1007 int headerTime;
1008 BoxNameType_t BoxNameType;
1009 char *command;
1010 char *audioCmd;
1011 char *title;
1012 Boolean origMode;
1013 Boolean nobeep;
1014 char *bgName;
1015 char *fgName;
1016 #ifdef USE_LED
1017 int led;
1018 #endif
1019 {
1020
1021 BoxInfo_t tempBox;
1022 int boxSize;
1023 char *ptr;
1024
1025 /* get rid of trailing whitespace in box */
1026
1027 ptr = box + NEWstrlen(box) - 1;
1028
1029 while (isspace(*ptr))
1030 *ptr-- = '\0';
1031
1032
1033 #ifdef DEBUG
1034 fprintf(stderr, "Init Box = *%s*\n", box);
1035 fprintf(stderr, "nboxes = %i\n", nBoxes);
1036 fprintf(stderr, "type = %i\n", BoxType);
1037 fprintf(stderr, "command = *%s*\n", command);
1038 fprintf(stderr, "audio = *%s*\n", audioCmd);
1039 fprintf(stderr, "boxTitle = *%s*\n", title);
1040 fprintf(stderr, "pollTime = %i headerTime = %i\n", pollTime, headerTime);
1041 fprintf(stderr, "nobeep = %i origMode = %i \n", nobeep, origMode);
1042 fprintf(stderr, "nametype = %i\n\n", BoxNameType);
1043 #endif
1044
1045 tempBox.box = NEWstrdup(box);
1046 tempBox.type = BoxType;
1047 tempBox.boxNum = nBoxes;
1048
1049 if (BoxType == NNTPBOX)
1050 {
1051 tempBox.articles = DynCreate(sizeof(Articles_t), 2);
1052 #ifdef DEBUG
1053 /* DynDebug(tempBox.articles, 1);
1054 DynParanoid(tempBox.articles, 1);*/
1055 #endif
1056
1057 } else if (BoxType == MAILBOX)
1058 {
1059 struct stat st;
1060 char tmp[_POSIX_PATH_MAX];
1061
1062 if (stat (box, &st) != -1) {
1063 if (S_ISDIR (st.st_mode)) {
1064 /* check for maildir mailbox */
1065 sprintf(tmp, "%s/cur", box);
1066 if (stat (tmp, &st) == 0 && S_ISDIR (st.st_mode)) {
1067 tempBox.type = MAILDIR;
1068 } else {
1069 /* check for mh mailbox */
1070 sprintf(tmp, "%s/.mh_sequences", box);
1071 if (access (tmp, F_OK) == 0) {
1072 tempBox.type = MHDIR;
1073 } else {
1074 sprintf(tmp, "%s/.xmhcache", box);
1075 if (access (tmp, F_OK) == 0) {
1076 tempBox.type = MHDIR;
1077 }
1078 }
1079 }
1080 }
1081 }
1082 }
1083 if ((pollTime <= 0) || (pollTime >= 3600))
1084 tempBox.pollTime = envPolltime;
1085 else
1086 tempBox.pollTime = pollTime;
1087
1088 if ((tempBox.type == NNTPBOX) && (tempBox.pollTime < 180))
1089 tempBox.pollTime = 180;
1090
1091 if ((headerTime < 0) || (headerTime >= 60))
1092 tempBox.headerTime = envHeadertime;
1093 else
1094 tempBox.headerTime = headerTime;
1095
1096 tempBox.BoxNameType = BoxNameType;
1097
1098 tempBox.boxTitle = NEWstrdup(title);
1099
1100 if (tempBox.BoxNameType == UNDEF)
1101 {
1102 if (data.shortNames)
1103 tempBox.BoxNameType = SHORT;
1104 if (data.longNames)
1105 tempBox.BoxNameType = LONG;
1106 }
1107
1108 boxSize = makeBoxTitle(&tempBox);
1109 if (boxSize > maxBoxSize)
1110 maxBoxSize = boxSize;
1111
1112 tempBox.command = NEWstrdup(command);
1113 tempBox.audioCmd = NEWstrdup(audioCmd);
1114 tempBox.origMode = origMode;
1115 tempBox.nobeep = nobeep;
1116
1117 if (bgName != NULL)
1118 tempBox.bg = convertColor(bgName,data.bg);
1119 else
1120 tempBox.bg = data.bg;
1121
1122 if (fgName != NULL)
1123 tempBox.fg = convertColor(fgName,data.fg);
1124 else
1125 tempBox.fg = data.fg;
1126
1127 #ifdef USE_LED
1128 if (led < 1 || led > 3)
1129 tempBox.led = -1;
1130 else
1131 tempBox.led = led;
1132 #endif
1133 tempBox.box_mtime = tempBox.st_size = 0;
1134
1135 DynAdd(DynBoxObj, &tempBox);
1136 boxInfo = (BoxInfo_t *) DynGet(DynBoxObj, 0);
1137
1138 nBoxes++;
1139 }
1140
ParseMailPath()1141 void ParseMailPath()
1142 {
1143 char *mailPath = 0;
1144 char *boxes = 0;
1145 char *str = 0;
1146
1147 /* get mail path */
1148 if ((mailPath = getenv("MAILPATH")) != 0)
1149 {
1150 boxes = mailPath;
1151 }
1152 else if ((mailPath = getenv("MAIL")) != 0)
1153 {
1154 boxes = mailPath;
1155 }
1156 else if (data.mailBoxes != 0)
1157 {
1158 boxes = data.mailBoxes;
1159 }
1160 else
1161 {
1162 return;
1163 }
1164
1165 str = (char *) strtok(boxes, ":, ");
1166 while (str != NULL)
1167 {
1168 #ifdef USE_LED
1169 initBox(NEWstrdup(str), MAILBOX, envPolltime, envHeadertime, UNDEF, data.command,
1170 data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL,-1);
1171 #else
1172 initBox(NEWstrdup(str), MAILBOX, envPolltime, envHeadertime, UNDEF, data.command,
1173 data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL);
1174 #endif
1175 str = (char *) strtok(NULL, ":, ");
1176 }
1177 }
1178
1179
EliminatePath(path)1180 char *EliminatePath(path)
1181 char *path;
1182 {
1183 char *file = 0;
1184
1185 file = (char *) strrchr(path, '/');
1186 file = (file ? ++file : path);
1187
1188 return (file);
1189 }
1190
1191 #ifdef USE_NNTP
ParseNewsPath()1192 void ParseNewsPath()
1193 {
1194 char *newsPath = 0;
1195 char *boxes = 0;
1196 char *str = 0;
1197
1198 /* get nntp path */
1199 if ((newsPath = getenv("NEWSPATH")) != 0)
1200 {
1201 boxes = newsPath;
1202 }
1203 else if (data.newsBoxes != 0)
1204 {
1205 boxes = data.newsBoxes;
1206 }
1207 else
1208 {
1209 return;
1210 }
1211
1212 str = strtok(boxes, ":, ");
1213 while (str != NULL)
1214 {
1215 initBox(NEWstrdup(str), NNTPBOX, envPolltime, envHeadertime, UNDEF,
1216 data.command, data.audioCmd, NULL, data.origMode, data.nobeep,
1217 NULL,NULL);
1218 str = strtok(NULL, ":, ");
1219 }
1220 }
1221
1222 #endif /* USE_NNTP */
1223
1224
1225
1226
1227 /* the the icon if it is not already loaded */
LoadIcon(w)1228 void LoadIcon(w)
1229 Widget w;
1230 {
1231 Display *display = XtDisplay(w);
1232 int screen;
1233 Pixmap icon_pixmap = (Pixmap) 0;
1234 Arg arg;
1235
1236 screen = DefaultScreen(display);
1237
1238 /* User sets iconPixmap resource, converter does the right thing.. */
1239 XtSetArg(arg, XtNiconPixmap, &icon_pixmap);
1240 XtGetValues(w, &arg, 1);
1241 if (icon_pixmap == (Pixmap) 0)
1242 {
1243 XtSetArg(arg, XtNiconPixmap,
1244 XCreateBitmapFromData(display,
1245 RootWindow(display, screen),
1246 xbuffy_bits, xbuffy_width,
1247 xbuffy_height));
1248 XtSetValues(w, &arg, 1);
1249 }
1250 }
1251
1252
makeBoxTitle(currentBox)1253 int makeBoxTitle(currentBox)
1254 BoxInfo_t *currentBox;
1255 {
1256 char line[MAX_STRING];
1257
1258 line[0] = '\0';
1259
1260 if ((currentBox->type == MAILBOX) || (currentBox->type == MAILDIR) ||
1261 (currentBox->type == MHDIR))
1262 {
1263 switch (currentBox->BoxNameType)
1264 {
1265 case SHORT:
1266 strcpy(line, EliminatePath(currentBox->box));
1267 break;
1268 case LONG:
1269 strcpy(line, currentBox->box);
1270 break;
1271 case NONE:
1272 case USR:
1273 case UNDEF:
1274 break;
1275 }
1276
1277 if (line[0] != '\0')
1278 currentBox->boxTitle = NEWstrdup(line);
1279 }
1280 else
1281 {
1282 switch (currentBox->BoxNameType)
1283 {
1284 case SHORT:
1285 case LONG:
1286 strcpy(line, currentBox->box);
1287 break;
1288 case NONE:
1289 case USR:
1290 case UNDEF:
1291 break;
1292 }
1293
1294 if (line[0] != '\0')
1295 currentBox->boxTitle = NEWstrdup(line);
1296 }
1297
1298 if ( currentBox->boxTitle != NULL)
1299 return(NEWstrlen(currentBox->boxTitle));
1300 else
1301 return(0);
1302
1303 }
1304
1305
Usage()1306 void Usage()
1307 {
1308 printf("Usage: %s [toolkit options] [options] <file> ...\n\n", programName);
1309 printf("Options are:\n");
1310 printf(" -help print this message\n");
1311 printf(" -version print the version number\n");
1312 printf(" -poll <secs> how often to poll the file(s); default: 60\n");
1313 printf(" -header <secs> popup header when mail is received\n");
1314 printf(" (use '0' for mouse press only)\n");
1315 printf(" -acmd <command> command for audio instead of <bell>\n");
1316 printf(" -boxfile <file> filename containing names of mailboxes\n");
1317 printf(" -horiz place the boxes horizontally; default: vertical\n");
1318 printf(" -nobeep don't ring bell when mail is received\n");
1319 printf(" -names display full path of mail files in the boxes\n");
1320 printf(" -shortnames display names of mail files in the boxes\n");
1321 printf(" -center center the names of the boxes\n");
1322 printf(" -fill make all the boxes the same size\n");
1323 printf(" -orig original mode - display all messages in the boxes\n");
1324 printf(" -command <cmd> system command to execute when middle button is pushed\n");
1325 printf(" -mail <files> specify a mailbox(s) to watch\n");
1326 #ifdef USE_NNTP
1327 printf(" -news <groups> specify a newsgroup(s) to watch\n");
1328 #endif /* USE_NNTP */
1329 printf("\n");
1330 printf("If there are any files specified on the command line, it will\n");
1331 printf("monitor those mail files, otherwise it will use your MAILPATH\n");
1332 printf("environment variable.\n");
1333 printf("\n");
1334 }
1335
1336
main(argc,argv)1337 int main(argc, argv)
1338 int argc;
1339 char *argv[];
1340
1341 {
1342 #ifdef USE_MOTIF
1343 static String fallback_resources[] = {
1344 "*.popup.translations: <Btn1Up>:Activate()",
1345 "*XmPushButton.translations: #override \
1346 <Btn2Down>:Arm()\n\
1347 <Btn2Up>:Disarm()",
1348 (String) NULL
1349 };
1350
1351 #endif
1352 static Boolean mailArgs;
1353 Widget form;
1354 int i;
1355 char *check;
1356 char name[MAX_STRING];
1357 Arg args[5];
1358 int nargs;
1359 int pid;
1360
1361 #ifdef DEBUG
1362 char pause_string[10];
1363 /* gets(pause_string);*/
1364 #endif
1365
1366 /* initialize program name and version string */
1367 programName = EliminatePath(argv[0]);
1368 sprintf(versionString, "%s v%s", programName, VERSION);
1369
1370 mailArgs = TRUE;
1371
1372 nBoxes = 0;
1373 DynBoxObj = DynCreate(sizeof(BoxInfo_t), 1);
1374
1375 #ifdef DEBUG
1376 DynDebug(DynBoxObj, 1);
1377 DynParanoid(DynBoxObj, 1);
1378 #endif
1379
1380 boxInfo = (BoxInfo_t *) DynGet(DynBoxObj, 0);
1381
1382 nargs = 0;
1383 XtSetArg(args[nargs], XtNallowShellResize, TRUE);
1384 nargs++;
1385
1386 #ifdef USE_MOTIF
1387 toplevel = XtAppInitialize(&app, X_RESOURCE_CLASS, options,
1388 XtNumber(options), &argc, argv, fallback_resources, args, nargs);
1389 #else
1390 toplevel = XtAppInitialize(&app, X_RESOURCE_CLASS, options,
1391 XtNumber(options), &argc, argv, 0, args, nargs);
1392 #endif
1393
1394 XtGetApplicationResources(toplevel, &data, resources, XtNumber(resources),
1395 0, 0);
1396
1397 /* initialize some values */
1398 if (data.pollTime != NULL)
1399 envPolltime = atoi(data.pollTime);
1400
1401 if ((data.pollTime == NULL) && ((check = getenv("MAILCHECK")) != 0))
1402 {
1403 if ((envPolltime = atoi(check)) < 0)
1404 {
1405 fprintf(stderr, "MAILCHECK has illegal value\n");
1406 }
1407 }
1408
1409 if ((envPolltime <= 0) || (envPolltime >= 3600))
1410 envPolltime = 60;
1411
1412 if (data.priority != NULL)
1413 envPriority = atoi(data.priority);
1414
1415 if ((envPriority < 0) || (envPriority >= 20))
1416 envPriority = 15;
1417
1418 if (data.headerTime != NULL)
1419 envHeadertime = atoi(data.headerTime);
1420
1421 if (envHeadertime <= 0)
1422 envHeadertime = 0;
1423 if (envHeadertime >= 60)
1424 envHeadertime = 60;
1425
1426 argc--;
1427 ++argv;
1428 while (argc)
1429 {
1430 if (strcmp("-help", *argv) == 0)
1431 {
1432 Usage();
1433 exit(0);
1434 }
1435 else if (strcmp("-version", *argv) == 0)
1436 {
1437 printf("%s\n", versionString);
1438 exit(0);
1439 }
1440 else if (strcmp("-news", *argv) == 0)
1441 {
1442 #ifndef USE_NNTP
1443 fprintf(stderr, "program not compiled with -DUSE_NNTP ignoring %s\n", *argv);
1444 #else
1445 mailArgs = FALSE;
1446 #endif /* !USE_NNTP */
1447 }
1448 else if (strcmp("-mail", *argv) == 0)
1449 {
1450 mailArgs = TRUE;
1451 }
1452 else
1453 {
1454 if (*argv[0] == '-')
1455 {
1456 fprintf(stderr, "Bad option: %s\n\n", *argv);
1457 Usage();
1458 exit(-1);
1459 }
1460
1461 if (mailArgs)
1462 {
1463 #ifdef USE_LED
1464 initBox(NEWstrdup(*argv), MAILBOX, envPolltime, envHeadertime,
1465 UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL,-1);
1466 #else
1467 initBox(NEWstrdup(*argv), MAILBOX, envPolltime, envHeadertime,
1468 UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL);
1469 #endif
1470
1471 }
1472
1473 #ifdef USE_NNTP
1474 else
1475 {
1476 #ifdef USE_LED
1477 initBox(NEWstrdup(*argv), NNTPBOX, envPolltime, envHeadertime,
1478 UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL,-1);
1479 #else
1480 initBox(NEWstrdup(*argv), NNTPBOX, envPolltime, envHeadertime,
1481 UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL);
1482 #endif
1483 }
1484 #endif /* USE_NNTP */
1485
1486 }
1487 argc--;
1488 ++argv;
1489 }
1490
1491
1492 if ((data.boxFile != 0) && (nBoxes == 0))
1493 {
1494 readBoxfile(data.boxFile);
1495 }
1496
1497
1498 if (nBoxes == 0)
1499 {
1500 ParseMailPath();
1501 #ifdef USE_NNTP
1502 ParseNewsPath();
1503 #endif /* USE_NNTP */
1504 }
1505
1506 /* if there are still no boxes, what's the point? */
1507 if (nBoxes == 0)
1508 {
1509 fprintf(stderr, "nothing to watch is specified\n");
1510 fprintf(stderr, "check $MAILPATH / XBuffy.mailboxes\n");
1511 #ifdef USE_NNTP
1512 fprintf(stderr, "check $NEWSPATH / XBuffy.newsboxes\n");
1513 #endif /* USE_NNTP */
1514 Usage();
1515 exit(-1);
1516 }
1517
1518 LoadIcon(toplevel);
1519
1520 nargs = 0;
1521 #ifndef USE_MOTIF
1522 if (data.horiz)
1523 {
1524 XtSetArg(args[nargs], XtNorientation, XtorientHorizontal);
1525 nargs++;
1526 }
1527 form = XtCreateManagedWidget("box", boxWidgetClass, toplevel, args, nargs);
1528 /* form = XtCreateManagedWidget("box", panedWidgetClass, toplevel, args, nargs);*/
1529 #else
1530 if (data.horiz)
1531 {
1532 XtSetArg(args[nargs], XmNorientation, XmHORIZONTAL);
1533 nargs++;
1534 XtSetArg(args[nargs], XmNpacking, XmPACK_COLUMN);
1535 nargs++;
1536 }
1537 else
1538 {
1539 XtSetArg(args[nargs], XmNorientation, XmVERTICAL);
1540 nargs++;
1541 XtSetArg(args[nargs], XmNpacking, XmPACK_TIGHT);
1542 nargs++;
1543 }
1544 XtSetArg(args[nargs], XmNisAligned, True);
1545 nargs++;
1546 XtSetArg(args[nargs], XmNentryVerticalAlignment, XmALIGNMENT_CENTER);
1547 nargs++;
1548
1549 form = XmCreateRowColumn(toplevel, "box", args, nargs);
1550 XtManageChild(form);
1551 #endif
1552
1553
1554
1555 if ((header = (Widget *) malloc(nBoxes * sizeof(Widget))) == 0)
1556 {
1557 fprintf(stderr, "Can't malloc header widgets\n");
1558 exit(-1);
1559 }
1560 if ((headerUp = (int *) malloc(nBoxes * sizeof(int))) == 0)
1561 {
1562 fprintf(stderr, "Can't malloc header flags\n");
1563 exit(-1);
1564 }
1565
1566 for (i = 0; i < nBoxes; i++)
1567 {
1568
1569 Boolean dummy;
1570
1571 headerUp[i] = FALSE;
1572
1573 if ((boxInfo[i].type == MAILBOX) || (boxInfo[i].type == MAILDIR) ||
1574 (boxInfo[i].type == MHDIR))
1575 boxInfo[i].n = CountUnixMail(&boxInfo[i], NULL, &dummy);
1576
1577 #ifdef USE_NNTP
1578 if (boxInfo[i].type == NNTPBOX)
1579 boxInfo[i].n = CountNNTP(&boxInfo[i], NULL, &dummy);
1580 #endif
1581
1582 sprintf(name, "box%d", i);
1583
1584 #ifndef USE_MOTIF
1585 nargs = 0;
1586 XtSetArg(args[nargs], XtNleft, XtChainLeft);
1587 nargs++;
1588 XtSetArg(args[nargs], XtNright, XtChainLeft);
1589 nargs++;
1590 XtSetArg(args[nargs], XtNresizable, True);
1591 nargs++;
1592 /*7!*/ XtSetArg(args[nargs], XtNshowGrip, False);
1593 nargs++;
1594 XtSetArg(args[nargs], XtNallowResize, True);
1595 nargs++;
1596
1597
1598
1599 boxInfo[i].w = XtCreateManagedWidget(name, commandWidgetClass, form, args, nargs);
1600
1601
1602 XtAddEventHandler(boxInfo[i].w, ButtonPressMask, True,
1603 ButtonDownHandler, &boxInfo[i].boxNum);
1604 XtAddEventHandler(boxInfo[i].w, ButtonReleaseMask, True,
1605 ButtonUpHandler, &boxInfo[i].boxNum);
1606
1607 #else
1608 nargs = 0;
1609 XtSetArg(args[nargs], XmNresizable, TRUE);
1610 nargs++;
1611 boxInfo[i].w = XmCreatePushButton(form, name, args, nargs);
1612 XtManageChild(boxInfo[i].w);
1613 XtAddEventHandler(boxInfo[i].w, ButtonPressMask, True,
1614 ButtonDownHandler, &boxInfo[i].boxNum);
1615 XtAddEventHandler(boxInfo[i].w, ButtonReleaseMask, True,
1616 ButtonUpHandler, &boxInfo[i].boxNum);
1617
1618 #endif
1619
1620 UpdateBoxNumber(&boxInfo[i]);
1621
1622 CheckBox(i);
1623 }
1624
1625 #ifdef DEBUG
1626 fprintf(stderr, "bg = %i, fg = %i maxSize = %i\n", data.bg, data.fg,maxBoxSize);
1627 for (i = 0; i < nBoxes; i++)
1628 {
1629 fprintf(stderr, "box = %s\n", boxInfo[i].box);
1630 fprintf(stderr, "pollTime = %i\n", boxInfo[i].pollTime);
1631 fprintf(stderr, "headerTime = %i\n", boxInfo[i].headerTime);
1632 fprintf(stderr, "origMode = %i\n", boxInfo[i].origMode);
1633 fprintf(stderr, "nobeep = %i\n", boxInfo[i].nobeep);
1634 #ifdef USE_LED
1635 fprintf(stderr, "led = %i\n", boxInfo[i].led);
1636 #endif
1637 fprintf(stderr, "command = %s\n", boxInfo[i].command);
1638 fprintf(stderr, "nameType = %i\n", boxInfo[i].BoxNameType);
1639
1640 }
1641 #endif
1642 XtRealizeWidget(toplevel);
1643
1644 #ifndef DEBUG
1645 #ifdef HAVE_SETPRIORITY
1646 if (setpriority(PRIO_PROCESS, 0, envPriority) == -1)
1647 perror("Proirity change Failed");
1648 #endif
1649 /* put ourself in the background */
1650 switch (pid = fork())
1651 {
1652 case 0:
1653 XtAppMainLoop(app); /* in child do the stuff */
1654 break;
1655 case -1:
1656 perror("Fork failure");
1657 XtAppMainLoop(app); /* fork failed - carry on in the parent instead */
1658 break;
1659 default:
1660 exit(0); /* ok its going we can stop now */
1661 break;
1662 }
1663 #else
1664 XtAppMainLoop(app);
1665 #endif
1666 return 0;
1667 }
1668