BSD 3 development
authorEric Schmidt <schmidt@ucbvax.Berkeley.EDU>
Sun, 9 Dec 1979 06:41:19 +0000 (22:41 -0800)
committerEric Schmidt <schmidt@ucbvax.Berkeley.EDU>
Sun, 9 Dec 1979 06:41:19 +0000 (22:41 -0800)
Work on file usr/src/cmd/net/READ_ME
Work on file usr/src/cmd/net/config.h
Work on file usr/src/cmd/net/Paths.h
Work on file usr/src/cmd/net/mach.h
Work on file usr/src/cmd/net/filecat.c
Work on file usr/src/cmd/net/mach.c
Work on file usr/src/cmd/net/nbs.c
Work on file usr/src/cmd/net/nsh.c
Work on file usr/src/cmd/net/netstart.c
Work on file usr/src/cmd/net/netrm.c
Work on file usr/src/cmd/net/setup.c

Synthesized-from: 3bsd

usr/src/cmd/net/Paths.h [new file with mode: 0644]
usr/src/cmd/net/READ_ME [new file with mode: 0644]
usr/src/cmd/net/config.h [new file with mode: 0644]
usr/src/cmd/net/filecat.c [new file with mode: 0644]
usr/src/cmd/net/mach.c [new file with mode: 0644]
usr/src/cmd/net/mach.h [new file with mode: 0644]
usr/src/cmd/net/nbs.c [new file with mode: 0644]
usr/src/cmd/net/netrm.c [new file with mode: 0644]
usr/src/cmd/net/netstart.c [new file with mode: 0644]
usr/src/cmd/net/nsh.c [new file with mode: 0644]
usr/src/cmd/net/setup.c [new file with mode: 0644]

diff --git a/usr/src/cmd/net/Paths.h b/usr/src/cmd/net/Paths.h
new file mode 100644 (file)
index 0000000..7a3f84f
--- /dev/null
@@ -0,0 +1,71 @@
+/* note that only the first 8 letters are significant to cpp */
+
+/* adjustable path names, may differ on each machine */
+# define NETCMD                "/usr/net/bin/net"
+# define NETCMD1       "/usr/net/bin/net"
+# define NETDAEMON     "/usr/net/bin/netdaemon"
+# define NETQSTAT      "/usr/net/bin/netqstats"
+
+# ifdef CSVAX
+# define LOGFILE       "/usr/spool/berknet/plogfileX"
+# define PUBLOGFILE    "/usr/spool/berknet/logfile"
+# define DUMPFILE      "/usr/spool/berknet/netstatX"
+# define NAMEFILE      "/usr/spool/berknet/usernames"
+
+# define RESFILE       "/usr/spool/berknet/rcv/rfaaXXXXX"
+# define TEMPFILE      "/usr/spool/berknet/rcv/tfaaXXXXX"
+# define SENDDIR       "/usr/spool/berknet/send?"
+# define DFNAME        "/usr/spool/berknet/send?/dfaaXXXXX"
+# define NETRMPATH     "/usr/spool/berknet/sendY/cfxx0000x"
+# define NETRMNAME     "/usr/spool/berknet/sendY/cfaa0000x"
+
+# else
+
+# define LOGFILE       "/usr/net/plogfileX"
+# define PUBLOGFILE    "/usr/net/logfile"
+# define DUMPFILE      "/usr/net/netstatX"
+# define NAMEFILE      "/usr/net/usernames"
+
+# define RESFILE       "/usr/net/rcv/rfaaXXXXX"
+# define TEMPFILE      "/usr/net/rcv/tfaaXXXXX"
+# define SENDDIR       "/usr/net/send?"
+# define DFNAME        "/usr/net/send?/dfaaXXXXX"
+# define NETRMPATH     "/usr/net/sendY/cfxx0000x"
+# define NETRMNAME     "/usr/net/sendY/cfaa0000x"
+
+# endif
+
+# ifdef CORY
+# define BINSH         "/bin/csh"
+# else
+# define BINSH         "/bin/sh"
+# endif
+
+# ifdef CSVAX
+# define SYSMAIL1      "/usr/ucb/Mail"
+# define SYSMAIL2      "/bin/mail"
+# else
+# define SYSMAIL1      "/bin/mail"
+# define SYSMAIL2      "/usr/bin/mail"
+# endif
+
+# define SYSMAIL3      "/bin/mail"
+# define SYSMAIL4      "/usr/bin/mail"
+
+/* 
+   Adjustable path names, must be the same on all machines.
+
+   MMAILCMD    sent by sendberkmail
+   MWRITECMD   sent by netdaemon
+   NETCPCMD    sent by netcp
+   PRMAIL      sent by netmail
+   CATCMD      sent by netcp and netdaemon
+   FILECAT     should be sent by netcp and netdaemon
+
+*/
+# define MMAILCMD      "/usr/net/bin/mmail"
+# define MWRITECMD     "/usr/net/bin/mwrite"
+# define NETCPCMD      "/usr/net/bin/netcp"
+# define PRMAIL                "/usr/net/bin/prmail"
+# define CATCMD        "/bin/cat"
+# define FILECAT       "/usr/net/bin/filecat"
diff --git a/usr/src/cmd/net/READ_ME b/usr/src/cmd/net/READ_ME
new file mode 100644 (file)
index 0000000..ba17f14
--- /dev/null
@@ -0,0 +1,157 @@
+
+       B E R K E L E Y   N E T W O R K
+
+
+The code in this directory is the most up-to-date network source
+on the machine.
+
+*** Pre-processor Flags ***
+
+This set of code is controlled by this set of conditional
+compilation flags:
+
+TESTING                if defined, do not generate tests, etc. which require
+               super-user status.
+
+OLDTTY         if defined, compile for old 1 character TTY names
+CCTTY          if defined, compile for CC tty name format
+               if neither is defined, use v7 ttyname format
+
+PASSWDF                compile in code to handle /etc/passwdf - split passwd files
+
+NEWPROT                use the new protocol, instead of the default protocol
+
+V7             use the v7 features
+
+FUID           use the funny uid's present on Cory and CC
+ROPTION                The local machine mail program has the magic -r option
+ROPTION2       The local machine mail program has the magic -r option
+
+HPASSWD                The local machine has the hashed password stuff
+
+SPACCT         under certain circumstances, allow remote login without acct
+
+SPOOLMAIL      mail is in /usr/spool/mail/name
+OLDMAIL                mail is in home-directory/.mail
+               (default is /usr/mail/name)
+
+CC             machine is a Computer Center machine
+NUID           userid (as returned by getuid()) on this machine
+UID1CHAR       uses vanila Version6 userid's (only 1 byte for uid)
+NOEUID         does not have the geteuid() system call
+
+
+At Berkeley, the conditonal flags are first defined
+in "/usr/include/whoami.h" on the local machine..
+They are VAX, CORY, A, C, D, E, SRC.
+
+For "normal" version 6 machines, there is a dummy machine
+definition for "VANILLA6" which indicates the v6 UNIX options.
+
+For "normal" version 7 machines, there is a dummy machine
+definition for "VANILLA7" which indicates the v7 UNIX options.
+
+*** Adding a new machine
+
+To add another machine to the network, change these programs:
+The machine tables are all in config.h.
+1. Change the path names in "Paths.h" and "nsh.c", and the makefile to suit.
+2. Change "defs.h" to suit.
+3. add in LOCALx section of config.h
+   the usual information about the machine interconnections
+4. add the name of the machine to the machine
+   name table and its type to the machine type table
+4.5 check routine "gothru" in sub.c
+5. compile the network specifying the code type (CC, VAX, Cory, VANILLA)
+   and the machine type
+
+*** Other files ***
+interact.c, listen.c - manually send packets
+speeds.c, speedr.c -   send various length packets, use "time" to evaluate
+store.c, receive.c -   send a file (use for backup)
+nettest.c -            run daemons locally, using pipes instead of tty lines
+setmode.c -            set the mode on the tty line driver to "cat" things thru
+
+***    Taxonomy of net pgms being sent around:
+
+Internal:      sendberkmail, prmail, mmail, mwrite
+External:      net, netcp, netlpr, netmail
+Other:         netdaemon, netstart, netq, netrm
+
+
+***    Naming Conventions (in progress) ***
+The names of simple variables are composed of three parts.
+       [type char] [string] [type tag]
+where
+       typechar is one of
+       i       integer (int)
+       l       long integer (long)
+       ch      character (char)
+       s       string (char *)
+       f       logical (char)
+the (optional) string is any short descriptive string.
+the (optional) type tag is noe of (assume string is "foo"):
+       
+       fooMin  minimum value of foo, for all foo, foo >= fooMin
+       fooMax  maximum value of foo, foo <= fooMax
+       fooMac  current maximum of foo, fooMin <= fooMac <= fooMax
+               usually used for array substript
+       fooOld  old value of foo, as opposed to fooNew
+       fooNew  new value of foo, as opposes to fooOld
+
+Example:
+       sdate   a string containing a date
+       sdateOld        a string containing an old date
+       sdateNew        a string containing the "current" date
+
+Pointers
+
+       pointer names are composed of the
+       previous set of names precedd by a character "p", e.g.
+
+               pch     pointer to char (same as string)
+               pi      pointer to integer
+               pltime  pointer to a long with the time in it
+
+Counters
+       Variables that count instances of things are preceded
+       by 'n', e.g.
+               nch     number of chars
+               nsdate  number of date strings
+Indices
+       Are stored as integers and preceded by 'i':
+               ich     index into char array
+               is      same as above
+
+Added types:
+       uid     userid as set by getuid()
+       sn      local name, w/o ':'
+       fd      (FILE *) file descriptor
+       mch     (char) 1 - letter machine code
+       addr    (char *) address, may include ':'
+
+Procedure names list
+parameters appear after procedure name, return value before.
+(Remember for external names only the first 7 characters are significant.)
+
+Compile Time Constants
+Are in upper-case.
+(Remember only first 8 characters are significant to the preprocessor).
+
+
+PROBLEMS
+
+       If you have any problems or questions, don't hesitate
+       to call me.
+               Eric Schmidt
+               706 International House
+               Berkeley, Cal. 94720
+               415-642-9365
+               415-642-9490 (messages)
+
+       or
+               C.S. Department
+               Evans Hall
+               U.C. Berkeley
+               Berkeley, Cal. 94720
+               415-642-4951
diff --git a/usr/src/cmd/net/config.h b/usr/src/cmd/net/config.h
new file mode 100644 (file)
index 0000000..3b4b675
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+       These are machine-configuration dependent
+       tables.  To add a machine, be sure to update all
+       these tables and to add the "ifdef" entry in "mach.h".
+       This file corresponds to the following network:
+
+       Ing70-----------CSVAX           A              B
+         |              |              |              |
+         |              |              |              |
+         |              |              |              |
+         |              |              |              |
+       IngVAX          Cory------------C--------------D------------Q
+                        |              |              |\
+                        |              |              | \
+                        |              |              |  \
+                        |              |              |   \
+       EECS40----------OptVAX          E             SRC   F
+                        |
+                        |
+                        |
+                        |
+                       Image
+
+       The tables must be consistent.
+       To be added:
+
+*/
+/* Computer Center A Machine (A) */
+char configA[] = {             /* to get to i, config[i] */
+       'a','c','c','c','c',            /* a,b,c,d,e */
+       'c',000,000,'c','c',            /* f,g,h,i,j */
+       000,000,'c',000,'c',            /* k,l,m,n,o */
+       000,'c',000,'c',000,            /* p,q,r,s,t */
+       000,'c',000,000,'c',            /* u,v,w,x,y */
+       'c',0                           /* z */
+       };
+/* Computer Center B Machine (B) */
+char configB[] = {             /* to get to i, config[i] */
+       'd','b','d','d','d',            /* a,b,c,d,e */
+       'd',000,000,'d','d',            /* f,g,h,i,j */
+       000,000,'d',000,'d',            /* k,l,m,n,o */
+       000,'d',000,'d',000,            /* p,q,r,s,t */
+       000,'d',000,000,'d',            /* u,v,w,x,y */
+       'd',0                           /* z */
+       };
+/* Computer Center C Machine (C) */
+char configC[] = {             /* to get to i, config[i] */
+       'a','d','c','d','e',            /* a,b,c,d,e */
+       'd',000,000,'y','y',            /* f,g,h,i,j */
+       000,000,'y',000,'y',            /* k,l,m,n,o */
+       000,'d',000,'d',000,            /* p,q,r,s,t */
+       000,'y',000,000,'y',            /* u,v,w,x,y */
+       'y',0                           /* z */
+       };
+/* Computer Center D Machine (D) */
+char configD[] = {             /* to get to i, config[i] */
+       'c','b','c','d','c',            /* a,b,c,d,e */
+       'f',000,000,'c','c',            /* f,g,h,i,j */
+       000,000,'c',000,'c',            /* k,l,m,n,o */
+       000,'q',000,'s',000,            /* p,q,r,s,t */
+       000,'c',000,000,'c',            /* u,v,w,x,y */
+       'c',0                           /* z */
+       };
+/* Computer Center E Machine (E) */
+char configE[] = {             /* to get to i, config[i] */
+       'c','c','c','c','e',            /* a,b,c,d,e */
+       'c',000,000,'c','c',            /* f,g,h,i,j */
+       000,000,'c',000,'c',            /* k,l,m,n,o */
+       000,'c',000,'c',000,            /* p,q,r,s,t */
+       000,'c',000,000,'c',            /* u,v,w,x,y */
+       'c',0                           /* z */
+       };
+/* Computer Center F Machine (F) */
+char configF[] = {             /* to get to i, config[i] */
+       'd','d','d','d','d',            /* a,b,c,d,e */
+       'f',000,000,'d','d',            /* f,g,h,i,j */
+       000,000,'d',000,'d',            /* k,l,m,n,o */
+       000,'d',000,'d',000,            /* p,q,r,s,t */
+       000,'d',000,000,'d',            /* u,v,w,x,y */
+       'd',0                           /* z */
+       };
+/* Project INGRES 11/70 (Ing70) */
+char configI[] = {             /* to get to i, config[i] */
+       'v','v','v','v','v',            /* a,b,c,d,e */
+       'v',000,000,'i','j',            /* f,g,h,i,j */
+       000,000,'v',000,'v',            /* k,l,m,n,o */
+       000,'v',000,'v',000,            /* p,q,r,s,t */
+       000,'v',000,000,'v',            /* u,v,w,x,y */
+       'v',0                           /* z */
+       };
+/* Project INGRES VAX (IngVAX) */
+char configJ[] = {             /* to get to i, config[i] */
+       'i','i','i','i','i',            /* a,b,c,d,e */
+       'i',000,000,'i','j',            /* f,g,h,i,j */
+       000,000,'i',000,'i',            /* k,l,m,n,o */
+       000,'i',000,'i',000,            /* p,q,r,s,t */
+       000,'i',000,000,'i',            /* u,v,w,x,y */
+       'i',0                           /* z */
+       };
+/* Sakrison's Image Project 11/40 (Image) */
+char configM[] = {             /* to get to i, config[i] */
+       'o','o','o','o','o',            /* a,b,c,d,e */
+       'o',000,000,'o','o',            /* f,g,h,i,j */
+       000,000,'m',000,'o',            /* k,l,m,n,o */
+       000,'o',000,'o',000,            /* p,q,r,s,t */
+       000,'o',000,000,'o',            /* u,v,w,x,y */
+       'o',0                           /* z */
+       };
+/* Pfeister - Pollack - Sangiovanni Optimization VAX (OptVAX) */
+char configO[] = {             /* to get to i, config[i] */
+       'y','y','y','y','y',            /* a,b,c,d,e */
+       'y',000,000,'y','y',            /* f,g,h,i,j */
+       000,000,'m',000,'o',            /* k,l,m,n,o */
+       000,'y',000,'y',000,            /* p,q,r,s,t */
+       000,'y',000,000,'y',            /* u,v,w,x,y */
+       'z',0                           /* z */
+       };
+/* Computer Center Q Machine (Q) */
+char configQ[] = {             /* to get to i, config[i] */
+       'd','d','d','d','d',            /* a,b,c,d,e */
+       'd',000,000,'d','d',            /* f,g,h,i,j */
+       000,000,'d',000,'d',            /* k,l,m,n,o */
+       000,'q',000,'d',000,            /* p,q,r,s,t */
+       000,'d',000,000,'d',            /* u,v,w,x,y */
+       'd',0                           /* z */
+       };
+/* Survey Research Center 11/40 (SRC) */
+char configS[] = {             /* to get to i, config[i] */
+       'd','d','d','d','d',            /* a,b,c,d,e */
+       'd',000,000,'d','d',            /* f,g,h,i,j */
+       000,000,'d',000,'d',            /* k,l,m,n,o */
+       000,'d',000,'s',000,            /* p,q,r,s,t */
+       000,'d',000,000,'d',            /* u,v,w,x,y */
+       'd',0                           /* z */
+       };
+/* EECS Research (Fateman - Ernie) VAX (CSVAX) */
+char configV[] = {             /* to get to i, config[i] */
+       'y','y','y','y','y',            /* a,b,c,d,e */
+       'y',000,000,'i','i',            /* f,g,h,i,j */
+       000,000,'y',000,'y',            /* k,l,m,n,o */
+       000,'y',000,'y',000,            /* p,q,r,s,t */
+       000,'v',000,000,'y',            /* u,v,w,x,y */
+       'y',0                           /* z */
+       };
+/* EECS Instructional 11/70 (199 Cory) (Cory) */
+char configY[] = {             /* to get to i, config[i] */
+       'c','c','c','c','c',            /* a,b,c,d,e */
+       'c',000,000,'v','v',            /* f,g,h,i,j */
+       000,000,'o',000,'o',            /* k,l,m,n,o */
+       000,'c',000,'c',000,            /* p,q,r,s,t */
+       000,'v',000,000,'y',            /* u,v,w,x,y */
+       'o',0                           /* z */
+       };
+/* EECS Departmental 11/40  (EECS40) */
+char configZ[] = {             /* to get to i, config[i] */
+       'o','o','o','o','o',            /* a,b,c,d,e */
+       'o',000,000,'o','o',            /* f,g,h,i,j */
+       000,000,'o',000,'o',            /* k,l,m,n,o */
+       000,'o',000,'o',000,            /* p,q,r,s,t */
+       000,'o',000,000,'o',            /* u,v,w,x,y */
+       'z',0                           /* z */
+       };
+/* this table is used by netlpr to do lpr w/o an acct
+   and by net and netdaemon to do pre-emption */
+/* sub.c uses the table in initdaemon to check machine
+   type - errormsg may be ignored */
+char machtype[]= {
+       M_CC, M_CC, M_CC, M_CC, M_CC,   /* a,b,c,d,e */
+       M_CC, 0, 0, M_INGRES, M_INGRES, /* f,g,h,i,j */
+       0, 0, M_OTHER, 0, M_VAX,                /* k,l,m,n,o */
+       0, M_CC, 0, M_SRC, 0,           /* p,q,r,s,t */
+       0, M_VAX, 0, 0, M_CORY,         /* u,v,w,x,y */
+       M_OTHER, 0};                            /* z */
+
+/* this is basically the default machine for each local machine */
+char remtable[] = {
+       'c','d','a','c','c',            /* a,b,c,d,e */
+       'd',000,000,'j','i',            /* f,g,h,i,j */
+       000,000,'v',000,'v',            /* k,l,m,n,o */
+       000,'d',000,'d',000,            /* p,q,r,s,t */
+       000,'y',000,000,'v',            /* u,v,w,x,y */
+       'i',0                           /* z */
+       };
+/* bad login names */
+struct bstruct btable[] = {
+       "op", 'a',
+       0,0 };
+/* this table shows the correspondence between
+   machine names like 'Cory' and their internal
+   names, like 'y' */
+static struct tt {
+       char *bigname;
+       char lname;
+       } table[] = {
+       "A",            'a',
+       "B",            'b',
+       "C",            'c',
+       "D",            'd',
+       "E",            'e',
+       "F",            'f',
+       "CCVAX",        'f',
+       "Ing70",        'i',
+       "Ingres",       'i',
+       "IngVAX",       'j',
+       "Image",        'm',
+       "OptVAX",       'o',
+       "SESM",         'o',
+       "Q",            'q',
+       "SRC",          's',
+       "CSVAX",        'v',
+       "ucbvax",       'v',
+       "VAX",          'v',
+       "Cory",         'y',
+       "EECS40",       'z',
+       0,              0
+       };
diff --git a/usr/src/cmd/net/filecat.c b/usr/src/cmd/net/filecat.c
new file mode 100644 (file)
index 0000000..e203f52
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+
+       filecat
+
+       does nothing more than copy standard input to standard
+       output, like the cat command, but reports write errors.
+       Takes no arguments.
+       Uses getc and putc rather than fwrite and fread because
+       the latter call getc and putc.
+
+       Exit codes:
+               0       ok
+               1       error on read
+               2       error on write
+
+*/
+# include <stdio.h>
+main(){
+       char c,sOutbuf[BUFSIZ];
+
+       setbuf(stdout,sOutbuf);
+
+       while((c = getc(stdin)) != EOF){
+               putc(c,stdout);
+               if(ferror(stdout)){
+                       perror("filecat: stdout");
+                       exit(2);
+               }
+       }
+       if(ferror(stdin)){
+               perror("filecat: stdin");
+               exit(1);
+       }
+       fclose(stdin);
+       fclose(stdout);
+       exit(0);
+}
diff --git a/usr/src/cmd/net/mach.c b/usr/src/cmd/net/mach.c
new file mode 100644 (file)
index 0000000..007a6a4
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+   This file is meant to handle all the machine
+   dependencies in the network code.
+   Everything is conditionally compiled.
+
+   It can be uses w/o network stuff to simulate
+   v7 for other programs, too.
+*/
+# include <stdio.h>
+# include "mach.h"
+
+char shomedir[100];
+
+# ifndef CC
+submit(a) {}
+# endif
+
+# ifdef FUID
+setgid() {};
+# endif
+
+/* 
+   Set the owner uid/gid of a file.
+   On v7, this is done by the chown command
+   with three args - (file, uid, gid).
+   On Vanilla V6 this is done using the
+   top byte of the second parameter as the gid byte.
+   On Berkeley Funny uids on V6, no gid is specified.
+*/
+mchown(sfn,uid,gid)
+       char *sfn;
+       int uid;
+       int gid;
+{
+# ifndef V6
+       chown(sfn,uid,gid);
+# else
+# ifndef FUID
+               uid = uidmask(uid);
+               uid = ((gid&0377) << 8) | (uid & 0377);
+# endif
+       chown(sfn,uid);
+# endif
+}
+       
+
+char vaxtovax;
+long fixuplong(a)
+       long a; {
+# ifdef ISVAX
+       register char *p,c1,c2;
+       char c3,c4;
+       if(!vaxtovax){
+               p = (char*) &a;
+               c1 = *p++;
+               c2 = *p++;
+               c3 = *p++;
+               c4 = *p++;
+               p = (char*) &a;
+               *p++ = c3;
+               *p++ = c4;
+               *p++ = c1;
+               *p++ = c2;
+               }
+# endif
+       return(a);
+       }
+/*
+       SnFromuid(uid)
+
+       The login name corresponding to uid.
+       Reads the password file.
+       Successive calls overwrite the static string returned.
+       Returns NULL if error.
+*/
+char *SnFromUid(uid)
+       register int uid;
+{
+       register struct passwd *pwd;
+       static int ouid = -1;
+       static char oresult[20] = "";
+       uid = uidmask(uid);
+       if(uid == ouid)
+               return(oresult);
+# ifdef HPASSWD
+       if(getname(uid,oresult) == 0){
+               ouid = uid;
+               return(oresult);
+       }
+# endif
+       pwd = getpwuid(uid);
+       if(pwd != NULL){
+               strcpy(oresult,pwd->pw_name);
+               ouid = uid;
+               return(oresult);
+       }
+       return(NULL);
+}
+
+/* handle the regular unix and local mods difference for user id's */
+/* this call returns the 1 word uid = to what getuid will return */
+guid(uid,gid){
+       uid = uidmask(uid);
+# ifdef FUID
+       return((uid & 0377) | (gid << 8));
+# else
+       return(uid);
+# endif
+       }
+
+# ifdef OLDTTY
+isatty(i){
+       return(ttyn(i) != 'x');
+       }
+char *ttyname(i){              /* return NULL if not TTY */
+       char c;
+       static char ttystr[] = "/dev/ttyx";
+       c = ttyn(i);
+       ttystr[8] = c;
+       return(c == 'x' ? NULL : ttystr);
+       }
+# endif
+
+# ifdef CCTTY
+# undef ttyname()
+myttyname(i){          /* return NULL for non tty */
+       static char s[15],*p;
+       p = ttyname(i);
+       if(p == NULL)return(NULL);
+       strcpy(s,"/dev/");
+       strcat(s,p);
+       return(s);
+       }
+# define ttyname(S) myttyname(S)
+# endif
+
+/* get passwd from passwdf */
+getpwdf(pwd)
+  struct passwd *pwd; {
+# ifdef PASSWDF
+# ifndef TESTING
+       register char *p, *q;
+       char buf1[BUFSIZ], found;
+       FILE *pw;
+       pwd->pw_passwd[0] = 0;
+       pw = fopen("/etc/passwdf","r");
+       if(pw == NULL) return;
+       found = 0;
+       while(fgets(buf1,BUFSIZ,pw) != NULL){
+               for(p=buf1; *p && *p != ':'; p++);
+               *p = 0;
+               if(strcmp(buf1,pwd->pw_name) == 0){
+                       found = 1;
+                       break;
+                       }
+               }
+       fclose(pw);
+       if(!found)return;
+       q = ++p;
+       for(;*p && *p != ':';p++);
+       *p = 0;
+       strcpy(pwd->pw_passwd,q);
+       /*
+       debug("user %s passwd %s %s",pwd->pw_name,pwd->pw_passwd);
+       */
+# endif
+# endif
+       }
+/*
+   these are all the v7 routines not available on the v6 machines
+*/
+
+# ifdef V6
+
+char **environ;                        /* global environment pointer */
+
+ioctl(a,b,c){
+       return(0);              /* always succeeds */
+       }
+long atol(s)
+  register char *s; {
+       long i = 0;
+       while('0' <= *s && *s <= '9')
+               i = i * 10 + (*s++ - '0');
+       return(i);
+       }
+long gettime(){
+       long tt;
+       time(&tt);
+       return(tt);
+       }
+long getsize(str)
+  struct stat *str; {
+       long wk;
+       wk = ((long)(str->st_size0 & 0377)) << 16;
+       wk += (long)((unsigned)str->st_size1);
+       return(wk);
+       }
+/*
+       getenv("HOME")
+
+       always returns home directory.
+       returns NULL if there is error.
+*/
+char *getenv(){
+       register char *shdir = NULL;
+       register struct passwd *pwd;
+       register int it;
+       if(shomedir[0] != 0)return(shomedir);
+       it = ttyn(2);
+# ifdef OLDTTY
+       if(it == 'x')it = ttyn(1);
+       if(it == 'x')it = ttyn(0);
+       if(it != 'x' && hget(it) == 0)shdir = hgethome();
+# endif
+# ifdef CCTTY
+       if(it == -1)it = ttyn(1);
+       if(it == -1)it = ttyn(0);
+       if(it != -1 && hget(it) == 0)shdir = hgethome();
+# endif
+       if(shdir == NULL){
+               pwd = PwdCurrent();
+               if(pwd != NULL)shdir = pwd->pw_dir;
+               }
+       if(shdir != NULL)strcpy(shomedir,shdir);
+       return(shdir);
+       }
+
+/* doesn't handle split passwd files */
+struct passwd *
+getpwuid(uid)
+register uid;
+{
+       register struct passwd *p;
+       struct passwd *getpwent();
+
+       uid = uidmask(uid);
+       setpwent();
+       while( (p = getpwent()) && guid(p->pw_uid,p->pw_gid) != uid );
+       endpwent();
+       return(p);
+}
+
+static char PASSWD[]   = "/etc/passwd";
+static char EMPTY[] = "";
+static FILE *pwf = NULL;
+static char line[BUFSIZ+1];
+static struct passwd passwd;
+
+setpwent()
+{
+       if( pwf == NULL )
+               pwf = fopen( PASSWD, "r" );
+       else
+               rewind( pwf );
+}
+
+endpwent()
+{
+       if( pwf != NULL ){
+               fclose( pwf );
+               pwf = NULL;
+       }
+}
+
+static char *
+pwskip(p)
+register char *p;
+{
+       while( *p && *p != ':' )
+               ++p;
+       if( *p ) *p++ = 0;
+       return(p);
+}
+
+struct passwd *
+getpwent()
+{
+       register char *p;
+
+       if (pwf == NULL) {
+               if( (pwf = fopen( PASSWD, "r" )) == NULL )
+                       return(0);
+       }
+       p = fgets(line, BUFSIZ, pwf);
+       if (p==NULL)
+               return(0);
+       passwd.pw_name = p;
+       p = pwskip(p);
+       passwd.pw_passwd = p;
+       p = pwskip(p);
+       passwd.pw_uid = atoi(p);
+       passwd.pw_uid = uidmask(passwd.pw_uid);
+       p = pwskip(p);
+       passwd.pw_gid = atoi(p);
+       passwd.pw_quota = 0;
+       passwd.pw_comment = EMPTY;
+       p = pwskip(p);
+       passwd.pw_gecos = p;
+       p = pwskip(p);
+       passwd.pw_dir = p;
+       p = pwskip(p);
+       passwd.pw_shell = p;
+       while(*p && *p != '\n') p++;
+       *p = '\0';
+       return(&passwd);
+}
+
+struct passwd *
+getpwnam(name)
+char *name;
+{
+       register struct passwd *p;
+       struct passwd *getpwent();
+
+       setpwent();
+       while( (p = getpwent()) && strcmp(name,p->pw_name) );
+       endpwent();
+       return(p);
+}
+/*
+       getlogin()
+
+       Return current user name by looking at /etc/utmp.
+       Returns NULL if not found.
+*/
+char *getlogin()
+{
+       struct utmp utmpstr;
+       static char snSave[10];
+       register char *sttyname,*s;
+       register FILE *fp;
+
+       sttyname = ttyname(2);
+       if(sttyname == NULL)sttyname = ttyname(1);
+       if(sttyname == NULL)sttyname = ttyname(0);
+       if(sttyname == NULL)return(NULL);
+
+       fp = fopen("/etc/utmp","r");
+       if(fp == NULL)return(NULL);
+
+       snSave[0] = 0;
+       while(fread(&utmpstr,1,sizeof utmpstr,fp) == sizeof utmpstr){
+# ifdef OLDTTY
+               if(utmpstr.ut_tty == sttyname[8]){
+# else
+               if(strcmp(utmpstr.ut_line,sttyname+5) == 0){
+# endif
+                       utmpstr.ut_tty = 0;
+                       strcpy(snSave,utmpstr.ut_name);
+               }
+       }
+
+       fclose(fp);
+       s = snSave;
+       while(*s != 0 && *s != ' ')s++;
+       *s = 0;
+       if(snSave[0] == 0)return(NULL);
+       return(snSave);
+}
+/*
+ * Unix routine to do an "fopen" on file descriptor
+ * The mode has to be repeated because you can't query its
+ * status
+ */
+
+FILE *
+fdopen(fd, mode)
+register char *mode;
+{
+       extern int errno;
+       register FILE *iop;
+       extern FILE *_lastbuf;
+
+       for (iop = _iob; iop->_flag&(_IOREAD|_IOWRT); iop++)
+               if (iop >= _lastbuf)
+                       return(NULL);
+       iop->_cnt = 0;
+       iop->_file = fd;
+       if (*mode != 'r') {
+               iop->_flag |= _IOWRT;
+               if (*mode == 'a')
+                       lseek(fd, 0L, 2);
+       } else
+               iop->_flag |= _IOREAD;
+       return(iop);
+}
+system(s)
+char *s;
+{
+       int status, pid, w;
+       register int (*istat)(), (*qstat)();
+
+       while((pid = fork()) == -1)sleep(2);
+       if (pid == 0) {
+               execl("/bin/sh", "sh", "-c", s, 0);
+               _exit(127);
+       }
+       istat = signal(SIGINT, SIG_IGN);
+       qstat = signal(SIGQUIT, SIG_IGN);
+       while ((w = wait(&status)) != pid && w != -1)
+               ;
+       if (w == -1)
+               status = -1;
+       signal(SIGINT, istat);
+       signal(SIGQUIT, qstat);
+       return(status);
+}
+
+char *
+getpass(prompt)
+char *prompt;
+{
+       struct sgttyb ttyb;
+       int flags;
+       register char *p;
+       register c;
+       FILE *fi = NULL;
+       static char pbuf[9];
+       int (*signal())();
+       int (*sig)();
+
+       /*      modified because Cory needs super-user to stty /dev/tty */
+# ifndef CORY
+       if ((fi = fopen("/dev/tty", "r")) == NULL)
+               fi = stdin;
+       else
+               setbuf(fi, (char *)NULL);
+       gtty(fileno(fi), &ttyb);
+# else
+       if(gtty(0,&ttyb) >= 0)fi = stdin;
+       else if(gtty(2,&ttyb) >= 0)fi = stderr;
+       else {
+               pbuf[0] = 0;
+               return(pbuf);
+               }
+# endif
+       sig = signal(SIGINT, SIG_IGN);
+       flags = ttyb.sg_flags;
+       ttyb.sg_flags &= ~ECHO;
+       if(stty(fileno(fi), &ttyb) < 0) perror("stty:");
+       fprintf(stderr, prompt);
+       for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
+               if (p < &pbuf[8])
+                       *p++ = c;
+       }
+       *p = '\0';
+       fprintf(stderr, "\n");
+       ttyb.sg_flags = flags;
+       stty(fileno(fi), &ttyb);
+       signal(SIGINT, sig);
+# ifndef CORY
+       if (fi != stdin)
+               fclose(fi);
+# endif
+       return(pbuf);
+}
+/* end of non-vax v7 routines */
+# endif
diff --git a/usr/src/cmd/net/mach.h b/usr/src/cmd/net/mach.h
new file mode 100644 (file)
index 0000000..fdfed9c
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+
+       mach.h  -- define machine-dependent things
+
+*** Pre-processor Flags ***
+
+This set of code is controlled by this set of conditional
+compilation flags:
+
+TESTING                if defined, do not generate tests, etc. which require
+               super-user status.
+
+OLDTTY         if defined, compile for old 1 character TTY names
+CCTTY          if defined, compile for CC tty name format
+               if neither is defined, use v7 ttyname format
+
+PASSWDF                compile in code to handle /etc/passwdf - split passwd files
+
+NEWPROT                use the new protocol, instead of the default protocol
+
+V6             Assume the v6 features insted of the v7 ones.
+
+FUID           use the funny uid's present on Cory and CC
+ROPTION                The local machine mail program has the magic -r option
+ROPTION2       The local machine mail program has the magic -r option
+
+HPASSWD                The local machine has the hashed password stuff
+
+SPACCT         under certain circumstances, allow remote login without acct
+
+OLDMAIL                mail is in home-directory/.mail
+USRMAIL                mail is in /usr/mail/name
+               (mail is in /usr/spool/mail/name)
+
+CC             Machine is a Computer Center machine
+NUID           userid (as returned by getuid()) on this machine
+UID1CHAR       Uses vanila Version6 userid's (only 1 byte for uid)
+NOEUID         Does not have the geteuid() system call
+
+
+The conditonal flags are first defined
+in "/usr/include/whoami.h" on the local machine.
+
+For "normal" version 6 machines, there is a dummy machine
+definition for "VANILLA6" which indicates the v6 UNIX options.
+
+For "normal" version 7 machines, there is a dummy machine
+definition for "VANILLA7" which indicates the v7 UNIX options.
+*/
+/* be sure to include <stdio.h> before these defns */
+
+# include <whoami.h>
+
+/* note NUID is only used in mmail.c */
+
+# ifdef A
+# define CC
+# define LOCAL 'a'
+# endif
+
+# ifdef B
+# define CC
+# define LOCAL 'b'
+# endif
+
+# ifdef C
+# define CC
+# define LOCAL 'c'
+# endif
+
+# ifdef D
+# define CC
+# define LOCAL 'd'
+# endif
+
+# ifdef E
+# define CC
+# define LOCAL 'e'
+# endif
+
+# ifdef F
+# define ROPTION2
+# define LOCAL 'f'
+# define NUID (501)
+# define ISVAX
+# endif
+
+# ifdef ING70
+# define V6
+# define OLDTTY
+# define UID1CHAR
+# define PASSWDF
+# define ROPTION2
+# define MULTNAMS
+# define FREELPR
+# define LOCAL 'i'
+# define NUID (174)
+/* correct vers. 7 = LOCAL, NUID */
+# endif
+
+# ifdef INGVAX
+# define LOCAL 'j'
+# define NUID (37)
+# define ROPTION2
+# define ISVAX
+# define FREELPR
+# endif
+
+# ifdef IMAGE
+# define V6
+# define OLDTTY
+# define UID1CHAR
+# define USRMAIL
+# define LOCAL 'm'
+# define NUID (-1)
+/* correct vers. 7 = LOCAL, NUID */
+# endif
+
+# ifdef OPTVAX
+# define LOCAL 'o'
+# define NUID (-1)
+# define ISVAX
+# endif
+
+# ifdef Q
+# define V6
+# define OLDTTY
+# define FUID
+# define NOEUID
+# define LOCAL 'q'
+# define NUID ((11 << 8) | 38)
+/* correct vers. 7 = LOCAL, NUID */
+# endif
+
+# ifdef SRC
+# define V6
+# define OLDTTY
+# define FUID
+# define NOEUID
+# define SPACCT
+# define LOCAL 's'
+# define NUID ((11 << 8) | 38)
+/* correct vers. 7 = LOCAL, NUID */
+# endif
+
+# ifdef CSVAX
+# define ROPTION
+# define LOCAL 'v'
+# define NUID (501)
+# define ISVAX
+# endif
+
+# ifdef CORY
+# define LOCAL 'y'
+# define NUID (10)
+# define ROPTION
+# endif
+
+# ifdef EECS40
+# define V6
+# define OLDTTY
+# define USRMAIL
+# define UID1CHAR
+# define LOCAL 'z'
+# define NUID (-1)
+/* correct vers. 7 = LOCAL, NUID */
+# endif
+
+/*
+       the CC V6 machines are all the same.
+       splitting their type into a separate group will
+       allow the binary patching program "patchd" to be
+       used to patch the binaries so the sources can be compiled
+       on one CC machine and the binaries shipped around
+       to the other CC machines.
+*/
+# ifdef CC
+# define V6
+# define CCTTY
+# define PASSWDF
+# define FUID
+# define USRMAIL
+# define SPACCT
+# define NUID ((217 << 8) | 2)
+/* correct vers. 7 = LOCAL, NUID, CC */
+# endif
+
+/* default version 6 options */
+# ifdef VANILLA6
+# define V6
+# define UID1CHAR
+# define OLDTTY
+# endif
+
+/* default version 7 options */
+# ifdef VANILLA7
+# endif
+
+# ifndef V6
+# include <sys/param.h>
+# include <sys/stat.h>
+# include <sys/dir.h>
+# include <sys/times.h>
+/* # include <signal.h> */
+# include <ctype.h>
+# include <sgtty.h>
+# include <errno.h>
+# include <pwd.h>
+# include <assert.h>
+# include <setjmp.h>
+# define getsize(S)    ((S)->st_size)
+# define gettime()     (time(0))
+# define SIG_IGN       1
+
+# else
+
+# define ETXTBSY 26
+# define S_IREAD 0400
+# define S_IFMT 060000
+# define S_IFDIR 0040000
+# define ANYP 0300
+# define ECHO 010
+# define ROOTINO 1
+# define DIRSIZ 14
+# define TIOCEXCL 0
+# define SIGHUP                1
+# define SIGINT        2
+# define SIGQUIT       3
+# define SIGKIL                9
+# define SIGCLK        14
+# define SIGTRM        15
+# define SIG_IGN       1
+# define ASSERT "Assertion failed: file %s, line %d\n", __FILE__, __LINE__);exit(1);}}
+# define assert(ex) {if (!(ex)){fprintf(stderr,ASSERT
+# define isprint(c) (040 <= c && c <= 0176)
+# define longjmp(a,b) reset()
+# define setjmp(a) setexit()
+
+struct stat {
+       int st_dev;
+       int st_ino;
+       int st_mode;
+       char st_nlink:8;
+       char st_uid:8;
+       char st_gid:8;
+       char st_size0;
+       int st_size1;
+       int st_addr[8];
+       long st_atime;
+       long st_mtime;
+       };
+struct direct {
+       int d_ino;
+       char d_name[DIRSIZ];
+       };
+struct tms {                           /* see times - sect 2 */
+       int     tms_utime;              /* user time */
+       int     tms_stime;              /* system time */
+       long    tms_cutime;             /* user time, children */
+       long    tms_cstime;             /* system time, children */
+       };
+struct sgttyb {
+       char sg_ispeed;
+       char sg_ospeed;
+       char sg_erase;
+       char sg_kill;
+       int sg_flags;
+       };
+struct passwd { /* see getpwent(3) */
+       char    *pw_name;
+       char    *pw_passwd;
+       int     pw_uid;
+       int     pw_gid;
+       int     pw_quota;
+       char    *pw_comment;
+       char    *pw_gecos;
+       char    *pw_dir;
+       char    *pw_shell;
+       };
+typedef int jmp_buf[10];
+long gettime(), getsize();
+# endif
+/* end of non-v7 defns */
+
+# ifdef FUID
+# define getgid(s) (0)
+# endif
+
+# ifdef UID1CHAR
+# define uidmask(S) (S & 0377)
+# define geteuid() ((getuid()>>8)&0377)
+# else
+# define uidmask(S) (S)
+# endif
+
+# ifdef NOEUID
+# define geteuid(S) (-1)
+# endif
+
+# ifdef CCTTY
+# define ttyname(S) myttyname(S)
+# endif
+
+# ifdef OLDTTY
+struct utmp {
+       char ut_name[8];
+       char ut_tty;
+       char ut_fill;
+       long ut_time;
+       int  ut_fill1;
+       };
+# else
+# include <utmp.h>
+# endif
+
+/* functions */
+
+char *hgethome(), *calloc(), *ctime(), *getenv();
+char *getname(), *getun(), *getlogin();
+struct passwd *getpwnam(), *getpwuid();
+long fixuplong(),atol(),time();
diff --git a/usr/src/cmd/net/nbs.c b/usr/src/cmd/net/nbs.c
new file mode 100644 (file)
index 0000000..817d4d8
--- /dev/null
@@ -0,0 +1,521 @@
+# include <stdio.h>
+/* file nbs.c
+   This file has the necessary procedures to use the NBS algorithm
+   to encrypt and decrypt strings of arbitrary length.
+
+   Basically
+
+               ciphertext = nbsencrypt(cleartext,secretkey,ciphertext);
+
+   yields a string ciphertext from string cleartext using
+   the secret string secretkey.
+   Then
+
+               cleartext = nbsdecrypt(ciphertext,secretkey,cleartext);
+               
+   yields the original string cleartext IF the string secretkey
+   is the same for both calls.
+   The third parameter is filled with the result of the call-
+   it must be (11/8)*size(firstarg).
+   The first and third areguments must be different.
+   The cleartext must be ASCII - the top eighth bit is ignored,
+   so binary data won't work.
+   The plaintext is broken into 8 character sections,
+   encrypted, and concatenated separated by $'s to make the ciphertext.
+   The first 8 letter section uses the secretkey, subsequent
+   sections use the cleartext of the previous section as
+   the key.
+   Thus the ciphertext depends on itself, except for
+   the first section, which depends on the key.
+   This means that sections of the ciphertext, except the first,
+   may not stand alone.
+   Only the first 8 characters of the key matter.
+*/
+char *deblknot(), *deblkclr();
+char *nbs8decrypt(), *nbs8encrypt();
+static char    E[48];
+char e[];
+char *nbsencrypt(str,key,result)
+  char *result;
+  register char *str, *key; {
+       static char buf[20],oldbuf[20];
+       register int j;
+       result[0] = 0;
+       strcpy(oldbuf,key);
+       while(*str){
+               for(j=0;j<10;j++)buf[j] = 0;
+               for(j=0;j<8 && *str;j++)buf[j] = *str++;
+               strcat(result,nbs8encrypt(buf,oldbuf));
+               strcat(result,"$");
+               strcpy(oldbuf,buf);
+               }
+       return(result);
+       }
+char *nbsdecrypt(cpt,key,result)
+  char *result;
+  register char *cpt,*key; {
+       register char *s;
+       char c,oldbuf[20];
+       result[0] = 0;
+       strcpy(oldbuf,key);
+       while(*cpt){
+               for(s = cpt;*s && *s != '$';s++);
+               c = *s;
+               *s = 0;
+               strcpy(oldbuf,nbs8decrypt(cpt,oldbuf));
+               strcat(result,oldbuf);
+               if(c == 0)break;
+               cpt = s + 1;
+               }
+       return(result);
+       }
+/* all other calls are private */
+/*
+testing(){
+       static char stbuf[BUFSIZ],res[BUFSIZ];
+       register char *s;
+       char str[BUFSIZ];
+       setbuf(stdout,stbuf);
+       while(!feof(stdin)){
+               fprintf(stderr,"String:\n");
+               fgets(str,BUFSIZ,stdin);
+               if(feof(stdin))break;
+               strcat(str,"\n");
+               s = nbsencrypt(str,"hellothere",res);
+               fprintf(stderr,"encrypted:\n%s\n",s);
+               fprintf(stderr,"decrypted:\n");
+               printf("%s",nbsdecrypt(s,"hellothere",str));
+               fprintf(stderr,"\n");
+               }
+       }
+*/
+/*
+       To encrypt:
+       The first level of call splits the input strings into strings
+       no longer than 8 characters, for encryption.
+       Then the encryption of 8 characters breaks all but the top bit
+       of each character into a 64-character block, each character
+       with 1 or 0 corresponding to binary.
+       The key is set likewise.
+       The encrypted form is then converted, 6 bits at a time,
+       into an ASCII string.
+
+       To decrypt:
+       We take the result of the encryption, 6 significant bits
+       per character, and convert it to the block(64-char) fmt.
+       This is decrypted by running the nbs algorithm in reverse,
+       and transformed back into 7bit ASCII.
+
+       The subroutines to do ASCII blocking and deblocking
+       are .....clr and the funny 6-bit code are .....not.
+
+*/
+
+char *nbs8encrypt(str,key)
+register char *str, *key; {
+       static char keyblk[100], blk[100];
+       register int i;
+
+       enblkclr(keyblk,key);
+       nbssetkey(keyblk);
+
+       for(i=0;i<48;i++) E[i] = e[i];
+       enblkclr(blk,str);
+       blkencrypt(blk,0);                      /* forward dir */
+
+       return(deblknot(blk));
+}
+char *nbs8decrypt(crp,key)
+register char *crp, *key; {
+       static char keyblk[100], blk[100];
+       register int i;
+
+       enblkclr(keyblk,key);
+       nbssetkey(keyblk);
+
+       for(i=0;i<48;i++) E[i] = e[i];
+       enblknot(blk,crp);
+       blkencrypt(blk,1);                      /* backward dir */
+
+       return(deblkclr(blk));
+}
+enblkclr(blk,str)              /* ignores top bit of chars in string str */
+char *blk,*str; {
+       register int i,j;
+       register char c;
+       for(i=0;i<70;i++)blk[i] = 0;
+       for(i=0; (c= *str) && i<64; str++){
+               for(j=0; j<7; j++, i++)
+                       blk[i] = (c>>(6-j)) & 01;
+               i++;
+               }
+       }
+char *deblkclr(blk)
+char *blk; {
+       register int i,j;
+       register char c;
+       static char iobuf[30];
+       for(i=0; i<10; i++){
+               c = 0;
+               for(j=0; j<7; j++){
+                       c <<= 1;
+                       c |= blk[8*i+j];
+                       }
+               iobuf[i] = c;
+       }
+       iobuf[i] = 0;
+       return(iobuf);
+       }
+enblknot(blk,crp)
+char *blk;
+char *crp; {
+       register int i,j;
+       register char c;
+       for(i=0;i<70;i++)blk[i] = 0;
+       for(i=0; (c= *crp) && i<64; crp++){
+               if(c>'Z') c -= 6;
+               if(c>'9') c -= 7;
+               c -= '.';
+               for(j=0; j<6; j++, i++)
+                       blk[i] = (c>>(5-j)) & 01;
+               }
+       }
+char *deblknot(blk)
+char *blk; {
+       register int i,j;
+       register char c;
+       static char iobuf[30];
+       for(i=0; i<11; i++){
+               c = 0;
+               for(j=0; j<6; j++){
+                       c <<= 1;
+                       c |= blk[6*i+j];
+                       }
+               c += '.';
+               if(c > '9')c += 7;
+               if(c > 'Z')c += 6;
+               iobuf[i] = c;
+       }
+       iobuf[i] = 0;
+       return(iobuf);
+       }
+/*
+ * This program implements the
+ * Proposed Federal Information Processing
+ *  Data Encryption Standard.
+ * See Federal Register, March 17, 1975 (40FR12134)
+ */
+
+/*
+ * Initial permutation,
+ */
+static char    IP[] = {
+       58,50,42,34,26,18,10, 2,
+       60,52,44,36,28,20,12, 4,
+       62,54,46,38,30,22,14, 6,
+       64,56,48,40,32,24,16, 8,
+       57,49,41,33,25,17, 9, 1,
+       59,51,43,35,27,19,11, 3,
+       61,53,45,37,29,21,13, 5,
+       63,55,47,39,31,23,15, 7,
+};
+
+/*
+ * Final permutation, FP = IP^(-1)
+ */
+static char    FP[] = {
+       40, 8,48,16,56,24,64,32,
+       39, 7,47,15,55,23,63,31,
+       38, 6,46,14,54,22,62,30,
+       37, 5,45,13,53,21,61,29,
+       36, 4,44,12,52,20,60,28,
+       35, 3,43,11,51,19,59,27,
+       34, 2,42,10,50,18,58,26,
+       33, 1,41, 9,49,17,57,25,
+};
+
+/*
+ * Permuted-choice 1 from the key bits
+ * to yield C and D.
+ * Note that bits 8,16... are left out:
+ * They are intended for a parity check.
+ */
+static char    PC1_C[] = {
+       57,49,41,33,25,17, 9,
+        1,58,50,42,34,26,18,
+       10, 2,59,51,43,35,27,
+       19,11, 3,60,52,44,36,
+};
+
+static char    PC1_D[] = {
+       63,55,47,39,31,23,15,
+        7,62,54,46,38,30,22,
+       14, 6,61,53,45,37,29,
+       21,13, 5,28,20,12, 4,
+};
+
+/*
+ * Sequence of shifts used for the key schedule.
+*/
+static char    shifts[] = {
+       1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
+};
+
+/*
+ * Permuted-choice 2, to pick out the bits from
+ * the CD array that generate the key schedule.
+ */
+static char    PC2_C[] = {
+       14,17,11,24, 1, 5,
+        3,28,15, 6,21,10,
+       23,19,12, 4,26, 8,
+       16, 7,27,20,13, 2,
+};
+
+static char    PC2_D[] = {
+       41,52,31,37,47,55,
+       30,40,51,45,33,48,
+       44,49,39,56,34,53,
+       46,42,50,36,29,32,
+};
+
+/*
+ * The C and D arrays used to calculate the key schedule.
+ */
+
+static char    C[28];
+static char    D[28];
+/*
+ * The key schedule.
+ * Generated from the key.
+ */
+static char    KS[16][48];
+
+/*
+ * Set up the key schedule from the key.
+ */
+
+nbssetkey(key)
+char *key;
+{
+       register i, j, k;
+       int t;
+
+       /*
+        * First, generate C and D by permuting
+        * the key.  The low order bit of each
+        * 8-bit char is not used, so C and D are only 28
+        * bits apiece.
+        */
+       for (i=0; i<28; i++) {
+               C[i] = key[PC1_C[i]-1];
+               D[i] = key[PC1_D[i]-1];
+       }
+       /*
+        * To generate Ki, rotate C and D according
+        * to schedule and pick up a permutation
+        * using PC2.
+        */
+       for (i=0; i<16; i++) {
+               /*
+                * rotate.
+                */
+               for (k=0; k<shifts[i]; k++) {
+                       t = C[0];
+                       for (j=0; j<28-1; j++)
+                               C[j] = C[j+1];
+                       C[27] = t;
+                       t = D[0];
+                       for (j=0; j<28-1; j++)
+                               D[j] = D[j+1];
+                       D[27] = t;
+               }
+               /*
+                * get Ki. Note C and D are concatenated.
+                */
+               for (j=0; j<24; j++) {
+                       KS[i][j] = C[PC2_C[j]-1];
+                       KS[i][j+24] = D[PC2_D[j]-28-1];
+               }
+       }
+}
+
+/*
+ * The E bit-selection table.
+ */
+static char    e[] = {
+       32, 1, 2, 3, 4, 5,
+        4, 5, 6, 7, 8, 9,
+        8, 9,10,11,12,13,
+       12,13,14,15,16,17,
+       16,17,18,19,20,21,
+       20,21,22,23,24,25,
+       24,25,26,27,28,29,
+       28,29,30,31,32, 1,
+};
+
+/*
+ * The 8 selection functions.
+ * For some reason, they give a 0-origin
+ * index, unlike everything else.
+ */
+static char    S[8][64] = {
+       14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
+        0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
+        4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
+       15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
+
+       15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
+        3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
+        0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
+       13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
+
+       10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
+       13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
+       13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
+        1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
+
+        7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
+       13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
+       10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
+        3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
+
+        2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
+       14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
+        4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
+       11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
+
+       12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
+       10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
+        9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
+        4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
+
+        4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
+       13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
+        1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
+        6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
+
+       13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
+        1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
+        7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
+        2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
+};
+
+/*
+ * P is a permutation on the selected combination
+ * of the current L and key.
+ */
+static char    P[] = {
+       16, 7,20,21,
+       29,12,28,17,
+        1,15,23,26,
+        5,18,31,10,
+        2, 8,24,14,
+       32,27, 3, 9,
+       19,13,30, 6,
+       22,11, 4,25,
+};
+
+/*
+ * The current block, divided into 2 halves.
+ */
+static char    L[32], R[32];
+static char    tempL[32];
+static char    f[32];
+
+/*
+ * The combination of the key and the input, before selection.
+ */
+static char    preS[48];
+
+/*
+ * The payoff: encrypt a block.
+ */
+
+blkencrypt(block, edflag)
+char *block;
+{
+       int i, ii;
+       register t, j, k;
+
+       /*
+        * First, permute the bits in the input
+        */
+       for (j=0; j<64; j++)
+               L[j] = block[IP[j]-1];
+       /*
+        * Perform an encryption operation 16 times.
+        */
+       for (ii=0; ii<16; ii++) {
+               /*
+                * Set direction
+                */
+               if (edflag)
+                       i = 15-ii;
+               else
+                       i = ii;
+               /*
+                * Save the R array,
+                * which will be the new L.
+                */
+               for (j=0; j<32; j++)
+                       tempL[j] = R[j];
+               /*
+                * Expand R to 48 bits using the E selector;
+                * exclusive-or with the current key bits.
+                */
+               for (j=0; j<48; j++)
+                       preS[j] = R[E[j]-1] ^ KS[i][j];
+               /*
+                * The pre-select bits are now considered
+                * in 8 groups of 6 bits each.
+                * The 8 selection functions map these
+                * 6-bit quantities into 4-bit quantities
+                * and the results permuted
+                * to make an f(R, K).
+                * The indexing into the selection functions
+                * is peculiar; it could be simplified by
+                * rewriting the tables.
+                */
+               for (j=0; j<8; j++) {
+                       t = 6*j;
+                       k = S[j][(preS[t+0]<<5)+
+                               (preS[t+1]<<3)+
+                               (preS[t+2]<<2)+
+                               (preS[t+3]<<1)+
+                               (preS[t+4]<<0)+
+                               (preS[t+5]<<4)];
+                       t = 4*j;
+                       f[t+0] = (k>>3)&01;
+                       f[t+1] = (k>>2)&01;
+                       f[t+2] = (k>>1)&01;
+                       f[t+3] = (k>>0)&01;
+               }
+               /*
+                * The new R is L ^ f(R, K).
+                * The f here has to be permuted first, though.
+                */
+               for (j=0; j<32; j++)
+                       R[j] = L[j] ^ f[P[j]-1];
+               /*
+                * Finally, the new L (the original R)
+                * is copied back.
+                */
+               for (j=0; j<32; j++)
+                       L[j] = tempL[j];
+       }
+       /*
+        * The output L and R are reversed.
+        */
+       for (j=0; j<32; j++) {
+               t = L[j];
+               L[j] = R[j];
+               R[j] = t;
+       }
+       /*
+        * The final output
+        * gets the inverse permutation of the very original.
+        */
+       for (j=0; j<64; j++)
+               block[j] = L[FP[j]-1];
+}
diff --git a/usr/src/cmd/net/netrm.c b/usr/src/cmd/net/netrm.c
new file mode 100644 (file)
index 0000000..8689fb2
--- /dev/null
@@ -0,0 +1,118 @@
+# include "defs.h"
+
+/*
+ *     netrm - remove an entry from the network queue.
+ *
+ *     first does a creat to truncate the file to zero length in
+ *     case it is being sent. (this stops the daemon!) Next the
+ *     file is removed. 
+ *     must be setuid root
+ */
+
+char   path[] =        NETRMPATH;
+char   pathname[]=     NETRMNAME;
+
+int hisuid, hisgid;
+static char visit[26];
+static struct stat statbuf;
+static struct direct dirbuf;
+
+main(argc,argv)
+char   *argv[];
+{
+       int cnt, mach, i, all = 0;
+
+       if (argc < 2)
+       {
+               printf("usage: netrm [-] file1 file2 ... filen\n");
+               exit(1);
+       }
+
+       hisuid = getuid();
+       hisuid = uidmask(hisuid);
+       hisgid = getgid();
+       
+       if(argv[1][0] == '-'){
+               all++;
+               argv++;
+               argc--;
+               }
+       cnt = 0;
+
+       while (++cnt < argc)rmfile(argv[cnt]);
+       if(all){
+               visit[local - 'a'] = 1;                 /* skip this machine */
+               for(i = 'a'; i <= 'z'; i++)
+                       if((mach = gothru(local,i)) && !visit[mach - 'a']){
+                               visit[mach - 'a'] = 1;
+                               senddir[strlen(senddir)-1] = mach;
+                               pdir(senddir);
+                               }
+               }
+       }
+static pdir(str)
+  char *str; {
+       FILE *df;
+       df = fopen(str,"r");
+       if(df == NULL || chdir(str) < 0){
+               perror(str);
+               exit(1);
+               }
+       while(fread(&dirbuf,1,sizeof dirbuf,df) == sizeof dirbuf){
+               if(dirbuf.d_ino == 0
+               || dirbuf.d_name[0] != 'd'
+               || dirbuf.d_name[1] != 'f'
+               || stat(dirbuf.d_name,&statbuf) < 0)
+                        continue;
+               if(guid(statbuf.st_uid,statbuf.st_gid) != hisuid)
+                       continue;
+               /* kludge in file name */
+               dirbuf.d_name[3] = dirbuf.d_name[2];
+               rmfile(dirbuf.d_name+3);
+               }
+       fclose(df);
+       }
+rmfile(str)
+  char *str;
+  {
+       register char *ap, *cp;
+       int tt;
+       char *ostr,*rem,buf[20];
+       ostr = str;
+       if(str[0] != 'd' || str[1] != 'f' || str[3] != 'a'){
+               strcpy(buf+3,str);
+               buf[0] = 'd';
+               buf[1] = 'f';
+               buf[2] = str[0];
+               buf[3] = 'a';
+               str = buf;
+               }
+       cp = path;
+       ap = pathname;
+       while (*ap++ = *cp++);
+       cp = pathname + strlen(pathname) - 10;
+       while(*cp++ != 'f');
+       cp--;
+       cp--;
+       rem = cp;
+       ap = str;
+       while(*cp != '\0' && (*cp++ = *ap++));
+       pathname[strlen(pathname) - 11] = str[2];       /* set dir for mach */
+
+       if (stat(pathname,&statbuf) < 0) {
+               perror(ostr);
+               return;
+       }
+
+       tt = guid(statbuf.st_uid,statbuf.st_gid);
+       if(tt != hisuid && hisuid != 0) {
+               printf("%s: Permission Denied\n",ostr);
+               return;
+       }
+
+       printf("removing file %s\n",ostr);
+       creat(pathname,0600);
+       unlink(pathname);
+       *rem = 'c';
+       unlink(pathname);
+}
diff --git a/usr/src/cmd/net/netstart.c b/usr/src/cmd/net/netstart.c
new file mode 100644 (file)
index 0000000..4b0a692
--- /dev/null
@@ -0,0 +1,41 @@
+# include <stdio.h>
+# include "mach.h"
+# include "Paths.h"
+/*
+ * this is a simple program to start up the net daemon,
+ * and when it fails, restart it
+ * 
+ * 
+ */
+static int daemon = 32767;             /* a nice safe process number */
+main(argc,argv)
+  char **argv; {
+       char *s,mchTo;
+       int r,killit(),pid;
+       while((pid = fork()) == -1)sleep(2);
+       if(pid != 0)exit(0);
+       submit(getpid());
+       signal(SIGQUIT,SIG_IGN);
+       signal(SIGHUP,SIG_IGN);
+       signal(SIGINT,SIG_IGN);
+       signal(SIGTRM,killit);
+       s = argc == 1 ? 0 : argv[1];
+       mchTo = argc == 1 ? 'a' : lookup(s);
+       for(;;){
+               while((daemon=fork()) == -1)sleep(2);
+               if(daemon == 0){
+                       execl(NETDAEMON,"netdaemon",s,0);
+                       exit(1);
+                       }
+               wait(&r);
+               addtolog(mchTo,"Net daemon exit code %d, low byte %o\n",
+                       (r>>8), (r&0377));
+               sleep(100);             /* avoid looping too fast */
+               }
+       }
+killit(){
+       kill(daemon,SIGTRM);            /* send terminate */
+       sleep(2);                       /* wait till cleanup */
+       kill(daemon,SIGKIL);            /* kill in case too */
+       exit(0);
+       }
diff --git a/usr/src/cmd/net/nsh.c b/usr/src/cmd/net/nsh.c
new file mode 100644 (file)
index 0000000..8977c62
--- /dev/null
@@ -0,0 +1,96 @@
+# include "defs.h"
+/*
+       nsh -c "comand to be executed"
+
+       This pseudo-shell is executed over the network
+       as the login shell of an acount "network", no passwd.
+       It will only execute certain allowed commands.
+
+       has these exit codes:
+               8 = wrong # arguments to nsh
+               9 = command you execute may not take arguments
+               10= the execl failed
+               11= could not find full path name for the command
+
+       count is the # of arguments (= argc) allowed.
+       a count of 0 turns off the command
+*/
+
+struct {
+       char *app;
+       char count;
+       char *full;
+       char *full1;
+       } st[] = {
+       "bpq",          20,     "/usr/bin/bpq",         "/bin/bpq",
+       "epq",          20,     "/usr/bin/epq",         "/bin/epq",
+       "finger",       20,     "/usr/ucb/finger",      "/usr/bin/finger",
+       "lpq",          20,     "/usr/bin/lpq",         "/bin/lpq",
+# ifdef FREELPR
+       "lpr",          20,     "/usr/bin/lpr",         "/bin/lpr",
+# endif
+       "mmail",        20,     "/usr/net/bin/mmail",   "/usr/net/bin/mmail",
+       "mwrite",       20,     "/usr/net/bin/mwrite",  "/usr/net/bin/mwrite",
+       "netlog",       20,     "/usr/bin/netlog",      "/usr/ucb/netlog",
+       "netq",         20,     "/usr/bin/netq",        "/usr/ucb/netq",
+       "prmail",       20,     "/usr/net/bin/prmail",  "/usr/net/bin/prmail",
+       "ps",           20,     "/bin/ps",              "/usr/bin/ps",
+       "pstat",        20,     "/usr/bin/pstat",       "/bin/pstat",
+       "rcs",          20,     "/usr/bin/rcs",         "/bin/rcs",
+       "rcslog",       1,      "/usr/bin/rcslog",      "/bin/rcslog",
+       "rcsq",         20,     "/usr/bin/rcsq",        "/bin/rcsq",
+       "trq",          20,     "/usr/bin/trq",         "/bin/trq",
+       "w",            20,     "/usr/bin/w",           "/usr/ucb/w",
+       "where",        20,     "/usr/bin/where",       "/bin/where",
+       "who",          20,     "/bin/who",             "/usr/bin/who",
+       "whom",         20,     "/usr/ucb/whom",        "/usr/bin/whom",
+       "write",        20,     "/usr/bin/write",       "/bin/write",
+       "yank",         20,     "/usr/ucb/yank",        "/usr/bin/yank",
+       0,              0,              0,              0
+       };
+/* nsh -c cmd */
+main(argc,argv)
+  char **argv; {
+       char *s, buf[500];
+       int i, flg = 0;
+       if(argc != 3){
+               fprintf(stderr,"Wrong number of arguments to nsh.\n");
+               exit(8);
+       }
+       s = argv[2];
+       while(*s && *s != ' ')s++;
+       if(*s == ' ')flg++;
+       *s = 0;
+       if((i = mlookup(argv[2])) < 0){
+               fprintf(stderr,
+               "Command '%s' is not allowed if logged in as 'network'.\n",
+                       argv[2]);
+               exit(11);
+       }
+       if(st[i].count == 0){
+               fprintf(stderr,
+               "The command '%s' is not allowed to have arguments.\n",argv[2]);
+               exit(9);
+               }
+       if(stat(st[i].full,buf) >= 0)
+               strcpy(buf,st[i].full);
+       else strcpy(buf,st[i].full1);
+       if(flg && st[i].count > 1){  /* some cmds don't allow parms */
+               *s = ' ';
+               strcat(buf,s);
+               }
+       /*
+       fprintf(stderr,"%s\n",buf);
+       */
+       execl(Bsh,"sh","-c",buf,0);
+       fprintf(stderr,"Execute of shell failed.\n");
+       exit(10);
+       }
+mlookup(s)
+  char *s; {
+       int i;
+       for(i = 0; st[i].app; i++)
+               if(strcmp(st[i].app,s) == 0 || strcmp(st[i].full,s) == 0
+                || strcmp(st[i].full1,s) == 0)return(i);
+       return(-1);
+       }
diff --git a/usr/src/cmd/net/setup.c b/usr/src/cmd/net/setup.c
new file mode 100644 (file)
index 0000000..aefc598
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+       setup.c
+
+       support procedures used in setting up the network
+
+*/
+
+# include "defs.h"
+
+char logfile[] =       LOGFILE;
+
+/* global variables */
+int datasize = SIZE;           /* best if mult of 512 */
+char vaxtovax = 0;
+int linkspeed = LINKS;
+char local;
+char device[];
+int debugflg;
+int maxbread,atime;
+int onlyuid;
+
+short masterseqno;
+FILE *readtty,*writetty;
+int readfd, writefd, pipesim;
+/*
+       called in netdaemon and debugging software
+       handles parameter lists to setup
+       remote machine and pipes
+*/
+setupdaemon(argc,argv)
+  char **argv; {
+       remote = argc > 1 ? lookup(argv[1]) : getremote(local);
+       if(argc == 4){  /* simulate using pipes */
+               readfd = atoi(argv[2]);
+               writefd = atoi(argv[3]);
+               pipesim++;
+               }
+       initdaemon();
+       }
+/*
+       set the correct mode on the link device
+*/
+setup(str)
+  char *str; {
+       struct sgttyb stt;
+       static char readbuf[BUFSIZ],writebuf[BUFSIZ];
+       if(str == 0 || str[0] == 0){
+               err("invalid net device\n");
+               exit(1);
+               }
+       masterseqno = 1;
+       readtty = pipesim ? fdopen(readfd,"r") : fopen(str,"r");
+       if(readtty == NULL){
+               perror(str);
+               exit(1);
+               }
+       writetty = pipesim ? fdopen(writefd,"w") : fopen(str,"w");
+       if(writetty == NULL){
+               perror(str);
+               exit(1);
+               }
+       if(!pipesim){
+               /* set exclusive use for line */
+               if(ioctl(fileno(readtty),TIOCEXCL,&stt) != 0 ||
+                       gtty(fileno(readtty),&stt) < 0){
+                       perror(str);
+                       exit(1);
+                       }
+               stt.sg_ispeed = stt.sg_ospeed = linkspeed;  /* user-set baud */
+               stt.sg_erase = stt.sg_kill = 0;         /* erase and kill off */
+               stt.sg_flags = ANYP;    /* even and odd parity, off everything else */
+               if(stty(fileno(readtty),&stt) < 0){
+                       perror(str);
+                       exit(1);
+                       }
+               }
+       setbuf(readtty,readbuf);
+       setbuf(writetty,writebuf);
+       }
+/*
+       initialize various data structures and print banner
+*/
+initdaemon(){
+       long timev;
+       int timei;
+       FILE *cfile;
+       cfile = fopen(INITFILE,"r");
+       rdnetfile(cfile);
+       fclose(cfile);
+       err("remote %c local %c link %s speed %d vtov %d length %d\n",
+       remote,local,device,linkspeed,vaxtovax,datasize);
+       err("debug %d time %d count %d onlyuid %d\n",debugflg,atime,
+               maxbread,onlyuid);
+       setup(device);
+       timev = gettime();
+       timei = timev >> 16;
+       srand(timei);
+# ifdef IMAGE
+       if(machtype[local - 'a'] != M_OTHER)
+# endif
+# ifdef EECS40
+       if(machtype[local - 'a'] != M_OTHER)
+# endif
+# ifdef OPTVAX
+       if(machtype[local - 'a'] != M_OTHER)
+# endif
+# ifdef CSVAX
+       if(machtype[local - 'a'] != M_VAX)
+# endif
+# ifdef CORY
+       if(machtype[local - 'a'] != M_CORY)
+# endif
+# ifdef INGVAX
+       if(machtype[local - 'a'] != M_INGRES)
+# endif
+# ifdef ING70
+       if(machtype[local - 'a'] != M_INGRES)
+# endif
+# ifdef CC
+       if(machtype[local -'a'] != M_CC && machtype[local - 'a'] != M_SRC)
+# endif
+               err("Machine type disagrees with local machine\n");
+       }
+/*VARARGS0*/
+error(s,a,b,c,d,e,f,g,h)
+char *s; {
+       char buf[10];
+       if(remote != 0) sprintf(buf,"%s",longname(remote));
+       else buf[0] = 0;
+       fflush(stdout);
+       if(debugflg){
+               fprintf(stderr,s,a,b,c,d,e,f,g,h);
+               putc('\n',stderr);
+               }
+       addtolog(remote,"Err %s: ",buf);
+       addtolog(remote,s,a,b,c,d,e,f,g,h);
+       addtolog(remote,"\n");
+       }
+/* this is really not right - we should use the rcslog format */
+/* also, the user must be able to write on the
+   public logfile to get error messages such as
+   directory not found after he has
+   setuid'd from root
+*/
+/*VARARGS0*/
+addtolog(mach,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n)
+char *s;
+{
+       static FILE *log = NULL;
+       struct stat statbuf;
+       logfile[strlen(logfile)-1] = mach;
+       if(log == NULL){
+               if(stat(logfile,&statbuf) < 0)return;
+               log = fopen(logfile,"a");
+               }
+       if(log == NULL)return;
+       fseek(log,0L,2);
+       fprintf(log,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n);
+       fflush(log);
+       debug(s,a,b,c,d,e,f,g,h,i,h,k,l,m,n);
+       }