michael@uunet.UU.NET (Michael Wagnitz) (06/16/91)
Submitted-by: stratus!voder!nsc!berlioz.nsc.com!michael@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@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@uunet.uu.net argv@ora.com argv@zipcode.com