#include "xmh.h"
#include "tocintrnl.h"
#include "toc.h"
#include "tocutil.h"
#include "actions.h"
#include <sys/stat.h>
static int IsDir(char *name)
{
char str[500];
struct stat buf;
if (*name == '.')
return FALSE;
(void) sprintf(str, "%s/%s", app_resources.mail_path, name);
if (stat(str, &buf) ) return False;
#ifdef S_ISDIR
return S_ISDIR(buf.st_mode);
#else
return (buf.st_mode & S_IFMT) == S_IFDIR;
#endif
}
static void MakeSureFolderExists(
char ***namelistptr,
int *numfoldersptr,
char *name)
{
int i;
char str[200];
for (i=0 ; i<*numfoldersptr ; i++)
if (strcmp((*namelistptr)[i], name) == 0) return;
(void) sprintf(str, "%s/%s", app_resources.mail_path, name);
(void) mkdir(str, 0700);
*numfoldersptr = ScanDir(app_resources.mail_path, namelistptr, IsDir);
for (i=0 ; i<*numfoldersptr ; i++)
if (strcmp((*namelistptr)[i], name) == 0) return;
Punt("Can't create new mail folder!");
}
static void MakeSureSubfolderExists(
char *** namelistptr,
int * numfoldersptr,
char * name)
{
char folder[300];
char subfolder_path[300];
char *subfolder;
struct stat buf;
subfolder = strchr( strcpy(folder, name), '/');
*subfolder = '\0';
subfolder++;
MakeSureFolderExists(namelistptr, numfoldersptr, folder);
(void) sprintf(subfolder_path, "%s/%s", app_resources.mail_path, name);
if (stat(subfolder_path, &buf) ) {
(void) mkdir(subfolder_path, 0700);
if (stat(subfolder_path, &buf) )
Punt("Can't create new xmh subfolder!");
}
#ifdef S_ISDIR
if (!S_ISDIR(buf.st_mode))
#else
if ((buf.st_mode & S_IFMT) != S_IFDIR)
#endif
Punt("Can't create new xmh subfolder!");
}
int TocFolderExists(Toc toc)
{
struct stat buf;
if (! toc->path) {
char str[500];
(void) sprintf(str, "%s/%s", app_resources.mail_path, toc->foldername);
toc->path = XtNewString(str);
}
return ((stat(toc->path, &buf) == 0) &&
#ifdef S_ISDIR
(S_ISDIR(buf.st_mode)));
#else
((buf.st_mode & S_IFMT) == S_IFDIR));
#endif
}
static void LoadCheckFiles(void)
{
FILE *fid;
char str[1024];
(void) sprintf(str, "%s/.xmhcheck", homeDir);
fid = myfopen(str, "r");
if (fid) {
int i;
char *ptr, *ptr2;
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 = XtNewString(ptr2);
break;
}
}
}
myfclose(fid);
} else if ( app_resources.initial_inc_file &&
*app_resources.initial_inc_file)
InitialFolder->incfile = app_resources.initial_inc_file;
}
void TocInit(void)
{
Toc toc;
char **namelist;
int i;
numFolders = ScanDir(app_resources.mail_path, &namelist, IsDir);
if (numFolders < 0) {
(void) mkdir(app_resources.mail_path, 0700);
numFolders = ScanDir(app_resources.mail_path, &namelist, IsDir);
if (numFolders < 0)
Punt("Can't create or read mail directory!");
}
if (IsSubfolder(app_resources.initial_folder_name))
MakeSureSubfolderExists(&namelist, &numFolders,
app_resources.initial_folder_name);
else
MakeSureFolderExists(&namelist, &numFolders,
app_resources.initial_folder_name);
if (IsSubfolder(app_resources.drafts_folder_name))
MakeSureSubfolderExists(&namelist, &numFolders,
app_resources.drafts_folder_name);
else
MakeSureFolderExists(&namelist, &numFolders,
app_resources.drafts_folder_name);
folderList = (Toc *) XtMalloc((Cardinal)numFolders * sizeof(Toc));
for (i=0 ; i<numFolders ; i++) {
toc = folderList[i] = TUMalloc();
toc->foldername = XtNewString(namelist[i]);
free((char *)namelist[i]);
}
if (! (InitialFolder = TocGetNamed(app_resources.initial_folder_name)))
InitialFolder = TocCreate(app_resources.initial_folder_name);
if (! (DraftsFolder = TocGetNamed(app_resources.drafts_folder_name)))
DraftsFolder = TocCreate(app_resources.drafts_folder_name);
free((char *)namelist);
LoadCheckFiles();
}
Toc TocCreate(char *foldername)
{
Toc toc = TUMalloc();
toc->foldername = XtNewString(foldername);
folderList = (Toc *) XtRealloc((char *) folderList,
(unsigned) ++numFolders * sizeof(Toc));
folderList[numFolders - 1] = toc;
return toc;
}
Toc TocCreateFolder(char *foldername)
{
Toc toc;
char str[500];
if (TocGetNamed(foldername)) return NULL;
(void) sprintf(str, "%s/%s", app_resources.mail_path, foldername);
if (mkdir(str, 0700) < 0) return NULL;
toc = TocCreate(foldername);
return toc;
}
int TocHasMail(Toc toc)
{
return toc->mailpending;
}
static int CheckForNewMail(Toc toc)
{
if (toc->incfile)
return (GetFileLength(toc->incfile) > 0);
else if (toc == InitialFolder) {
char **argv;
char *result;
int hasmail;
argv = MakeArgv(4);
argv[0] = "msgchk";
argv[1] = "-nonotify";
argv[2] = "nomail";
argv[3] = "-nodate";
result = DoCommandToString(argv);
hasmail = (*result != '\0');
XtFree(result);
XtFree((char*)argv);
return hasmail;
}
return False;
}
void TocCheckForNewMail(
Boolean update)
{
Toc toc;
Scrn scrn;
int i, j, hasmail;
Boolean mail_waiting = False;
if (update) {
for (i=0 ; i<numFolders ; i++) {
toc = folderList[i];
if (TocCanIncorporate(toc)) {
toc->mailpending = hasmail = CheckForNewMail(toc);
if (hasmail) mail_waiting = True;
for (j=0 ; j<numScrns ; j++) {
scrn = scrnList[j];
if (scrn->kind == STtocAndView)
BBoxMailFlag(scrn->folderbuttons, TocName(toc),
hasmail);
}
}
}
} else {
for (i=0; i < numFolders; i++) {
toc = folderList[i];
if (toc->mailpending) {
mail_waiting = True;
break;
}
}
}
if (app_resources.mail_waiting_flag) {
Arg args[1];
static Boolean icon_state = -1;
if (icon_state != mail_waiting) {
icon_state = mail_waiting;
for (i=0; i < numScrns; i++) {
scrn = scrnList[i];
if (scrn->kind == STtocAndView) {
XtSetArg(args[0], XtNiconPixmap,
(mail_waiting ? app_resources.new_mail_icon
: app_resources.no_mail_icon));
XtSetValues(scrn->parent, args, (Cardinal)1);
}
}
}
}
}
Boolean TocTestAndSetDeletePending(Toc toc)
{
Boolean flag;
flag = toc->delete_pending;
toc->delete_pending = True;
return flag;
}
void TocClearDeletePending(Toc toc)
{
toc->delete_pending = False;
}
static void NukeDirectory(char *path)
{
struct stat buf;
#ifdef S_IFLNK
if (lstat(path, &buf) )
return;
if ((buf.st_mode & S_IFMT) == S_IFLNK) {
(void) unlink(path);
return;
}
#endif
if (stat(path, &buf) )
return;
if (buf.st_mode & S_IWRITE) {
char **argv = MakeArgv(3);
argv[0] = "/bin/rm";
argv[1] = "-rf";
argv[2] = path;
(void) DoCommand(argv, (char*)NULL, (char*)NULL);
XtFree((char*)argv);
}
}
void TocDeleteFolder(Toc toc)
{
Toc toc2;
int i, j, w;
if (toc == NULL) return;
TUGetFullFolderInfo(toc);
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];
}
void TocSetScrn(Toc toc, Scrn scrn)
{
Cardinal i;
if (toc == NULL && scrn == NULL) return;
if (scrn == NULL) {
for (i=0 ; i<toc->num_scrns ; i++)
TocSetScrn((Toc) NULL, toc->scrn[i]);
return;
}
if (scrn->toc == toc) return;
if (scrn->toc != NULL) {
for (i=0 ; i<scrn->toc->num_scrns ; i++)
if (scrn->toc->scrn[i] == scrn) break;
if (i >= scrn->toc->num_scrns)
Punt("Couldn't find scrn in TocSetScrn!");
scrn->toc->scrn[i] = scrn->toc->scrn[--scrn->toc->num_scrns];
}
scrn->toc = toc;
if (toc == NULL) {
TUResetTocLabel(scrn);
TURedisplayToc(scrn);
StoreWindowName(scrn, progName);
} else {
toc->num_scrns++;
toc->scrn = (Scrn *) XtRealloc((char *) toc->scrn,
(unsigned)toc->num_scrns*sizeof(Scrn));
toc->scrn[toc->num_scrns - 1] = scrn;
TUEnsureScanIsValidAndOpen(toc, True);
TUResetTocLabel(scrn);
if (app_resources.prefix_wm_and_icon_name) {
char wm_name[64];
int length = strlen(progName);
(void) strncpy(wm_name, progName, length);
(void) strncpy(wm_name + length , ": ", 2);
(void) strcpy(wm_name + length + 2, toc->foldername);
StoreWindowName(scrn, wm_name);
}
else
StoreWindowName(scrn, toc->foldername);
TURedisplayToc(scrn);
SetCurrentFolderName(scrn, toc->foldername);
}
EnableProperButtons(scrn);
}
void TocRemoveMsg(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 && toc->num_scrns > 0 && !toc->needsrepaint)
TSourceInvalid(toc, msg->position, -msg->length);
TocSetCurMsg(toc, newcurmsg);
TUSaveTocFile(toc);
}
void TocRecheckValidity(Toc toc)
{
Cardinal i;
if (toc && toc->validity == valid && TUScanFileOutOfDate(toc)) {
if (app_resources.block_events_on_busy) ShowBusyCursor();
TUScanFileForToc(toc);
if (toc->source)
TULoadTocFile(toc);
for (i=0 ; i<toc->num_scrns ; i++)
TURedisplayToc(toc->scrn[i]);
if (app_resources.block_events_on_busy) UnshowBusyCursor();
}
}
void TocSetCurMsg(Toc toc, Msg msg)
{
Msg msg2;
Cardinal i;
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->num_scrns) {
if (toc->stopupdate)
toc->needsrepaint = TRUE;
else {
for (i=0 ; i<toc->num_scrns ; i++)
XawTextSetInsertionPoint(toc->scrn[i]->tocwidget,
msg->position);
}
}
}
}
Msg TocGetCurMsg(Toc toc)
{
return toc->curmsg;
}
Msg TocMsgAfter(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];
}
Msg TocMsgBefore(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];
}
void TocForceRescan(Toc toc)
{
register Cardinal i;
if (toc->num_scrns) {
toc->viewedseq = toc->seqlist[0];
for (i=0 ; i<toc->num_scrns ; i++)
TUResetTocLabel(toc->scrn[i]);
TUScanFileForToc(toc);
TULoadTocFile(toc);
for (i=0 ; i<toc->num_scrns ; i++)
TURedisplayToc(toc->scrn[i]);
} else {
TUGetFullFolderInfo(toc);
(void) unlink(toc->scanfile);
toc->validity = invalid;
}
}
void TocReloadSeqLists(Toc toc)
{
Cardinal i;
TocSetCacheValid(toc);
TULoadSeqLists(toc);
TURefigureWhatsVisible(toc);
for (i=0 ; i<toc->num_scrns ; i++) {
TUResetTocLabel(toc->scrn[i]);
EnableProperButtons(toc->scrn[i]);
}
}
void XmhReloadSeqLists(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
TocReloadSeqLists(scrn->toc);
TUCheckSequenceMenu(scrn->toc);
}
int TocHasSequences(Toc toc)
{
return toc && toc->numsequences > 1;
}
void TocChangeViewedSeq(Toc toc, Sequence seq)
{
if (seq == NULL) seq = toc->viewedseq;
toc->viewedseq = seq;
toc->force_reset = True;
TURefigureWhatsVisible(toc);
}
Sequence TocGetSeqNamed(Toc toc, char *name)
{
register int i;
if (name == NULL)
return (Sequence) NULL;
for (i=0 ; i<toc->numsequences ; i++)
if (strcmp(toc->seqlist[i]->name, name) == 0)
return toc->seqlist[i];
return (Sequence) NULL;
}
Sequence TocViewedSequence(Toc toc)
{
return toc->viewedseq;
}
void TocSetSelectedSequence(
Toc toc,
Sequence sequence)
{
if (toc)
toc->selectseq = sequence;
}
Sequence TocSelectedSequence(Toc toc)
{
if (toc) return (toc->selectseq);
else return (Sequence) NULL;
}
#define SrcScan XawTextSourceScan
MsgList TocCurMsgList(Toc toc)
{
MsgList result;
XawTextPosition pos1, pos2;
if (toc->num_scrns == 0) return NULL;
result = MakeNullMsgList();
XawTextGetSelectionPos( toc->scrn[0]->tocwidget, &pos1, &pos2);
if (pos1 < pos2) {
pos1 = SrcScan(toc->source, pos1, XawstEOL, XawsdLeft, 1, FALSE);
pos2 = SrcScan(toc->source, pos2, XawstPositions, XawsdLeft, 1, TRUE);
pos2 = SrcScan(toc->source, pos2, XawstEOL, XawsdRight, 1, FALSE);
while (pos1 < pos2) {
AppendMsgList(result, MsgFromPosition(toc, pos1, XawsdRight));
pos1 = SrcScan(toc->source, pos1, XawstEOL, XawsdRight, 1, TRUE);
}
}
return result;
}
void TocUnsetSelection(Toc toc)
{
if (toc->source)
XawTextUnsetSelection(toc->scrn[0]->tocwidget);
}
Msg TocMakeNewMsg(Toc toc)
{
Msg msg;
static int looping = False;
TUEnsureScanIsValidAndOpen(toc, False);
msg = TUAppendToc(toc, "#### empty\n");
if (FileExists(MsgFileName(msg))) {
if (looping++) Punt( "Cannot correct scan file" );
DEBUG2("**** FOLDER %s WAS INVALID; msg %d already existed!\n",
toc->foldername, msg->msgid);
TocForceRescan(toc);
return TocMakeNewMsg(toc);
}
CopyFileAndCheck("/dev/null", MsgFileName(msg));
looping = False;
return msg;
}
void TocStopUpdate(Toc toc)
{
Cardinal i;
for (i=0 ; i<toc->num_scrns ; i++)
XawTextDisableRedisplay(toc->scrn[i]->tocwidget);
toc->stopupdate++;
}
void TocStartUpdate(Toc toc)
{
Cardinal i;
if (toc->stopupdate && --(toc->stopupdate) == 0) {
for (i=0 ; i<toc->num_scrns ; i++) {
if (toc->needsrepaint)
TURedisplayToc(toc->scrn[i]);
if (toc->needslabelupdate)
TUResetTocLabel(toc->scrn[i]);
}
if (toc->needscachesave)
TUSaveTocFile(toc);
}
for (i=0 ; i<toc->num_scrns ; i++)
XawTextEnableRedisplay(toc->scrn[i]->tocwidget);
}
void TocSetCacheValid(Toc toc)
{
TUSaveTocFile(toc);
}
char *TocMakeFolderName(Toc toc)
{
char* name = XtMalloc((Cardinal) (strlen(toc->path) + 2) );
(void)sprintf( name, "+%s", toc->path );
return name;
}
char *TocName(Toc toc)
{
return toc->foldername;
}
Toc TocGetNamed(char *name)
{
int i;
for (i=0; i<numFolders ; i++)
if (strcmp(folderList[i]->foldername, name) == 0) return folderList[i];
return NULL;
}
Boolean TocHasChanges(Toc toc)
{
int i;
for (i=0 ; i<toc->nummsgs ; i++)
if (toc->msgs[i]->fate != Fignore) return True;
return False;
}
static void TocCataclysmOkay(
Widget widget,
XtPointer client_data,
XtPointer call_data)
{
Toc toc = (Toc) client_data;
register int i;
for (i=0; i < toc->nummsgs; i++)
MsgSetFate(toc->msgs[i], Fignore, (Toc)NULL);
for (i=0; i < toc->nummsgs; i++)
MsgSetScrn(toc->msgs[i], (Scrn) NULL, (XtCallbackList) NULL,
(XtCallbackList) NULL);
}
int TocConfirmCataclysm(
Toc toc,
XtCallbackList confirms,
XtCallbackList cancels)
{
register int i;
static XtCallbackRec yes_callbacks[] = {
{TocCataclysmOkay, (XtPointer) NULL},
{(XtCallbackProc) NULL, (XtPointer) NULL},
{(XtCallbackProc) NULL, (XtPointer) NULL}
};
if (! toc)
return 0;
if (TocHasChanges(toc)) {
char str[300];
Widget tocwidget;
(void)sprintf(str,"Are you sure you want to remove all changes to %s?",
toc->foldername);
yes_callbacks[0].closure = (XtPointer) toc;
yes_callbacks[1].callback = confirms[0].callback;
yes_callbacks[1].closure = confirms[0].closure;
tocwidget = NULL;
for (i=0; i < toc->num_scrns; i++)
if (toc->scrn[i]->mapped) {
tocwidget = toc->scrn[i]->tocwidget;
break;
}
PopupConfirm(tocwidget, str, yes_callbacks, cancels);
return NEEDS_CONFIRMATION;
}
else {
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, confirms, cancels))
return NEEDS_CONFIRMATION;
return 0;
}
}
void TocCommitChanges(
Widget widget,
XtPointer client_data,
XtPointer call_data)
{
Toc toc = (Toc) client_data;
Msg msg;
int i, cur = 0;
char str[100], **argv = NULL;
FateType curfate, fate;
Toc desttoc;
Toc curdesttoc = NULL;
XtCallbackRec confirms[2];
confirms[0].callback = TocCommitChanges;
confirms[0].closure = (XtPointer) toc;
confirms[1].callback = (XtCallbackProc) NULL;
confirms[1].closure = (XtPointer) NULL;
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, confirms, (XtCallbackList) NULL)
== NEEDS_CONFIRMATION)
return;
}
XFlush(XtDisplay(toc->scrn[0]->parent));
for (i=0 ; i<numFolders ; i++)
TocStopUpdate(folderList[i]);
toc->haschanged = TRUE;
if (app_resources.block_events_on_busy) ShowBusyCursor();
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] = XtNewString("rmm");
argv[1] = TocMakeFolderName(toc);
cur = 2;
curdesttoc = NULL;
break;
case Fmove:
case Fcopy:
argv[0] = XtNewString("refile");
cur = 1;
curdesttoc = desttoc;
break;
default:
break;
}
}
if (curfate != Fignore &&
curfate == fate && desttoc == curdesttoc) {
argv = ResizeArgv(argv, cur + 1);
(void) sprintf(str, "%d", MsgGetId(msg));
argv[cur++] = XtNewString(str);
MsgSetFate(msg, Fignore, (Toc)NULL);
if (curdesttoc) {
(void) TUAppendToc(curdesttoc, MsgGetScanLine(msg));
curdesttoc->haschanged = TRUE;
}
if (curfate != Fcopy) {
TocRemoveMsg(toc, msg);
MsgFree(msg);
i--;
}
if (cur > 40)
break;
}
i++;
}
if (curfate != Fignore) {
switch (curfate) {
case Fmove:
case Fcopy:
argv = ResizeArgv(argv, cur + 4);
argv[cur++] = XtNewString(curfate == Fmove ? "-nolink"
: "-link");
argv[cur++] = XtNewString("-src");
argv[cur++] = TocMakeFolderName(toc);
argv[cur++] = TocMakeFolderName(curdesttoc);
break;
default:
break;
}
if (app_resources.debug) {
for (i = 0; i < cur; i++)
(void) fprintf(stderr, "%s ", argv[i]);
(void) fprintf(stderr, "\n");
(void) fflush(stderr);
}
DoCommand(argv, (char *) NULL, (char *) 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]->haschanged) {
TocReloadSeqLists(folderList[i]);
folderList[i]->haschanged = FALSE;
}
TocStartUpdate(folderList[i]);
}
if (app_resources.block_events_on_busy) UnshowBusyCursor();
}
int TocCanIncorporate(Toc toc)
{
return (toc && (toc == InitialFolder || toc->incfile));
}
int TocIncorporate(Toc toc)
{
char **argv;
char str[100], *file, *ptr;
Msg msg, firstmessage = NULL;
FILEPTR fid;
argv = MakeArgv(toc->incfile ? 7 : 4);
argv[0] = "inc";
argv[1] = TocMakeFolderName(toc);
argv[2] = "-width";
(void) sprintf(str, "%d", app_resources.toc_width);
argv[3] = str;
if (toc->incfile) {
argv[4] = "-file";
argv[5] = toc->incfile;
argv[6] = "-truncate";
}
if (app_resources.block_events_on_busy) ShowBusyCursor();
file = DoCommandToFile(argv);
XtFree(argv[1]);
XtFree((char *)argv);
TUGetFullFolderInfo(toc);
if (toc->validity == valid) {
fid = FOpenAndCheck(file, "r");
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);
myfclose(fid);
}
DeleteFileAndCheck(file);
if (app_resources.block_events_on_busy) UnshowBusyCursor();
toc->mailpending = False;
return (firstmessage != NULL);
}
void TocMsgChanged(Toc toc, Msg msg)
{
char **argv, str[100], str2[10], *ptr;
int length, delta;
int i;
FateType fate;
Toc desttoc;
if (toc->validity != valid) return;
fate = MsgGetFate(msg, &desttoc);
MsgSetFate(msg, Fignore, (Toc) NULL);
argv = MakeArgv(6);
argv[0] = "scan";
argv[1] = TocMakeFolderName(toc);
(void) sprintf(str, "%d", msg->msgid);
argv[2] = str;
argv[3] = "-width";
(void) sprintf(str2, "%d", app_resources.toc_width);
argv[4] = str2;
argv[5] = "-noheader";
ptr = DoCommandToString(argv);
XtFree(argv[1]);
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;
}
for (i=0 ; i<toc->num_scrns ; i++)
TURedisplayToc(toc->scrn[i]);
}
MsgSetFate(msg, fate, desttoc);
TUSaveTocFile(toc);
} else XtFree(ptr);
}
Msg TocMsgFromId(Toc toc, int msgid)
{
int h, l, m;
l = 0;
h = toc->nummsgs - 1;
if (h < 0) {
if (app_resources.debug) {
char str[100];
(void)sprintf(str, "Toc is empty! folder=%s\n", toc->foldername);
DEBUG( str )
}
return NULL;
}
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];
if (app_resources.debug) {
char str[100];
(void) sprintf(str,
"TocMsgFromId search failed! hi=%d, lo=%d, msgid=%d\n",
h, l, msgid);
DEBUG( str )
}
return NULL;
}
void XmhPushSequence(
Widget w,
XEvent *event,
String *params,
Cardinal *count)
{
Scrn scrn = ScrnFromWidget(w);
Toc toc;
Cardinal i;
if (! (toc = scrn->toc)) return;
if (*count == 0) {
if (toc->selectseq)
Push(&toc->sequence_stack, XtNewString(toc->selectseq->name));
}
else
for (i=0; i < *count; i++)
Push(&toc->sequence_stack, XtNewString(params[i]));
}
void XmhPopSequence(
Widget w,
XEvent *event,
String *params,
Cardinal *count)
{
Scrn scrn = ScrnFromWidget(w);
char *seqname;
Widget sequenceMenu, selected, original;
Button button;
Sequence sequence;
if ((seqname = Pop(&scrn->toc->sequence_stack)) != NULL) {
button = BBoxFindButtonNamed(scrn->mainbuttons,
MenuBoxButtons[XMH_SEQUENCE].button_name);
sequenceMenu = BBoxMenuOfButton(button);
if ((selected = XawSimpleMenuGetActiveEntry(sequenceMenu)))
ToggleMenuItem(selected, False);
if ((original = XtNameToWidget(sequenceMenu, seqname))) {
ToggleMenuItem(original, True);
sequence = TocGetSeqNamed(scrn->toc, seqname);
TocSetSelectedSequence(scrn->toc, sequence);
}
XtFree(seqname);
}
}