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