Flush out the last dregs in the terminal before quitting when
[unix-history] / usr / src / usr.bin / mail / optim.c
index cf495f8..f998f8d 100644 (file)
@@ -1,4 +1,18 @@
-#
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#ifdef notdef
+static char sccsid[] = "@(#)optim.c    5.9 (Berkeley) %G%";
+#endif /* notdef */
 
 /*
  * Mail -- a program for sending and receiving mail.
 
 /*
  * Mail -- a program for sending and receiving mail.
@@ -7,9 +21,7 @@
  */
 
 #include "rcv.h"
  */
 
 #include "rcv.h"
-#include <ctype.h>
-
-static char *SccsId = "@(#)optim.c     1.2 %G%";
+#include "configdefs.h"
 
 /*
  * Map a name into the correct network "view" of the
 
 /*
  * Map a name into the correct network "view" of the
@@ -18,8 +30,6 @@ static char *SccsId = "@(#)optim.c    1.2 %G%";
  * nonsense.
  */
 
  * nonsense.
  */
 
-char   *metanet = "!^:%@.";
-
 char *
 netmap(name, from)
        char name[], from[];
 char *
 netmap(name, from)
        char name[], from[];
@@ -30,7 +40,7 @@ netmap(name, from)
        if (strlen(from) == 0)
                return(name);
        if (any('@', name) || any('%', name))
        if (strlen(from) == 0)
                return(name);
        if (any('@', name) || any('%', name))
-               return(arpafix(name, from));
+               return(savestr(arpafix(name, from)));
        cp = revarpa(from);
        if (cp == NOSTR)
                return(name);
        cp = revarpa(from);
        if (cp == NOSTR)
                return(name);
@@ -41,111 +51,32 @@ netmap(name, from)
        if (cp == nbuf)
                return(name);
        *++cp = 0;
        if (cp == nbuf)
                return(name);
        *++cp = 0;
-       strcat(nbuf, revarpa(name));
+       if ((cp = revarpa(name)) != NOSTR)
+               strcat(nbuf, cp);
        optim(nbuf, ret);
        cp = revarpa(ret);
        optim(nbuf, ret);
        cp = revarpa(ret);
-       if (!icequal(name, cp))
-               return((char *) savestr(cp));
+       if (cp && !icequal(name, cp))
+               return(savestr(cp));
        return(name);
 }
 
        return(name);
 }
 
-/*
- * Rename the given network path to use
- * the kinds of names that we would right here.
- */
-
-char *
-rename(str)
-       char str[];
-{
-       register char *cp, *cp2;
-       char buf[BUFSIZ], path[BUFSIZ];
-       register int c, host;
-
-       strcpy(path, "");
-       for (;;) {
-               if ((c = *cp++) == 0)
-                       break;
-               cp2 = buf;
-               while (!any(c, metanet) && c != 0) {
-                       *cp2++ = c;
-                       c = *cp++;
-               }
-               *cp2 = 0;
-               if (c == 0) {
-                       strcat(path, buf);
-                       break;
-               }
-               host = netlook(buf, ntype(c));
-               strcat(path, netname(host));
-               stradd(path, c);
-       }
-       if (strcmp(str, path) != 0)
-               return(savestr(path));
-       return(str);
-}
 /*
  * Turn a network machine name into a unique character
 /*
  * Turn a network machine name into a unique character
- * + give connection-to status.  BN -- connected to Bell Net.
- * AN -- connected to ARPA net, SN -- connected to Schmidt net.
- * CN -- connected to COCANET.
  */
  */
-
-#define        AN      1                       /* Connected to ARPA net */
-#define        BN      2                       /* Connected to BTL net */
-#define        CN      4                       /* Connected to COCANET */
-#define        SN      8                       /* Connected to Schmidt net */
-
-struct netmach {
-       char    *nt_machine;
-       char    nt_mid;
-       short   nt_type;
-} netmach[] = {
-       "a",            'a',            SN,
-       "b",            'b',            SN,
-       "c",            'c',            SN,
-       "d",            'd',            SN,
-       "e",            'e',            SN,
-       "f",            'f',            SN,
-       "g",            'g',            SN,
-       "ingres",       'i',            AN|SN,
-       "ing70",        'i',            AN|SN,
-       "berkeley",     'i',            AN|SN,
-       "ingvax",       'j',            SN,
-       "virus",        'k',            SN,
-       "vlsi",         'l',            SN,
-       "image",        'm',            SN,
-       "esvax",        'o',            SN,
-       "sesm",         'o',            SN,
-       "q",            'q',            SN,
-       "research",     'R',            BN,
-       "arpavax",      'r',            SN,
-       "src",          's',            SN,
-       "mathstat",     't',            SN,
-       "csvax",        'v',            BN|SN,
-       "vax",          'v',            BN|SN,
-       "ucb",          'v',            BN|SN,
-       "ucbvax",       'v',            BN|SN,
-       "onyx",         'x',            SN,
-       "vax135",       'X',            BN,
-       "cory",         'y',            SN,
-       "eecs40",       'z',            SN,
-       0,              0,              0
-};
-
 netlook(machine, attnet)
        char machine[];
 {
        register struct netmach *np;
        register char *cp, *cp2;
 netlook(machine, attnet)
        char machine[];
 {
        register struct netmach *np;
        register char *cp, *cp2;
-       char nbuf[20];
+       char nbuf[BUFSIZ];
 
        /*
         * Make into lower case.
         */
 
        for (cp = machine, cp2 = nbuf; *cp; *cp2++ = little(*cp++))
 
        /*
         * Make into lower case.
         */
 
        for (cp = machine, cp2 = nbuf; *cp; *cp2++ = little(*cp++))
-               ;
+               if (cp2 >= &nbuf[sizeof(nbuf)-1])
+                       break;
        *cp2 = 0;
 
        /*
        *cp2 = 0;
 
        /*
@@ -228,7 +159,7 @@ arpafix(name, from)
        if (cp == NOSTR)
                cp = rindex(name, '%');
        if (cp == NOSTR) {
        if (cp == NOSTR)
                cp = rindex(name, '%');
        if (cp == NOSTR) {
-               fprintf(stderr, "Somethings amiss -- no @ or % in arpafix\n");
+               fprintf(stderr, "Somethings amiss -- no @ or %% in arpafix\n");
                return(name);
        }
        cp++;
                return(name);
        }
        cp++;
@@ -307,7 +238,6 @@ short       midfree;                        /* Next free machine id */
 minit()
 {
        register struct xtrahash *xp, **tp;
 minit()
 {
        register struct xtrahash *xp, **tp;
-       register int i;
 
        midfree = 0;
        tp = &xtab[0];
 
        midfree = 0;
        tp = &xtab[0];
@@ -333,6 +263,7 @@ mstash(name, attnet)
 {
        register struct xtrahash *xp;
        struct xtrahash *xlocate();
 {
        register struct xtrahash *xp;
        struct xtrahash *xlocate();
+       int x;
 
        xp = xlocate(name);
        if (xp == (struct xtrahash *) 0) {
 
        xp = xlocate(name);
        if (xp == (struct xtrahash *) 0) {
@@ -348,22 +279,11 @@ mstash(name, attnet)
                xp->xh_name = savestr(name);
                xp->xh_mid = 0200 + midfree++;
        }
                xp->xh_name = savestr(name);
                xp->xh_mid = 0200 + midfree++;
        }
-       switch (attnet) {
-       case '!':
-       case '^':
-               xp->xh_attnet |= BN;
-               break;
-
-       default:
-       case ':':
+       x = ntype(attnet);
+       if (x == 0)
                xp->xh_attnet |= SN;
                xp->xh_attnet |= SN;
-               break;
-
-       case '@':
-       case '%':
-               xp->xh_attnet |= AN;
-               break;
-       }
+       else
+               xp->xh_attnet |= x;
        return(xp->xh_mid);
 }
 
        return(xp->xh_mid);
 }
 
@@ -396,7 +316,7 @@ xlocate(name)
                if (strcmp(cp, xp->xh_name) == 0)
                        return(xp);
                if (h - q < 0)
                if (strcmp(cp, xp->xh_name) == 0)
                        return(xp);
                if (h - q < 0)
-                       q += XHSIZE;
+                       h += XHSIZE;
                xp = &xtrahash[(h - q) % XHSIZE];
                if (xp->xh_name == NOSTR)
                        return(xp);
                xp = &xtrahash[(h - q) % XHSIZE];
                if (xp->xh_name == NOSTR)
                        return(xp);
@@ -447,7 +367,7 @@ mtype(mid)
 
 /*
  * Take a network name and optimize it.  This gloriously messy
 
 /*
  * Take a network name and optimize it.  This gloriously messy
- * opertions takes place as follows:  the name with machine names
+ * operation takes place as follows:  the name with machine names
  * in it is tokenized by mapping each machine name into a single
  * character machine id (netlook).  The separator characters (network
  * metacharacters) are left intact.  The last component of the network
  * in it is tokenized by mapping each machine name into a single
  * character machine id (netlook).  The separator characters (network
  * metacharacters) are left intact.  The last component of the network
@@ -515,6 +435,9 @@ err:
        while (*cp) {
                if ((cp2 = netname(*cp++)) == NOSTR) {
                        printf("Made up bad net name\n");
        while (*cp) {
                if ((cp2 = netname(*cp++)) == NOSTR) {
                        printf("Made up bad net name\n");
+                       printf("Machine code %c (0%o)\n", cp[-1], cp[-1]);
+                       printf("Sorry -- dumping now.  Alert K. Shoens\n");
+                       core();
                        goto err;
                }
                strcat(name, cp2);
                        goto err;
                }
                strcat(name, cp2);
@@ -530,9 +453,6 @@ err:
  * optimizer and concatenating the results.
  */
 
  * optimizer and concatenating the results.
  */
 
-#define        IMPLICIT        1
-#define        EXPLICIT        2
-
 optim1(netstr, name)
        char netstr[], name[];
 {
 optim1(netstr, name)
        char netstr[], name[];
 {
@@ -543,6 +463,12 @@ optim1(netstr, name)
        cp = netstr;
        prefer(cp);
        strcpy(name, "");
        cp = netstr;
        prefer(cp);
        strcpy(name, "");
+       /*
+        * If the address ultimately points back to us,
+        * just return a null network path.
+        */
+       if (strlen(cp) > 1 && cp[strlen(cp) - 2] == LOCAL)
+               return;
        while (*cp != 0) {
                strcpy(path, "");
                tp = ntype(cp[1]);
        while (*cp != 0) {
                strcpy(path, "");
                tp = ntype(cp[1]);
@@ -584,24 +510,12 @@ optim1(netstr, name)
 ntype(nc)
        register int nc;
 {
 ntype(nc)
        register int nc;
 {
+       register struct ntypetab *np;
 
 
-       switch (nc) {
-       case '^':
-       case '!':
-               return(BN);
-
-       case ':':
-       case '.':
-               return(SN);
-
-       case '@':
-       case '%':
-               return(AN);
-
-       default:
-               return(0);
-       }
-       /* NOTREACHED */
+       for (np = ntypetab; np->nt_char != 0; np++)
+               if (np->nt_char == nc)
+                       return(np->nt_bcode);
+       return(0);
 }
 
 /*
 }
 
 /*
@@ -614,19 +528,12 @@ ntype(nc)
 netkind(nt)
        register int nt;
 {
 netkind(nt)
        register int nt;
 {
+       register struct nkindtab *np;
 
 
-       switch (nt) {
-       case BN:
-               return(EXPLICIT);
-
-       case AN:
-       case SN:
-               return(IMPLICIT);
-
-       default:
-               return(0);
-       }
-       /* NOTREACHED */
+       for (np = nkindtab; np->nk_type != 0; np++)
+               if (np->nk_type == nt)
+                       return(np->nk_kind);
+       return(0);
 }
 
 /*
 }
 
 /*
@@ -638,7 +545,6 @@ optimex(net, name)
 {
        register char *cp, *rp;
        register int m;
 {
        register char *cp, *rp;
        register int m;
-       char *rindex();
 
        strcpy(name, net);
        cp = name;
 
        strcpy(name, net);
        cp = name;
@@ -682,7 +588,6 @@ optimimp(net, name)
 }
 
 /*
 }
 
 /*
-
  * Perform global optimization on the given network path.
  * The trick here is to look ahead to see if there are any loops
  * in the path and remove them.  The interpretation of loops is
  * Perform global optimization on the given network path.
  * The trick here is to look ahead to see if there are any loops
  * in the path and remove them.  The interpretation of loops is
@@ -721,6 +626,7 @@ rpair(str, mach)
 {
        register char *cp, *last;
 
 {
        register char *cp, *last;
 
+       cp = str;
        last = NOSTR;
        while (*cp) {
                if (*cp == mach)
        last = NOSTR;
        while (*cp) {
                if (*cp == mach)
@@ -754,18 +660,6 @@ prefer(name)
  * Return the best network separator for the given machine pair.
  */
 
  * Return the best network separator for the given machine pair.
  */
 
-struct netorder {
-       short   no_stat;
-       char    no_char;
-} netorder[] = {
-       CN,     ':',
-       AN,     '@',
-       AN,     '%',
-       SN,     ':',
-       BN,     '!',
-       -1,     0
-};
-
 best(src, dest)
 {
        register int dtype, stype;
 best(src, dest)
 {
        register int dtype, stype;
@@ -773,24 +667,40 @@ best(src, dest)
 
        stype = nettype(src);
        dtype = nettype(dest);
 
        stype = nettype(src);
        dtype = nettype(dest);
+       fflush(stdout);
        if (stype == 0 || dtype == 0) {
                printf("ERROR:  unknown internal machine id\n");
                return(0);
        }
        if (stype == 0 || dtype == 0) {
                printf("ERROR:  unknown internal machine id\n");
                return(0);
        }
-       if ((stype & dtype) == 0) {
-#ifdef DELIVERMAIL
-               if (src != LOCAL)
-#endif
-                       printf("No way to get from \"%s\" to \"%s\"\n", 
-                           netname(src), netname(dest));
+       if ((stype & dtype) == 0)
                return(0);
                return(0);
-       }
        np = &netorder[0];
        while ((np->no_stat & stype & dtype) == 0)
                np++;
        return(np->no_char);
 }
 
        np = &netorder[0];
        while ((np->no_stat & stype & dtype) == 0)
                np++;
        return(np->no_char);
 }
 
+#ifdef GETHOST
+/*
+ * Initialize the network name of the current host.
+ */
+inithost()
+{
+       register struct netmach *np;
+       static char host[64];
+
+       gethostname(host, sizeof host);
+       for (np = netmach; np->nt_machine != 0; np++)
+               if (strcmp(np->nt_machine, EMPTY) == 0)
+                       break;
+       if (np->nt_machine == 0) {
+               printf("Cannot find empty slot for dynamic host entry\n");
+               exit(1);
+       }
+       np->nt_machine = host;
+}
+#endif GETHOST
+
 /*
  * Code to twist around arpa net names.
  */
 /*
  * Code to twist around arpa net names.
  */
@@ -912,14 +822,14 @@ yylex()
                cp++;
        if (*cp == 0)
                return(0);
                cp++;
        if (*cp == 0)
                return(0);
-       if (any(*cp, "!^@:%")) {
+       if (any(*cp, metanet)) {
                charp = cp+1;
                return(*cp);
        }
        dot = cp;
                charp = cp+1;
                return(*cp);
        }
        dot = cp;
-       while (*cp && !any(*cp, " \t!^@:%"))
+       while (*cp && !any(*cp, metanet) && !any(*cp, " \t"))
                cp++;
                cp++;
-       if (any(*cp, "!^@:%"))
+       if (any(*cp, metanet))
                nexttok = *cp;
        if (*cp == 0)
                charp = cp;
                nexttok = *cp;
        if (*cp == 0)
                charp = cp;
@@ -929,17 +839,3 @@ yylex()
        yylval = dot;
        return(WORD);
 }
        yylval = dot;
        return(WORD);
 }
-
-/*
- * Add a single character onto a string.
- */
-
-stradd(str, c)
-       register char *str;
-       register int c;
-{
-
-       str += strlen(str);
-       *str++ = c;
-       *str = 0;
-}