home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-27 | 57.1 KB | 1,639 lines |
- Newsgroups: comp.sources.x
- From: markham@cadence.com (Jeff Markham)
- Subject: v19i031: xmail - X Window System interface to the mail program, Part06/10
- Message-ID: <1993Mar10.202924.11037@sparky.imd.sterling.com>
- X-Md4-Signature: 4128d6ffa5af6933a1bdecde395edd9e
- Date: Wed, 10 Mar 1993 20:29:24 GMT
- Approved: chris@sparky.imd.sterling.com
-
- Submitted-by: markham@cadence.com (Jeff Markham)
- Posting-number: Volume 19, Issue 31
- Archive-name: xmail/part06
- Environment: X11
- Supersedes: xmail: Volume 15, Issue 18-26
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: Makefile.IBMRT environs.c parser.c
- # Wrapped by chris@sparky on Wed Mar 10 14:17:48 1993
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 6 (of 10)."'
- if test -f 'Makefile.IBMRT' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile.IBMRT'\"
- else
- echo shar: Extracting \"'Makefile.IBMRT'\" \(11852 characters\)
- sed "s/^X//" >'Makefile.IBMRT' <<'END_OF_FILE'
- X# Makefile generated by imake - do not edit!
- X# $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $
- X#
- X# The cpp used on this machine replaces all newlines and multiple tabs and
- X# spaces in a macro expansion with a single space. Imake tries to compensate
- X# for this, but is not always successful.
- X#
- X
- X###########################################################################
- X# Makefile generated from "Imake.tmpl" and <Imakefile>
- X# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
- X#
- X# Platform-specific parameters may be set in the appropriate .cf
- X# configuration files. Site-wide parameters may be set in the file
- X# site.def. Full rebuilds are recommended if any parameters are changed.
- X#
- X# If your C preprocessor doesn't define any unique symbols, you'll need
- X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
- X# "make Makefile", "make Makefiles", or "make World").
- X#
- X# If you absolutely can't get imake to work, you'll need to set the
- X# variables at the top of each Makefile as well as the dependencies at the
- X# bottom (makedepend will do this automatically).
- X#
- X
- X###########################################################################
- X# platform-specific configuration parameters - edit sun.cf to change
- X
- X# platform: $XConsortium: sun.cf,v 1.38 89/12/23 16:10:10 jim Exp $
- X# operating system: SunOS 4.0.3
- X
- X###########################################################################
- X# site-specific configuration parameters - edit site.def to change
- X
- X# site: $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $
- X
- X SHELL = /bin/sh
- X
- X TOP = .
- X CURRENT_DIR = .
- X
- X AR = ar cq
- X BOOTSTRAPCFLAGS =
- X CC = cc
- X
- X COMPRESS = compress
- X CPP = /lib/cpp $(STD_CPP_DEFINES)
- X PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
- X INSTALL = install
- X LD = ld
- X LINT = lint
- X LINTLIBFLAG = -C
- X LINTOPTS = -axz
- X LN = ln -s
- X MAKE = make
- X MV = mv
- X CP = cp
- X RANLIB = ranlib
- X RANLIBINSTFLAGS =
- X RM = rm -f
- X STD_INCLUDES =
- X STD_CPP_DEFINES = -DSYSV -DAIXV3
- X STD_DEFINES = -DSYSV -DAIXV3
- X EXTRA_LOAD_FLAGS = -bnodelcsect
- X EXTRA_LIBRARIES =
- X TAGS = ctags
- X
- X SHAREDCODEDEF = -DSHAREDCODE
- X SHLIBDEF = -DSUNSHLIB
- X
- X PROTO_DEFINES =
- X
- X INSTPGMFLAGS = -s -m 0755
- X
- X INSTBINFLAGS = -m 0755
- X INSTUIDFLAGS = -m 4755
- X INSTLIBFLAGS = -m 0664
- X INSTINCFLAGS = -m 0444
- X INSTMANFLAGS = -m 0444
- X INSTDATFLAGS = -m 0444
- X INSTKMEMFLAGS = -m 4755
- X
- X DESTDIR =
- X
- X TOP_INCLUDES = -I/n/X11/R5/Binaries/include -I$(INCROOT)
- X
- X CDEBUGFLAGS = -g
- X CCOPTIONS =
- X COMPATFLAGS =
- X
- X ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES)
- X ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
- X CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
- X LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
- X LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
- X LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS)
- X LDCOMBINEFLAGS = -X -r
- X
- X MACROFILE = sun.cf
- X RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
- X
- X IMAKE_DEFINES =
- X
- X IRULESRC = $(CONFIGDIR)
- X IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
- X
- X ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
- X $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
- X $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
- X
- X###########################################################################
- X# X Window System Build Parameters
- X# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
- X
- X###########################################################################
- X# X Window System make variables; this need to be coordinated with rules
- X# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
- X
- X PATHSEP = /
- X USRLIBDIR = $(DESTDIR)/usr/lib
- X BINDIR = $(DESTDIR)/usr/bin/X11
- X INCROOT = $(DESTDIR)/usr/include
- X BUILDINCROOT = $(TOP)
- X BUILDINCDIR = $(BUILDINCROOT)/X11
- X BUILDINCTOP = ..
- X INCDIR = $(INCROOT)/X11
- X ADMDIR = $(DESTDIR)/usr/adm
- X LIBDIR = $(USRLIBDIR)/X11
- X CONFIGDIR = $(LIBDIR)/config
- X LINTLIBDIR = $(USRLIBDIR)/lint
- X
- X FONTDIR = $(LIBDIR)/fonts
- X XINITDIR = $(LIBDIR)/xinit
- X XDMDIR = $(LIBDIR)/xdm
- X AWMDIR = $(LIBDIR)/awm
- X TWMDIR = $(LIBDIR)/twm
- X GWMDIR = $(LIBDIR)/gwm
- X MANPATH = $(DESTDIR)/usr/man
- X MANSOURCEPATH = $(MANPATH)/man
- X MANDIR = $(MANSOURCEPATH)n
- X LIBMANDIR = $(MANSOURCEPATH)3
- X XAPPLOADDIR = $(LIBDIR)/app-defaults
- X
- X SOXLIBREV = 4.2
- X SOXTREV = 4.0
- X SOXAWREV = 4.0
- X SOOLDXREV = 4.0
- X SOXMUREV = 4.0
- X SOXEXTREV = 4.0
- X
- X FONTCFLAGS = -t
- X
- X INSTAPPFLAGS = $(INSTDATFLAGS)
- X
- X IMAKE = imake
- X DEPEND = makedepend
- X RGB = rgb
- X FONTC = bdftosnf
- X MKFONTDIR = mkfontdir
- X MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier.sh
- X
- X CONFIGSRC = $(TOP)/config
- X CLIENTSRC = $(TOP)/clients
- X DEMOSRC = $(TOP)/demos
- X LIBSRC = $(TOP)/lib
- X FONTSRC = $(TOP)/fonts
- X INCLUDESRC = $(TOP)/X11
- X SERVERSRC = $(TOP)/server
- X UTILSRC = $(TOP)/util
- X SCRIPTSRC = $(UTILSRC)/scripts
- X EXAMPLESRC = $(TOP)/examples
- X CONTRIBSRC = $(TOP)/../contrib
- X DOCSRC = $(TOP)/doc
- X RGBSRC = $(TOP)/rgb
- X DEPENDSRC = $(UTILSRC)/makedepend
- X IMAKESRC = $(CONFIGSRC)
- X XAUTHSRC = $(LIBSRC)/Xau
- X XLIBSRC = $(LIBSRC)/X
- X XMUSRC = $(LIBSRC)/Xmu
- X TOOLKITSRC = $(LIBSRC)/Xt
- X AWIDGETSRC = $(LIBSRC)/Xaw
- X OLDXLIBSRC = $(LIBSRC)/oldX
- X XDMCPLIBSRC = $(LIBSRC)/Xdmcp
- X BDFTOSNFSRC = $(FONTSRC)/bdftosnf
- X MKFONTDIRSRC = $(FONTSRC)/mkfontdir
- X EXTENSIONSRC = $(TOP)/extensions
- X
- X DEPEXTENSIONLIB = $(USRLIBDIR)/libXext.a
- X EXTENSIONLIB = -lXext
- X
- X DEPXLIB = $(DEPEXTENSIONLIB)
- X XLIB = $(EXTENSIONLIB) -lX11
- X
- X DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
- X XAUTHLIB = -lXau
- X
- X DEPXMULIB =
- X XMULIB = -lXmu
- X
- X DEPOLDXLIB =
- X OLDXLIB = -loldX
- X
- X DEPXTOOLLIB =
- X XTOOLLIB = -lXt
- X
- X DEPXAWLIB =
- X XAWLIB = -lXaw
- X
- X LINTEXTENSIONLIB = $(USRLIBDIR)/llib-lXext.ln
- X LINTXLIB = $(USRLIBDIR)/llib-lX11.ln
- X LINTXMU = $(USRLIBDIR)/llib-lXmu.ln
- X LINTXTOOL = $(USRLIBDIR)/llib-lXt.ln
- X LINTXAW = $(USRLIBDIR)/llib-lXaw.ln
- X
- X DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
- X
- X DEPLIBS1 = $(DEPLIBS)
- X DEPLIBS2 = $(DEPLIBS)
- X DEPLIBS3 = $(DEPLIBS)
- X
- X USRINCDIR = $(DESTDIR)/usr/include
- X TESTSRC = $(TOP)/tests
- X MTOOLKITSRC = $(LIBSRC)/Xt
- X MWIDGETSRC = $(LIBSRC)/Xm
- X MRESOURCESRC = $(LIBSRC)/Mrm
- X UILSRC = $(CLIENTSRC)/uil
- X UIL = $(UILSRC)/uil
- X XMTOOLLIB = $(MTOOLKITSRC)/libXt.a
- X XMLIB = $(MWIDGETSRC)/libXm.a
- X MRESOURCELIB = $(MRESOURCESRC)/libMrm.a
- X UILLIB = $(UILSRC)/libUil.a
- X LINTMRESOURCE = $(MRESOURCESRC)/libMrm.a
- XLINTXMWIDGETLIB = $(MWIDGETSRC)/llib-l/Xm.ln
- X LINTXMTOOL = $(MTOOLKITSRC)/llib-lXt.ln
- X LINTUILLIB = $(UILSRC)/llib-lUil.ln
- X SYSLIBS = -lXt -lX11
- X MWM_DEFINES = -DSHAPE -DOPAQUE -DSTRINGS_ALIGNED -D_NO_PROTO -DNO_REGEX
- X
- X###########################################################################
- X# Imake rules for building libraries, programs, scripts, and data files
- X# rules: $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $
- X
- X###########################################################################
- X# start of Imakefile
- X
- X#
- X# @(#)Imakefile - for xmail version 1 patchlevel 5
- X#
- X# Uncomment USE_DIRENT if readdir() uses <dirent.h> instead of <sys/dir.h>
- X#
- X USE_DIRENT = -DUSE_DIRENT
- X#
- X# Uncomment X_FACE and COMPFACE if you have the compface library installed
- X# and you want xmail to automatically display the X-Face: header, if found
- X# in a message.
- X#
- X X_FACE = -DX_FACE
- X COMPFACE = -lcompface
- X#
- X# Uncomment XPM if you have the Xpm version 3 library and want color icons
- X#
- X XPM = -DXPM
- X LIBXPM = -lXpm
- X#
- X# Uncomment LPT if you require att environment support for pseudo ports.
- X#
- X# LPT = -lpt
- X#
- X# Uncomment REGEXP if your system supplies the regexp.h include file.
- X# Otherwise, xmail will use the regex procedures re_comp and re_exec.
- X#
- X# REGEXP = -DUSE_REGEXP
- X#
- X# Define MAILBOX_DIRECTORY if your mail spool is located in other than the
- X# default /usr/spool/mail. (If not specified, the default will be used.)
- X#
- X# MAILBOX_DIR = -DMAILBOX_DIRECTORY=\"/usr/spool/mail\"
- X#
- X# Define DEFAULT_VISUAL if your copy of vi lies in some place other than
- X# /usr/ucb. (If not specified, /usr/ucb/vi will be the default editor.)
- X#
- X# DEF_VISUAL = -DDEFAULT_VISUAL=\"/usr/ucb/vi\"
- X#
- X# Define DEFAULT_MAILER if your mail program is not the standard
- X# /usr/ucb/Mail. CAUTION - Operation is NOT guaranteed with other mailers.
- X#
- X# DEF_MAILER = -DDEFAULT_MAILER=\"/usr/ucb/Mail\"
- X#
- X# Define SIGACTION if your system utilizes the sigaction() call rather
- X# than the sigvec() call (true on most SYSV and POSIX compilant systems)
- X# You may also need to add the following BSD define (true on SGI systems)
- X#
- X# SIGDEF = -D_BSD_SIGNALS
- X#
- X# SIGACT = -DSIGACTION
- X#
- X
- X XMAIL_DEFINES = $(MAILBOX_DIR) $(DEF_VISUAL) $(DEF_MAILER) $(SIGACT) $(SIGDEF)
- X DEFINES = $(USE_DIRENT) $(X_FACE) $(XPM) $(REGEXP) $(XMAIL_DEFINES)
- X
- X DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
- XLOCAL_LIBRARIES = -L/n/X11/R5/Binaries/lib/ibmrt $(LIBXPM) -L/n/X11/R5/Binaries/lib/ibmrt $(XAWLIB) -L/n/X11/R5/Binaries/lib/ibmrt $(XMULIB) -L/n/X11/R5/Binaries/lib/ibmrt $(XTOOLLIB) -L/n/X11/R5/Binaries/lib/ibmrt $(XLIB) -L/n/X11/R5/Binaries/lib/ibmrt $(COMPFACE) $(LPT)
- X
- X SRCS = Mailwatch.c HelpText.c actions.c callMail.c callbacks.c \
- X confirm.c directory.c environs.c handler.c mail.c parser.c \
- X utils.c windows.c xmail.c
- X
- X OBJS = Mailwatch.o HelpText.o actions.o callMail.o callbacks.o \
- X confirm.o directory.o environs.o handler.o mail.o parser.o \
- X utils.o windows.o xmail.o
- X
- X PROGRAM = xmail
- X
- Xall:: xmail
- X
- Xxmail: $(OBJS) $(DEPLIBS)
- X $(RM) $@
- X $(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
- X
- Xinstall:: xmail
- X $(INSTALL) -c $(INSTPGMFLAGS) xmail $(BINDIR)
- X
- Xinstall.man:: xmail.man
- X $(INSTALL) -c $(INSTMANFLAGS) xmail.man $(MANDIR)/xmail.n
- X
- Xdepend::
- X $(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
- X
- Xlint:
- X $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
- Xlint1:
- X $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
- X
- Xclean::
- X $(RM) $(PROGRAM)
- X
- Xinstall:: XMail.ad
- X $(INSTALL) -c $(INSTAPPFLAGS) XMail.ad $(XAPPLOADDIR)/XMail
- X
- X###########################################################################
- X# common rules for all Makefiles - do not edit
- X
- Xemptyrule::
- X
- Xclean::
- X $(RM_CMD) \#*
- X
- XMakefile::
- X -@if [ -f Makefile ]; then \
- X echo " $(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
- X $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
- X else exit 0; fi
- X $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
- X
- Xtags::
- X $(TAGS) -w *.[ch]
- X $(TAGS) -xw *.[ch] > TAGS
- X
- X###########################################################################
- X# empty rules for directories that do not have SUBDIRS - do not edit
- X
- Xinstall::
- X @echo "install in $(CURRENT_DIR) done"
- X
- Xinstall.man::
- X @echo "install.man in $(CURRENT_DIR) done"
- X
- XMakefiles::
- X
- Xincludes::
- X
- X###########################################################################
- X# dependencies generated by makedepend
- X
- END_OF_FILE
- if test 11852 -ne `wc -c <'Makefile.IBMRT'`; then
- echo shar: \"'Makefile.IBMRT'\" unpacked with wrong size!
- fi
- # end of 'Makefile.IBMRT'
- fi
- if test -f 'environs.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'environs.c'\"
- else
- echo shar: Extracting \"'environs.c'\" \(18935 characters\)
- sed "s/^X//" >'environs.c' <<'END_OF_FILE'
- X/*
- X * xmail - X window system interface to the mail program
- X *
- X * Copyright 1990,1991,1992 by National Semiconductor Corporation
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose is hereby granted without fee, provided that
- X * the above copyright notice appear in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation, and that the name of National Semiconductor Corporation not
- X * be used in advertising or publicity pertaining to distribution of the
- X * software without specific, written prior permission.
- X *
- X * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
- X * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS"
- X * WITHOUT EXPRESS OR IMPLIED WARRANTY. NATIONAL SEMICONDUCTOR CORPORATION
- X * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO
- X * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
- X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- X * PERFORMANCE OF THIS SOFTWARE.
- X *
- X * Author: Michael C. Wagnitz - National Semiconductor Corporation
- X *
- X */
- X#include "global.h"
- X
- Xextern char *mailrcFile();
- XString list = NULL; /* list of aliases */
- Xint list_length; /* size of alias list */
- X
- X
- X
- Xalias_compare(a1, a2)
- XAliasRec **a1, **a2;
- X{
- X return(strcmp((*a1)->name, (*a2)->name));
- X}
- X
- X
- X/*
- X** @(#)addtobuf() - add text to recipient or file and folder names buffer
- X** drop any leading backslash from a recipient name
- X*/
- Xvoid
- Xaddtobuf(text, buffer, otherBuffer)
- Xchar *text;
- Xchar *buffer;
- Xchar *otherBuffer;
- X{
- X int current_line_length;
- X char *last_line;
- X
- X
- X if (strchr("./+|", *text) != NULL) {
- X if (*otherBuffer)
- X (void) strcat(otherBuffer, ",");
- X (void) strcat(otherBuffer, text);
- X } else {
- X if (*buffer) (void) strcat(buffer, ", ");
- X if (last_line = strrchr(buffer, '\t')) last_line++;
- X else last_line = buffer;
- X current_line_length = strlen(last_line);
- X if (current_line_length && current_line_length + strlen(text) > 71) {
- X (void) strcat(buffer, "\n\t"); /* make it a continuation of header */
- X }
- X (void) strcat(buffer, (*text == '\\') ? &text[1] : text);
- X }
- X} /* addtobuf */
- X
- X
- X/*
- X** @(#) de_alias() - move (possibly) comma separated aliases into buffers
- X*/
- Xvoid
- Xde_alias(text, buffer, otherBuffer)
- Xchar *text;
- Xchar *buffer;
- Xchar *otherBuffer;
- X{
- X char *cp, *next_alias, buf[BUFSIZ];
- X
- X
- X if (strchr(text, ',') == NULL)
- X addtobuf(text, buffer, otherBuffer);
- X else {
- X (void) strncpy(buf, text, BUFSIZ);
- X for (next_alias = buf; *next_alias; next_alias = cp) {
- X if (cp = strchr(next_alias, ',')) *cp++ = '\0';
- X else cp = next_alias + strlen(next_alias);
- X addtobuf(next_alias, buffer, otherBuffer);
- X }
- X }
- X} /* de_alias */
- X
- X
- X/*
- X** @(#)alias() - return alias value(s) from mail, or name if no alias found
- X*/
- Xchar *
- Xalias(name)
- Xchar *name;
- X{
- X int i, n, testing_for_compound_address;
- X char tmp[BUFSIZ], buf[BUFSIZ];
- X String ep, s, p, value;
- X
- X
- X tmp[0] = '\0';
- X if (name)
- X (void) strncpy(tmp, name, BUFSIZ);
- X/*
- X** If not already done, extract the mail alias list and build the alias table.
- X** Provide support for the possibility of multiple names for an alias with or
- X** without comma separations.
- X*/
- X if (! aliases) {
- X if (mailpid) list = XtNewString(QueryMail("alias"));
- X else if (! (list = XtNewString(GetMailrc("alias")))) {
- X list = (String) XtMalloc((unsigned) 2);
- X list[0] = '\0';
- X }
- X/*
- X** count up the number of aliases in the list and allocate the list size
- X*/
- X ep = &list[strlen(list)];
- X for (i = 1, p = list; p < ep; p++) if (*p == '\n') i++;
- X aliases = (AliasRec **) XtMalloc((unsigned) (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 < ep; n++, p++) {
- X aliases[n] = (AliasRec *) XtMalloc((unsigned) 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 && strchr(" \t\"\'", *p); p++);
- X testing_for_compound_address = True;
- X for (aliases[n]->alias = p; *p && *p != '\n'; p++) {
- X/*
- X** If it contains a chevron, parenthesis, or pipe symbol, then just treat
- X** the whole line as one alias entry.
- X*/
- X if (*p == '|') {
- X if (s = strchr(p, '\n'))
- X p = s;
- X else p += strlen(p);
- X break;
- X }
- X if (testing_for_compound_address) {
- X if ((s = strchr(p, '<')) || (s = strchr(p, '('))) {
- X if (value = strchr(p, '\n')) { /* could be more than one */
- X if (s < value) { /* if its within this alias */
- X p = value; /* point to end of this alias */
- X if (*(p - 1) == '"' || /* could be true (no mailpid) */
- X *(p - 1) == '\'')
- X *(p - 1) = '\0';
- X break;
- X } else {
- X if (*s == '<' && (s = strchr(p, '(')) && s < value) {
- X p = value; /* point to end of this alias */
- X if (*(p - 1) == '"' || /* possibly not in mail */
- X *(p - 1) == '\'')
- X *(p - 1) = '\0';
- X break;
- X } else testing_for_compound_address = False;
- X }
- X } else { /* last entry of this record */
- X p += strlen(p); /* point to the end of line */
- X break;
- X }
- X } else testing_for_compound_address = False;
- X } /* end - if testing_for_compound_address */
- X if ((*p == ' ' || *p == '\t') && *(p+1) && *(p+1) != '\n' &&
- X *(p-1) != *p && *(p-1) != ',') *p = ',';
- X }
- X for (s = p - 1; strchr(", \t", *s); s--);
- X if (strchr(", \t", *++s)) *s = '\0';
- X if (*p) *p = '\0';
- X }
- X aliases[n] = NULL;
- X
- X if (n)
- X qsort((char *)aliases, n, sizeof(char *), alias_compare);
- X } /* end - if no alias list */
- X/*
- X** In deference to those who didn't install the app-defaults file, accept a
- X** newline character as a word separator as well as the comma normally found.
- X** If input is made up of more than one word, check each word for aliasing.
- X** If it contains a chevron or parenthesis, it is a 'compound' address type.
- X** If line length approaches 80 characters, add a newline-tab and continue.
- X*/
- X if (*(value = tmp)) {
- X buf[0] = '\0';
- X for (p = value; *p;) { /* 'value' points to current 'word' */
- X for (s = p; *s && strchr(", \t\n", *s) == NULL; s++);
- X if (*s) {
- X /*
- X ** First, check for case of possible compound address.
- X ** Could be a form of either: "(user[ ]name) [<]addr[>]",
- X ** "<addr> [(]user name[)]",
- X ** or "[<]addr[>] (user name)".
- X ** If any of these, skip to end of that address/name.
- X */
- X if (strchr(" \t", *s)) {
- X if (*value == '(') {
- X s = strchr(value, ')');
- X if (*s) { /* if form is '(user) addr', skip to */
- X for (s++; *s && strchr(" \t", *s); s++); /* start of addr */
- X for (; *s && ! strchr(", \t\n", *s); s++); /* then to end */
- X }
- X } else if (*value == '<') {
- X s = strchr(value, '>');
- X if (*s) {
- X /*
- X ** if form is '<addr> [(]user[)]', skip to end of user str
- X */
- X for (s++; *s && strchr(" \t", *s); s++);
- X for (; *s && ! strchr(",\t\n", *s); s++);
- X }
- X } else { /* 'addr (usr)|usr <addr>'? find end */
- X for (; *s && strchr(" \t", *s); s++);
- X if (! strchr("(<", *s)) s--; /* NOT one of these, back up */
- X else {
- X if (*s == '<')
- X s = strchr(s, '>'); /* find end of <address> or */
- X else
- X s = strchr(s, ')'); /* find end of (user name) */
- X if (s && *s) s++;
- X }
- X }
- X }
- X if (s) *s++ = '\0';
- X p = s;
- X } else p = &value[strlen(value)];
- X
- X for (n = 0; aliases[n]; n++) {
- X if (strcmp(value, aliases[n]->name) == 0) {
- X de_alias(aliases[n]->alias, buf, otherBuf);
- X break;
- X }
- X }
- X
- X if (! aliases[n]) /* If not an alias, use the name supplied. */
- X de_alias(value, buf, otherBuf);
- X
- X for (; *p && strchr(", \t\n", *p); p++);
- X value = p;
- X }
- X value = buf;
- X }
- X return ((char *)value);
- X} /* alias */
- X
- X/*
- X** @(#)GetMailEnv() - Get environment value from mail or shell
- X** Accommodate the case of trailing blanks on the item.
- X** Expand environment variables.
- X*/
- Xchar *
- XGetMailEnv(item)
- XString item;
- X{
- X int length;
- X String ep, mailenv, s, c, value, getenv();
- X char buf[BUFSIZ];
- X
- X
- X value = NULL;
- X (void) 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 ep = &mailenv[strlen(mailenv)];
- X for (s = mailenv; s < ep && strncmp(s, buf, length) != 0; s++)
- X for (; s < ep && *s != '\n'; s++);
- X
- X if (! *s) {
- X if (s = getenv(buf))
- X value = XtNewString(s);
- X } else {
- X /*
- X ** Try to accomodate Berkeley mail (versus SunOS) whose ``set''
- X ** command returns a sorted list with no equal sign between the
- X ** item and its value.
- X */
- X if (c = strchr(s, '\n')) *c = '\0';
- X c = &s[strlen(buf)]; /* point just past the item */
- X if (*c != '=') { /* We're NOT running Sunmail */
- X for (;(*c == ' ' || *c == '\t'); c++);
- X if (! *c)
- X value = XtNewString("True"); /* use boolean if no value */
- X else {
- X if (! (ep = strchr(c+1, '"')) && ! (ep = strchr(c+1, "'"[0])))
- X value = XtNewString(c); /* most things will be okay */
- X else { /* if value is fully quoted */
- X c++;
- X *ep = '\0';
- X value = XtNewString(c);
- X }
- X }
- X } else { /* We're are running Sunmail */
- X if (! (c = strchr(s, '"'))) c = strchr(s, "'"[0]);
- X s = c;
- X if (! s) /* variable is flag only, no value */
- X value = XtNewString("True"); /* use boolean if no value */
- X else {
- X for (c = ++s; *c && *c != *(s - 1); c++);
- X length = c - s;
- X value = (String) XtMalloc((unsigned) length + 1);
- X (void) strncpy(value, s, length);
- X value[length] = '\0';
- X }
- X }
- X }
- X }
- X /*
- X * Expand shell variables in value
- X */
- X if (value) {
- X String v, e, nvalue;
- X
- X while (s = strchr(value, '$')) {
- X for (c = s + 1; *c && !strchr(" \t\n$/\"\'", *c); c++);
- X length = c - s - 1;
- X (void) strncpy(buf, s + 1, length);
- X buf[length] = '\0';
- X if (*buf == '{') { /* if variable is braced... */
- X for (v = buf, e = buf + 1; *e && *e != '}';) *v++ = *e++;
- X *v = '\0';
- X }
- X if (!(e = getenv(buf)))
- X e = "";
- X if (nvalue = (String) XtMalloc((unsigned) strlen(value) - length + strlen(e) + 2)) {
- X for (c = nvalue, v = value; v != s;) *c++ = *v++;
- X for (s = e; *s;) *c++ = *s++;
- X for (v += length + 1; *v;) *c++ = *v++;
- X *c = '\0';
- X XtFree((String) value);
- X value = nvalue;
- X }
- X }
- X }
- X return(value);
- X} /* GetMailEnv */
- X
- X
- X/*
- X** @(#)mailrcFile() - Return a path to environment or default .mailrc file
- X*/
- Xchar *
- XmailrcFile()
- X{
- X char *s, *getenv();
- X char buf[BUFSIZ];
- X
- X if (s = getenv("MAILRC"))
- X (void) strcpy(buf, s);
- X else
- X (void) sprintf(buf, "%s/.mailrc", HOME);
- X
- X return((char *)buf);
- X} /* mailrcFile */
- X
- X
- X/*
- X** @(#)add_to_list - save buffer of aliases in the global alias list
- X*/
- Xvoid
- Xadd_to_list(s)
- XString s;
- X{
- X if (! list) {
- X list_length = BUFSIZ;
- X list = (String) XtMalloc((unsigned) list_length);
- X list[0] = '\0';
- X }
- X
- X for (; *s == ' ' || *s == '\t'; s++); /* skip leading whitespace */
- X if (strlen(list) + strlen(s) + 1 >= list_length) {
- X list_length += BUFSIZ;
- X list = (String) XtRealloc(list, list_length);
- X }
- X (void) strcat(list, s); /* append the entire line */
- X} /* end - add_to_list */
- X
- X
- X/*
- X** @(#)get_mailrc - item and return it's value
- X** Handle continuation lines, source of additional files, more
- X** than one occurance of the item, and aliases/groups.
- X*/
- Xint
- Xget_mailrc(item, value, filename)
- Xchar *item;
- Xchar **value;
- Xchar *filename;
- X{
- X int unset, n, status = 0;
- X int negated = strncmp(item, "no", 2) == 0 ? 1 : 0;
- X int size = strlen(item) - 2 * negated;
- X int we_want_aliases = (strcmp(item, "alias") == 0);
- X String c, d, getenv(), s = NULL;
- X char e[1], tmp[BUFSIZ], buf[BUFSIZ];
- X FILE *fp = NULL;
- X
- X
- X if ((fp = fopen(filename, "r")) != NULL) {
- X s = fgets(buf, BUFSIZ, fp);
- X while (s) {
- X if (strncmp(buf, "source", 6) == 0) {
- X bcopy(buf + 7, buf, strlen(buf) - 6);
- X LASTCH(buf) = '\0'; /* drop the newline character */
- X if (buf[0] == '$' || (buf[0] == '~' && buf[1] == '/')) {
- X for (unset = 0, n = 1; buf[n] && buf[n] != '/'; n++)
- X if (! strchr("{()}", buf[n]))
- X tmp[unset++] = buf[n];
- X tmp[unset] = '\0';
- X if (tmp[0])
- X d = getenv(tmp);
- X else
- X d = HOME;
- X (void) sprintf(tmp, "%s%s", d, &buf[n]);
- X (void) strcpy(buf, tmp);
- X }
- X if ((status = get_mailrc(item, &s, buf))) {
- X if (we_want_aliases) *value = list;
- X else {
- X XtFree((String) *value);
- X *value = s;
- X }
- X } /* end - if something was found in another source */
- X } else {
- X if (we_want_aliases) {
- X if (strncmp(buf,"alias",5) == 0 || strncmp(buf,"group",5) == 0) {
- X status = 1; /* we have found at least one alias */
- X add_to_list(&buf[5]);
- X if (buf[strlen(buf) - 2] == '\\') { /* alias is continued */
- X list[strlen(list) - 2] = '\0'; /* drop the "\\n" */
- X while (s = fgets(buf, BUFSIZ, fp)) {
- X if (strlen(s) > 1 && s[strlen(s) - 2] == '\\') {
- X (void) strcpy(&buf[strlen(buf) - 2], " "); /* drop "\\n" */
- X add_to_list(s); /* add continuations */
- X } else break;
- X }
- X if (s) add_to_list(s); /* don't forget the last line */
- X } /* end - if this is a continued alias definition line */
- X } /* end - if we found a match */
- X *value = list;
- X } else { /* I'm looking for 'set' or 'unset' records */
- X if (! (strncmp(buf, "set", 3) && strncmp(buf, "unset", 5))) {
- X unset = (buf[0] == 'u')? 1:0; /* find out which one matched */
- X s = &buf[(unset?5:3)]; /* starting just beyond 'set' */
- X while (*s) { /* could be multiple assigns */
- X for (; *s && strchr(" \t\\\n", *s); s++); /* next word */
- X if (*s) {
- X if ((strncmp(s, item, size) != 0) && (!unset ||
- X !negated || strncmp(s, &item[2], size) != 0))
- X for (;*s&&!strchr(" \t\\\n",*s);s++); /* skip item */
- X else {
- X status = 1; /* we have at least one match */
- X s = s + size; /* look for a value to it */
- X if (*s++ != '=') { /* variable only, no value */
- X XtFree((String) *value);
- X *value = (unset && ! negated)? NULL: XtNewString("True");
- X } else {
- X if (*s == '"' || *s == "'"[0]) /* if quoted */
- X for (c = s + 1; *c && *c != *s; c++);
- X else
- X for (c = s--; *c && !strchr(" \t\\\n", *c); c++);
- X e[0] = *c; /* save the current character */
- X *c = '\0'; /* mark the end of the value */
- X d = c + 1; /* save point after value */
- X c = s + 1; /* point to start of value */
- X XtFree((String) *value); /* toss any previous */
- X *value = XtNewString(c); /* keep latest value */
- X s = d--; /* look for any more matches */
- X *d = e[0]; /* restore saved character */
- X } /* end - if boolean variable or valued item */
- X } /* end - we have a match */
- X } /* end - if some word(s) still exist on the line */
- X if (! *s && buf[strlen(buf) - 2] == '\\') /* if continued */
- X s = fgets(buf, BUFSIZ, fp); /* then keep looking */
- X } /* end - while examining this set|unset record */
- X } /* end - if we have a set|unset record */
- X } /* end - looking for alias or set/unset records */
- X } /* end - if not a ``source'' record */
- X s = fgets(buf, BUFSIZ, fp); /* now read the next line of the file */
- X } /* end - while something to read in the mailrc file */
- X (void) fclose(fp);
- X }
- X return(status);
- X}
- X/* end - get_mailrc */
- X
- X
- X/*
- X** @(#)GetMailrc() - Get mail environment variable value from the mailrc file
- X** Added support for source'd files within the .mailrc file
- X*/
- Xchar *
- XGetMailrc(item)
- Xchar *item;
- X{
- X char *s = NULL;
- X
- X (void) get_mailrc(item, &s, mailrcFile());
- X
- X return((char *)s);
- X} /* GetMailrc */
- END_OF_FILE
- if test 18935 -ne `wc -c <'environs.c'`; then
- echo shar: \"'environs.c'\" unpacked with wrong size!
- fi
- # end of 'environs.c'
- fi
- if test -f 'parser.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'parser.c'\"
- else
- echo shar: Extracting \"'parser.c'\" \(23345 characters\)
- sed "s/^X//" >'parser.c' <<'END_OF_FILE'
- X/*
- X * xmail - X window system interface to the mail program
- X *
- X * Copyright 1990,1991,1992 by National Semiconductor Corporation
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose is hereby granted without fee, provided that
- X * the above copyright notice appear in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation, and that the name of National Semiconductor Corporation not
- X * be used in advertising or publicity pertaining to distribution of the
- X * software without specific, written prior permission.
- X *
- X * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
- X * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS"
- X * WITHOUT EXPRESS OR IMPLIED WARRANTY. NATIONAL SEMICONDUCTOR CORPORATION
- X * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO
- X * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
- X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- X * PERFORMANCE OF THIS SOFTWARE.
- X *
- X * Author: Michael C. Wagnitz - National Semiconductor Corporation
- X *
- X *
- X * The following software modules were created and are Copyrighted by
- X * National Semiconductor Corporation:
- X *
- X * 1. regerr:
- X * 2. compile_pattern:
- X * 3. match: and
- X * 4. update_times.
- X *
- X * Author: Michael C. Wagnitz - National Semiconductor Corporation
- X *
- X */
- X
- X#define PARSER
- X
- X#include "global.h"
- X#include "xmailregexp.h"
- X#include <ctype.h>
- X#include <utime.h>
- X#include "MailwatchP.h"
- X
- Xextern void reset_mailbox();
- Xstatic char MailPrompt[80]; /* overkill on size, but to be safe */
- X
- X#if defined(USE_REGEXP)
- X#define INIT register char *sp=instring; int sed=1;
- X#define GETC() (*sp++)
- X#define PEEKC() (*sp)
- X#define UNGETC(c) (--sp)
- X#define RETURN(c) return
- X#define ERROR(c) regerr(c)
- X
- X#include <regexp.h>
- X
- Xint regexp_indx;
- X
- Xstatic char *regexp_error[] = {
- X "","","","","","","","","","","",
- X /* 11 */ "Range endpoint too large", "","","","",
- X /* 16 */ "Bad number", "","","","","","","","",
- X /* 25 */ "``\\digit'' out of range", "","","","","","","","","","",
- X /* 36 */ "Illegal or missing delimiter", "","","","",
- X /* 41 */ "No remembered search string",
- X /* 42 */ "\\(\\) imbalance",
- X /* 43 */ "Too many \\(",
- X /* 44 */ "More than 2 numbers given in \\{\\}",
- X /* 45 */ "} expected after \\",
- X /* 46 */ "First number exceeds second in \\{\\}", "", "",
- X /* 49 */ "[] imbalance",
- X /* 50 */ "Regular expression too long",
- X NULL
- X};
- X
- X
- Xregerr(c)
- Xint c;
- X{
- X (void) fprintf(stderr, "xmail: %s (item %d).\n", regexp_error[c], regexp_indx);
- X exit(0);
- X}
- X
- X
- X/*
- X** @(#)compile_pattern() - compile regular expression patterns in a table.
- X** A pattern table is an array of pattern records. Each pattern record
- X** consists of a regular expression, and a buffer for the compiled expression.
- X*/
- Xvoid
- Xcompile_pattern(patternTable)
- XPatternRecPtr patternTable;
- X{
- X String bp;
- X PatternRecPtr cp;
- X
- X
- X for (regexp_indx=0, cp=patternTable; cp->pat||cp->buf; regexp_indx++, cp++) {
- X if (! cp->pat) continue; /* skip over grouping separations */
- X bp = (String) XtMalloc((unsigned) BUFSIZ);
- X (void) compile(cp->pat, bp, &bp[BUFSIZ], '\0');
- X cp->buf = bp;
- X }
- X}
- X#endif
- X
- X
- X/*
- X** @(#)match() - string against regular expressions in pattern table.
- X*/
- Xint
- Xmatch(patternTable, string)
- XPatternRecPtr patternTable;
- Xchar *string;
- X{
- X PatternRecPtr cp;
- X char *bp;
- X int n, id;
- X
- X
- X if (strcmp(string, "") == 0) return -1;
- X
- X for (id = 0, cp = patternTable; cp->pat || cp->buf; cp++) {
- X if (! cp->pat) { id++; continue; }
- X
- X#if defined(USE_REGEXP)
- X if (advance(string, cp->buf))
- X return (id);
- X#else
- X if (bp = (char *)re_comp(cp->pat)) {
- X (void) fprintf(stderr, "xmail: re_comp: %s\n", bp);
- X return -1;
- X } else {
- X if ((n = re_exec(string)) == 1)
- X return (id);
- X else if (n < 0) {
- X (void) fprintf(stderr, "xmail: re_exec: internal error\n");
- X return -1;
- X }
- X }
- X#endif
- X }
- X return (-1);
- X}
- X
- X
- X/*
- X** @(#)parser_init()- compile command and output pattern tables.
- X*/
- Xvoid
- Xparser_init()
- X{
- X#if defined(USE_REGEXP)
- X (void) compile_pattern(command_pattern);
- X (void) compile_pattern(output_pattern);
- X#else
- X ;
- X#endif
- X}
- X
- X/*
- X** @(#)update_times - update previous folder's timestamps, so SetNewness()
- X** will restore no unread message flag for that folder.
- X*/
- Xstatic
- Xupdate_times()
- X{
- X MailwatchWidget mb = (MailwatchWidget) XtNameToWidget(toplevel,"icon.mailbox");
- X char *p, *q, tmp[BUFSIZ];
- X
- X/*
- X** we need to strip the foldername from the previous title-bar contents
- X*/
- X p = strrchr(lastFolder, '"');
- X q = strchr(lastFolder, '"');
- X if (p && q && p != q) {
- X *p = '\0';
- X if (strcmp(++q, mb->mailbox.filename) != 0) { /* not system folder */
- X if (*q == '+') { /* the majority of the times */
- X initfoldir();
- X (void) sprintf(tmp, "%s%s", foldir, ++q);
- X q = tmp;
- X }
- X (void) utime(q, (struct utimbuf *) 0);
- X }
- X }
- X
- X} /* end - update_times */
- X
- X
- X/*
- X** @(#)Reissue_Is_Valid - true/false reissue of Copy/Save to author was valid
- X*/
- Xint
- XReissue_Is_Valid()
- X{
- X int n;
- X String p, h, strchr(), strrchr();
- X char buf[BUFSIZ], tmp[BUFSIZ];
- X
- X
- X if (Command[0] != 'C' && Command[0] != 'S')
- X return(False);
- X
- X SetCursor(WATCH);
- X if (1 == sscanf(Command, "%*s %d", &n)) {
- X Command[0] = (Command[0] == 'C' ? 'c' : 's');
- X LASTCH(Command) = ' ';
- X } else {
- X n = SelectionNumber(False);
- X sprintf(buf, "%c %d ", Command[0] == 'C' ? 'c' : 's', n);
- X (void) strcpy(Command, buf);
- X }
- X
- X (void) sprintf(buf, "f %d", n);
- X p = QueryMail(buf);
- X
- X buf[0] = '\0';
- X if (1 != sscanf(p, "> %*d %s", buf))
- X (void) sscanf(p, " %*d %s", buf);
- X
- X if (strchr(buf, '<')) {
- X if (! sscanf(buf, "%*[^<]<%[^>]>", tmp))
- X (void) sscanf(buf, "<%[^>]>", tmp);
- X (void) strcpy(buf, tmp);
- X } else
- X if (strchr(buf, '(')) {
- X for (h = buf; *h && strchr(" \t", *h); h++);
- X if (1 != sscanf(h, "%*[^)]) %s", tmp))
- X (void) sscanf(h, "%s", tmp);
- X (void) strcpy(buf, tmp);
- X }
- X if (strlen(buf)) {
- X if (h = strrchr(buf, '!')) /* UUCP - host![host!]user[@host]... */
- X bcopy(h + 1, buf, strlen(h));
- X
- X if (h = strchr(buf, '@')) { /* ARPA address - user[%host]@host */
- X *h = '\0';
- X if (h = strchr(buf, '%'))
- X *h = '\0';
- X if (h = strrchr(buf, ':')) /* DECNet form - host::user%host@host */
- X bcopy(h + 1, buf, strlen(h));
- X if (strchr("'\"", buf[0])) /* or - ["']user[@host]["']%host@host */
- X bcopy(buf + 1, buf, strlen(buf));
- X }
- X }
- X
- X if (h = GetMailEnv("outfolder")) {
- X XtFree((String) h);
- X (void) strcat(Command, "+");
- X }
- X (void) strcat(Command, buf);
- X (void) strcat(Command, "\n");
- X writeMail(Command);
- X return (True);
- X} /* end - Reissue_Is_Valid */
- X
- X
- X/*
- X** @(#)parse() - command and output and call appropriate handler
- X*/
- Xvoid
- Xparse(msg)
- XString msg;
- X{
- X static Boolean first_time = True;
- X int j, k, msgnum;
- X String c, s;
- X char tmp[128];
- X Widget button, icon, iw;
- X
- X
- X j = match(command_pattern, Command);
- X switch (j) {
- X /*
- X ** If error on startup, mail has terminated connection. Remove our input
- X ** handler, close the file from our end, and indicate that no connection
- X ** exists. Otherwise, establish conversation requirements and display the
- X ** current message. If *Show_Last: resource is NOT False, show latest, if
- X ** none are newer. We delay setting the icon event handler until now, to
- X ** ensure mail startup completed before being interrupted by a map event,
- X ** for the case where we have been started iconic.
- X */
- X case XM_C_START : /*
- X ** test to ensure we are not running binmail by mistake
- X */
- X if ((strlen(msg) >= 17) &&
- X (! strcmp("unknown option N\n", &msg[strlen(msg)-17]))) {
- X Bell(msg);
- X XCloseDisplay(XtDisplay(toplevel));
- X (void) fprintf(stderr,
- X "\007xmail: The specified (or default) mail handler is not supported.\n");
- X _exit(0);
- X }
- X
- X if (XM_O_BELL == match(output_pattern, msg)) {
- X if (mailpid) {
- X XtRemoveInput(mailInputId);
- X (void) close(mail_fd);
- X mailpid = 0;
- X MailPrompt[0] = '\0';
- X }
- X
- X if (strncmp(msg, "No mail for ", 12) == 0)
- X Bell("No mail in your system mailbox\n");
- X else Bell(msg);
- X (void) UpdateTitleBar("No current folder");
- X *msg = '\0';
- X } else {
- X /*
- X ** To prevent a race condition (?) when starting the
- X ** application iconic, (which would cause this loop to
- X ** repeat multiple times), test the value of the mail
- X ** environment variable ``screen''. If its value is
- X ** 10,000 then we're done.
- X */
- X if (c = GetMailEnv("screen")) {
- X j = (strcmp("10000", c) != 0) ? True : False;
- X XtFree((String) c);
- X } else j = True;
- X
- X if (j) { /* if not yet set to 10000... */
- X (void) strcpy(tmp, "set screen=10000 toplines=100 ");
- X
- X /* default action for xmail is hold (ala mailtool) */
- X
- X if (c = GetMailrc("nohold")) XtFree((String) c);
- X else (void) strcat(tmp, "hold");
- X
- X msg = QueryMail(tmp);
- X
- X (void) strcpy(tmp, "unset crt replyall cmd");
- X
- X msg = QueryMail(tmp);
- X
- X *msg = '\0';
- X
- X if (msgnum = file_handler()) {
- X (void) sprintf(tmp, "%d", msgnum);
- X msg = QueryMail(tmp);
- X }
- X Bell(""); /* reset any worthy-ness flag */
- X Bell(Default_Status_Info);
- X } else *msg = '\0';
- X }
- X if (first_time) { /* only need to do this once */
- X Waiting = FALSE;
- X first_time = False;
- X icon = XtNameToWidget(toplevel, "icon");
- X XtAddEventHandler(icon, StructureNotifyMask, False,
- X icon_handler, NULL);
- X if (In_Bogus_Mail_File) {
- X (void) sprintf(tmp, "%s+", tmpName);
- X (void) unlink(tmp);
- X *msg = '\0'; /* ignore 'skipping' message */
- X }
- X }
- X break;
- X/*
- X** In response to normal or change folder commands, test output. If an
- X** error, display message in status window, and ring bell unless command
- X** was save, Save to author, or undelete. If Save or Copy results in an
- X** error, and the error response begins with 'Unknown', then this is not
- X** Sun mail, and we should try and compensate for these missing functions.
- X** If our current mail message folder is the bogus folder, erase any text
- X** and index and note state. If we have text of next mail message, tell
- X** index_handler to mark its number, else retrieve the appropriate message
- X** text (which also marks its number). If *Show_Last: resource is NOT False,
- X** file cmd shows latest, if none new.
- X*/
- X case XM_C_EXEC :
- X case XM_C_FILE : j = match(output_pattern, msg);
- X switch (j) {
- X case XM_O_BELL:
- X if (strchr("SsCcw", Command[0]) != NULL) {
- X if (strncmp(msg, "Unknown ", 8) == 0 &&
- X Reissue_Is_Valid()) {
- X *msg = '\0';
- X break;
- X }
- X if (isdigit(msg[strlen(msg) - 2]))
- X LASTCH(msg) = '\0';
- X else Command[0] = '\0';
- X }
- X if (strncmp(msg, tmpName, strlen(tmpName)) == 0)
- X Bell("No mail in your system mailbox");
- X else {
- X Bell(msg);
- X *msg = '\0';
- X }
- X/*
- X** Save our current message number, because asking about our 'file' status
- X** will reset mail's idea of the 'current message' count to one, regardless.
- X*/
- X msgnum = SelectionNumber(False);
- X/*
- X** Now ask for 'file' status to determine if we are still caught in our 'bogus'
- X** mailfile, in order to generate a more meaningful title-bar status message.
- X*/
- X msg = QueryMail("file");
- X if (strncmp(&msg[1], tmpName, strlen(tmpName)) == 0) {
- X (void) UpdateTitleBar("No current folder");
- X iw = XtNameToWidget(toplevel, "topBox");
- X writeTo(XtNameToWidget(iw, "indexWindow"), " ", REPLACE);
- X writeText(" ");
- X } else {
- X (void) UpdateTitleBar(msg);
- X/*
- X** If not in our bogus mail folder, reset the current message
- X** number in Mail by again pointing at that numbered message.
- X*/
- X (void) sprintf(tmp, "f %d", msgnum);
- X msg = QueryMail(tmp);
- X if (Command[0] != NULL)
- X if (strchr("Ssw", Command[0]))
- X markIndex(">S");
- X }
- X *msg = '\0';
- X break;
- X case XM_O_EXEC: writeText(msg);
- X if (strchr("-np", Command[0]))
- X msgnum = index_handler(0, 0);
- X else markIndex("> ");
- X *msg = '\0';
- X break;
- X case XM_O_FILE: c = strchr(msg, '\n');
- X if ((int)(c - msg) < strlen(msg) - 1) {
- X *c = '\0'; /* don't bell this */
- X Bell(""); /* clear worthy flag */
- X Bell(msg);
- X }
- X *msg = '\0';
- X msgnum = file_handler();
- X update_times(); /* now that we're out */
- X if (msgnum) {
- X (void) sprintf(tmp, "%d", msgnum);
- X msg = QueryMail(tmp);
- X }
- X break;
- X }
- X break;
- X/*
- X** When deleting a message, simply mark that index line with a capital 'D'.
- X** If un-deleting, mark that index line with a blank ' '. If no current
- X** index, restore it. If autoprinting, mail will include text of next msg.
- X*/
- X case XM_C_DELETE : if (XM_O_BELL == match(output_pattern, msg)) {
- X Bell(msg);
- X *msg = '\0';
- X } else {
- X writeText(msg);
- X msgnum = SelectionNumber(False);
- X if (Command[0] == 'd') {
- X if (msgnum) {
- X markIndex("D");
- X msgnum = index_handler(msgnum + 1, 0);
- X }
- X } else { /* if we are 'undeleting' */
- X c = QueryMail("=");
- X (void) sscanf(c, "%d", &msgnum);
- X XtFree((String) c);
- X iw = XtNameToWidget(toplevel, "topBox.indexWindow");
- X if (TextGetLastPos(iw) < (XawTextPosition) 4) {
- X c = QueryMail("h");
- X writeTo(iw, c, REPLACE);
- X }
- X msgnum = index_handler(msgnum, 1);
- X }
- X c = QueryMail("file"); /* resets current msg to 1 */
- X (void) UpdateTitleBar(c);
- X
- X if (msgnum == 0) /* if this was the last msg */
- X writeText(" "); /* in folder, erase its text */
- X else {
- X /*
- X ** reset mail's idea of what is the current message
- X */
- X (void) sprintf(tmp, "f %d", msgnum);
- X msg = QueryMail(tmp);
- X }
- X *msg = '\0';
- X }
- X break;
- X/*
- X** In response to a request to view new mail, first reset the mailbox flag.
- X** If mail came back with an error, complain to the user. Otherwise, clear
- X** the Newmail command button highlighting. Then display any new mail text.
- X*/
- X case XM_C_NEWMAIL:
- X button = XtNameToWidget(toplevel, "topBox.commandPanel.Folder");
- X UnsetNewmail(button, NULL, NULL);
- X if (XM_O_BELL == match(output_pattern, msg)) {
- X if (strncmp(msg, "No mail for ", 12) == 0) {
- X Bell("No mail in your system mailbox\n");
- X } else { Bell(msg); }
- X *msg = '\0';
- X } else {
- X Bell(""); /* reset any worthy-ness flag */
- X Bell(Default_Status_Info);
- X if (*msg) {
- X s = msg;
- X c = strchr(msg, '\n');
- X if ((c - s) + 1 < strlen(msg)) {
- X *c = '\0'; /* don't bell this */
- X Bell(msg);
- X }
- X }
- X msgnum = file_handler();
- X update_times(); /* we're out of prev. folder */
- X *msg = '\0';
- X if (msgnum) {
- X (void) sprintf(tmp, "%d", msgnum);
- X msg = QueryMail(tmp);
- X }
- X }
- X break;
- X
- X default: j = match(output_pattern, msg);
- X switch (j) {
- X case XM_O_BELL:
- X Bell(msg);
- X *msg = '\0';
- X break;
- X/*
- X** If output is from the print command, display a status message
- X*/
- X case XM_O_PRINT:
- X (void) sscanf(&Command[2], "%d", &j);
- X c = strrchr(msg, '/');
- X (void) sscanf(c, "/%d", &k);
- X (void) sprintf(tmp,
- X "Message %d sent to printer -- %d bytes\n", j, k);
- X Bell(tmp);
- X *msg = '\0';
- X break;
- X/*
- X** If we didn't specifically ask for it, and its not an error, just toss it.
- X** Preserve post processing moved here, in case we weren't allowed to do it.
- X*/
- X default:
- X if (strncmp(Command, "preserve", 8) == 0)
- X markIndex("P");
- X *msg = '\0';
- X break;
- X }
- X break;
- X }
- X/*
- X** If any text remains, display it in the bottom (text) window.
- X*/
- X if (*msg) {
- X for (j = strlen(msg)-1; j > 1 && msg[j] == '\n' && msg[j-1] == '\n'; j--);
- X msg[++j] = '\0'; /* drop all but the last newline */
- X writeText(msg);
- X *msg = '\0';
- X }
- X SetCursor(NORMAL);
- X} /* parse */
- X
- X#define FILEBUF 8192
- X
- X/*
- X** @(#)QueryMail() - Sends a command and returns corresponding output.
- X** If called by the Xt input procedure readMail, no command is included.
- X** In an attempt to eliminate the occasional segmentation violation in
- X** either malloc or free, we no longer free this buffer each time it is
- X** used. Instead we simply allow it to grow to the maximum size of a
- X** read ever performed on the mail pipe.
- X*/
- Xchar *
- XQueryMail(cmd)
- Xchar *cmd;
- X{
- X static int outputsize = 0;
- X int j, size, length = 0;
- X static String output;
- X String temp;
- X char s[FILEBUF];
- X
- X
- X if (MailPrompt[0] != '\0') length = strlen(MailPrompt);
- X/*
- X** allocate one block to 'output' to begin with
- X*/
- X if (outputsize <= 0) {
- X outputsize = FILEBUF;
- X output = (String) XtMalloc((unsigned) outputsize);
- X }
- X output[0] = '\0';
- X
- X if (! mailpid)
- X Bell("No current mail program connection\n");
- X else {
- X if (*cmd) { /* allow us to be called by readMail */
- X if (LASTCH(cmd) != '\n')
- X (void) sprintf(s, "%s\n", cmd);
- X else
- X (void) strcpy(s, cmd);
- X writeMail(s);
- X }
- X
- X for (;;) {
- X if ((size = read(mail_fd, s, FILEBUF)) < 1) { /* EOF or an error? */
- X if (! *output) { /* For some reason Mail has gone away */
- X (void) strcpy(output, "No current mail service connection\n");
- X if (mailpid) {
- X XtRemoveInput(mailInputId);
- X (void) close(mail_fd);
- X mailpid = 0;
- X MailPrompt[0] = '\0';
- X (void) strcpy(Command, "Start"); /* Focus our errors */
- X writeText(" "); /* erase any current message display */
- X writeTo(XtNameToWidget(toplevel, "topBox.indexWindow"), " ", REPLACE);
- X }
- X }
- X break;
- X }
- X
- X if (size < FILEBUF)
- X s[size] = '\0';
- X
- X if (strlen(output) + size >= outputsize) {
- X outputsize += FILEBUF;
- X temp = (String) XtRealloc(output, outputsize);
- X output = temp;
- X }
- X (void) strcat(output, s);
- X
- X if (strcmp(Command, "Start") == 0) {
- X /*
- X ** Check for no message response before we try to catch the prompt.
- X */
- X if (XM_O_BELL == match(output_pattern, output))
- X break;
- X /*
- X ** If we have no prompt and are just starting, get the prompt string.
- X ** This makes the GROSS assumption that we will have gotten it here.
- X */
- X if (*output && ! *MailPrompt) {
- X if ((temp = strrchr(output, '\n')) != NULL)
- X (void) strcpy(MailPrompt, temp + 1);
- X else
- X (void) strcpy(MailPrompt, output);
- X length = strlen(MailPrompt);
- X }
- X }
- X
- X j = strlen(output) - length;
- X if (j < 0) j = 0; /* no references before zero */
- X if (*MailPrompt && strcmp(&output[j], MailPrompt) == 0) {
- X output[j] = '\0'; /* Drop prompt from end of text */
- X break; /* and return from read routine */
- X }
- X }
- X
- X if (*cmd)
- X LASTCH(output) = '\0'; /* drop newline for normal queries */
- X }
- X
- X return(output);
- X} /* QueryMail */
- END_OF_FILE
- if test 23345 -ne `wc -c <'parser.c'`; then
- echo shar: \"'parser.c'\" unpacked with wrong size!
- fi
- # end of 'parser.c'
- fi
- echo shar: End of archive 6 \(of 10\).
- cp /dev/null ark6isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 10 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
- --
- // chris@IMD.Sterling.COM | Send comp.sources.x submissions to:
- \X/ Amiga - The only way to fly! |
- "It's intuitively obvious to the most | sources-x@imd.sterling.com
- casual observer..." |
-