Annotation of researchv9/X11/src/X.V11R1/clients/xmh/toc.c, revision 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.