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