File:  [Research Unix] / researchv9 / X11 / src / X.V11R1 / clients / xmh / toc.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:22:00 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#ifndef lint
static char rcs_id[] = "$Header: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/clients/xmh/toc.c,v 1.1.1.1 2018/04/24 17:22:00 root Exp $";
#endif lint
/*
 *			  COPYRIGHT 1987
 *		   DIGITAL EQUIPMENT CORPORATION
 *		       MAYNARD, MASSACHUSETTS
 *			ALL RIGHTS RESERVED.
 *
 * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
 * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
 * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
 * ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
 *
 * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
 * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
 * SET FORTH ABOVE.
 *
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting documentation,
 * and that the name of Digital Equipment Corporation not be used in advertising
 * or publicity pertaining to distribution of the software without specific,
 * written prior permission.
 */

/* toc.c -- handle things in the toc window. */

#include "xmh.h"
#include "tocintrnl.h"
#include "toc.h"
#include "tocutil.h"
#include <sys/stat.h>
#include <sys/dir.h>

/*	PUBLIC ROUTINES 	*/


static int IsDir(ent)
struct direct *ent;
{
    char str[500];
    struct stat buf;
    if (ent->d_name[0] == '.')
	return FALSE;
    (void) sprintf(str, "%s/%s", mailDir, ent->d_name);
    (void) stat(str, &buf);
    return (buf.st_mode & S_IFMT) == S_IFDIR;
}



static void MakeSureFolderExists(namelistptr, numfoldersptr, name)
struct direct ***namelistptr;
int *numfoldersptr;
char *name;
{
    int i;
    extern alphasort();
    char str[200];
    for (i=0 ; i<*numfoldersptr ; i++)
	if (strcmp((*namelistptr)[i]->d_name, name) == 0) return;
    (void) sprintf(str, "%s/%s", mailDir, name);
    (void) mkdir(str, 0700);
    *numfoldersptr = scandir(mailDir, namelistptr, IsDir, alphasort);
    for (i=0 ; i<*numfoldersptr ; i++)
	if (strcmp((*namelistptr)[i]->d_name, name) == 0) return;
    Punt("Can't create new mail folder!");
}


static void LoadCheckFiles()
{
    FILE *fid;
    char str[1024], *ptr, *ptr2;
    int i;
    (void) sprintf(str, "%s/.xmhcheck", homeDir);
    fid = myfopen(str, "r");
    if (fid) {
	while (ptr = ReadLine(fid)) {
	    while (*ptr == ' ' || *ptr == '\t') ptr++;
	    ptr2 = ptr;
	    while (*ptr2 && *ptr2 != ' ' && *ptr2 != '\t') ptr2++;
	    if (*ptr2 == 0) continue;
	    *ptr2++ = 0;
	    while (*ptr2 == ' ' || *ptr2 == '\t') ptr2++;
	    if (*ptr2 == 0) continue;
	    for (i=0 ; i<numFolders ; i++) {
		if (strcmp(ptr, folderList[i]->foldername) == 0) {
		    folderList[i]->incfile = MallocACopy(ptr2);
		    break;
		}
	    }
	}
	myfclose(fid);
    } else if (initialIncFile) {
        if (*initialIncFile != '\0')
	    InitialFolder->incfile = initialIncFile;
    } else {
	ptr = getenv("MAIL");
	if (ptr == NULL) ptr = getenv("mail");
	if (ptr == NULL) {
	    ptr = getenv("USER");
	    if (ptr) {
		(void) sprintf(str, "/usr/spool/mail/%s", ptr);
		ptr = str;
	    }
	}
	if (ptr)
	    InitialFolder->incfile = MallocACopy(ptr);
    }
}
	    



/* Read in the list of folders. */

void TocInit()
{
    Toc toc;
    struct direct **namelist;
    int i;
    extern alphasort();
    numFolders = scandir(mailDir, &namelist, IsDir, alphasort);
    if (numFolders < 0) {
	(void) mkdir(mailDir, 0700);
	numFolders = scandir(mailDir, &namelist, IsDir, alphasort);
	if (numFolders < 0)
	    Punt("Can't create or read mail directory!");
    }
    MakeSureFolderExists(&namelist, &numFolders, initialFolderName);
    MakeSureFolderExists(&namelist, &numFolders, draftsFolderName);
    folderList = (Toc *) XtMalloc((unsigned) numFolders * sizeof(Toc));
    for (i=0 ; i<numFolders ; i++) {
	toc = folderList[i] = TUMalloc();
	toc->foldername = MallocACopy(namelist[i]->d_name);
	XtFree((char *)namelist[i]);
    }
    InitialFolder = TocGetNamed(initialFolderName);
    DraftsFolder = TocGetNamed(draftsFolderName);
    XtFree((char *)namelist);
    if (defNewMailCheck) LoadCheckFiles();
}


/* Create a new folder with the given name. */

Toc TocCreateFolder(foldername)
char *foldername;
{
    Toc toc;
    int i, j;
    char str[500];
    if (TocGetNamed(foldername)) return NULL;
    (void) sprintf(str, "%s/%s", mailDir, foldername);
    if (mkdir(str, 0700) < 0) return NULL;
    toc = TUMalloc();
    toc->foldername = MallocACopy(foldername);
    for (i=0 ; i<numFolders ; i++)
	if (strcmp(foldername, folderList[i]->foldername) < 0) break;
    folderList = (Toc *) XtRealloc((char *) folderList,
				   (unsigned) ++numFolders * sizeof(Toc));
    for (j=numFolders - 1 ; j > i ; j--)
	folderList[j] = folderList[j-1];
    folderList[i] = toc;
    return toc;
}



/* Check to see if what folders have new mail, and highlight their
   folderbuttons appropriately. */

void TocCheckForNewMail()
{
#ifdef X11
    Toc toc;
    Scrn scrn;
    int i, j, hasmail;
    if (!defNewMailCheck) return;
    for (i=0 ; i<numFolders ; i++) {
	toc = folderList[i];
	if (toc->incfile) {
	    hasmail =  (GetFileLength(toc->incfile) > 0);
	    if (hasmail != toc->mailpending) {
		toc->mailpending = hasmail;
		for (j=0 ; j<numScrns ; j++) {
		    scrn = scrnList[j];
		    if (scrn->kind == STtocAndView) {
			if (toc == InitialFolder) {
			    scrn->hints.icon_pixmap =
				hasmail ? NewMailPixmap : NoMailPixmap;
			    XSetWMHints(theDisplay, scrn->window,
					&(scrn->hints));
			} else {
			    BBoxChangeBorderWidth(   /* %%% HACK */
			       BBoxButtonNumber(scrnList[j]->folderbuttons, i),
						(unsigned)(hasmail ? 2 : 1));
			}
		    }
		}
	    }
	}
    }
#endif X11
}


/* Recursively delete an entire directory.  Nasty. */

static void NukeDirectory(path)
char *path;
{
    char str[500];
    (void) sprintf(str, "rm -rf %s", path);
    (void) system(str);
}



/* Destroy the given folder. */

void TocDeleteFolder(toc)
Toc toc;
{
    Toc toc2;
    int i, j, w;
    TUGetFullFolderInfo(toc);
    if (TocConfirmCataclysm(toc)) return;
    TocSetScrn(toc, (Scrn) NULL);
    w = -1;
    for (i=0 ; i<numFolders ; i++) {
	toc2 = folderList[i];
	if (toc2 == toc)
	    w = i;
	else if (toc2->validity == valid)
	    for (j=0 ; j<toc2->nummsgs ; j++)
		if (toc2->msgs[j]->desttoc == toc)
		    MsgSetFate(toc2->msgs[j], Fignore, (Toc) NULL);
    }
    if (w < 0) Punt("Couldn't find it in TocDeleteFolder!");
    NukeDirectory(toc->path);
    if (toc->validity == valid) {
	for (i=0 ; i<toc->nummsgs ; i++) {
	    MsgSetScrnForce(toc->msgs[i], (Scrn) NULL);
	    MsgFree(toc->msgs[i]);
	}
	XtFree((char *) toc->msgs);
    }
    XtFree((char *)toc);
    numFolders--;
    for (i=w ; i<numFolders ; i++) folderList[i] = folderList[i+1];
}



/* Display the given toc in the given scrn. */

void TocSetScrn(toc, scrn)
  Toc toc;
  Scrn scrn;
{
    if (toc == NULL && scrn == NULL) return;
    if (scrn && scrn->toc != NULL)
	TocSetScrn(scrn->toc, (Scrn) NULL);
    if (toc == NULL) return;
    if (toc->scrn == scrn) return;
    if (toc->scrn) {
	toc->scrn->toc = NULL;
	TUResetTocLabel(toc->scrn);
	TURedisplayToc(toc->scrn);
	QXStoreName(theDisplay, toc->scrn->window, progName);
	EnableProperButtons(toc->scrn);
	toc->scrn = NULL;
	if (scrn == NULL) return;
    }

    scrn->toc = toc;
    toc->scrn = scrn;

    TUEnsureScanIsValidAndOpen(toc);
    TUResetTocLabel(scrn);
    QXStoreName(theDisplay, toc->scrn->window, toc->foldername);
    TURedisplayToc(toc->scrn);

    BBoxSetRadio(scrn->folderbuttons,
		 BBoxFindButtonNamed(scrn->folderbuttons, toc->foldername));

    EnableProperButtons(scrn);

    return;
}



/* Remove the given message from the toc.  Doesn't actually touch the file.
   Also note that it does not free the storage for the msg. */

void TocRemoveMsg(toc, msg)
Toc toc;
Msg msg;
{
    Msg newcurmsg;
    MsgList mlist;
    int i;
    if (toc->validity == unknown)
	TUGetFullFolderInfo(toc);
    if (toc->validity != valid)
	return;
    newcurmsg = TocMsgAfter(toc, msg);
    if (newcurmsg) newcurmsg->changed = TRUE;
    newcurmsg = toc->curmsg;
    if (msg == toc->curmsg) {
	newcurmsg = TocMsgAfter(toc, msg);
	if (newcurmsg == NULL) newcurmsg = TocMsgBefore(toc, msg);
	toc->curmsg = NULL;
    }
    toc->length -= msg->length;
    if (msg->visible) toc->lastPos -= msg->length;
    for(i = TUGetMsgPosition(toc, msg), toc->nummsgs--; i<toc->nummsgs ; i++) {
	toc->msgs[i] = toc->msgs[i+1];
	if (msg->visible) toc->msgs[i]->position -= msg->length;
    }
    for (i=0 ; i<toc->numsequences ; i++) {
	mlist = toc->seqlist[i]->mlist;
	if (mlist) DeleteMsgFromMsgList(mlist, msg);
    }
    
    if (msg->visible) TURedisplayToc(toc->scrn);
    TocSetCurMsg(toc, newcurmsg);
    TUSaveTocFile(toc);
}
    


void TocRecheckValidity(toc)
  Toc toc;
{
    if (toc && toc->validity == valid && TUScanFileOutOfDate(toc)) {
	TUScanFileForToc(toc);
	if (toc->source)
	    TULoadTocFile(toc);
	TURedisplayToc(toc->scrn);
    }
}


/* Set the current message. */

void TocSetCurMsg(toc, msg)
  Toc toc;
  Msg msg;
{
    Msg msg2;
    if (toc->validity != valid) return;
    if (msg != toc->curmsg) {
	msg2 = toc->curmsg;
	toc->curmsg = msg;
	if (msg2)
	    MsgSetFate(msg2, msg2->fate, msg2->desttoc);
    }
    if (msg) {
	MsgSetFate(msg, msg->fate, msg->desttoc);
	if (toc->scrn) {
	    if (toc->stopupdate)
		toc->needsrepaint = TRUE;
	    else
		XtTextSetInsertionPoint(DISPLAY toc->scrn->tocwindow,
					msg->position);
	}
    }
}


/* Return the current message. */

Msg TocGetCurMsg(toc)
Toc toc;
{
    return toc->curmsg;
}




/* Return the message after the given one.  (If none, return NULL.) */

Msg TocMsgAfter(toc, msg)
  Toc toc;
  Msg msg;
{
    int i;
    i = TUGetMsgPosition(toc, msg);
    do {
	i++;
	if (i >= toc->nummsgs)
	    return NULL;
    } while (!(toc->msgs[i]->visible));
    return toc->msgs[i];
}



/* Return the message before the given one.  (If none, return NULL.) */

Msg TocMsgBefore(toc, msg)
  Toc toc;
  Msg msg;
{
    int i;
    i = TUGetMsgPosition(toc, msg);
    do {
	i--;
	if (i < 0)
	    return NULL;
    } while (!(toc->msgs[i]->visible));
    return toc->msgs[i];
}



/* The caller KNOWS the toc's information is out of date; rescan it. */

void TocForceRescan(toc)
  Toc toc;
{
    if (toc->scrn) {
	toc->viewedseq = toc->seqlist[0];
	TUResetTocLabel(toc->scrn);
	TUScanFileForToc(toc);
	TULoadTocFile(toc);
	TURedisplayToc(toc->scrn);
    } else {
	TUGetFullFolderInfo(toc);
	(void) unlink(toc->scanfile);
	toc->validity = invalid;
    }
}



/* The caller has just changed a sequence list.  Reread them from mh. */

void TocReloadSeqLists(toc)
Toc toc;
{
    TocSetCacheValid(toc);
    TULoadSeqLists(toc);
    TURefigureWhatsVisible(toc);
    TUResetTocLabel(toc->scrn);
    EnableProperButtons(toc->scrn);
}


/* Return TRUE if the toc has an interesting sequence. */

int TocHasSequences(toc)
Toc toc;
{
    return toc && toc->numsequences > 1;
}


/* Change which sequence is being viewed. */

void TocChangeViewedSeq(toc, seq)
  Toc toc;
  Sequence seq;
{
    if (seq == NULL) seq = toc->viewedseq;
    toc->viewedseq = seq;
    TURefigureWhatsVisible(toc);
    if (toc->scrn && toc->scrn->seqbuttons)
	BBoxSetRadio(toc->scrn->seqbuttons,
		     BBoxFindButtonNamed(toc->scrn->seqbuttons, seq->name));
    TUResetTocLabel(toc->scrn);
}


/* Return the sequence with the given name in the given toc. */

Sequence TocGetSeqNamed(toc, name)
Toc toc;
char *name;
{
    int i;
    for (i=0 ; i<toc->numsequences ; i++)
	if (strcmp(toc->seqlist[i]->name, name) == 0)
	    return toc->seqlist[i];
    return (Sequence) NULL;
}


/* Return the sequence currently being viewed in the toc. */

Sequence TocViewedSequence(toc)
Toc toc;
{
    return toc->viewedseq;
}


/* Return the list of messages currently selected. */

MsgList TocCurMsgList(toc)
  Toc toc;
{
    MsgList result;
    XtTextPosition pos1, pos2;
    extern Msg MsgFromPosition();
    if (toc->scrn == NULL) return NULL;
    result = MakeNullMsgList();
    XtTextGetSelectionPos(DISPLAY toc->scrn->tocwindow, &pos1, &pos2);
    if (pos1 < pos2) {
	pos1 = toc->source->scan(toc->source, pos1, XtstEOL, XtsdLeft,
				 1, FALSE);
	pos2 = toc->source->scan(toc->source, pos2, XtstPositions, XtsdLeft,
				 1, TRUE);
	pos2 = toc->source->scan(toc->source, pos2, XtstEOL, XtsdRight,
				 1, FALSE);
	while (pos1 < pos2) {
	    AppendMsgList(result, MsgFromPosition(toc, pos1, XtsdRight));
	    pos1 = toc->source->scan(toc->source, pos1, XtstEOL, XtsdRight,
				     1, TRUE);
	}
    }
    return result;
}



/* Unset the current selection. */

void TocUnsetSelection(toc)
Toc toc;
{
    if (toc->scrn)
	XtTextUnsetSelection(DISPLAY toc->scrn->tocwindow);
}



/* Create a brand new, blank message. */

Msg TocMakeNewMsg(toc)
Toc toc;
{
    Msg msg;
    TUEnsureScanIsValidAndOpen(toc);
    msg = TUAppendToc(toc, "####  empty\n");
    if (FileExists(MsgFileName(msg))) {
	if (debug) (void) fprintf(stderr, "**** FOLDER %s WAS INVALID!!!\n",
				  toc->foldername);
	TocForceRescan(toc);
	return TocMakeNewMsg(toc); /* Try again.  Using recursion here is ugly,
				      but what the hack ... */
    }
    CopyFileAndCheck("/dev/null", MsgFileName(msg));
    return msg;
}


/* Set things to not update cache or display until further notice. */

void TocStopUpdate(toc)
Toc toc;
{
    toc->stopupdate++;
}


/* Start updating again, and do whatever updating has been queued. */

void TocStartUpdate(toc)
Toc toc;
{
    if (toc->stopupdate && --(toc->stopupdate) == 0) {
	if (toc->needsrepaint) 
	    TURedisplayToc(toc->scrn);
	if (toc->needslabelupdate)
	    TUResetTocLabel(toc->scrn);
	if (toc->needscachesave)
	    TUSaveTocFile(toc);
    }
}



/* Something has happened that could later convince us that our cache is out
   of date.  Make this not happen; our cache really *is* up-to-date. */

void TocSetCacheValid(toc)
Toc toc;
{
    TUSaveTocFile(toc);
}


/* Return the foldername of the given toc. */

char *TocGetFolderName(toc)
Toc toc;
{
    return toc->foldername;
}



/* Given a foldername, return the corresponding toc. */

Toc TocGetNamed(name)
char *name;
{
    int i;
    for (i=0; i<numFolders ; i++)
	if (strcmp(folderList[i]->foldername, name) == 0) return folderList[i];
    return NULL;
}



/* Throw out all changes to this toc, and close all views of msgs in it.
   Requires confirmation by the user. */

int TocConfirmCataclysm(toc)
Toc toc;
{
    int i;
    int found = FALSE;
    char str[500];
    for (i=0 ; i<toc->nummsgs && !found ; i++)
	if (toc->msgs[i]->fate != Fignore) found = TRUE;
    if (found) {
	(void)sprintf(str,"Are you sure you want to remove all changes to %s?",
		      toc->foldername);
	if (!Confirm(toc->scrn, str))
	    return DELETEABORTED;
    }
    for (i=0 ; i<toc->nummsgs ; i++)
	MsgSetFate(toc->msgs[i], Fignore, (Toc)NULL);
    for (i=0 ; i<toc->nummsgs ; i++)
	if (MsgSetScrn(toc->msgs[i], (Scrn) NULL)) return DELETEABORTED;
    return 0;
}



/* Commit all the changes in this toc; all messages will meet their 'fate'. */

void TocCommitChanges(toc)
Toc toc;
{
    Msg msg;
    int i, cur;
    char str[100], **argv;
    FateType curfate, fate; 
    Toc desttoc;
    Toc curdesttoc;

    if (toc == NULL) return;
    for (i=0 ; i<toc->nummsgs ; i++) {
	msg = toc->msgs[i];
	fate = MsgGetFate(msg, (Toc *)NULL);
	if (fate != Fignore && fate != Fcopy)
	    if (MsgSetScrn(msg, (Scrn) NULL))
	        return;
    }
    QXFlush(theDisplay);
    for (i=0 ; i<numFolders ; i++)
	TocStopUpdate(folderList[i]);
    do {
	curfate = Fignore;
	i = 0;
	while (i < toc->nummsgs) {
	    msg = toc->msgs[i];
	    fate = MsgGetFate(msg, &desttoc);
	    if (curfate == Fignore && fate != Fignore) {
		curfate = fate;
		argv = MakeArgv(2);
		switch (curfate) {
		  case Fdelete:
		    argv[0] = MallocACopy("rmm");
		    (void) sprintf(str, "+%s", toc->foldername);
		    argv[1] = MallocACopy(str);
		    cur = 2;
		    curdesttoc = NULL;
		    break;
		  case Fmove:
		  case Fcopy:
		    argv[0] = MallocACopy("refile");
		    cur = 1;
		    curdesttoc = desttoc;
		    break;
		}
	    }
	    if (curfate != Fignore &&
		  curfate == fate && desttoc == curdesttoc) {
		argv = ResizeArgv(argv, cur + 1);
		(void) sprintf(str, "%d", MsgGetId(msg));
		argv[cur++] = MallocACopy(str);
		MsgSetFate(msg, Fignore, (Toc)NULL);
		if (curdesttoc)
		    (void) TUAppendToc(curdesttoc, MsgGetScanLine(msg));
		if (curfate != Fcopy) {
		    TocRemoveMsg(toc, msg);
		    MsgFree(msg);
		    i--;
		}
		if (cur > 40)
		    break;	/* Do only 40 at a time, just to be safe. */
	    } 
	    i++;
	}
	if (curfate != Fignore) {
	    switch (curfate) {
	      case Fmove:
	      case Fcopy:
		argv = ResizeArgv(argv, cur + 4);
		argv[cur++] = MallocACopy(curfate == Fmove ? "-nolink"
				       			   : "-link");
		argv[cur++] = MallocACopy("-src");
		(void) sprintf(str, "+%s", toc->foldername);
		argv[cur++] = MallocACopy(str);
		(void) sprintf(str, "+%s", curdesttoc->foldername);
		argv[cur++] = MallocACopy(str);
		break;
	    }
	    if (debug) {
		for (i = 0; i < cur; i++)
		    (void) fprintf(stderr, "%s ", argv[i]);
		(void) fprintf(stderr, "\n");
	    }
	    DoCommand(argv, (char *) NULL, "/dev/null");
	    for (i = 0; argv[i]; i++)
		XtFree((char *) argv[i]);
	    XtFree((char *) argv);
	}
    } while (curfate != Fignore);
    for (i=0 ; i<numFolders ; i++) {
	if (folderList[i]->needsrepaint) TocReloadSeqLists(folderList[i]);
	TocStartUpdate(folderList[i]);
    }
}



/* Return whether the given toc can incorporate mail. */

int TocCanIncorporate(toc)
Toc toc;
{
    return (toc && (toc == InitialFolder || toc->incfile));
}


/* Incorporate new messages into the given toc. */

void TocIncorporate(toc)
Toc toc;
{
    char **argv;
    char str[100], str2[10], *file, *ptr;
    Msg msg, firstmessage;
    FILEPTR fid;
    argv = MakeArgv(toc->incfile ? 7 : 5);
    argv[0] = "inc";
    (void) sprintf(str, "+%s", toc->foldername);
    argv[1] = str;
    argv[2] = "-width";
    (void) sprintf(str2, "%d", defTocWidth);
    argv[3] = str2;
    if (toc->incfile) {
	argv[4] = "-file";
	argv[5] = toc->incfile;
	argv[6] = "-truncate";
    } else argv[4] = "-truncate";
    file = DoCommandToFile(argv);
    XtFree((char *)argv);
    TUGetFullFolderInfo(toc);
    if (toc->validity == valid) {
	fid = FOpenAndCheck(file, "r");
	firstmessage = NULL;
	TocStopUpdate(toc);
	while (ptr = ReadLineWithCR(fid)) {
	    if (atoi(ptr) > 0) {
		msg = TUAppendToc(toc, ptr);
		if (firstmessage == NULL) firstmessage = msg;
	    }
	}
	if (firstmessage && firstmessage->visible) {
	    TocSetCurMsg(toc, firstmessage);
	}
	TocStartUpdate(toc);
	(void) myfclose(fid);
    }
    DeleteFileAndCheck(file);
}



/* The given message has changed.  Rescan it and change the scanfile. */

void TocMsgChanged(toc, msg)
Toc toc;
Msg msg;
{
    char **argv, str[100], str2[10], str3[10], *ptr;
    int length, delta, i;
    FateType fate;
    Toc desttoc;
    if (toc->validity != valid) return;
    fate = MsgGetFate(msg, &desttoc);
    MsgSetFate(msg, Fignore, (Toc) NULL);
    argv = MakeArgv(5);
    argv[0] = "scan";
    (void) sprintf(str, "+%s", toc->foldername);
    argv[1] = str;
    (void) sprintf(str2, "%d", msg->msgid);
    argv[2] = str2;
    argv[3] = "-width";
    (void) sprintf(str3, "%d", defTocWidth);
    argv[4] = str3;
    ptr = DoCommandToString(argv);
    XtFree((char *) argv);
    if (strcmp(ptr, msg->buf) != 0) {
	length = strlen(ptr);
	delta = length - msg->length;
	XtFree(msg->buf);
	msg->buf = ptr;
	msg->length = length;
	toc->length += delta;
	if (msg->visible) {
	    if (delta != 0) {
		for (i=TUGetMsgPosition(toc, msg)+1; i<toc->nummsgs ; i++)
		    toc->msgs[i]->position += delta;
		toc->lastPos += delta;
		TURedisplayToc(toc->scrn);
	    } else {
		if (toc->scrn)
		    XtTextInvalidate(DISPLAY toc->scrn->tocwindow,
				     msg->position,
				     msg->position + msg->length);
	    }
	}
	MsgSetFate(msg, fate, desttoc);
	TUSaveTocFile(toc);
    } else XtFree(ptr);
}



Msg TocMsgFromId(toc, msgid)
Toc toc;
int msgid;
{
    int h, l, m;
    char str[100];
    l = 0;
    h = toc->nummsgs - 1;
    while (l < h - 1) {
	m = (l + h) / 2;
	if (toc->msgs[m]->msgid > msgid)
	    h = m;
	else
	    l = m;
    }
    if (toc->msgs[l]->msgid == msgid) return toc->msgs[l];
    if (toc->msgs[h]->msgid == msgid) return toc->msgs[h];
    (void) sprintf(str, "TocMsgFromId search failed! hi=%d, lo=%d, msgid=%d",
		   h, l, msgid);
    Punt(str);
    return 0; /* Keep lint happy. */
}

unix.superglobalmegacorp.com

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