|
|
1.1 root 1: #ifndef lint
2: static char rcs_id[] = "$Header: toc.c,v 1.17 87/08/06 13:23:54 toddb Exp $";
3: #endif lint
4: /*
5: * COPYRIGHT 1987
6: * DIGITAL EQUIPMENT CORPORATION
7: * MAYNARD, MASSACHUSETTS
8: * ALL RIGHTS RESERVED.
9: *
10: * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
11: * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
12: * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
13: * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
14: *
15: * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
16: * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
17: * SET FORTH ABOVE.
18: *
19: *
20: * Permission to use, copy, modify, and distribute this software and its
21: * documentation for any purpose and without fee is hereby granted, provided
22: * that the above copyright notice appear in all copies and that both that
23: * copyright notice and this permission notice appear in supporting documentation,
24: * and that the name of Digital Equipment Corporation not be used in advertising
25: * or publicity pertaining to distribution of the software without specific,
26: * written prior permission.
27: */
28:
29: /* toc.c -- handle things in the toc window. */
30:
31: #include "xmh.h"
32: #include "tocintrnl.h"
33: #include "toc.h"
34: #include "tocutil.h"
35: #include <sys/stat.h>
36: #include <sys/dir.h>
37:
38: /* PUBLIC ROUTINES */
39:
40:
41: static int IsDir(ent)
42: struct direct *ent;
43: {
44: char str[500];
45: struct stat buf;
46: if (ent->d_name[0] == '.')
47: return FALSE;
48: (void) sprintf(str, "%s/%s", mailDir, ent->d_name);
49: (void) stat(str, &buf);
50: return (buf.st_mode & S_IFMT) == S_IFDIR;
51: }
52:
53:
54:
55: static void MakeSureFolderExists(namelistptr, numfoldersptr, name)
56: struct direct ***namelistptr;
57: int *numfoldersptr;
58: char *name;
59: {
60: int i;
61: extern alphasort();
62: char str[200];
63: for (i=0 ; i<*numfoldersptr ; i++)
64: if (strcmp((*namelistptr)[i]->d_name, name) == 0) return;
65: (void) sprintf(str, "%s/%s", mailDir, name);
66: (void) mkdir(str, 0700);
67: *numfoldersptr = scandir(mailDir, namelistptr, IsDir, alphasort);
68: for (i=0 ; i<*numfoldersptr ; i++)
69: if (strcmp((*namelistptr)[i]->d_name, name) == 0) return;
70: Punt("Can't create new mail folder!");
71: }
72:
73:
74: static void LoadCheckFiles()
75: {
76: FILE *fid;
77: char str[1024], *ptr, *ptr2;
78: int i;
79: (void) sprintf(str, "%s/.xmhcheck", homeDir);
80: fid = myfopen(str, "r");
81: if (fid) {
82: while (ptr = ReadLine(fid)) {
83: while (*ptr == ' ' || *ptr == '\t') ptr++;
84: ptr2 = ptr;
85: while (*ptr2 && *ptr2 != ' ' && *ptr2 != '\t') ptr2++;
86: if (*ptr2 == 0) continue;
87: *ptr2++ = 0;
88: while (*ptr2 == ' ' || *ptr2 == '\t') ptr2++;
89: if (*ptr2 == 0) continue;
90: for (i=0 ; i<numFolders ; i++) {
91: if (strcmp(ptr, folderList[i]->foldername) == 0) {
92: folderList[i]->incfile = MallocACopy(ptr2);
93: break;
94: }
95: }
96: }
97: myfclose(fid);
98: } else if (initialIncFile) {
99: if (*initialIncFile != '\0')
100: InitialFolder->incfile = initialIncFile;
101: } else {
102: ptr = getenv("MAIL");
103: if (ptr == NULL) ptr = getenv("mail");
104: if (ptr == NULL) {
105: ptr = getenv("USER");
106: if (ptr) {
107: (void) sprintf(str, "/usr/spool/mail/%s", ptr);
108: ptr = str;
109: }
110: }
111: if (ptr)
112: InitialFolder->incfile = MallocACopy(ptr);
113: }
114: }
115:
116:
117:
118:
119: /* Read in the list of folders. */
120:
121: void TocInit()
122: {
123: Toc toc;
124: struct direct **namelist;
125: int i;
126: extern alphasort();
127: numFolders = scandir(mailDir, &namelist, IsDir, alphasort);
128: if (numFolders < 0) {
129: (void) mkdir(mailDir, 0700);
130: numFolders = scandir(mailDir, &namelist, IsDir, alphasort);
131: if (numFolders < 0)
132: Punt("Can't create or read mail directory!");
133: }
134: MakeSureFolderExists(&namelist, &numFolders, initialFolderName);
135: MakeSureFolderExists(&namelist, &numFolders, draftsFolderName);
136: folderList = (Toc *) XtMalloc((unsigned) numFolders * sizeof(Toc));
137: for (i=0 ; i<numFolders ; i++) {
138: toc = folderList[i] = TUMalloc();
139: toc->foldername = MallocACopy(namelist[i]->d_name);
140: XtFree((char *)namelist[i]);
141: }
142: InitialFolder = TocGetNamed(initialFolderName);
143: DraftsFolder = TocGetNamed(draftsFolderName);
144: XtFree((char *)namelist);
145: if (defNewMailCheck) LoadCheckFiles();
146: }
147:
148:
149: /* Create a new folder with the given name. */
150:
151: Toc TocCreateFolder(foldername)
152: char *foldername;
153: {
154: Toc toc;
155: int i, j;
156: char str[500];
157: if (TocGetNamed(foldername)) return NULL;
158: (void) sprintf(str, "%s/%s", mailDir, foldername);
159: if (mkdir(str, 0700) < 0) return NULL;
160: toc = TUMalloc();
161: toc->foldername = MallocACopy(foldername);
162: for (i=0 ; i<numFolders ; i++)
163: if (strcmp(foldername, folderList[i]->foldername) < 0) break;
164: folderList = (Toc *) XtRealloc((char *) folderList,
165: (unsigned) ++numFolders * sizeof(Toc));
166: for (j=numFolders - 1 ; j > i ; j--)
167: folderList[j] = folderList[j-1];
168: folderList[i] = toc;
169: return toc;
170: }
171:
172:
173:
174: /* Check to see if what folders have new mail, and highlight their
175: folderbuttons appropriately. */
176:
177: void TocCheckForNewMail()
178: {
179: #ifdef X11
180: Toc toc;
181: Scrn scrn;
182: int i, j, hasmail;
183: if (!defNewMailCheck) return;
184: for (i=0 ; i<numFolders ; i++) {
185: toc = folderList[i];
186: if (toc->incfile) {
187: hasmail = (GetFileLength(toc->incfile) > 0);
188: if (hasmail != toc->mailpending) {
189: toc->mailpending = hasmail;
190: for (j=0 ; j<numScrns ; j++) {
191: scrn = scrnList[j];
192: if (scrn->kind == STtocAndView) {
193: if (toc == InitialFolder) {
194: scrn->hints.icon_pixmap =
195: hasmail ? NewMailPixmap : NoMailPixmap;
196: XSetWMHints(theDisplay, scrn->window,
197: &(scrn->hints));
198: } else {
199: BBoxChangeBorderWidth( /* %%% HACK */
200: BBoxButtonNumber(scrnList[j]->folderbuttons, i),
201: (unsigned)(hasmail ? 2 : 1));
202: }
203: }
204: }
205: }
206: }
207: }
208: #endif X11
209: }
210:
211:
212: /* Recursively delete an entire directory. Nasty. */
213:
214: static void NukeDirectory(path)
215: char *path;
216: {
217: char str[500];
218: (void) sprintf(str, "rm -rf %s", path);
219: (void) system(str);
220: }
221:
222:
223:
224: /* Destroy the given folder. */
225:
226: void TocDeleteFolder(toc)
227: Toc toc;
228: {
229: Toc toc2;
230: int i, j, w;
231: TUGetFullFolderInfo(toc);
232: if (TocConfirmCataclysm(toc)) return;
233: TocSetScrn(toc, (Scrn) NULL);
234: w = -1;
235: for (i=0 ; i<numFolders ; i++) {
236: toc2 = folderList[i];
237: if (toc2 == toc)
238: w = i;
239: else if (toc2->validity == valid)
240: for (j=0 ; j<toc2->nummsgs ; j++)
241: if (toc2->msgs[j]->desttoc == toc)
242: MsgSetFate(toc2->msgs[j], Fignore, (Toc) NULL);
243: }
244: if (w < 0) Punt("Couldn't find it in TocDeleteFolder!");
245: NukeDirectory(toc->path);
246: if (toc->validity == valid) {
247: for (i=0 ; i<toc->nummsgs ; i++) {
248: MsgSetScrnForce(toc->msgs[i], (Scrn) NULL);
249: MsgFree(toc->msgs[i]);
250: }
251: XtFree((char *) toc->msgs);
252: }
253: XtFree((char *)toc);
254: numFolders--;
255: for (i=w ; i<numFolders ; i++) folderList[i] = folderList[i+1];
256: }
257:
258:
259:
260: /* Display the given toc in the given scrn. */
261:
262: void TocSetScrn(toc, scrn)
263: Toc toc;
264: Scrn scrn;
265: {
266: if (toc == NULL && scrn == NULL) return;
267: if (scrn && scrn->toc != NULL)
268: TocSetScrn(scrn->toc, (Scrn) NULL);
269: if (toc == NULL) return;
270: if (toc->scrn == scrn) return;
271: if (toc->scrn) {
272: toc->scrn->toc = NULL;
273: TUResetTocLabel(toc->scrn);
274: TURedisplayToc(toc->scrn);
275: QXStoreName(theDisplay, toc->scrn->window, progName);
276: EnableProperButtons(toc->scrn);
277: toc->scrn = NULL;
278: if (scrn == NULL) return;
279: }
280:
281: scrn->toc = toc;
282: toc->scrn = scrn;
283:
284: TUEnsureScanIsValidAndOpen(toc);
285: TUResetTocLabel(scrn);
286: QXStoreName(theDisplay, toc->scrn->window, toc->foldername);
287: TURedisplayToc(toc->scrn);
288:
289: BBoxSetRadio(scrn->folderbuttons,
290: BBoxFindButtonNamed(scrn->folderbuttons, toc->foldername));
291:
292: EnableProperButtons(scrn);
293:
294: return;
295: }
296:
297:
298:
299: /* Remove the given message from the toc. Doesn't actually touch the file.
300: Also note that it does not free the storage for the msg. */
301:
302: void TocRemoveMsg(toc, msg)
303: Toc toc;
304: Msg msg;
305: {
306: Msg newcurmsg;
307: MsgList mlist;
308: int i;
309: if (toc->validity == unknown)
310: TUGetFullFolderInfo(toc);
311: if (toc->validity != valid)
312: return;
313: newcurmsg = TocMsgAfter(toc, msg);
314: if (newcurmsg) newcurmsg->changed = TRUE;
315: newcurmsg = toc->curmsg;
316: if (msg == toc->curmsg) {
317: newcurmsg = TocMsgAfter(toc, msg);
318: if (newcurmsg == NULL) newcurmsg = TocMsgBefore(toc, msg);
319: toc->curmsg = NULL;
320: }
321: toc->length -= msg->length;
322: if (msg->visible) toc->lastPos -= msg->length;
323: for(i = TUGetMsgPosition(toc, msg), toc->nummsgs--; i<toc->nummsgs ; i++) {
324: toc->msgs[i] = toc->msgs[i+1];
325: if (msg->visible) toc->msgs[i]->position -= msg->length;
326: }
327: for (i=0 ; i<toc->numsequences ; i++) {
328: mlist = toc->seqlist[i]->mlist;
329: if (mlist) DeleteMsgFromMsgList(mlist, msg);
330: }
331:
332: if (msg->visible) TURedisplayToc(toc->scrn);
333: TocSetCurMsg(toc, newcurmsg);
334: TUSaveTocFile(toc);
335: }
336:
337:
338:
339: void TocRecheckValidity(toc)
340: Toc toc;
341: {
342: if (toc && toc->validity == valid && TUScanFileOutOfDate(toc)) {
343: TUScanFileForToc(toc);
344: if (toc->source)
345: TULoadTocFile(toc);
346: TURedisplayToc(toc->scrn);
347: }
348: }
349:
350:
351: /* Set the current message. */
352:
353: void TocSetCurMsg(toc, msg)
354: Toc toc;
355: Msg msg;
356: {
357: Msg msg2;
358: if (toc->validity != valid) return;
359: if (msg != toc->curmsg) {
360: msg2 = toc->curmsg;
361: toc->curmsg = msg;
362: if (msg2)
363: MsgSetFate(msg2, msg2->fate, msg2->desttoc);
364: }
365: if (msg) {
366: MsgSetFate(msg, msg->fate, msg->desttoc);
367: if (toc->scrn) {
368: if (toc->stopupdate)
369: toc->needsrepaint = TRUE;
370: else
371: XtTextSetInsertionPoint(DISPLAY toc->scrn->tocwindow,
372: msg->position);
373: }
374: }
375: }
376:
377:
378: /* Return the current message. */
379:
380: Msg TocGetCurMsg(toc)
381: Toc toc;
382: {
383: return toc->curmsg;
384: }
385:
386:
387:
388:
389: /* Return the message after the given one. (If none, return NULL.) */
390:
391: Msg TocMsgAfter(toc, msg)
392: Toc toc;
393: Msg msg;
394: {
395: int i;
396: i = TUGetMsgPosition(toc, msg);
397: do {
398: i++;
399: if (i >= toc->nummsgs)
400: return NULL;
401: } while (!(toc->msgs[i]->visible));
402: return toc->msgs[i];
403: }
404:
405:
406:
407: /* Return the message before the given one. (If none, return NULL.) */
408:
409: Msg TocMsgBefore(toc, msg)
410: Toc toc;
411: Msg msg;
412: {
413: int i;
414: i = TUGetMsgPosition(toc, msg);
415: do {
416: i--;
417: if (i < 0)
418: return NULL;
419: } while (!(toc->msgs[i]->visible));
420: return toc->msgs[i];
421: }
422:
423:
424:
425: /* The caller KNOWS the toc's information is out of date; rescan it. */
426:
427: void TocForceRescan(toc)
428: Toc toc;
429: {
430: if (toc->scrn) {
431: toc->viewedseq = toc->seqlist[0];
432: TUResetTocLabel(toc->scrn);
433: TUScanFileForToc(toc);
434: TULoadTocFile(toc);
435: TURedisplayToc(toc->scrn);
436: } else {
437: TUGetFullFolderInfo(toc);
438: (void) unlink(toc->scanfile);
439: toc->validity = invalid;
440: }
441: }
442:
443:
444:
445: /* The caller has just changed a sequence list. Reread them from mh. */
446:
447: void TocReloadSeqLists(toc)
448: Toc toc;
449: {
450: TocSetCacheValid(toc);
451: TULoadSeqLists(toc);
452: TURefigureWhatsVisible(toc);
453: TUResetTocLabel(toc->scrn);
454: EnableProperButtons(toc->scrn);
455: }
456:
457:
458: /* Return TRUE if the toc has an interesting sequence. */
459:
460: int TocHasSequences(toc)
461: Toc toc;
462: {
463: return toc && toc->numsequences > 1;
464: }
465:
466:
467: /* Change which sequence is being viewed. */
468:
469: void TocChangeViewedSeq(toc, seq)
470: Toc toc;
471: Sequence seq;
472: {
473: if (seq == NULL) seq = toc->viewedseq;
474: toc->viewedseq = seq;
475: TURefigureWhatsVisible(toc);
476: if (toc->scrn && toc->scrn->seqbuttons)
477: BBoxSetRadio(toc->scrn->seqbuttons,
478: BBoxFindButtonNamed(toc->scrn->seqbuttons, seq->name));
479: TUResetTocLabel(toc->scrn);
480: }
481:
482:
483: /* Return the sequence with the given name in the given toc. */
484:
485: Sequence TocGetSeqNamed(toc, name)
486: Toc toc;
487: char *name;
488: {
489: int i;
490: for (i=0 ; i<toc->numsequences ; i++)
491: if (strcmp(toc->seqlist[i]->name, name) == 0)
492: return toc->seqlist[i];
493: return (Sequence) NULL;
494: }
495:
496:
497: /* Return the sequence currently being viewed in the toc. */
498:
499: Sequence TocViewedSequence(toc)
500: Toc toc;
501: {
502: return toc->viewedseq;
503: }
504:
505:
506: /* Return the list of messages currently selected. */
507:
508: MsgList TocCurMsgList(toc)
509: Toc toc;
510: {
511: MsgList result;
512: XtTextPosition pos1, pos2;
513: extern Msg MsgFromPosition();
514: if (toc->scrn == NULL) return NULL;
515: result = MakeNullMsgList();
516: XtTextGetSelectionPos(DISPLAY toc->scrn->tocwindow, &pos1, &pos2);
517: if (pos1 < pos2) {
518: pos1 = toc->source->scan(toc->source, pos1, XtstEOL, XtsdLeft,
519: 1, FALSE);
520: pos2 = toc->source->scan(toc->source, pos2, XtstPositions, XtsdLeft,
521: 1, TRUE);
522: pos2 = toc->source->scan(toc->source, pos2, XtstEOL, XtsdRight,
523: 1, FALSE);
524: while (pos1 < pos2) {
525: AppendMsgList(result, MsgFromPosition(toc, pos1, XtsdRight));
526: pos1 = toc->source->scan(toc->source, pos1, XtstEOL, XtsdRight,
527: 1, TRUE);
528: }
529: }
530: return result;
531: }
532:
533:
534:
535: /* Unset the current selection. */
536:
537: void TocUnsetSelection(toc)
538: Toc toc;
539: {
540: if (toc->scrn)
541: XtTextUnsetSelection(DISPLAY toc->scrn->tocwindow);
542: }
543:
544:
545:
546: /* Create a brand new, blank message. */
547:
548: Msg TocMakeNewMsg(toc)
549: Toc toc;
550: {
551: Msg msg;
552: TUEnsureScanIsValidAndOpen(toc);
553: msg = TUAppendToc(toc, "#### empty\n");
554: if (FileExists(MsgFileName(msg))) {
555: if (debug) (void) fprintf(stderr, "**** FOLDER %s WAS INVALID!!!\n",
556: toc->foldername);
557: TocForceRescan(toc);
558: return TocMakeNewMsg(toc); /* Try again. Using recursion here is ugly,
559: but what the hack ... */
560: }
561: CopyFileAndCheck("/dev/null", MsgFileName(msg));
562: return msg;
563: }
564:
565:
566: /* Set things to not update cache or display until further notice. */
567:
568: void TocStopUpdate(toc)
569: Toc toc;
570: {
571: toc->stopupdate++;
572: }
573:
574:
575: /* Start updating again, and do whatever updating has been queued. */
576:
577: void TocStartUpdate(toc)
578: Toc toc;
579: {
580: if (toc->stopupdate && --(toc->stopupdate) == 0) {
581: if (toc->needsrepaint)
582: TURedisplayToc(toc->scrn);
583: if (toc->needslabelupdate)
584: TUResetTocLabel(toc->scrn);
585: if (toc->needscachesave)
586: TUSaveTocFile(toc);
587: }
588: }
589:
590:
591:
592: /* Something has happened that could later convince us that our cache is out
593: of date. Make this not happen; our cache really *is* up-to-date. */
594:
595: void TocSetCacheValid(toc)
596: Toc toc;
597: {
598: TUSaveTocFile(toc);
599: }
600:
601:
602: /* Return the foldername of the given toc. */
603:
604: char *TocGetFolderName(toc)
605: Toc toc;
606: {
607: return toc->foldername;
608: }
609:
610:
611:
612: /* Given a foldername, return the corresponding toc. */
613:
614: Toc TocGetNamed(name)
615: char *name;
616: {
617: int i;
618: for (i=0; i<numFolders ; i++)
619: if (strcmp(folderList[i]->foldername, name) == 0) return folderList[i];
620: return NULL;
621: }
622:
623:
624:
625: /* Throw out all changes to this toc, and close all views of msgs in it.
626: Requires confirmation by the user. */
627:
628: int TocConfirmCataclysm(toc)
629: Toc toc;
630: {
631: int i;
632: int found = FALSE;
633: char str[500];
634: for (i=0 ; i<toc->nummsgs && !found ; i++)
635: if (toc->msgs[i]->fate != Fignore) found = TRUE;
636: if (found) {
637: (void)sprintf(str,"Are you sure you want to remove all changes to %s?",
638: toc->foldername);
639: if (!Confirm(toc->scrn, str))
640: return DELETEABORTED;
641: }
642: for (i=0 ; i<toc->nummsgs ; i++)
643: MsgSetFate(toc->msgs[i], Fignore, (Toc)NULL);
644: for (i=0 ; i<toc->nummsgs ; i++)
645: if (MsgSetScrn(toc->msgs[i], (Scrn) NULL)) return DELETEABORTED;
646: return 0;
647: }
648:
649:
650:
651: /* Commit all the changes in this toc; all messages will meet their 'fate'. */
652:
653: void TocCommitChanges(toc)
654: Toc toc;
655: {
656: Msg msg;
657: int i, cur;
658: char str[100], **argv;
659: FateType curfate, fate;
660: Toc desttoc;
661: Toc curdesttoc;
662:
663: if (toc == NULL) return;
664: for (i=0 ; i<toc->nummsgs ; i++) {
665: msg = toc->msgs[i];
666: fate = MsgGetFate(msg, (Toc *)NULL);
667: if (fate != Fignore && fate != Fcopy)
668: if (MsgSetScrn(msg, (Scrn) NULL))
669: return;
670: }
671: QXFlush(theDisplay);
672: for (i=0 ; i<numFolders ; i++)
673: TocStopUpdate(folderList[i]);
674: do {
675: curfate = Fignore;
676: i = 0;
677: while (i < toc->nummsgs) {
678: msg = toc->msgs[i];
679: fate = MsgGetFate(msg, &desttoc);
680: if (curfate == Fignore && fate != Fignore) {
681: curfate = fate;
682: argv = MakeArgv(2);
683: switch (curfate) {
684: case Fdelete:
685: argv[0] = MallocACopy("rmm");
686: (void) sprintf(str, "+%s", toc->foldername);
687: argv[1] = MallocACopy(str);
688: cur = 2;
689: curdesttoc = NULL;
690: break;
691: case Fmove:
692: case Fcopy:
693: argv[0] = MallocACopy("refile");
694: cur = 1;
695: curdesttoc = desttoc;
696: break;
697: }
698: }
699: if (curfate != Fignore &&
700: curfate == fate && desttoc == curdesttoc) {
701: argv = ResizeArgv(argv, cur + 1);
702: (void) sprintf(str, "%d", MsgGetId(msg));
703: argv[cur++] = MallocACopy(str);
704: MsgSetFate(msg, Fignore, (Toc)NULL);
705: if (curdesttoc)
706: (void) TUAppendToc(curdesttoc, MsgGetScanLine(msg));
707: if (curfate != Fcopy) {
708: TocRemoveMsg(toc, msg);
709: MsgFree(msg);
710: i--;
711: }
712: if (cur > 40)
713: break; /* Do only 40 at a time, just to be safe. */
714: }
715: i++;
716: }
717: if (curfate != Fignore) {
718: switch (curfate) {
719: case Fmove:
720: case Fcopy:
721: argv = ResizeArgv(argv, cur + 4);
722: argv[cur++] = MallocACopy(curfate == Fmove ? "-nolink"
723: : "-link");
724: argv[cur++] = MallocACopy("-src");
725: (void) sprintf(str, "+%s", toc->foldername);
726: argv[cur++] = MallocACopy(str);
727: (void) sprintf(str, "+%s", curdesttoc->foldername);
728: argv[cur++] = MallocACopy(str);
729: break;
730: }
731: if (debug) {
732: for (i = 0; i < cur; i++)
733: (void) fprintf(stderr, "%s ", argv[i]);
734: (void) fprintf(stderr, "\n");
735: }
736: DoCommand(argv, (char *) NULL, "/dev/null");
737: for (i = 0; argv[i]; i++)
738: XtFree((char *) argv[i]);
739: XtFree((char *) argv);
740: }
741: } while (curfate != Fignore);
742: for (i=0 ; i<numFolders ; i++) {
743: if (folderList[i]->needsrepaint) TocReloadSeqLists(folderList[i]);
744: TocStartUpdate(folderList[i]);
745: }
746: }
747:
748:
749:
750: /* Return whether the given toc can incorporate mail. */
751:
752: int TocCanIncorporate(toc)
753: Toc toc;
754: {
755: return (toc && (toc == InitialFolder || toc->incfile));
756: }
757:
758:
759: /* Incorporate new messages into the given toc. */
760:
761: void TocIncorporate(toc)
762: Toc toc;
763: {
764: char **argv;
765: char str[100], str2[10], *file, *ptr;
766: Msg msg, firstmessage;
767: FILEPTR fid;
768: argv = MakeArgv(toc->incfile ? 7 : 5);
769: argv[0] = "inc";
770: (void) sprintf(str, "+%s", toc->foldername);
771: argv[1] = str;
772: argv[2] = "-width";
773: (void) sprintf(str2, "%d", defTocWidth);
774: argv[3] = str2;
775: if (toc->incfile) {
776: argv[4] = "-file";
777: argv[5] = toc->incfile;
778: argv[6] = "-truncate";
779: } else argv[4] = "-truncate";
780: file = DoCommandToFile(argv);
781: XtFree((char *)argv);
782: TUGetFullFolderInfo(toc);
783: if (toc->validity == valid) {
784: fid = FOpenAndCheck(file, "r");
785: firstmessage = NULL;
786: TocStopUpdate(toc);
787: while (ptr = ReadLineWithCR(fid)) {
788: if (atoi(ptr) > 0) {
789: msg = TUAppendToc(toc, ptr);
790: if (firstmessage == NULL) firstmessage = msg;
791: }
792: }
793: if (firstmessage && firstmessage->visible) {
794: TocSetCurMsg(toc, firstmessage);
795: }
796: TocStartUpdate(toc);
797: (void) myfclose(fid);
798: }
799: DeleteFileAndCheck(file);
800: }
801:
802:
803:
804: /* The given message has changed. Rescan it and change the scanfile. */
805:
806: void TocMsgChanged(toc, msg)
807: Toc toc;
808: Msg msg;
809: {
810: char **argv, str[100], str2[10], str3[10], *ptr;
811: int length, delta, i;
812: FateType fate;
813: Toc desttoc;
814: if (toc->validity != valid) return;
815: fate = MsgGetFate(msg, &desttoc);
816: MsgSetFate(msg, Fignore, (Toc) NULL);
817: argv = MakeArgv(5);
818: argv[0] = "scan";
819: (void) sprintf(str, "+%s", toc->foldername);
820: argv[1] = str;
821: (void) sprintf(str2, "%d", msg->msgid);
822: argv[2] = str2;
823: argv[3] = "-width";
824: (void) sprintf(str3, "%d", defTocWidth);
825: argv[4] = str3;
826: ptr = DoCommandToString(argv);
827: XtFree((char *) argv);
828: if (strcmp(ptr, msg->buf) != 0) {
829: length = strlen(ptr);
830: delta = length - msg->length;
831: XtFree(msg->buf);
832: msg->buf = ptr;
833: msg->length = length;
834: toc->length += delta;
835: if (msg->visible) {
836: if (delta != 0) {
837: for (i=TUGetMsgPosition(toc, msg)+1; i<toc->nummsgs ; i++)
838: toc->msgs[i]->position += delta;
839: toc->lastPos += delta;
840: TURedisplayToc(toc->scrn);
841: } else {
842: if (toc->scrn)
843: XtTextInvalidate(DISPLAY toc->scrn->tocwindow,
844: msg->position,
845: msg->position + msg->length);
846: }
847: }
848: MsgSetFate(msg, fate, desttoc);
849: TUSaveTocFile(toc);
850: } else XtFree(ptr);
851: }
852:
853:
854:
855: Msg TocMsgFromId(toc, msgid)
856: Toc toc;
857: int msgid;
858: {
859: int h, l, m;
860: char str[100];
861: l = 0;
862: h = toc->nummsgs - 1;
863: while (l < h - 1) {
864: m = (l + h) / 2;
865: if (toc->msgs[m]->msgid > msgid)
866: h = m;
867: else
868: l = m;
869: }
870: if (toc->msgs[l]->msgid == msgid) return toc->msgs[l];
871: if (toc->msgs[h]->msgid == msgid) return toc->msgs[h];
872: (void) sprintf(str, "TocMsgFromId search failed! hi=%d, lo=%d, msgid=%d",
873: h, l, msgid);
874: Punt(str);
875: return 0; /* Keep lint happy. */
876: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.