Annotation of researchv9/X11/src/X.V11R1/clients/xmh/toc.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.