v07i081: xmail -- Mail front end for X11, Patch1, Part01/06
news
news at sun.Eng.Sun.COM
Fri Jun 1 13:39:47 AEST 1990
Submitted-by: parns.nsc.com!michael (Michael C. Wagnitz)
Posting-number: Volume 7, Issue 81
Archive-name: xmail/patch1.01
Patch-To: xmail: Volume 6, Issue 41-46
The following files constitute the first (and only) official patch to the
Mail X11 front-end xmail. Due to a most fortunate delay in shipment of these
patches, I have been able to re-combine the full set of enhancements originally
announced as two sets of patches into this one complete set. This should help
to reduce the net bandwidth.
After unsharing these files, you will have a MANIFEST of this patch
distribution, a file of CHANGES, and a set of five files named Patch.01[a-e]
that must be concatenated into one patch file (PATCH.01) which is then to be
applied to an original set of xmail sources.
My thanks go to the many contributors of patches and suggestions for xmail.
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 1 (of 5)."
# Contents: CHANGES MANIFEST Patch.01b
# Wrapped by michael at harley on Tue May 29 10:33:49 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'CHANGES' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CHANGES'\"
else
echo shar: Extracting \"'CHANGES'\" \(6361 characters\)
sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
X
X May, 1990
X
X The following changes have been effected for Patchlevel 1 of xmail.
X
X
XImakefile: Made improvements in dependencies and SunOS defines.
X Removed requirement for linkage to system math library.
X
XHelpText.c: Text revised and reformatted to better fit the help window
X
XMailwatch.c: Corrected illegal pointer combinations and added resources
X to allow the user to specify the number of times to ring the
X bell when new mail has arrived. Fixed new mail bell to ring
X only if flag is not already up.
X
XMailwatch.h: Eliminated warning for duplicate XtNfile definition
X
Xactions.c: Corrected illegal pointer combinations, added support for
X improved index handler and Blind carbon copies. Also added
X support for .mailrc "printmail" definition, and improved error
X messages when attempting to select non-existant or undefined
X mail folders. Used integer math instead of sqrt() function to
X calculate box dimensions for aliases list.
X
XcallMail.c: Corrected attempts to write to read-only strings, and fixed
X case where fork child dies for improper command arguments or
X illegal or unfound image execution which tried to write error
X messages to the xmail pipe instead of the terminal screen.
X A dying child process now also terminates the xmail process.
X
Xcallbacks.c: Added support for external sendmail function, improved index
X handler, and mail variable 'alwaysignore' which is now used
X to determine header levels for reply, forward, and printed
X messages. If recipient selection fails to find a value for
X the <Return_Path:> to a message, the <From:> designate is now
X used, to eliminate failures to provide a <To:> addressee.
X Also fixed bug in replyalls which failed to pick up names from
X the original To: field when preparing addresses for the reply.
X
Xdefs.h: Changed TITLE definition to accomodate use of PATCHLEVEL.
X
Xenvirons.c: Alias support has been extended to include the word 'group'
X when manually extracting mail aliases from the user's .mailrc
X file. Support has also been included for continuation lines.
X Mechanisms to expand the MAILRC environment variable definition
X have been eliminated, so that xmail behaves more like mail.
X Corrected a bug in getMailEnv to return 'True' for variables
X which have no additional value, such as 'hold' or 'autoprint'.
X Changed strchr() calls to index().
X
Xhandler.c: Function icon_handler() has been added to switch xmail to a
X dummy mail folder whenever the application is iconified, and
X to switch back to the previous folder on de-iconification.
X Improved index_handler() to eliminate repaints of the index
X window for every deletion or undeletion. Also added code to
X display as many new message headers as possible, to elminate
X unnecessary scrolling of the index window.
X
Xmail.c: Changed the fputs() to a write() to help eliminate i/o hanging,
X added Blind Carbon Copy support to the sendMail function, and
X added XMail class resources to the xterm messsage entry window.
X Changed strrchr() call declarations to rindex().
X
Xparser.c: Eliminated multiple redraws of the index window during message
X deletions, and corrected index message markers for 'N'ew,
X 'D'eleted, and undeleted mail messages. Corrected a bug in the
X delete processing to not reread entire message and corrected a
X bug to erase index and text window datas if no current folder.
X
Xutils.c: Added use of PATCHLEVEL in determining TITLE version revision
X and changed calls for strchr() to index().
X
Xwindows.c: Changed name of "hold" button to "preserve", to better match
X error message text when used incorrectly, eliminated making
X the preserve button insensitive, to allow use of "set" menu
X in any folder, added a "set" menu to the "preserve" command
X button, to toggle mail variables, "alwaysignore", "autoprint",
X and "hold", and corrected character processing in the file
X window, to allow deletion and insertion within the line,
X instead of always at the end. Added use of PATCHLEVEL in
X determining TITLE version revision
X
Xxmail.c: added support for the -iconic command line option, corrected
X resource handling for iconGeometry, and improved default font
X handling for minimum dimensions of the xmail application window.
X Also fixed processing of geometry specifications for the top
X level window. Update the 'what' database string to reflect
X current version.
X
X
X
XI would like to thank the many contributors of suggestions and actual patches.
XI would also like to thank those persons who sent in complaints, as they were
Xoften the predictors of the many other corrections and enhancements to xmail.
X
X*) Message size tests in parser.c were extended to include support for DEC
X mail return on size requests, to prevent core dumps under Ultrix UWS 2.2
X thanks to patches from Dirk Grunwald <grunwald at foobar.Colorado.EDU>
X
X*) Corrections to Imakefile to eliminate the need to set SunOS dependency
X flags manually were driven by suggestions from Casey Leedom
X <casey at gauss.llnl.gov> and David Elliott <dce at smsc.sony.com>.
X
X*) The regular expressions definitions in xmailregex.h were corrected as a
X result of suggestions from Casey Leedom.
X
X*) Suggestions from Casey Leedom, Mark Williams <msw at cpsc.UCalgary.CA>,
X and Mark Scholl <scholl at inf.ethz.ch> helped identify a problem in the
X communications links with mail. writeMail() now uses a write instead
X of fputs, and the connection parameters are set for APPEND instead of
X non-blocking i/o, to eliminate run-away cpu cycles.
X
X*) Many, many illegal pointer combination errors were identified and corrected
X by Christos Zoulas <christos at guillemin.EE.cornell.edu>
X
X*) Thanks go to Robert Viduya <robert at shangri-la.gatech.ude> for suggestions
X and assistance in adding an icon handler to switch to a dummy mail folder
X during iconification, to prevent collisions in mail if run from another
X process while xmail is running.
X
X*) Support for an alternate sendmail function was provided after receiving
X suggestions from Jim Blythe <jsblythe%uk.co.gec-mrc at nsfnet-relay.ac.uk>
X
X*) Blind carbon copy support and correction of several bugs were suggested
X by Jeff Dauber <dauber at parns.nsc.com>
X
X*) Support for mail variables autoprint and hold were corrected thanks to
X requests from Dwayne Lee <dwayne at asic.nsc.com>
END_OF_FILE
if test 6361 -ne `wc -c <'CHANGES'`; then
echo shar: \"'CHANGES'\" unpacked with wrong size!
fi
# end of 'CHANGES'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(460 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X File Name Archive # Description
X-----------------------------------------------------------
X CHANGES 1 List of enhancements to xmail
X MANIFEST 1 This shipping list
X Patch.01a 2 Patch file for xmail
X Patch.01b 1 Patch file for xmail
X Patch.01c 3 Patch file for xmail
X Patch.01d 4 Patch file for xmail
X Patch.01e 5 Patch file for xmail
END_OF_FILE
if test 460 -ne `wc -c <'MANIFEST'`; then
echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'Patch.01b' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Patch.01b'\"
else
echo shar: Extracting \"'Patch.01b'\" \(46474 characters\)
sed "s/^X//" >'Patch.01b' <<'END_OF_FILE'
X! tmp[x] = '\0';
X! foldir[foldlen] = '\0';
X! strcat(foldir, &tmp[1]);
X! if ((dirp = opendir(foldir)) != NULL) {
X! tmp[x++] = '/';
X tmp[x] = '\0';
X! }
X! n = 4;
X! XtSetArg(args[n], XtNlabel, tmp); n++;
X! XtSetArg(args[n], XtNfromHoriz, to_left); n++;
X! if (! to_left) XtSetArg(args[n], XtNfromVert, above); n++;
X
X! this_one = XtCreateManagedWidget("listbutton", commandWidgetClass,
X lw, args, n);
X! if (dirp != NULL) {
X! closedir(dirp);
X! sprintf(trans, dir_Trans, &tmp[1], foldir, "0");
X! XtOverrideTranslations(this_one, XtParseTranslationTable(trans));
X }
X }
X- }
X } /* end - if some trans strlen */
X /*
X ** If folders menu exists, pop it up, after setting x,y coordinates
X */
X if (popup->core.being_destroyed) {
X! Bell("No mail folders exist\n");
X } else {
X if (! XtIsRealized(popup)) /* see if folder list is small */
X XtRealizeWidget(popup); /* enough to fit if anchored at */
X--- 791,836 ----
X } else {
X if (x == 0) tmp[x++] = '+'; /* start folder names with a 'plus' */
X tmp[x++] = *p;
X+ }
X }
X
X! if (x) {
X tmp[x] = '\0';
X! foldir[foldlen] = '\0';
X! strcat(foldir, &tmp[1]);
X! if ((dirp = opendir(foldir)) != NULL) {
X! tmp[x++] = '/';
X! tmp[x] = '\0';
X! }
X! XtSetArg(args[4], XtNlabel, tmp);
X! XtSetArg(args[5], XtNfromHoriz, to_left); n = 6;
X! if (! to_left) XtSetArg(args[n], XtNfromVert, above); n++;
X
X! this_one = XtCreateManagedWidget("listbutton", commandWidgetClass,
X lw, args, n);
X! if (dirp != NULL) {
X! closedir(dirp);
X! sprintf(trans, dir_Trans, &tmp[1], foldir, "0");
X! XtOverrideTranslations(this_one, XtParseTranslationTable(trans));
X! }
X }
X }
X } /* end - if some trans strlen */
X /*
X ** If folders menu exists, pop it up, after setting x,y coordinates
X */
X if (popup->core.being_destroyed) {
X! if (! *foldir)
X! Bell("No value set for \"folder\"\n");
X! else {
X! if (dirp && !mailpid) {
X! Bell("No mail folders exist\n");
X! } else {
X! foldir[foldlen - 1] = '\0';
X! sprintf(tmp, "%s not found\n", foldir);
X! Bell(tmp);
X! }
X! }
X } else {
X if (! XtIsRealized(popup)) /* see if folder list is small */
X XtRealizeWidget(popup); /* enough to fit if anchored at */
X***************
X*** 790,810 ****
X ad = XtDisplay(w);
X n = XMail.buttonHeight / 2;
X } else {
X! aw = XtWindow(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"));
X! ad = XtDisplay(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"));
X! n = XMail.commandMinHeight / 2;
X }
X root = RootWindow(ad, DefaultScreen(ad));
X
X! XTranslateCoordinates(ad, aw, root, XMail.menuX, n, &x, &y, &dumy);
X
X! n = 0;
X! XtSetArg(args[n], XtNx, x); n++;
X! XtSetArg(args[n], XtNy, y); n++;
X! XtSetValues(popup, (ArgList) args, n);
X }
X
X! XtFree(List);
X
X } /* SetFolders */
X
X--- 841,860 ----
X ad = XtDisplay(w);
X n = XMail.buttonHeight / 2;
X } else {
X! aw = XtWindow(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"));
X! ad = XtDisplay(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"));
X! n = XMail.commandMinHeight / 2;
X }
X root = RootWindow(ad, DefaultScreen(ad));
X
X! XTranslateCoordinates(ad, aw, root, XMail.menuX, n, &x, &y, &dumy);
X
X! XtSetArg(args[0], XtNx, x);
X! XtSetArg(args[1], XtNy, y);
X! XtSetValues(popup, (ArgList) args, 2);
X }
X
X! XtFree((char *)List);
X
X } /* SetFolders */
X
X***************
X*** 820,827 ****
X String *params;
X Cardinal *num_params;
X {
X! Arg args[3];
X! Widget tw;
X Window aw, dumy;
X Display *ad;
X int indx, status, x, y, scn;
X--- 870,877 ----
X String *params;
X Cardinal *num_params;
X {
X! Arg args[2];
X! Widget tb, tw;
X Window aw, dumy;
X Display *ad;
X int indx, status, x, y, scn;
X***************
X*** 834,844 ****
X if (strcmp(params[0], HelpNames[indx]) == 0) break;
X
X if (HelpNames[indx]) {
X! XtTextSetSource(WidgetOf(WidgetOf(WidgetOf(toplevel, "vpane"), "help"), "helpWindow"), HelpStrings[indx], (XtTextPosition) 0);
X /*
X ** Position help relative to textWindow
X */
X! tw = WidgetOf(WidgetOf(toplevel, "vpane"), "textWindow");
X aw = XtWindow(tw);
X ad = XtDisplay(tw);
X scn = DefaultScreen(ad);
X--- 884,895 ----
X if (strcmp(params[0], HelpNames[indx]) == 0) break;
X
X if (HelpNames[indx]) {
X! tb = WidgetOf(toplevel, "topBox");
X! XtTextSetSource(WidgetOf(WidgetOf(tb, "help"), "helpWindow"), HelpStrings[indx], (XtTextPosition) 0);
X /*
X ** Position help relative to textWindow
X */
X! tw = WidgetOf(tb, "textWindow");
X aw = XtWindow(tw);
X ad = XtDisplay(tw);
X scn = DefaultScreen(ad);
X***************
X*** 848,861 ****
X
X XtSetArg(args[0], XtNx, x);
X XtSetArg(args[1], XtNy, y);
X! XtSetValues(WidgetOf(WidgetOf(toplevel, "vpane"), "help"), args, 2);
X
X! XtPopup(WidgetOf(WidgetOf(toplevel, "vpane"), "help"), XtGrabNone);
X }
X } /* SetHelp */
X
X
X /*
X ** @(#)SetPopup() - place named popup at menuX, menuY relative to Widget w.
X */
X /* ARGSUSED */
X--- 899,988 ----
X
X XtSetArg(args[0], XtNx, x);
X XtSetArg(args[1], XtNy, y);
X! XtSetValues(WidgetOf(tb, "help"), args, 2);
X
X! XtPopup(WidgetOf(tb, "help"), XtGrabNone);
X }
X } /* SetHelp */
X
X
X+ /*
X+ ** @(#)SetMenu() - create a menu for toggling selected mail options
X+ */
X+ XtActionProc
X+ SetMenu(parent, event, params, num_params)
X+ Widget parent;
X+ XEvent *event; /* unused */
X+ String *params;
X+ Cardinal *num_params;
X+ {
X+ Arg args[6];
X+ Display *ad;
X+ Widget menu, layout, previous, next;
X+ Window aw, dumy, root;
X+ char *c, label[BUFSIZ], name[BUFSIZ];
X+ int indx, x, y;
X+
X+ static String b_Trans =
X+ "<EnterWindow>: set() \n\
X+ <LeaveWindow>: reset() \n\
X+ <Btn3Up>: SetCursor(True) notify() SetCursor() unset()";
X+
X+ static String m_Trans =
X+ "<Btn3Up>: MenuPopdown(set_menu)";
X+
X+ static String list[] = { "alwaysignore", "autoprint", "hold", NULL };
X+
X+
X+ menu = XtNameToWidget(parent, "set_menu");
X+
X+ if (! menu || menu->core.being_destroyed) {
X+ XtSetArg(args[0], XtNtranslations, XtParseTranslationTable(m_Trans));
X+ menu = XtCreatePopupShell("set_menu",overrideShellWidgetClass,parent,args,1);
X+
X+ XtSetArg(args[0], XtNdefaultDistance, (XtArgVal) 1);
X+ layout = XtCreateManagedWidget("menu", formWidgetClass, menu, args, ONE);
X /*
X+ ** create the menu buttons
X+ */
X+ indx = XTextWidth(TextFontStr, " ", 1) * 18 + 12;
X+ previous = NULL;
X+ XtSetArg(args[0], XtNwidth, indx);
X+ XtSetArg(args[1], XtNfont, TextFontStr);
X+ XtSetArg(args[2], XtNjustify, XtJustifyLeft);
X+ XtSetArg(args[3], XtNtranslations, XtParseTranslationTable(b_Trans));
X+ for (indx = 0; list[indx] != NULL; indx++) {
X+ strcpy(label, "set ");
X+ if ((c = GetMailEnv(list[indx])) != NULL) {
X+ strcat(label, "no");
X+ XtFree(c);
X+ }
X+ strcat(label, list[indx]); /* set window name by label */
X+ strcpy(name, &label[4]);
X+ XtSetArg(args[4], XtNlabel, label);
X+ XtSetArg(args[5], XtNfromVert, previous);
X+ next = XtCreateManagedWidget(name, commandWidgetClass, layout, args, 6);
X+ XtAddCallback(next, XtNcallback, (XtCallbackProc) DoSet, NULL);
X+ previous = next;
X+ }
X+
X+ XtRealizeWidget(menu);
X+ }
X+
X+ aw = XtWindow(parent);
X+ ad = XtDisplay(parent);
X+ indx = XMail.buttonHeight / 2;
X+ root = RootWindow(ad, DefaultScreen(ad));
X+
X+ XTranslateCoordinates(ad, aw, root, XMail.menuX, indx, &x, &y, &dumy);
X+
X+ XtSetArg(args[0], XtNx, x);
X+ XtSetArg(args[1], XtNy, y);
X+ XtSetValues(menu, (ArgList) args, 2);
X+ } /* SetMenu */
X+
X+
X+ /*
X ** @(#)SetPopup() - place named popup at menuX, menuY relative to Widget w.
X */
X /* ARGSUSED */
X***************
X*** 939,945 ****
X cm.format = 32;
X cm.data.l[0] = XA_PRIMARY;
X
X! XSendEvent(XtDisplay(w), cm.window, TRUE, NoEventMask, &cm);
X
X for (; *s && !isdigit(*s); s++);
X left = s - IndexBuf;
X--- 1066,1072 ----
X cm.format = 32;
X cm.data.l[0] = XA_PRIMARY;
X
X! XSendEvent(XtDisplay(w), cm.window, TRUE, NoEventMask, (XEvent *) &cm);
X
X for (; *s && !isdigit(*s); s++);
X left = s - IndexBuf;
X***************
X*** 963,971 ****
X String *params;
X Cardinal *num_params;
X {
X! caddr_t client_data;
X! caddr_t call_data;
X!
X! client_data = params[0];
X! DoQuit(w, client_data, call_data);
X } /* Quit */
X--- 1090,1094 ----
X String *params;
X Cardinal *num_params;
X {
X! DoQuit(w, *params, NULL);
X } /* Quit */
X*** ../v1.0/callMail.c Sun May 27 21:05:43 1990
X--- callMail.c Sun May 27 21:09:56 1990
X***************
X*** 43,56 ****
X #include <sgtty.h>
X #include "global.h"
X
X! FILE *mailfp = NULL; /* file pointer to mail */
X int mail_fd; /* mail process master tty id */
X int mailpid; /* mail process id */
X int mailInputId; /* mail input id */
X
X- static char *pty = "/dev/pty??"; /* master side of pseudo-terminal */
X- static char *tty = "/dev/tty??"; /* slave side of pseudo-terminal */
X-
X /*
X * Xmail talks to mail through a pseudo terminal which is a pair of master
X * and slave devices: /dev/pty?? and /dev/tty??, where ?? goes from p0 to
X--- 43,57 ----
X #include <sgtty.h>
X #include "global.h"
X
X! #define PTYTEMPL "/dev/pty??"
X! #define TTYTEMPL "/dev/tty??"
X!
X int mail_fd; /* mail process master tty id */
X int mailpid; /* mail process id */
X int mailInputId; /* mail input id */
X+ char pty[10]; /* master side of pseudo-terminal */
X+ char tty[10]; /* slave side of pseudo-terminal */
X
X /*
X * Xmail talks to mail through a pseudo terminal which is a pair of master
X * and slave devices: /dev/pty?? and /dev/tty??, where ?? goes from p0 to
X***************
X*** 65,70 ****
X--- 66,72 ----
X int i, master;
X char c;
X
X+ (void) strcpy(pty, PTYTEMPL);
X for (c='p'; c<='s'; c++) {
X pty[8] = c;
X for (i=0; i<16; i++) {
X***************
X*** 86,91 ****
X--- 88,94 ----
X {
X int slave;
X
X+ (void) strcpy(tty, TTYTEMPL);
X tty[8] = pty[8];
X tty[9] = pty[9];
X if ((slave = open(tty, O_RDWR)) != -1) {
X***************
X*** 106,122 ****
X int argc;
X char *argv[];
X {
X! struct sgttyb Sgtty;
X! int master; /* file descriptor of master pty */
X! int slave; /* file descriptor to slave pty */
X! char *Mailpgm, /* name of executable Mailpgm */
X! errmsg[BUFSIZ];
X
X! Mailpgm = (char *) getenv("XMAILER"); /* first looks up env var */
X! if (Mailpgm == NULL)
X! Mailpgm = XtNewString(XMAILER);
X
X! master = openMaster();
X slave = openSlave();
X
X ioctl(slave, TIOCGETP, &Sgtty);
X--- 109,124 ----
X int argc;
X char *argv[];
X {
X! struct sgttyb Sgtty;
X! int slave; /* file descriptor to slave pty */
X! char *Mailpgm; /* name of executable Mailpgm */
X! char buf[BUFSIZ];
X
X!
X! if (! (Mailpgm = (char *)getenv("XMAILER"))) /* first looks up env var */
X! Mailpgm = "Mail";
X
X! mail_fd = openMaster();
X slave = openSlave();
X
X ioctl(slave, TIOCGETP, &Sgtty);
X***************
X*** 125,158 ****
X
X mailpid = fork();
X if (mailpid == -1) {
X! perror("Cannot fork mail process");
X exit(1);
X } else if (mailpid) {
X /*
X * Parent : close the slave side of pty
X * close stdin and stdout
X! * set the mail file descriptor to nonblocking mode
X! * open file pointer with read/write access to mail
X! * set unbuffered mode
X * register mail input with X
X */
X close(slave);
X! if (master != 0) /* if we're restarting, master IS 0 */
X close(0);
X close(1);
X! fcntl(master, F_SETFL, FNDELAY);
X! mail_fd = master; /* use descriptor for reads */
X! mailfp = fdopen(master, "r+"); /* need mailfp for fputs */
X! setbuf(mailfp, NULL);
X! mailInputId = XtAddInput(master, XtInputReadMask, readMail, NULL);
X } else {
X /*
X! * Child : close master side of pty
X * redirect stdin, stdout, stderr of mail to pty
X * unbuffer output data from mail
X * exec mail with arguments
X */
X! close(master);
X dup2(slave, 0);
X dup2(slave, 1);
X dup2(slave, 2);
X--- 127,155 ----
X
X mailpid = fork();
X if (mailpid == -1) {
X! perror("callMail: Cannot fork Mail process");
X exit(1);
X } else if (mailpid) {
X /*
X * Parent : close the slave side of pty
X * close stdin and stdout
X! * set the mail file descriptor to append mode
X * register mail input with X
X */
X close(slave);
X! if (mail_fd != 0) /* if we're restarting, mail_fd IS 0 */
X close(0);
X close(1);
X! fcntl(mail_fd, F_SETFL, FAPPEND);
X! mailInputId = XtAddInput(mail_fd, XtInputReadMask, readMail, NULL);
X } else {
X /*
X! * Child : close mail_fd side of pty
X * redirect stdin, stdout, stderr of mail to pty
X * unbuffer output data from mail
X * exec mail with arguments
X */
X! close(mail_fd);
X dup2(slave, 0);
X dup2(slave, 1);
X dup2(slave, 2);
X***************
X*** 162,169 ****
X setbuf(stdout, NULL);
X argv[0] = Mailpgm;
X execvp(Mailpgm, argv);
X! sprintf(errmsg, "callMail: Cannot call %s", Mailpgm);
X! perror(errmsg);
X exit(1);
X }
X } /* callMail */
X--- 159,177 ----
X setbuf(stdout, NULL);
X argv[0] = Mailpgm;
X execvp(Mailpgm, argv);
X! /*
X! * If we fail to make contact, we must re-establish
X! * access to the terminal screen that started us for
X! * our error message, because we don't want to send
X! * it up the xmail pipe. Also, terminate our parent.
X! */
X! if ((slave = open("/dev/tty", O_RDWR)) != -1) {
X! dup2(slave, 1);
X! dup2(slave, 2);
X! perror(Mailpgm);
X! }
X! sprintf(buf, "kill -INT %s\n", &tmpName[10]);
X! system(buf);
X exit(1);
X }
X } /* callMail */
X*** ../v1.0/callbacks.c Sun May 27 21:05:44 1990
X--- callbacks.c Sun May 27 21:09:57 1990
X***************
X*** 30,35 ****
X--- 30,36 ----
X #include "global.h"
X #include <sys/wait.h>
X #include <sys/stat.h>
X+ #include <pwd.h>
X
X
X /*
X***************
X*** 91,96 ****
X--- 92,98 ----
X FILE *fp;
X char *p, *record, *folder, *getenv();
X char From[BUFSIZ], Copy[BUFSIZ], s[BUFSIZ];
X+ int n;
X struct stat st_buf;
X
X
X***************
X*** 115,120 ****
X--- 117,125 ----
X if (*CcBuf)
X fprintf(fp, "Cc: %s\n", alias(CcBuf));
X
X+ if (*BccBuf)
X+ fprintf(fp, "Bcc: %s\n", alias(BccBuf));
X+
X fprintf(fp, "\n"); /* separate header from text */
X fclose(fp);
X }
X***************
X*** 126,133 ****
X */
X if (*Recipient && (*SubjBuf ||
X (stat(tmpName, &st_buf) == 0 && st_buf.st_size))) {
X! sprintf(s, "cat %s_ %s | /usr/lib/sendmail -toi -om 2> /dev/null", tmpName, tmpName);
X system(s);
X /*
X ** If user has set 'record' in their .mailrc, add a message copy to that file
X */
X--- 131,141 ----
X */
X if (*Recipient && (*SubjBuf ||
X (stat(tmpName, &st_buf) == 0 && st_buf.st_size))) {
X! if ((p = GetMailEnv("sendmail")) == NULL)
X! p = XtNewString("/usr/lib/sendmail");
X! sprintf(s, "cat %s_ %s | %s -toi -om 2> /dev/null", tmpName, tmpName, p);
X system(s);
X+ XtFree(p);
X /*
X ** If user has set 'record' in their .mailrc, add a message copy to that file
X */
X***************
X*** 177,187 ****
X sprintf(Copy, "%s/%s", getenv("HOME"), &record[1]);
X XtFree(record);
X }
X! if (*Recipient && (*SubjBuf ||
X! (stat(tmpName, &st_buf) == 0 && st_buf.st_size))) {
X sprintf(s, "cat %s_ %s >> %s 2> /dev/null", tmpName, tmpName, Copy);
X system(s);
X! sprintf(s, "Canceled letter appended to %s\n", Copy);
X Bell(s);
X } else Bell("Nothing to save in your dead letter box\n");
X }
X--- 185,202 ----
X sprintf(Copy, "%s/%s", getenv("HOME"), &record[1]);
X XtFree(record);
X }
X! st_buf.st_size = 0; /* (in case msg file does not exist) */
X! if (*Recipient || *SubjBuf ||
X! (stat(tmpName, &st_buf) == 0 && st_buf.st_size)) {
X! n = st_buf.st_size; /* remember num bytes in msg */
X! if (stat((char *)sprintf(s, "%s_", tmpName), &st_buf) == 0)
X! n += st_buf.st_size; /* include bytes in header */
X! st_buf.st_size = -1; /* see if our target exists */
X! stat(Copy, &st_buf);
X sprintf(s, "cat %s_ %s >> %s 2> /dev/null", tmpName, tmpName, Copy);
X system(s);
X! sprintf(s, "\"%s\" [%s] (%d bytes)\n", Copy,
X! (st_buf.st_size >= 0) ? "Appended" : "New file", n);
X Bell(s);
X } else Bell("Nothing to save in your dead letter box\n");
X }
X***************
X*** 213,228 ****
X else if (strcmp(Command, "file %\n") != 0 && strcmp(Command, "inc\n") != 0)
X Bell("No mail\n"); /* But if no new mail, complain */
X else {
X! for (n = 0; n < mailargc; n++) {
X! if (strcmp(mailargv[n], "-f") == 0) {
X! for (i = n + 2; i <= mailargc;) mailargv[n++] = mailargv[i++];
X! mailargc -= 2; /* throw away any folder argument */
X! n -= 2; /* re-examine new mailargv value */
X! }
X! }
X callMail(mailargc, mailargv); /* restart the mail connections */
X strcpy(Command, "Start"); /* Let em know we've re-started */
X! UnsetNewmail(w, closure, call_data);
X }
X } /* DoIt */
X
X--- 228,240 ----
X else if (strcmp(Command, "file %\n") != 0 && strcmp(Command, "inc\n") != 0)
X Bell("No mail\n"); /* But if no new mail, complain */
X else {
X! if (strcmp(mailargv[mailargc - 2], "-f") == 0) {
X! mailargc -= 2; /* throw away any folder argument */
X! mailargv[mailargc] = NULL; /* and NULL end of argument list */
X! }
X callMail(mailargc, mailargv); /* restart the mail connections */
X strcpy(Command, "Start"); /* Let em know we've re-started */
X! UnsetNewmail(w, NULL, NULL);
X }
X } /* DoIt */
X
X***************
X*** 265,271 ****
X--- 277,308 ----
X } /* DoQuit */
X
X
X+ /*
X+ ** @(#)DoSet() - send specified set request to mail and destroy current menu.
X+ */
X /* ARGSUSED */
X+ XtCallbackProc
X+ DoSet(w, closure, call_data)
X+ Widget w;
X+ caddr_t closure;
X+ caddr_t call_data;
X+ {
X+ char *c, buf[32];
X+
X+
X+ if (! mailpid) /* If connections are okay,... */
X+ Bell("No mail\n"); /* if no new mail, complain */
X+ else {
X+ sprintf(buf, "set %s", w->core.name);
X+ c = QueryMail(buf);
X+ XtFree(c);
X+
X+ XtDestroyWidget(XtParent(XtParent(w)));
X+ }
X+ } /* DoSet */
X+
X+
X+ /* ARGSUSED */
X /*
X ** @(#)DoWith() - send client_data command to mail with selected msg number
X */
X***************
X*** 281,288 ****
X if (! mailpid)
X Bell("No mail\n");
X else {
X! pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "vpane"), "indexWindow"));
X num = PositionToMsgNumber(pos); /* no current message returns zero */
X if (num) sprintf(Command, "%s %d\n", client_data, num);
X else sprintf(Command, "%s \n", client_data);
X writeMail(Command);
X--- 318,326 ----
X if (! mailpid)
X Bell("No mail\n");
X else {
X! pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "topBox"), "indexWindow"));
X num = PositionToMsgNumber(pos); /* no current message returns zero */
X+ if (*client_data == 'u' && IndexBuf[pos + 1] != 'D') num = 0;
X if (num) sprintf(Command, "%s %d\n", client_data, num);
X else sprintf(Command, "%s \n", client_data);
X writeMail(Command);
X***************
X*** 353,359 ****
X }
X sprintf(buf, "File: +%s%s", tmp, folder_name);
X }
X! writeText(WidgetOf(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"), "fileWindow"), buf, 0);
X } /* GetFolderName */
X
X
X--- 391,397 ----
X }
X sprintf(buf, "File: +%s%s", tmp, folder_name);
X }
X! writeText(WidgetOf(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"), "fileWindow"), buf, 0);
X } /* GetFolderName */
X
X
X***************
X*** 371,388 ****
X Cardinal *num_params;
X FILE *fp;
X Position pos;
X! String *params, p, q, r, txt, author, subject, others, date, reference;
X! XEvent *event;
X int erasable = 0;
X
X
X! txt = author = subject = others = date = reference = "";
X if (*client_data != 's') {
X if ((fp = fopen(tmpName, "w")) == NULL)
X Bell("xmail: Cannot open temp file for writing\n");
X
X! pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "vpane"), "indexWindow"));
X! sprintf(Command, "P %d", PositionToMsgNumber(pos));
X txt = QueryMail(Command);
X if (fp) {
X switch (*client_data) {
X--- 409,438 ----
X Cardinal *num_params;
X FILE *fp;
X Position pos;
X! String *params, p, q, r;
X! String txt, ccList, author, subject, others, date, reference, empty;
X! char *us, *getlogin();
X int erasable = 0;
X+ int alwaysIgnore;
X
X
X! txt = ccList = author = subject = others = date = reference = empty = "";
X if (*client_data != 's') {
X if ((fp = fopen(tmpName, "w")) == NULL)
X Bell("xmail: Cannot open temp file for writing\n");
X
X! pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "topBox"), "indexWindow"));
X!
X! if (p = GetMailEnv("alwaysignore")) {
X! XtFree(p);
X! alwaysIgnore = 1;
X! } else alwaysIgnore = 0;
X!
X! if (alwaysIgnore) /* use 'alwaysignore' to decide how we print */
X! sprintf(Command, "p %d", PositionToMsgNumber(pos));
X! else
X! sprintf(Command, "P %d", PositionToMsgNumber(pos));
X!
X txt = QueryMail(Command);
X if (fp) {
X switch (*client_data) {
X***************
X*** 419,429 ****
X /*
X ** strip author, subject, and Carbon copy information from the selected message
X */
X for (p = txt; *p; p++) {
X! if (strcmp(p, "") == 0 || strncmp(p, "Status:", 7) == 0) break;
X
X if (strncmp(p, "Return-Path:", 12) == 0) {
X! author = p + 14;
X for (p = author; *p && *p != '>'; p++);
X if (*p) *p++ = '\0';
X for (; *p && *p != '\n'; p++);
X--- 469,484 ----
X /*
X ** strip author, subject, and Carbon copy information from the selected message
X */
X+ if (alwaysIgnore) { /* we must now get full headers, for data */
X+ XtFree(txt);
X+ sprintf(Command, "P %d", PositionToMsgNumber(pos));
X+ txt = QueryMail(Command);
X+ }
X for (p = txt; *p; p++) {
X! if (strcmp(p, empty) == 0 || strncmp(p, "Status:", 7) == 0) break;
X
X if (strncmp(p, "Return-Path:", 12) == 0) {
X! author = p + 14; /* step over the opening '<' chevron */
X for (p = author; *p && *p != '>'; p++);
X if (*p) *p++ = '\0';
X for (; *p && *p != '\n'; p++);
X***************
X*** 441,446 ****
X--- 496,507 ----
X if (*p) *p = '\0';
X }
X
X+ else if (strncmp(p, "To:", 3) == 0) {
X+ others = p + 4;
X+ for (p = others; *p && *p != '\n'; p++);
X+ if (*p) *p = '\0';
X+ }
X+
X else if (strncmp(p, "Subject:", 8) == 0) {
X subject = p + 9;
X for (p = subject; *p && *p != '\n'; p++);
X***************
X*** 448,485 ****
X }
X
X else if (strncmp(p, "Cc:", 3) == 0) {
X! others = p + 4;
X! for (p = others; *p && *p != '\n'; p++);
X if (*p) *p = '\0';
X }
X else for (; *p && *p != '\n'; p++);
X } /* end - for all of message body */
X
X! if (*client_data != 'a' && *client_data != 'A')
X! others = ""; /* If not [rR]eplyall, make sender enter any Cc: */
X
X if (fp) fclose(fp);
X
X XtFree(txt);
X } /* end - if client_data does not equal 's' */
X
X! if (*client_data != 'S' && *client_data != 's')
X strcpy(Recipient, author);
X
X! strcpy(InReply, "");
X if (*client_data != 's' && *reference && *date) {
X r = (*client_data == 'S') ? "Forwarding" : "In-Reply-To";
X sprintf(InReply, "%s: Mail from '%s' dated %s", r, reference, date);
X }
X
X if (*subject) {
X! strcpy(SubjBuf, "");
X! if (strncmp(subject, "Re: ", 4) != 0)
X strcat(SubjBuf, "Re: ");
X strcat(SubjBuf, subject);
X }
X
X! strcpy(CcBuf, others);
X
X sendMail(w);
X } /* Reply */
X--- 509,592 ----
X }
X
X else if (strncmp(p, "Cc:", 3) == 0) {
X! ccList = p + 4;
X! for (p = ccList; *p && *p != '\n'; p++);
X if (*p) *p = '\0';
X }
X else for (; *p && *p != '\n'; p++);
X } /* end - for all of message body */
X
X! if (*client_data != 'a' && *client_data != 'A') {
X! ccList = empty; /* If not [rR]eplyall, make sender enter any Cc: */
X! others = empty;
X! } else { /* otherwise, remove ourself from the others list */
X! us = getlogin();
X! if (! us) {
X! struct passwd *pw = getpwuid(getuid());
X
X+ if (pw)
X+ us = pw->pw_name;
X+ }
X+ for (p = others; *us && *p; p++) {
X+ if (strncmp(p, us, strlen(us)) == 0) {
X+ for (us = p + strlen(us); *us && *us != ',' && *us != ' ';) us++;
X+ for (; *us && (*us == ',' || *us == ' ');) us++;
X+ for (; *us;) *p++ = *us++;
X+ *p = '\0';
X+ break;
X+ }
X+ while (*p && *p != ',' && *p != ' ') p++;
X+ while (*p && (*p == ',' || *p == ' ')) p++;
X+ p--;
X+ }
X+ }
X+
X if (fp) fclose(fp);
X
X XtFree(txt);
X } /* end - if client_data does not equal 's' */
X
X! strcpy(Recipient, empty);
X! /*
X! ** If message did not have a 'Return-Path', use 'From' for reply recipient
X! */
X! if (*client_data != 'S' && *client_data != 's') {
X strcpy(Recipient, author);
X+ if (! *Recipient && *reference) {
X+ erasable = 0;
X+ author = reference;
X+ for (p = author; *p && *p != ' '; p++);
X+ if (*p) {
X+ erasable = 1;
X+ *p = '\0';
X+ }
X+ strcpy(Recipient, author);
X+ if (erasable) *p = ' ';
X+ }
X+ if (*others && (*client_data == 'a' || *client_data == 'A')) {
X+ if (LASTCH(Recipient) != ',')
X+ strcat(Recipient, ", ");
X+ strcat(Recipient, others);
X+ for (p = Recipient + strlen(Recipient) - 1; *p == ' ' || *p == ','; p--);
X+ *++p = '\0'; /* drop any trailing ", " garbage */
X+ }
X+ }
X
X! strcpy(InReply, empty);
X if (*client_data != 's' && *reference && *date) {
X r = (*client_data == 'S') ? "Forwarding" : "In-Reply-To";
X sprintf(InReply, "%s: Mail from '%s' dated %s", r, reference, date);
X }
X
X+ strcpy(SubjBuf, empty);
X if (*subject) {
X! if ((strncmp(subject, "Re:", 3) != 0 && strncmp(subject, "Re;", 3) != 0))
X strcat(SubjBuf, "Re: ");
X strcat(SubjBuf, subject);
X }
X
X! strcpy(CcBuf, ccList);
X! strcpy(BccBuf, empty);
X
X sendMail(w);
X } /* Reply */
X***************
X*** 503,509 ****
X if (! mailpid)
X Bell("No mail\n");
X else {
X! pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "vpane"), "indexWindow"));
X num = PositionToMsgNumber(pos); /* no current message returns zero */
X
X if (*cmd == 'C' || *cmd == 'S' || *cmd == 'W' || num == 0) {
X--- 610,616 ----
X if (! mailpid)
X Bell("No mail\n");
X else {
X! pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "topBox"), "indexWindow"));
X num = PositionToMsgNumber(pos); /* no current message returns zero */
X
X if (*cmd == 'C' || *cmd == 'S' || *cmd == 'W' || num == 0) {
X***************
X*** 513,519 ****
X sprintf(Command, "%s \n", cmd);
X }
X } else {
X! if ((n = TextGetLastPos(WidgetOf(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"), "fileWindow")) - StartPos) > 0) {
X FileBuf[StartPos + n] = '\0';
X p = FileBuf + StartPos;
X sprintf(Command, "%s %d %s\n", cmd, num, p);
X--- 620,626 ----
X sprintf(Command, "%s \n", cmd);
X }
X } else {
X! if ((n = TextGetLastPos(WidgetOf(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"), "fileWindow")) - StartPos) > 0) {
X FileBuf[StartPos + n] = '\0';
X p = FileBuf + StartPos;
X sprintf(Command, "%s %d %s\n", cmd, num, p);
X***************
X*** 554,560 ****
X Widget cw;
X
X if (! Highlighted) {
X! cw = WidgetOf(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"), "Newmail");
X XSetWindowBackgroundPixmap(XtDisplay(toplevel), XtWindow(cw), hatch);
X XtUnmapWidget(cw);
X XtMapWidget(cw);
X--- 661,667 ----
X Widget cw;
X
X if (! Highlighted) {
X! cw = WidgetOf(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"), "Newmail");
X XSetWindowBackgroundPixmap(XtDisplay(toplevel), XtWindow(cw), hatch);
X XtUnmapWidget(cw);
X XtMapWidget(cw);
X***************
X*** 573,585 ****
X caddr_t client_data; /* unused */
X caddr_t call_data; /* unused */
X {
X! Widget cw;
X
X if (Highlighted) {
X- cw = WidgetOf(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"), "Newmail");
X XSetWindowBackground(XtDisplay(toplevel), XtWindow(cw), cw->core.background_pixel);
X XtUnmapWidget(cw);
X XtMapWidget(cw);
X Highlighted = 0;
X }
X } /* UnsetNewmail */
X--- 680,692 ----
X caddr_t client_data; /* unused */
X caddr_t call_data; /* unused */
X {
X! Widget cw = WidgetOf(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"), "Newmail");
X
X if (Highlighted) {
X XSetWindowBackground(XtDisplay(toplevel), XtWindow(cw), cw->core.background_pixel);
X XtUnmapWidget(cw);
X XtMapWidget(cw);
X Highlighted = 0;
X+ reset_mailbox(WidgetOf(WidgetOf(toplevel, "icon"), "mailbox"));
X }
X } /* UnsetNewmail */
X*** ../v1.0/defs.h Sun May 27 21:05:48 1990
X--- defs.h Sun May 27 21:11:35 1990
X***************
X*** 48,65 ****
X #include <X11/StringDefs.h>
X #include <X11/Shell.h>
X #include <X11/Xatom.h>
X! #ifdef X11R3
X! #include <X11/Cardinals.h>
X! #include <X11/VPaned.h>
X! #include <X11/Form.h>
X! #include <X11/AsciiText.h>
X! #include <X11/TextP.h>
X! #include <X11/Box.h>
X! #include <X11/List.h>
X! #include <X11/Command.h>
X! #include <X11/Dialog.h>
X! #include <X11/Label.h>
X! #else
X #include <X11/Xaw/Cardinals.h>
X #include <X11/Xaw/VPaned.h>
X #include <X11/Xaw/Form.h>
X--- 48,56 ----
X #include <X11/StringDefs.h>
X #include <X11/Shell.h>
X #include <X11/Xatom.h>
X!
X! #if XtSpecificationRelease >= 4
X! /* R4 */
X #include <X11/Xaw/Cardinals.h>
X #include <X11/Xaw/VPaned.h>
X #include <X11/Xaw/Form.h>
X***************
X*** 70,81 ****
X #include <X11/Xaw/Command.h>
X #include <X11/Xaw/Dialog.h>
X #include <X11/Xaw/Label.h>
X #endif
X
X! #define TITLE "xmail 1.0" /* program title and version string */
X! #define MAXARGS 20 /* max number of args */
X #define StartPos 6 /* size of 'File: ' (del stop point) */
X- #define XMAILER "Mail" /* name of mail program executable */
X #define LASTCH(s) (s[strlen(s)-1])
X #define TEXTWIDTH (TextFontStr->max_bounds.width)
X #define TEXTHEIGHT (TextFontStr->max_bounds.descent + TextFontStr->max_bounds.ascent)
X--- 61,82 ----
X #include <X11/Xaw/Command.h>
X #include <X11/Xaw/Dialog.h>
X #include <X11/Xaw/Label.h>
X+ #else
X+ /* R3 */
X+ #include <X11/Cardinals.h>
X+ #include <X11/VPaned.h>
X+ #include <X11/Form.h>
X+ #include <X11/AsciiText.h>
X+ #include <X11/TextP.h>
X+ #include <X11/Box.h>
X+ #include <X11/List.h>
X+ #include <X11/Command.h>
X+ #include <X11/Dialog.h>
X+ #include <X11/Label.h>
X #endif
X
X! #define TITLE "xmail 1." /* program title and version string */
X #define StartPos 6 /* size of 'File: ' (del stop point) */
X #define LASTCH(s) (s[strlen(s)-1])
X #define TEXTWIDTH (TextFontStr->max_bounds.width)
X #define TEXTHEIGHT (TextFontStr->max_bounds.descent + TextFontStr->max_bounds.ascent)
X***************
X*** 89,94 ****
X--- 90,97 ----
X typedef struct {
X String textFont; /* xmail text font */
X String helpFont; /* xmail help font */
X+ String iconGeometry; /* xmail icon geometry */
X+ String MFileName; /* mail option -f filename */
X Dimension shellWidth; /* xmail window width */
X Dimension fileBoxWidth; /* file window box width */
X Dimension indexHeight; /* index window height */
X***************
X*** 105,117 ****
X Dimension helpY; /* help y offset from textWindow */
X Dimension menuX; /* menu x offset from parent */
X Dimension menuY; /* menu y offset from parent */
X!
X Boolean bellRing; /* xmail audible bell option */
X- Boolean mailopt_i; /* mail option -i */
X Boolean mailopt_n; /* mail option -n */
X Boolean mailopt_U; /* mail option -U */
X- String MFileName; /* mail option -f filename */
X- String SubjectStr; /* mail option -s subject */
X Boolean Show_Last; /* xmail show latest option -ls */
X } XmailResources;
X
X--- 108,117 ----
X Dimension helpY; /* help y offset from textWindow */
X Dimension menuX; /* menu x offset from parent */
X Dimension menuY; /* menu y offset from parent */
X! Boolean iconic; /* xmail starts in withdrawn state */
X Boolean bellRing; /* xmail audible bell option */
X Boolean mailopt_n; /* mail option -n */
X Boolean mailopt_U; /* mail option -U */
X Boolean Show_Last; /* xmail show latest option -ls */
X } XmailResources;
X
X*** ../v1.0/directory.c Sun May 27 21:05:49 1990
X--- directory.c Sun May 27 21:09:58 1990
X***************
X*** 46,52 ****
X String *params;
X Cardinal *num_params;
X {
X! Arg args[MAXARGS];
X Cardinal label_width, path_length, n, depth, x, y;
X DIR *new_dir, *dirp;
X String name, path;
X--- 46,52 ----
X String *params;
X Cardinal *num_params;
X {
X! Arg args[6];
X Cardinal label_width, path_length, n, depth, x, y;
X DIR *new_dir, *dirp;
X String name, path;
X***************
X*** 106,121 ****
X if (label_width) {
X (void) sprintf(trans, b_Trans, depth, name);
X
X! n = 0;
X! XtSetArg(args[n], XtNwidth, label_width); n++;
X! XtSetArg(args[n], XtNfont, TextFontStr); n++;
X! XtSetArg(args[n], XtNcallback, callbacks); n++;
X! XtSetArg(args[n], XtNtranslations, XtParseTranslationTable(trans)); n++;
X /*
X ** create the menu buttons
X */
X bw = NULL;
X! for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp), n = 4) {
X if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
X /*
X ** If this 'folder file' is also a directory, mark it with a trailing slash '/'
X--- 106,120 ----
X if (label_width) {
X (void) sprintf(trans, b_Trans, depth, name);
X
X! XtSetArg(args[0], XtNwidth, label_width);
X! XtSetArg(args[1], XtNfont, TextFontStr);
X! XtSetArg(args[2], XtNcallback, callbacks);
X! XtSetArg(args[3], XtNtranslations, XtParseTranslationTable(trans));
X /*
X ** create the menu buttons
X */
X bw = NULL;
X! for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
X if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
X /*
X ** If this 'folder file' is also a directory, mark it with a trailing slash '/'
X***************
X*** 124,135 ****
X sprintf(s, "%s/%s", path, dp->d_name);
X if ((new_dir = opendir(s)) != NULL) {
X sprintf(tmp, "%s/", dp->d_name);
X! XtSetArg(args[n], XtNlabel, tmp);
X } else
X! XtSetArg(args[n], XtNlabel, dp->d_name);
X! n++;
X! XtSetArg(args[n], XtNfromVert, bw); n++;
X! bw = XtCreateManagedWidget("menubutton",commandWidgetClass,layout,args,n);
X /*
X ** If this 'folder' is a directory, add a button popup menu of its files.
X */
X--- 123,133 ----
X sprintf(s, "%s/%s", path, dp->d_name);
X if ((new_dir = opendir(s)) != NULL) {
X sprintf(tmp, "%s/", dp->d_name);
X! XtSetArg(args[4], XtNlabel, tmp);
X } else
X! XtSetArg(args[4], XtNlabel, dp->d_name);
X! XtSetArg(args[5], XtNfromVert, bw);
X! bw = XtCreateManagedWidget("menubutton",commandWidgetClass,layout,args,6);
X /*
X ** If this 'folder' is a directory, add a button popup menu of its files.
X */
X*** ../v1.0/environs.c Sun May 27 21:05:50 1990
X--- environs.c Sun May 27 21:11:35 1990
X***************
X*** 40,46 ****
X {
X static char tmp[BUFSIZ];
X static char buf[BUFSIZ];
X! char *s, *p, *list, *value;
X int i, n;
X FILE *fp;
X
X--- 40,46 ----
X {
X static char tmp[BUFSIZ];
X static char buf[BUFSIZ];
X! char *s, *p, *list, *value, *index();
X int i, n;
X FILE *fp;
X
X***************
X*** 50,55 ****
X--- 50,61 ----
X strcpy(tmp, name);
X /*
X ** If not already done, extract the mail alias list and build the alias table.
X+ **
X+ ** We also provide support for the alias alias group, and the possibility that
X+ ** the user has entered multiple names for an alias without comma separation,
X+ ** or that mail has handed us a list with wierd comma combinations due to the
X+ ** user's attempts to include commas in the list. Support is also provided
X+ ** for processing continuation lines, if we had to read the .mailrc ourselves.
X */
X if (! aliases) {
X if (mailpid)
X***************
X*** 59,66 ****
X list = XtMalloc(i);
X strcpy(list, "");
X if ((fp = fopen(mailrcFile(), "r")) != NULL) {
X! while (s = fgets(buf, BUFSIZ, fp)) {
X! if (strncmp(buf, "alias", 5) == 0) {
X for (s = &buf[5]; *s == ' ' || *s == '\t'; s++);
X if (strlen(list) + strlen(s) > i) {
X i += BUFSIZ;
X--- 65,73 ----
X list = XtMalloc(i);
X strcpy(list, "");
X if ((fp = fopen(mailrcFile(), "r")) != NULL) {
X! s = fgets(buf, BUFSIZ, fp);
X! while (s) {
X! if (strncmp(buf,"alias",5) == 0 || strncmp(buf,"group",5) == 0) {
X for (s = &buf[5]; *s == ' ' || *s == '\t'; s++);
X if (strlen(list) + strlen(s) > i) {
X i += BUFSIZ;
X***************
X*** 68,85 ****
X }
X strcat(list, s);
X }
X }
X fclose(fp);
X }
X }
X for (i = 1, p = list; *p; p++) if (*p == '\n') i++;
X aliases = (AliasRec **) XtMalloc((i + 1) * sizeof(AliasRec *));
X!
X for (n = 0, p = list; n < i && *p; n++, p++) {
X aliases[n] = (AliasRec *) XtMalloc(sizeof(AliasRec));
X for (aliases[n]->name = p; *p && *p != ' ' && *p != '\t'; p++);
X for (*p++ = '\0'; *p && (*p == ' ' || *p == '\t'); p++);
X! for (aliases[n]->alias = p; *p && *p != '\n'; p++);
X if (*p) *p = '\0';
X }
X aliases[n] = (AliasRec *) XtMalloc(sizeof(AliasRec));
X--- 75,128 ----
X }
X strcat(list, s);
X }
X+ if (s[strlen(s) - 2] != '\\') /* if not a continuation line */
X+ s = fgets(buf, BUFSIZ, fp); /* just read the next line */
X+ else { /* resolve continuation lines */
X+ while ((s = fgets(buf,BUFSIZ,fp)) && s[strlen(s)-2] == '\\') {
X+ strcpy(&list[strlen(list) - 2], " ");
X+ for (; *s == ' ' || *s == '\t'; s++);
X+ if (strlen(list) + strlen(s) + 1 > i) {
X+ i += BUFSIZ;
X+ list = XtRealloc(list, i);
X+ }
X+ strcat(list, s);
X+ }
X+ if (s) {
X+ strcpy(&list[strlen(list) - 2], " ");
X+ for (; *s == ' ' || *s == '\t'; s++);
X+ if (strlen(list) + strlen(s) + 1 > i) {
X+ i += BUFSIZ;
X+ list = XtRealloc(list, i);
X+ }
X+ strcat(list, s);
X+ s = fgets(buf, BUFSIZ, fp);
X+ }
X+ }
X }
X fclose(fp);
X }
X }
X+ /*
X+ ** count up the number of aliases in the list and allocate the list size
X+ */
X for (i = 1, p = list; *p; p++) if (*p == '\n') i++;
X aliases = (AliasRec **) XtMalloc((i + 1) * sizeof(AliasRec *));
X! /*
X! ** Copy the pointers for the alias names and values into an array, marking
X! ** the ends of each with a null and separating any multiple values with a
X! ** comma. Ensure there is no trailing comma in the value list.
X! */
X for (n = 0, p = list; n < i && *p; n++, p++) {
X aliases[n] = (AliasRec *) XtMalloc(sizeof(AliasRec));
X+ for (; *p && (*p == ' ' || *p == '\t'); p++);
X for (aliases[n]->name = p; *p && *p != ' ' && *p != '\t'; p++);
X for (*p++ = '\0'; *p && (*p == ' ' || *p == '\t'); p++);
X! for (aliases[n]->alias = p; *p && *p != '\n'; p++) {
X! if ((*p == ' ' || *p == '\t') && *(p+1) && *(p+1) != '\n' &&
X! *(p-1) != *p && *(p-1) != ',') *p = ',';
X! }
X! for (s = p - 1; *s == ',' || *s == ' ' || *s == '\t'; s--);
X! if (*++s == ',' || *s == ' ' || *s == '\t') *s = '\0';
X if (*p) *p = '\0';
X }
X aliases[n] = (AliasRec *) XtMalloc(sizeof(AliasRec));
X***************
X*** 86,95 ****
X aliases[n] = NULL;
X }
X /*
X! ** If name is made up of more than one word, check each word for aliasing.
X */
X if (value = tmp) {
X! if (strchr(tmp, ',') || strchr(tmp, ' ') || strchr(tmp, '\t')) {
X buf[0] = '\0';
X for (p = value; *p;) {
X for (; *p && *p != ',' && *p != ' ' && *p != '\t'; p++);
X--- 129,138 ----
X aliases[n] = NULL;
X }
X /*
X! ** If input is made up of more than one word, check each word for aliasing.
X */
X if (value = tmp) {
X! if (index(tmp, ',') || index(tmp, ' ') || index(tmp, '\t')) {
X buf[0] = '\0';
X for (p = value; *p;) {
X for (; *p && *p != ',' && *p != ' ' && *p != '\t'; p++);
X***************
X*** 127,158 ****
X
X /*
X ** @(#)GetMailEnv() - Get environment value from mail or shell
X */
X char *
X GetMailEnv(item)
X char *item;
X {
X! static char *mailenv;
X! char *s, *c, *value, *getenv();
X char buf[BUFSIZ];
X register int length;
X
X
X value = NULL;
X if (! mailpid) {
X! if (! (value = GetMailrc(item))) {
X! if ((s = getenv(item)) != NULL)
X value = XtNewString(s);
X }
X } else {
X! if (! mailenv)
X! mailenv = QueryMail("set");
X
X! for (s = mailenv; *s && strncmp(s, item, strlen(item)); s++)
X for (; *s && *s != '\n'; s++);
X
X if (! *s) {
X! if (s = getenv(item))
X value = XtNewString(s);
X } else {
X for (; *s && *s != '"' && *s != '\n'; s++);
X--- 170,204 ----
X
X /*
X ** @(#)GetMailEnv() - Get environment value from mail or shell
X+ ** Accomodate the case of trailing blanks on the item.
X */
X char *
X GetMailEnv(item)
X char *item;
X {
X! char *mailenv, *s, *c, *value, *getenv();
X char buf[BUFSIZ];
X register int length;
X
X
X value = NULL;
X+ strcpy(buf, item);
X+ for (length = 0; buf[length] && buf[length] != ' '; length++);
X+ buf[length] = '\0';
X+
X if (! mailpid) {
X! if (! (value = GetMailrc(buf))) {
X! if ((s = getenv(buf)) != NULL)
X value = XtNewString(s);
X }
X } else {
X! mailenv = QueryMail("set");
X
X! for (s = mailenv; *s && strncmp(s, buf, length); s++)
X for (; *s && *s != '\n'; s++);
X
X if (! *s) {
X! if (s = getenv(buf))
X value = XtNewString(s);
X } else {
X for (; *s && *s != '"' && *s != '\n'; s++);
X***************
X*** 166,171 ****
X--- 212,218 ----
X value[length] = '\0';
X }
X }
X+ XtFree(mailenv);
X }
X return(value);
X } /* GetMailEnv */
X***************
X*** 172,202 ****
X
X
X /*
X! ** @(#)mailrcFile() - Return a pointer to fully qualified mailrc file name
X */
X char *
X mailrcFile()
X {
X! char *s, *h, *p, *getenv();
X static char buf[BUFSIZ];
X
X! if ((s = getenv("MAILRC")) == NULL) {
X if ((s = getenv("HOME")) == NULL) s = "";
X sprintf(buf, "%s/.mailrc", s);
X- } else {
X- if (*s == '/' || (*s != '~' && *s != '$')) sprintf(buf, "%s", s);
X- else {
X- if (*s == '~') {
X- if ((h = getenv("HOME")) == NULL) h = "";
X- sprintf(buf, "%s%s", h, &s[1]);
X- } else {
X- for (p = s; *p && (*p == '$' || *p == '{' || *p == '('); p++);
X- for (s = p; *s && *s != '}' && *s != ')'; s++);
X- *s++ = '\0';
X- if ((h = getenv(p)) == NULL) h = "";
X- sprintf(buf, "%s/%s", h, s);
X- }
X- }
X }
X return((char *)buf);
X } /* mailrcFile */
X--- 219,237 ----
X
X
X /*
X! ** @(#)mailrcFile() - Return a path to environment or default .mailrc file
X */
X char *
X mailrcFile()
X {
X! char *s, *getenv();
X static char buf[BUFSIZ];
X
X! if (s = getenv("MAILRC"))
X! (void) strcpy(buf, s);
END_OF_FILE
if test 46474 -ne `wc -c <'Patch.01b'`; then
echo shar: \"'Patch.01b'\" unpacked with wrong size!
fi
# end of 'Patch.01b'
fi
echo shar: End of archive 1 \(of 5\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 5 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list