/*
* xmail - X window system interface to the mail program
*
* Copyright 1990,1991,1992 by National Semiconductor Corporation
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose is hereby granted without fee, 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 National Semiconductor Corporation not
* be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
* SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS"
* WITHOUT EXPRESS OR IMPLIED WARRANTY. NATIONAL SEMICONDUCTOR CORPORATION
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO
* EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* The following software modules were created and are Copyrighted by National
* Semiconductor Corporation:
*
* 1. In_System_Folder:
* 2. icon_handler:
* 3. index_handler:
* 4. info_handler: and
* 5. file_handler.
*
* Author: Michael C. Wagnitz - National Semiconductor Corporation
*
*/
#include <ctype.h>
#include "global.h"
#include "MailwatchP.h"
#include <X11/Xaw/LabelP.h>
Boolean In_Bogus_Mail_File = False; /* TRUE when we go iconic */
/*
** Examine the current value of the titleBar title and return TRUE/FALSE
** to the question "Does it match the system mail folder name?" The folder
** name in the title bar label should be surrounded by a pair of quote marks.
*/
int
In_System_Folder(void)
{
int len, result;
char *fq, *lq, *buf;
Arg args[1];
MailwatchWidget mb = (MailwatchWidget) XtNameToWidget(toplevel, "icon.mailbox");
Widget tb = XtNameToWidget(toplevel, "topBox.titleBar.title");
XtSetArg(args[0], XtNlabel, &buf);
XtGetValues(tb, args, 1);
if ((lq = strrchr(buf, '"')) == NULL) result = FALSE;
else { /* if a current folder name exists */
if ((fq = strchr(buf, '"')) == NULL) result = FALSE;
else {
++fq;
len = lq - fq;
result = (strncmp(mb->mailbox.filename, fq, len) == 0) ? TRUE : FALSE ;
}
}
return(result);
} /* In_System_Folder */
/*
** Process map and unmap events for the icon widget to manage our iconify and
** deiconify actions and switch to/from a bogus mail folder. This allows users
** to access mail from another process without colliding with an open folder.
** Once the bogus mail folder is accessed, we unlink it, to avoid having to
** explicitly remove it later.
*/
/* ARGSUSED */
void
icon_handler(Widget w, XtPointer closure , XEvent *event, Boolean *continueToDispatch)
{
static Boolean Was_System_Folder = False; /* TRUE if we had been in */
FILE *fp;
char *cp, cmd[BUFSIZ];
if (mailpid) {
switch (event->type) {
case MapNotify :
if (! In_Bogus_Mail_File) {
Was_System_Folder = In_System_Folder();
(void) sprintf(cmd, "%s+", tmpName);
if (fp = fopen(cmd, "w")) { /* create a bogus mail file */
(void) fprintf(fp, "\n");
(void) fclose(fp);
(void) sprintf(cmd, "file %s+", tmpName);
cp = QueryMail(cmd); /* focus our attention there */
*cp = '\0';
(void) UpdateTitleBar("No current folder");
writeTo(XtNameToWidget(toplevel, "*indexWindow"), " ", REPLACE);
writeText(" ");
(void) sprintf(cmd, "%s+", tmpName);
(void) unlink(cmd); /* toss it now that we're in */
In_Bogus_Mail_File = True;
}
}
break;
case UnmapNotify :
if (In_Bogus_Mail_File) {
if (strcmp(Command, "Start") != 0) { /* if not starting up */
if (Was_System_Folder) { /* go to system file */
(void) strcpy(Command, "file %\n");
} else { /* go to prev. file */
(void) strcpy(Command, "file #\n");
}
} else {
if (XMail.MFileName) { /* start in specified folder */
(void) sprintf(Command, "file %s\n", XMail.MFileName);
} else { /* or else use system folder */
(void) strcpy(Command, "file %\n");
}
}
SetCursor(WATCH);
writeMail(Command); /* let parser do the updating */
In_Bogus_Mail_File = False;
Was_System_Folder = False;
} else if (In_System_Folder())
UnsetNewmail(NULL, NULL, NULL);
break;
default:
break;
} /* end - switch on event type */
} /* end - if mail is active */
} /* icon_handler */
/*
** @(#)index_handler() - find value of specified or next appropriate message
*/
int
index_handler(int msg_num, int undeleting)
{
int j, k;
XawTextPosition pos;
String c, s, IBuf;
Widget iw;
Arg args[1];
Bell(""); /* reset bell worthyness flag */
Bell(Default_Status_Info);
k = msg_num; /* Try to use specified msg. */
if (k == 0) { /* But, if not specified... */
c = QueryMail("=");
if (*c)
(void) sscanf(c, "%d", &k); /* get msg num from mail. */
}
iw = XtNameToWidget(toplevel, "topBox.indexWindow");
IBuf = NULL;
XtSetArg(args[0], XtNstring, &IBuf);
XtGetValues(iw, args, 1);
if (k <= 50) { /* do short index from front */
s = IBuf;
for (j = k - 1; j > 0 && (c = strchr(s, '\n')) != NULL; j--) s = c + 1;
} else { /* if index is fairly large */
for (s = &IBuf[strlen(IBuf) - 2]; s > IBuf && *s != '\n'; s--);
for (c = s + 1; *c && !isdigit(*c); c++); /* get number of last entry */
j = 0;
if (*c)
(void) sscanf(c, "%d", &j); /* look backwards from there */
for (; j > k; j--) {
if (s > IBuf) s--;
for (; s > IBuf && *s != '\n'; s--);
}
if (*s == '\n') s++;
}
j = k;
for (;;) { /* allow for deleted msgs */
for (c = s; *c && !isdigit(*c); c++);
if (! *c || k == 0 ||
(sscanf(c, "%d", &j) && j <= k)) /* total may be less than us */
break;
if (s - 2 >= IBuf)
for (s -= 2; s > IBuf && *s != '\n'; s--);
if (*s == '\n') s++;
}
if (! undeleting && *(s + 1) == 'D') { /* If this is a deleted msg */
j = 0; /* then num is inappropriate */
for (;*s && *(s + 1) == 'D';) { /* try looking above deletes */
if (! (c = strchr(s,'\n'))) break; /* don't go past end of buf */
s = c + 1;
}
for (;s > IBuf && *(s + 1) == 'D';) {
for (s -= 2; s > IBuf && *s != '\n'; s--);
if (*s == '\n') s++;
}
if (*(s + 1) != 'D') { /* If we found a readable msg */
for (c = s; *c && !isdigit(*c); c++);
if (*c)
(void) sscanf(c, "%d", &j);
}
}
if (j) { /* if we have a valid msg num */
pos = s - IBuf; /* resolve our position */
XawTextSetInsertionPoint(iw, pos); /* point at selected line */
markIndex("> "); /* flag it as current */
}
return(j); /* return msg actually found */
} /* index_handler */
/*
** @(#)info_handler - use enter/leave_notify events to alter status window info
*/
/*ARGSUSED*/
void
info_handler(Widget w, XtPointer client_data, XEvent *event, Boolean *continueToDispatch)
/* unused */
{
if (event->type == LeaveNotify && ! Waiting) Bell(Default_Status_Info);
else if (event->type == EnterNotify) {
if (! Waiting) Bell(client_data);
Waiting = FALSE;
}
} /* end - info_handler */
/*
** @(#)file_handler() - Handle output of Start and file commands.
** If *Show_Last: resource is TRUE show last
** message in list, if none are marked as new.
*/
file_handler(void)
{
int New_Unread, msg_num = 0;
char *c, *p, *headers = NULL;
char msgnum_str[10];
XawTextPosition pos;
Widget iw = XtNameToWidget(toplevel, "topBox.indexWindow");
c = QueryMail("file"); /* Forces msg to first New/U */
if (! mailpid) return (msg_num);
if (! In_Bogus_Mail_File)
(void) UpdateTitleBar(c);
c = QueryMail("="); /* Get current mail msg num. */
while (! isdigit(*c)) {
if (! mailpid) return (msg_num);
c = QueryMail("=");
}
(void) sprintf(msgnum_str, c);
*c = '\0';
if (! mailpid) return (msg_num);
headers = QueryMail("h");
if (strncmp(headers, "No applicable messages", 22) == 0) {
Bell(headers);
writeTo(iw, " ", REPLACE);
writeText(" ");
} else {
/*
** find mail's idea of this folder's current message number
*/
if (*headers == '>') c = headers;
else /* start search from the end of buf */
if (c = strrchr(headers, '\n')) c++;
else c = headers;
while (c > headers) {
if (*c == '>' && *(c - 1) == '\n')
break;
for (c -= 2; c > headers && *c != '\n'; c--);
if (*c == '\n') c++;
}
/*
** If the current message is marked new or unread, ensure as many of the new
** message headers as possible are displayed in the index window (especially
** the current one), else if the Show_Last resource is not false, select the
** last message in the header.
*/
p = c; /* save position of current */
New_Unread = (*(c+1) == 'N' || *(c+1) == 'U');
if (! New_Unread && XMail.Show_Last) { /* find the last message */
if (*p == '>') *p = ' '; /* erase the original marker */
if (c == headers) { /* if we would've started @1 */
if (p = strrchr(headers, '\n')) p++;
else p = headers; /* go to last line of buffer */
}
for (c = p; *c && !isdigit(*c); c++);
if (*c)
(void) sscanf(c, "%d", &msg_num);
(void) sprintf(msgnum_str, "%d", msg_num);
}
/*
** mark the current message's index line
*/
*p = '>'; *(p+1) = ' ';
/*
** Install these headers in the index window
*/
writeTo(iw, headers, REPLACE);
/*
** Ensure if there are new or unread messages that as many as possible are
** displayed in the index window to reduce the amount of scrolling required
** when reading(/deleting) them.
*/
pos = p - headers;
if (New_Unread)
XawTextSetInsertionPoint(iw, strlen(headers));
XawTextSetInsertionPoint(iw, pos);
/*
** Return the current message number.
*/
msg_num = atoi(msgnum_str);
}
*headers = '\0';
return(msg_num);
} /* file_handler */
syntax highlighted by Code2HTML, v. 0.9.1