document distributed with 4.2BSD
[unix-history] / usr / src / usr.bin / mail / aux.c
index 1894134..9b7659d 100644 (file)
@@ -1,8 +1,15 @@
-#
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char *sccsid = "@(#)aux.c       5.4 (Berkeley) %G%";
+#endif not lint
 
 #include "rcv.h"
 #include <sys/stat.h>
 
 #include "rcv.h"
 #include <sys/stat.h>
-#include <sgtty.h>
 #include <ctype.h>
 
 /*
 #include <ctype.h>
 
 /*
@@ -11,8 +18,6 @@
  * Auxiliary functions.
  */
 
  * Auxiliary functions.
  */
 
-static char *SccsId = "@(#)aux.c       1.6 %G%";
-
 /*
  * Return a pointer to a dynamic copy of the argument.
  */
 /*
  * Return a pointer to a dynamic copy of the argument.
  */
@@ -123,20 +128,6 @@ isdir(name)
        return((sbuf.st_mode & S_IFMT) == S_IFDIR);
 }
 
        return((sbuf.st_mode & S_IFMT) == S_IFDIR);
 }
 
-/*
- * Compute the size in characters of the passed message
- */
-
-unsigned int
-msize(messp)
-       struct message *messp;
-{
-       register struct message *mp;
-
-       mp = messp;
-       return(mp->m_size);
-}
-
 /*
  * Count the number of arguments in the given string raw list.
  */
 /*
  * Count the number of arguments in the given string raw list.
  */
@@ -180,20 +171,6 @@ offsetof(off)
        return((int) a);
 }
 
        return((int) a);
 }
 
-/*
- * Determine if the passed file is actually a tty, via a call to
- * gtty.  This is not totally reliable, but . . .
- */
-
-isatty(f)
-{
-       struct sgttyb buf;
-
-       if (gtty(f, &buf) < 0)
-               return(0);
-       return(1);
-}
-
 /*
  * Return the desired header line from the passed message
  * pointer (or NOSTR if the desired header field is not available).
 /*
  * Return the desired header line from the passed message
  * pointer (or NOSTR if the desired header field is not available).
@@ -373,6 +350,21 @@ icequal(s1, s2)
        return(0);
 }
 
        return(0);
 }
 
+/*
+ * Copy a string, lowercasing it as we go.
+ */
+istrcpy(dest, src)
+       char *dest, *src;
+{
+       register char *cp, *cp2;
+
+       cp2 = dest;
+       cp = src;
+       do {
+               *cp2++ = little(*cp);
+       } while (*cp++ != 0);
+}
+
 /*
  * The following code deals with input stacking to do source
  * commands.  All but the current file pointer are saved on
 /*
  * The following code deals with input stacking to do source
  * commands.  All but the current file pointer are saved on
@@ -383,7 +375,8 @@ static      int     ssp = -1;               /* Top of file stack */
 struct sstack {
        FILE    *s_file;                /* File we were in. */
        int     s_cond;                 /* Saved state of conditionals */
 struct sstack {
        FILE    *s_file;                /* File we were in. */
        int     s_cond;                 /* Saved state of conditionals */
-} sstack[_NFILE];
+       int     s_loading;              /* Loading .mailrc, etc. */
+} sstack[NOFILE];
 
 /*
  * Pushdown current input file and switch to a new one.
 
 /*
  * Pushdown current input file and switch to a new one.
@@ -395,18 +388,23 @@ source(name)
        char name[];
 {
        register FILE *fi;
        char name[];
 {
        register FILE *fi;
+       register char *cp;
 
 
-       if ((fi = fopen(name, "r")) == NULL) {
-               perror(name);
+       if ((cp = expand(name)) == NOSTR)
+               return(1);
+       if ((fi = fopen(cp, "r")) == NULL) {
+               perror(cp);
                return(1);
        }
                return(1);
        }
-       if (ssp >= _NFILE-2) {
+       if (ssp >= NOFILE - 2) {
                printf("Too much \"sourcing\" going on.\n");
                fclose(fi);
                return(1);
        }
        sstack[++ssp].s_file = input;
        sstack[ssp].s_cond = cond;
                printf("Too much \"sourcing\" going on.\n");
                fclose(fi);
                return(1);
        }
        sstack[++ssp].s_file = input;
        sstack[ssp].s_cond = cond;
+       sstack[ssp].s_loading = loading;
+       loading = 0;
        cond = CANY;
        input = fi;
        sourcing++;
        cond = CANY;
        input = fi;
        sourcing++;
@@ -444,9 +442,10 @@ unstack()
        if (cond != CANY)
                printf("Unmatched \"if\"\n");
        cond = sstack[ssp].s_cond;
        if (cond != CANY)
                printf("Unmatched \"if\"\n");
        cond = sstack[ssp].s_cond;
+       loading = sstack[ssp].s_loading;
        input = sstack[ssp--].s_file;
        if (ssp < 0)
        input = sstack[ssp--].s_file;
        if (ssp < 0)
-               sourcing = 0;
+               sourcing = loading;
        return(0);
 }
 
        return(0);
 }
 
@@ -477,14 +476,9 @@ alter(name)
        time_p[1] = statb.st_mtime;
        utime(name, time_p);
 #else
        time_p[1] = statb.st_mtime;
        utime(name, time_p);
 #else
-       if ((pid = fork()) != 0)
-               return;
-       clrbuf(stdout);
-       clrbuf(stderr);
-       clrbuf(stdin);
        sleep(1);
        if ((f = open(name, 0)) < 0)
        sleep(1);
        if ((f = open(name, 0)) < 0)
-               exit(1);
+               return;
        read(f, &w, 1);
        exit(0);
 #endif
        read(f, &w, 1);
        exit(0);
 #endif
@@ -501,7 +495,7 @@ blankline(linebuf)
        register char *cp;
 
        for (cp = linebuf; *cp; cp++)
        register char *cp;
 
        for (cp = linebuf; *cp; cp++)
-               if (!any(*cp, " \t"))
+               if (*cp != ' ' && *cp != '\t')
                        return(0);
        return(1);
 }
                        return(0);
        return(1);
 }
@@ -515,12 +509,22 @@ char *
 nameof(mp, reptype)
        register struct message *mp;
 {
 nameof(mp, reptype)
        register struct message *mp;
 {
+       register char *cp, *cp2;
 
 
-       return(skin(name1(mp, reptype)));
+       cp = skin(name1(mp, reptype));
+       if (reptype != 0 || charcount(cp, '!') < 2)
+               return(cp);
+       cp2 = rindex(cp, '!');
+       cp2--;
+       while (cp2 > cp && *cp2 != '!')
+               cp2--;
+       if (*cp2 == '!')
+               return(cp2 + 1);
+       return(cp);
 }
 
 /*
 }
 
 /*
- * Skin an arpa net address according to the RFC 733 interpretation
+ * Skin an arpa net address according to the RFC 822 interpretation
  * of "host-phrase."
  */
 char *
  * of "host-phrase."
  */
 char *
@@ -529,37 +533,101 @@ skin(name)
 {
        register int c;
        register char *cp, *cp2;
 {
        register int c;
        register char *cp, *cp2;
+       char *bufend;
        int gotlt, lastsp;
        char nbuf[BUFSIZ];
        int gotlt, lastsp;
        char nbuf[BUFSIZ];
+       int nesting;
 
        if (name == NOSTR)
                return(NOSTR);
 
        if (name == NOSTR)
                return(NOSTR);
-       if (index(name, '(') == NOSTR && index(name, '<') == NOSTR)
+       if (index(name, '(') == NOSTR && index(name, '<') == NOSTR
+       && index(name, ' ') == NOSTR)
                return(name);
        gotlt = 0;
        lastsp = 0;
                return(name);
        gotlt = 0;
        lastsp = 0;
-       for (cp = name, cp2 = nbuf, c = *cp++; *cp; c = *cp++) {
+       bufend = nbuf;
+       for (cp = name, cp2 = bufend; c = *cp++; ) {
                switch (c) {
                case '(':
                switch (c) {
                case '(':
-                       while (*cp != ')' && *cp != 0)
+                       /*
+                        * Start of a "comment".
+                        * Ignore it.
+                        */
+                       nesting = 1;
+                       while ((c = *cp) != 0) {
                                cp++;
                                cp++;
-                       if (*cp)
+                               switch (c) {
+                               case '\\':
+                                       if (*cp == 0)
+                                               goto outcm;
+                                       cp++;
+                                       break;
+                               case '(':
+                                       nesting++;
+                                       break;
+
+                               case ')':
+                                       --nesting;
+                                       break;
+                               }
+
+                               if (nesting <= 0)
+                                       break;
+                       }
+               outcm:
+                       lastsp = 0;
+                       break;
+
+               case '"':
+                       /*
+                        * Start of a "quoted-string".
+                        * Copy it in its entirety.
+                        */
+                       while ((c = *cp) != 0) {
                                cp++;
                                cp++;
+                               switch (c) {
+                               case '\\':
+                                       if ((c = *cp) == 0)
+                                               goto outqs;
+                                       cp++;
+                                       break;
+                               case '"':
+                                       goto outqs;
+                               }
+                               *cp2++ = c;
+                       }
+               outqs:
+                       lastsp = 0;
                        break;
 
                case ' ':
                        break;
 
                case ' ':
-                       lastsp = 1;
+                       if (cp[0] == 'a' && cp[1] == 't' && cp[2] == ' ')
+                               cp += 3, *cp2++ = '@';
+                       else
+                       if (cp[0] == '@' && cp[1] == ' ')
+                               cp += 2, *cp2++ = '@';
+                       else
+                               lastsp = 1;
                        break;
 
                case '<':
                        break;
 
                case '<':
-                       cp2 = nbuf;
+                       cp2 = bufend;
                        gotlt++;
                        lastsp = 0;
                        break;
 
                case '>':
                        gotlt++;
                        lastsp = 0;
                        break;
 
                case '>':
-                       if (gotlt)
-                               goto done;
+                       if (gotlt) {
+                               gotlt = 0;
+                               while (*cp != ',' && *cp != 0)
+                                       cp++;
+                               if (*cp == 0 )
+                                       goto done;
+                               *cp2++ = ',';
+                               *cp2++ = ' ';
+                               bufend = cp2;
+                               break;
+                       }
 
                        /* Fall into . . . */
 
 
                        /* Fall into . . . */
 
@@ -596,12 +664,10 @@ name1(mp, reptype)
        register FILE *ibuf;
        int first = 1;
 
        register FILE *ibuf;
        int first = 1;
 
-#ifndef DELIVERMAIL
        if ((cp = hfield("from", mp)) != NOSTR)
                return(cp);
        if (reptype == 0 && (cp = hfield("sender", mp)) != NOSTR)
                return(cp);
        if ((cp = hfield("from", mp)) != NOSTR)
                return(cp);
        if (reptype == 0 && (cp = hfield("sender", mp)) != NOSTR)
                return(cp);
-#endif
        ibuf = setinput(mp);
        copy("", namebuf);
        if (readline(ibuf, linebuf) <= 0)
        ibuf = setinput(mp);
        copy("", namebuf);
        if (readline(ibuf, linebuf) <= 0)
@@ -643,11 +709,25 @@ newname:
        return(savestr(namebuf));
 }
 
        return(savestr(namebuf));
 }
 
+/*
+ * Count the occurances of c in str
+ */
+charcount(str, c)
+       char *str;
+{
+       register char *cp;
+       register int i;
+
+       for (i = 0, cp = str; *cp; cp++)
+               if (*cp == c)
+                       i++;
+       return(i);
+}
+
 /*
  * Find the rightmost pointer to an instance of the
  * character in the string and return it.
  */
 /*
  * Find the rightmost pointer to an instance of the
  * character in the string and return it.
  */
-
 char *
 rindex(str, c)
        char str[];
 char *
 rindex(str, c)
        char str[];
@@ -710,21 +790,34 @@ index(str, ch)
 }
 
 /*
 }
 
 /*
- * String compare two strings of bounded length.
+ * See if the given header field is supposed to be ignored.
  */
  */
+isign(field)
+       char *field;
+{
+       char realfld[BUFSIZ];
+
+       /*
+        * Lower-case the string, so that "Status" and "status"
+        * will hash to the same place.
+        */
+       istrcpy(realfld, field);
+
+       if (nretained > 0)
+               return (!member(realfld, retain));
+       else
+               return (member(realfld, ignore));
+}
 
 
-strncmp(as1, as2, an)
-       char *as1, *as2;
+member(realfield, table)
+       register char *realfield;
+       register struct ignore **table;
 {
 {
-       register char *s1, *s2;
-       register int n;
+       register struct ignore *igp;
 
 
-       s1 = as1;
-       s2 = as2;
-       n = an;
-       while (--n >= 0 && *s1 == *s2++)
-               if (*s1++ == '\0')
-                       return(0);
-       return(n<0 ? 0 : *s1 - *--s2);
-}
+       for (igp = table[hash(realfield)]; igp != 0; igp = igp->i_link)
+               if (equal(igp->i_field, realfield))
+                       return (1);
 
 
+       return (0);
+}