v13i046: xmail, Part04/11

Michael Wagnitz stratus!voder!nsc!berlioz.nsc.com!michael at uunet.UU.NET
Sun Jun 16 05:44:35 AEST 1991


Submitted-by: stratus!voder!nsc!berlioz.nsc.com!michael at uunet.UU.NET (Michael Wagnitz)
Posting-number: Volume 13, Issue 46
Archive-name: xmail/part04

#! /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 4 (of 11)."
# Contents:  environs.c xmail.c
# Wrapped by michael at harley on Fri May  3 13:35:50 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'environs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'environs.c'\"
else
echo shar: Extracting \"'environs.c'\" \(15866 characters\)
sed "s/^X//" >'environs.c' <<'END_OF_FILE'
X/*
X * xmail - X window system interface to the mail program
X *
X * Copyright 1990 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 TORTUOUS 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();
Xchar		otherBuf[BUFSIZ];
XString		list = NULL;		/* list of aliases */
Xint		list_length;		/* size of alias list */
X
XAliasRecPtr	*aliases = NULL;	/* array of mail alias strings	*/
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, current_length, otherBuffer)
Xchar	*text;
Xchar	*buffer;
Xint	current_length;
Xchar	*otherBuffer;
X{
X if (! strchr("./+", *text)) {
X    if (*buffer) strcat(buffer, ", ");
X    if (current_length && current_length + strlen(text) > 71) {
X       strcat(buffer, "\n\t");		/* make it a continuation of header */
X      }
X    strcat(buffer, (*text == '\\') ? &text[1] : text);
X   } else {
X    if (*otherBuffer) strcat(otherBuffer, ", ");
X       strcat(otherBuffer, text);
X   }
X} /* addtobuf */
X
X
X/*
X** @(#) de_alias(text, buffer, current_line, otherBuffer)
X*/
Xvoid
Xde_alias(text, buffer, current_length, otherBuffer)
Xchar	*text;
Xchar	*buffer;
Xint	current_length;
Xchar	*otherBuffer;
X{
X char	*cp, *list;
X int	in_comma;
X
X
X if (! strchr(text, ','))
X    addtobuf(text, buffer, current_length, otherBuffer);
X else {
X    for (list = text; *list;) {
X        in_comma = 0;
X        if (cp = strchr(list, ',')) {
X           *cp = '\0';
X           in_comma = 1;
X          } else cp = list + strlen(list);
X        addtobuf(list, buffer, current_length, otherBuffer);
X        if (in_comma) *cp++ = ',';
X        list = cp;
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 static	char	tmp[BUFSIZ];
X static	char	buf[BUFSIZ];
X char		*line, *s, *p, *value;
X int		i, n, in_alias = False;
X int		testing_for_compound_address;
X FILE		*fp;
X
X
X tmp[0] = '\0';
X if (name)
X    strcpy(tmp, name);
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 = QueryMail("alias");
X    else	 list = GetMailrc("alias");
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 && 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 or parenthesis, treat whole line as just one alias
X*/
X            if (testing_for_compound_address) {
X               if ((s = strchr(p, '<')) || (s = strchr(p, '('))) {
X                  if (line = strchr(p, '\n')) {	/* could be more than one */
X                     if (s < line) {		/* if its within this alias */
X                        p = line;		/* 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 < line) {
X                           p = line;		/* 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/*
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'; line = buf;
X    for (p = value; *p;) {		/* 'value' points to current 'word' */
X        for (; *p && !strchr(", \t", *p); p++);
X        if (*p) {
X           if (((s = strchr(p, '(')) || (s = strchr(p, '<'))) &&
X              NULL != strchr(p, ',') && s > strchr(p, ','))
X              s = NULL;
X           if (*value != '(' && *value != '<' && s == NULL) {
X              *p++ = '\0';		/* this is not a compound address */
X             } else {			/* address has more than one word */
X               if (*value == '(' || *value == '<')
X                  p = strchr(value, *value == '(' ? ')' : '>');
X               else
X                  p = strchr(value, *s == '(' ? ')' : '>');
X               if (*p == ' ' || *p == '\t') p++;
X               for (; *p && !strchr(", \t", *p); p++);
X               if (*p) *p++ = '\0';
X             }
X          }
X        for (n = 0; aliases[n]; n++) {
X            if (strcmp(value, aliases[n]->name) == 0) {
X               if (line = strrchr(buf, '\t')) line++;
X               else line = buf;
X
X               de_alias(aliases[n]->alias, buf, strlen(line), otherBuf);
X               break;
X              }
X           }
X        if (! aliases[n]) {	/* If not an alias, use the name supplied. */
X           if (line = strrchr(buf, '\t')) line++;
X           else line = buf;
X
X           de_alias(value, buf, strlen(line), otherBuf);
X          }
X        for (; *p && strchr(", \t", *p); p++);
X        value = p;
X        if (*p) 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)
Xchar	*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 != "'"[0] && *s != '\n'; s++);
X       if (! *s || *s == '\n') {	/* variable is flag only, no value */
X          value = XtNewString("True");	/* substitute boolean for no value */
X         } else {
X          for (c = ++s; *c && *c != *(s - 1); c++);
X          length = c - s;
X          value = XtMalloc(length + 1);
X          strncpy(value, s, length);
X          value[length] = '\0';
X	}
X      }
X    XtFree(mailenv);
X   }
X  /*
X   * Expand shell variables in value
X   */
X  if (value) {
X     char *v, *e, *nvalue;
X     while (s = strchr(value, '$')) {
X        for (c = s + 1; *c && !strchr(" \t\n$/\"\'", *c); c++);
X        length = c - s - 1;
X        strncpy(buf, s + 1, length);
X        buf[length] = '\0';
X        if (*buf == '{') {			/* if variable is braced... */
X           bcopy(buf + 1, buf, strlen(buf) - 2);
X           buf[strlen(buf) - 2] = '\0';
X          }
X        if (!(e = getenv(buf)))
X	   e = "";
X        if (nvalue = XtMalloc(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(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 static char	buf[BUFSIZ];
X
X if (s = getenv("MAILRC"))
X    (void) strcpy(buf, s);
X else {
X    if ((s = getenv("HOME")) == NULL) s = "";
X    sprintf(buf, "%s/.mailrc", s);
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 extern String	list;
X extern	int	list_length;
X
X
X if (! list) {
X    list_length = BUFSIZ;
X    list = XtMalloc(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 = XtRealloc(list, list_length);
X   }
X 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 FILE	*fp;
X char	*c, *d, *s = NULL;
X char	e[1], buf[BUFSIZ];
X int	testing_for_compound_address;
X int	unset, n, in_alias = False;
X int	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
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';
X          if ((status = get_mailrc(item, &s, buf))) {
X             if (we_want_aliases) add_to_list(s);
X             else {
X                if (*value) XtFree(*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) && strncmp(buf, "group", 5))) {
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                   strcpy(&list[strlen(list) - 2], " "); /* drop the "\\n" */
X                   while ((s=fgets(buf,BUFSIZ,fp)) && s[strlen(s)-2] == '\\') {
X                         strcpy(&buf[strlen(buf) - 2], " "); /* drop "\\n" */
X                         add_to_list(s);		/* add continuations */
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                            if (*value) XtFree(*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                            if (*value) XtFree(*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    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 15866 -ne `wc -c <'environs.c'`; then
    echo shar: \"'environs.c'\" unpacked with wrong size!
fi
# end of 'environs.c'
fi
if test -f 'xmail.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xmail.c'\"
else
echo shar: Extracting \"'xmail.c'\" \(15169 characters\)
sed "s/^X//" >'xmail.c' <<'END_OF_FILE'
X/*
X * xmail - X window system interface to the mail program
X *
X * Copyright 1989 The University of Texas at Austin
X *
X * Author:	Po Cheung
X * Date:	March 10, 1989
X *
X * Permission to use, copy, modify, and distribute this software and
X * its documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation.  The University of Texas at Austin makes no 
X * representations about the suitability of this software for any purpose.  
X * It is provided "as is" without express or implied warranty.
X *
X * Copyright 1990 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 TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * The following software modules were created and are Copyrighted by National
X * Semiconductor Corporation:
X *
X * 1. initialize: and
X * 2. SetHints.
X *
X * Author:  Michael C. Wagnitz - National Semiconductor Corporation
X *
X */
X
X#include "global.h"
X#include "Mailwatch.h"			/* use as icon and watch for newmail */
X#include "icon.nomail"			/* default icon pixmap source */
X#include <X11/Xaw/CommandP.h>
X#include <X11/Xaw/TextP.h>
X#include <X11/cursorfont.h>		/* use watch cursor for busy notify */
X#include <X11/bitmaps/cross_weave>	/* background use in Newmail notify */
X
X#define Offset(field) (XtOffset(XmailResources *, field))
X
Xstatic char what[] =
X "@(#)xmail.c 1.3 91/04/29 Copyright 1989-1991 National Semiconductor Corp.";
X
Xstatic XtResource resrcs[] = {
X    { XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
X	Offset(textFont), XtRString, "9x15"},
X    {"helpFont", "HelpFont", XtRFontStruct, sizeof (XFontStruct *),
X	Offset(helpFont), XtRString, "8x13bold"},
X    {"buttonFont", "ButtonFont", XtRFontStruct, sizeof (XFontStruct *),
X	Offset(buttonFont), XtRString, "9x15"},
X    {"iconGeometry", "IconGeometry", XtRString, sizeof(char *),
X        Offset(iconGeometry), XtRString, (caddr_t) NULL},
X    {"mFileName", "MFileName", XtRString, sizeof(char *), 
X	Offset(MFileName), XtRString, (caddr_t) NULL},
X    {"editorCommand", "EditorCommand", XtRString, sizeof(char *), 
X	Offset(editorCommand), XtRString, (caddr_t) NULL},
X    {"bellRing", "BellRing", XtRBoolean, sizeof(Boolean), 
X	Offset(bellRing), XtRImmediate, (caddr_t) True},
X    {"expert", "Expert", XtRBoolean, sizeof(Boolean), 
X	Offset(expert), XtRImmediate, (caddr_t) False},
X    {"iconic", "Iconic", XtRBoolean, sizeof(Boolean), 
X	Offset(iconic), XtRImmediate, (caddr_t) False},
X    {"mailopt_n", "Mailopt_n", XtRBoolean, sizeof(Boolean), 
X	Offset(mailopt_n), XtRImmediate, (caddr_t) False},
X    {"mailopt_U", "Mailopt_U", XtRBoolean, sizeof(Boolean), 
X	Offset(mailopt_U), XtRImmediate, (caddr_t) False},
X    {"show_Last", "Show_Last", XtRBoolean, sizeof(Boolean), 
X	Offset(Show_Last), XtRImmediate, (caddr_t) True},
X    {"show_Info", "Show_Info", XtRBoolean, sizeof(Boolean), 
X	Offset(Show_Info), XtRImmediate, (caddr_t) True},
X    { XtNborderWidth, XtCBorderWidth, XtRInt, sizeof (int),
X	Offset(borderWidth), XtRString, "1"},
X};
X
X#undef Offset
X
Xstatic XrmOptionDescRec Opts[] = {
X    {"-editorcommand",	"editorCommand",	XrmoptionSepArg, (caddr_t) NULL},
X    {"-editorCommand",	"editorCommand",	XrmoptionSepArg, (caddr_t) NULL},
X    {"-e",		"expert",	XrmoptionNoArg, (caddr_t) "True"},
X    {"-f",		"MFileName",	XrmoptionSepArg, (caddr_t) NULL},
X    {"-helpfont",	"helpFont",	XrmoptionSepArg, (caddr_t) NULL},
X    {"-helpFont",	"helpFont",	XrmoptionSepArg, (caddr_t) NULL},
X    {"-buttonfont",	"buttonFont",	XrmoptionSepArg, (caddr_t) NULL},
X    {"-buttonFont",	"buttonFont",	XrmoptionSepArg, (caddr_t) NULL},
X    {"-iconGeometry",	"iconGeometry",	XrmoptionSepArg, (caddr_t) NULL},
X    {"-iconic",		"iconic",	XrmoptionNoArg, (caddr_t) "True"},
X    {"-ls",		"Show_Last",	XrmoptionNoArg, (caddr_t) "False"},
X    {"-nb",		"bellRing",	XrmoptionNoArg, (caddr_t) "False"},
X    {"-noinfo",		"Show_Info",	XrmoptionNoArg, (caddr_t) "False"},
X    {"-n",		"mailopt_n",	XrmoptionNoArg, (caddr_t) "True"},
X    {"-U",		"mailopt_U",	XrmoptionNoArg, (caddr_t) "True"},
X    {"-u",		"icon*useName",	XrmoptionNoArg, (caddr_t) "True"},
X    {"-m",		"icon*useHost",	XrmoptionNoArg, (caddr_t) "True"},
X    {"-rv",		"icon*reverseVideo",	XrmoptionNoArg, (caddr_t) "True"},
X};
X
XAtom		wmDeleteWindow;
X
Xint		mailargc;		/* counter passed to mail child	*/
Xint		RootWidth, RootHeight;
Xint		Highlighted;		/* state of 'Newmail' highlighting */
X
Xchar		Command[BUFSIZ];	/* xmail command string */
Xchar	 	Recipient[BUFSIZ];	/* message addressee */
Xchar		FileBuf[BUFSIZ];	/* buffer for file widget */
Xchar	 	SubjBuf[BUFSIZ];	/* message subject */
Xchar	 	InReply[BUFSIZ];	/* reply reference string */
Xchar	 	CcBuf[BUFSIZ];		/* message Cc list */
Xchar	 	BccBuf[BUFSIZ];		/* message Bcc list */
Xchar	 	tmpName[BUFSIZ];	/* message temporary filename */
Xchar	 	*MailPrompt;		/* mail program prompt string */
Xchar		**mailargv;		/* array passed to mail child */
X
XCursor		waitC;
XCursor		xtermC;
XPixmap		hatch;			/* cross_weave used to note Newmail */
XWidget		toplevel; 		/* top level shell widget */
XhelpList	HelpList;
X
XXmailResources 	XMail;			/* application resources of xmail */
X
X/*
X** @(#)mailoptions() - construct command line arguments for calling mail.
X**                     Return the argument list for mail and new value of argc.
X*/
Xchar **
Xmailoptions(argc, argv)
Xint  *argc;
Xchar **argv;
X{
X XWMHints	*wm_hints;
X char		**mailargv;
X int		i;
X
X
X wm_hints = XGetWMHints(XtDisplay(toplevel), XtWindow(toplevel));
X mailargv = (char **) XtMalloc (6 * sizeof(char *));
X for (i=0; i < *argc; i++)
X	mailargv[i] = argv[i];
X
X mailargv[i++] = "-N";		/* no version or header info at start */
X if (XMail.mailopt_n)
X    mailargv[i++] = "-n";	/* don't initialize from Mail.rc file */
X if (XMail.mailopt_U)
X    mailargv[i++] = "-U";	/* Change uucp to Internet addresses */
X
X if (wm_hints->initial_state == IconicState) {	/* start iconic in bogus */
X    FILE	*fp;
X    char	bogus[BUFSIZ];
X
X    (void) sprintf(bogus, "%s+", tmpName);
X    if (fp = fopen(bogus, "w")) {	/* create our bogus mail file */
X       (void) fprintf(fp, "\n");
X       fclose(fp);
X       mailargv[i++] = "-f";		/* start in our bogus mail folder */
X       mailargv[i++] = bogus;
X       In_Bogus_Mail_File = True;
X      }
X   } else if (XMail.MFileName) {
X	     mailargv[i++] = "-f";	/* start from mail folder MFileName */
X	     mailargv[i++] = XMail.MFileName;
X            }
X mailargv[i] = NULL;
X *argc = i;
X XFree(wm_hints);
X return mailargv;
X} /* mailoptions */
X
X
X/*
X** @(#)initialize() - establish xmail program defaults and setups
X*/
Xvoid
Xinitialize()
X{
X String		disp, file;
X long		buttonSpace, i;
X
X HelpList.indx = 0;
X
X strcpy(Command, "Start");		/* let parser know we've started */
X
X if (! (MailPrompt = GetMailrc("prompt")))
X    MailPrompt = XtNewString("& ");
X
X sprintf(tmpName, "/tmp/xmail%d", getpid());
X/*
X** TRAP any stupid attempt to set the border width of this application to less
X** than the allowed minimum (0) or greater than an acceptable maximum.  This
X** to prevent a really wierd reaction to a negative number for border width.
X*/
X if (XMail.borderWidth < 0)
X     XMail.borderWidth = 1;
X if (XMail.borderWidth > 6)
X     XMail.borderWidth = 6;
X/*
X** Compute all window dimensions based on extents of the specified fonts.
X** Make shell wide enough to hold eight buttons on a row.  Total button width
X** includes width of text area plus width of separation plus width of border.
X*/
X XMail.commandHSpace	= 10;
X XMail.commandVSpace	= 10;
X XMail.buttonHeight	= CHARHEIGHT(XMail.buttonFont) + (XMail.buttonFont->ascent / 2);
X XMail.buttonWidth	= figureWidth(XMail.buttonFont) * 9; /* ' NewMail ' */
X       buttonSpace	= XMail.borderWidth * 2;
X       buttonSpace	+= XMail.buttonWidth + XMail.commandHSpace;
X XMail.shellWidth	= (8 * buttonSpace) + 26;    /*  8 buttons per row */
X XMail.fileBoxWidth	= (4 * buttonSpace) + XMail.buttonWidth;
X XMail.helpHeight	= CHARHEIGHT(XMail.helpFont) * 14 + 5;
X XMail.helpWidth	= figureWidth(XMail.helpFont) * 60 + 5;
X XMail.helpX		= (XMail.shellWidth - XMail.helpWidth) / 2;
X XMail.helpY		= 70;
X       buttonSpace	= CHARHEIGHT(XMail.textFont) + (XMail.textFont->ascent / 2);
X XMail.indexHeight	= 12 * buttonSpace;
X XMail.textHeight	= 23 * buttonSpace;
X XMail.commandHeight	= (XMail.buttonHeight*2) + (XMail.commandVSpace*3) +
X			  (4 * XMail.borderWidth);
X XMail.menuX		= 15;
X XMail.menuY		= 7;
X       RootWidth	= XDisplayWidth(XtDisplay(toplevel),
X			  DefaultScreen(XtDisplay(toplevel))) - 1;
X       RootHeight	= XDisplayHeight(XtDisplay(toplevel),
X			   DefaultScreen(XtDisplay(toplevel))) - 1;
X/*
X** Ensure xmail shell height does not exceed the height of the root window.
X*/
X      buttonSpace	= (2 * XMail.buttonHeight) + XMail.indexHeight +
X			  XMail.commandHeight + XMail.textHeight + 
X			  (6 * XMail.borderWidth);
X
X for (i = 0, buttonSpace -= RootHeight; buttonSpace > 0; i++) {
X     buttonSpace -= CHARHEIGHT(XMail.textFont);
X     if (i % 2)
X        XMail.indexHeight -= CHARHEIGHT(XMail.textFont);
X     else
X        XMail.textHeight -= CHARHEIGHT(XMail.textFont);
X    }
X/*
X** If editorCommand resource exists, warn if it doesn't have two %s entries.
X*/
X if (XMail.editorCommand)
X    if (! (disp =  strchr(XMail.editorCommand, '%')) || *(disp + 1) != 's' ||
X        ! (file = strrchr(XMail.editorCommand, '%')) || *(file + 1) != 's' ||
X           disp == file) {
X    XtWarning("xmail editorCommand resource improperly defined... ignoring");
X    XtFree(XMail.editorCommand);
X    XMail.editorCommand = NULL;
X   }
X
X parser_init();
X} /* initialize */
X
X
X/*
X** @(#)SetHints() - Sets hatching, cursor, icon and size hints, and wm protocol
X*/
XSetHints()
X{
X int			x, y;
X XWMHints		wm_hints;
X XSizeHints		size_hints;
X Window			win = XtWindow(toplevel);
X Display		*dpy = XtDisplay(toplevel);
X CommandWidget		nm = (CommandWidget)XtNameToWidget(toplevel, "topBox.commandPanel.Newmail");
X/*
X** We don't want to create an input-only window for our ``busy'' cursor (ala
X** FAQ) because the extra enter/leave notify events would mess with our info.
X*/
X waitC	= XCreateFontCursor(dpy, XC_watch);
X xtermC	= XCreateFontCursor(dpy, XC_xterm);
X hatch	= XCreatePixmapFromBitmapData(dpy, XtScreen(toplevel)->root,
X			cross_weave_bits, cross_weave_width, cross_weave_height,
X			nm->label.foreground, nm->core.background_pixel,
X			DefaultDepth(dpy, DefaultScreen(dpy)));
X/*
X** Notify the window manager about our icon window
X*/
X wm_hints.input		= True;
X wm_hints.initial_state	= (XMail.iconic) ? IconicState : NormalState;
X wm_hints.flags		= InputHint | StateHint;
X
X if (XMail.iconGeometry) {
X    ParseIconGeometry(XMail.iconGeometry, &x, &y);
X    wm_hints.icon_x	= x;
X    wm_hints.icon_y	= y;
X    wm_hints.flags	|= IconPositionHint;
X   }
X wm_hints.flags		|= IconWindowHint;
X wm_hints.icon_window	= XtWindow(XtNameToWidget(toplevel, "icon"));
X
X XSetWMHints(dpy, win, &wm_hints);
X/*
X** Set starting position and default geometry
X*/
X if (! XGetNormalHints(dpy, win, &size_hints)) {
X    size_hints.x = 56;
X    size_hints.y = 56;			/* slightly off from top left corner */
X   }
X
X size_hints.width	= XMail.shellWidth;
X size_hints.height	= (2 * XMail.buttonHeight) + XMail.indexHeight +
X			  XMail.commandHeight + XMail.textHeight +
X			  (6 * XMail.borderWidth);
X
X size_hints.min_width = size_hints.max_width = size_hints.width;
X size_hints.min_height = size_hints.max_height = size_hints.height;
X size_hints.flags = USPosition | USSize | PMinSize;
X
X XSetNormalHints(dpy, win, &size_hints);
X/*
X** Add a protocol flag indicating we wish to handle WM_DELETE_WINDOW requests
X*/
X wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
X XSetWMProtocols(dpy, win, &wmDeleteWindow, 1);
X} /* SetHints */
X
X
X/*
X** @(#)main() - main routine for the x11 interface to the mail utility
X*/
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
Xstatic XtActionsRec actionTable[] = {
X	{"CheckInsert",		(XtActionProc) CheckInsert},
X	{"DeleteChar",		(XtActionProc) DeleteChar},
X	{"DeleteLine",		(XtActionProc) DeleteLine},
X	{"DeleteWord",		(XtActionProc) DeleteWord},
X	{"DoCmd",		(XtActionProc) DoCmd},
X	{"DoNothing",		(XtActionProc) DoNothing},
X	{"DoReply",		(XtActionProc) DoReply},
X	{"DoSave",		(XtActionProc) DoSave},
X	{"DoSelected",		(XtActionProc) DoSelected},
X	{"Iconify",		(XtActionProc) Iconify},
X	{"Folder",		(XtActionProc) Folder},
X	{"MyNotify",		(XtActionProc) MyNotify},
X	{"NextField",		(XtActionProc) NextField},
X	{"PrintMsg",		(XtActionProc) PrintMsg},
X	{"Quit",		(XtActionProc) Quit},
X	{"SetAliases",		(XtActionProc) SetAliases},
X	{"SetDirectory",	(XtActionProc) SetDirectory},
X	{"SetFolders",		(XtActionProc) SetFolders},
X	{"SetMenu",		(XtActionProc) SetMenu},
X	{"SetPopup",		(XtActionProc) SetPopup},
X	{"SetSelect",		(XtActionProc) SetSelect},
X	{"ShowHelp",		(XtActionProc) ShowHelp},
X        {NULL, NULL}
X      };
X/*
X** First, initialize our toplevel widget and parse the command line
X*/
X toplevel = XtInitialize(*argv, "XMail", Opts, XtNumber(Opts), &argc, argv);
X if (argc > 1) {
X    fprintf(stderr, "Usage: %s [-toolkitoptions] [-xmailoptions]\n", *argv);
X    exit(-1);
X   }
X XtAddActions(actionTable, XtNumber(actionTable));	/* add xmail actions */
X XtAddActions(textActionsTable, textActionsTableCount);	/* and text actions */
X XtGetApplicationResources(toplevel, &XMail, resrcs, XtNumber(resrcs), NULL, 0);
X
X XtOverrideTranslations(toplevel, XtParseTranslationTable("<Message>WM_PROTOCOLS: Quit(q)"));
X
X initialize();				/* set window sizes based on font */
X CreateSubWindows(toplevel);		/* and build our widget hierarchy */
X XSync(XtDisplay(toplevel), False);	/* ensure everyone's on the same page */
X XtRealizeWidget(toplevel);		/* initialize widgets for our hints */
X SetHints();				/* tell WM about our icon and size */
X
X mailargc = argc;			/* pass Mail arguments to the child */
X mailargv = mailoptions(&mailargc, argv);
X callMail(mailargc, mailargv);		/* attempt to start Mail connection */
X
X XSync(XtDisplay(toplevel), False);	/* clear event queue before iconify */
X XtMainLoop();
X} /* main */
END_OF_FILE
if test 15169 -ne `wc -c <'xmail.c'`; then
    echo shar: \"'xmail.c'\" unpacked with wrong size!
fi
# end of 'xmail.c'
fi
echo shar: End of archive 4 \(of 11\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

--
Dan Heller
O'Reilly && Associates       Z-Code Software    Comp-sources-x:
Senior Writer                President          comp-sources-x at uunet.uu.net
argv at ora.com                 argv at zipcode.com



More information about the Comp.sources.x mailing list