formatting
[unix-history] / usr / src / usr.sbin / lpr / lpr / lpr.c
index 1ec6e43..4af05cf 100644 (file)
 
 char lpr_id[] = "~|^`lpr.c:\t4.2\t1 May 1981\n";
 
 
 char lpr_id[] = "~|^`lpr.c:\t4.2\t1 May 1981\n";
 
-/*     lpr.c   4.3     81/05/19        */
+/*     lpr.c   4.10    83/03/09        */
 /*
  *      lpr -- off line print
 /*
  *      lpr -- off line print
- *              also known as print
+ *
+ * Allows multiple printers and printers on remote machines by
+ * using information from a printer data base.
  */
 
 #include <sys/types.h>
 #include <sys/stat.h>
  */
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/file.h>
 #include <signal.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <ctype.h>
 #include "lp.local.h"
 
 #include <signal.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <ctype.h>
 #include "lp.local.h"
 
-/*
- * Multiple printer scheme using info from printer data base:
- *
- *     DN              who to invoke to print stuff
- *     SA              rectory used as spool queue
- *
- * daemon identifies what printer it should use (in the case of the
- *  same code being shared) by inspecting its argv[1].
- */
-char    *tfname;               /* tmp copy of df before linking */
-char    *cfname;               /* copy files */
-char    *lfname;               /* linked files */
-char    *dfname;               /* daemon files, linked from tf's */
+char    *tfname;               /* tmp copy of cf before linking */
+char    *cfname;               /* daemon control files, linked from tf's */
+char    *dfname;               /* data files */
 
 int    nact;                   /* number of jobs to act on */
 
 int    nact;                   /* number of jobs to act on */
-int    tff;                    /* daemon file descriptor */
+int    tfd;                    /* control file descriptor */
 int     mailflg;               /* send mail */
 int     mailflg;               /* send mail */
-int    jflag;                  /* job name specified */
-int    qflg;                   /* q job, but don't exec daemon */
-int    prflag;                 /* ``pr'' files */
+int    qflag;                  /* q job, but don't exec daemon */
+char   format = 'f';           /* format char for printing files */
+int    rflag;                  /* remove files upon completion */      
+int    lflag;                  /* link flag */
 char   *person;                /* user name */
 int    inchar;                 /* location to increment char in file names */
 int     ncopies = 1;           /* # of copies to make */
 int    iflag;                  /* indentation wanted */
 int    indent;                 /* amount to indent */
 char   *person;                /* user name */
 int    inchar;                 /* location to increment char in file names */
 int     ncopies = 1;           /* # of copies to make */
 int    iflag;                  /* indentation wanted */
 int    indent;                 /* amount to indent */
-char   *daemname;              /* path name to daemon program */
-char   *DN;                    /* daemon name */
-char   *SA;                    /* spooling area */
-char   *LP;                    /* line printer device */
+char   *DN;                    /* path name to daemon program */
+char   *LP;                    /* line printer device name */
+char   *RM;                    /* remote machine name if no local printer */
+char   *SD;                    /* spool directory */
 int     MX;                    /* maximum size in blocks of a print file */
 int     MX;                    /* maximum size in blocks of a print file */
-int    hdr = 1;                /* 1 =>'s default header */
-int     user;                  /* user id */
-int    spgroup;                /* daemon's group for creating spool files */
+int    hdr = 1;                /* print header or not (default is yes) */
+int     userid;                        /* user id */
 char   *title;                 /* pr'ing title */
 char   *title;                 /* pr'ing title */
-char   *class = SYSTEM_NAME;   /* class title on header page */
+char   *fonts[4];              /* troff font names */
+char   *width;                 /* width for versatec printing */
+char   host[32];               /* host name */
+char   *class = host;          /* class title on header page */
 char    *jobname;              /* job name on header page */
 char   *name;                  /* program name */
 char    *jobname;              /* job name on header page */
 char   *name;                  /* program name */
-char   *printer;               /* printer name */
 
 char   *pgetstr();
 
 char   *pgetstr();
-char   *mktmp();
 char   *malloc();
 char   *getenv();
 char   *rindex();
 char   *malloc();
 char   *getenv();
 char   *rindex();
+char   *linked();
 
 
+/*ARGSUSED*/
 main(argc, argv)
 main(argc, argv)
-int argc;
-char *argv[];
+       int argc;
+       char *argv[];
 {
 {
-       register char *arg;
-       int i, c, f, flag, out();
-       char *sp;
-       struct stat sbuf;
+       extern char *getlogin();
+       extern struct passwd *getpwuid(), *getpwnam();
+       struct passwd *pw;
+       extern char *itoa();
+       register char *arg, *cp;
+       int i, f, out();
+       char *printer = NULL;
+       struct stat stb;
 
        /*
         * Strategy to maintain protected spooling area:
 
        /*
         * Strategy to maintain protected spooling area:
@@ -130,296 +130,322 @@ char *argv[];
         *         root to access any file it wants (verifying things before
         *         with an access call) and group id to know how it should
         *         set up ownership of files in spooling area.
         *         root to access any file it wants (verifying things before
         *         with an access call) and group id to know how it should
         *         set up ownership of files in spooling area.
-        *      3. Files in spooling area are owned by printer and spooling
+        *      3. Files in spooling area are owned by daemon and spooling
         *         group, with mode 660.
         *         group, with mode 660.
-        *      4. lpd runs setuid daemon and setgrp spooling group to
+        *      4. lpd runs setuid root and setgrp spooling group to
         *         access files and printer.  Users can't get to anything
         *         access files and printer.  Users can't get to anything
-        *         w/o help of sq and dq programs.
+        *         w/o help of lpq and lprm programs.
         */
         */
-       user = getuid();
-       spgroup = getegid();
-       if(signal(SIGHUP, SIG_IGN) != SIG_IGN)
+       if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                signal(SIGHUP, out);
                signal(SIGHUP, out);
-       if(signal(SIGINT, SIG_IGN) != SIG_IGN)
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                signal(SIGINT, out);
                signal(SIGINT, out);
-       if(signal(SIGQUIT, SIG_IGN) != SIG_IGN)
+       if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
                signal(SIGQUIT, out);
                signal(SIGQUIT, out);
-       if(signal(SIGTERM, SIG_IGN) != SIG_IGN)
+       if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
                signal(SIGTERM, out);
                signal(SIGTERM, out);
-       flag = 0;
-       if ((printer = getenv("PRINTER")) == NULL)
-               printer = DEFLP;
+
+       gethostname(host, sizeof (host));
        name = argv[0];
 
        name = argv[0];
 
-       while (argc>1 && (arg = argv[1])[0]=='-') {
+       while (argc > 1 && (arg = argv[1])[0] == '-') {
+               argc--;
+               argv++;
                switch (arg[1]) {
 
                switch (arg[1]) {
 
-               case 'c':               /* force copy of files */
-                       flag = '+';
+               case 'P':               /* specifiy printer name */
+                       printer = &arg[2];
                        break;
 
                case 'C':               /* classification spec */
                        hdr++;
                        if (arg[2])
                                class = &arg[2];
                        break;
 
                case 'C':               /* classification spec */
                        hdr++;
                        if (arg[2])
                                class = &arg[2];
-                       else if (argc >= 2) {
-                               ++argv;
-                               arg = argv[1];
+                       else if (argc > 1) {
                                argc--;
                                argc--;
-                               class = arg;
+                               class = *++argv;
                        }
                        break;
 
                        }
                        break;
 
-               case 'r':               /* remove file when done */
-                       flag = '-';
+               case 'J':               /* job name */
+                       hdr++;
+                       if (arg[2])
+                               jobname = &arg[2];
+                       else if (argc > 1) {
+                               argc--;
+                               jobname = *++argv;
+                       }
                        break;
 
                        break;
 
-               case 'm':               /* send mail when done */
-                       mailflg++;
+               case 'T':               /* pr's title line */
+                       if (arg[2])
+                               title = &arg[2];
+                       else if (argc > 1) {
+                               argc--;
+                               title = *++argv;
+                       }
                        break;
 
                        break;
 
-               case 'q':               /* just q job */
-                       qflg++;
+               case 'l':               /* literal output */
+               case 'p':               /* print using ``pr'' */
+               case 't':               /* print troff output */
+               case 'c':               /* print cifplot output */
+               case 'v':               /* print vplot output */
+                       format = arg[1];
                        break;
 
                        break;
 
-               case 'J':               /* job spec */
-                       jflag++, hdr++;
-                       if (arg[2]) {
-                               jobname = &arg[2];
-                               break;
-                       }
-                       if (argc>=2) {
-                               ++argv;
-                               arg = argv[1];
-                               jobname = &arg[0];
+               case '4':               /* troff fonts */
+               case '3':
+               case '2':
+               case '1':
+                       if (argc > 1) {
                                argc--;
                                argc--;
+                               fonts[arg[1] - '1'] = *++argv;
+                               format = 't';
                        }
                        break;
 
                        }
                        break;
 
-               case 'i':               /* indent output */
-                       iflag++;
-                       indent = arg[2] ? atoi(&arg[2]) : 8;
+               case 'w':               /* versatec page width */
+                       width = arg+2;
                        break;
 
                        break;
 
-               case 'p':               /* use pr to print files */
-                       prflag++;
+               case 'r':               /* remove file when done */
+                       rflag++;
                        break;
 
                        break;
 
-               case 'h':               /* pr's title line */
-                       if (arg[2])
-                               title = &arg[2];
-                       else if (argc >= 2) {
-                               ++argv;
-                               arg = argv[1];
-                               argc--;
-                               title = arg;
-                       }
+               case 'm':               /* send mail when done */
+                       mailflg++;
                        break;
 
                        break;
 
-               case 'P':               /* specifiy printer name */
-                       printer = &arg[2];
+               case 'h':               /* toggle want of header page */
+                       hdr = !hdr;
                        break;
 
                        break;
 
-               case 'H':               /* toggle want of header page */
-                       hdr = !hdr;
+               case 's':               /* try to link files */
+                       lflag++;
+                       break;
+
+               case 'q':               /* just q job */
+                       qflag++;
                        break;
 
                        break;
 
-               default:                /* n copies ? */
-                       if (isdigit(arg[1]))
-                               ncopies = atoi(&arg[1]);
+               case 'i':               /* indent output */
+                       iflag++;
+                       indent = arg[2] ? atoi(&arg[2]) : 8;
+                       break;
+
+               case '#':               /* n copies */
+                       if (isdigit(arg[2]))
+                               ncopies = atoi(&arg[2]);
                }
                }
-               argc--;
-               argv++;
        }
        }
+       if (printer == NULL && (printer = getenv("PRINTER")) == NULL)
+               printer = DEFLP;
        if (!chkprinter(printer)) {
        if (!chkprinter(printer)) {
-               fprintf(stderr, "%s: no entry for default printer %s\n", name,
-                       printer);
+               printf("%s: unknown printer %s\n", name, printer);
                exit(2);
        }
                exit(2);
        }
-       i = getpid();
-       f = strlen(SA)+11;
-       tfname = mktmp("tf", i, f);
-       cfname = mktmp("cf", i, f);
-       lfname = mktmp("lf", i, f);
-       dfname = mktmp("df", i, f);
-       inchar = f-7;
-       tff = nfile(tfname);
-       if (jflag == 0) {
-               if(argc == 1)
-                       jobname = &dfname[f-10];
+       /*
+        * Get the identity of the person doing the lpr and initialize the
+        * control file.
+        */
+       userid = getuid();
+       if ((person = getlogin()) == NULL || strlen(person) == 0) {
+               if ((pw = getpwuid(userid)) == NULL)
+                       person = "Unknown User";
                else
                else
-                       jobname = argv[1];
+                       person = pw->pw_name;
+       } else if ((pw = getpwnam(person)) != NULL)
+               userid = pw->pw_uid;            /* in case of su */
+       mktemps();
+       tfd = nfile(tfname);
+       card('H', host);
+       card('P', person);
+       if (hdr) {
+               if (jobname == NULL) {
+                       if (argc == 1)
+                               jobname = "stdin";
+                       else
+                               jobname = argv[1];
+               }
+               card('J', jobname);
+               card('C', class);
+               card('L', person);
        }
        }
-       ident();
-
-       if(argc == 1)
+       if (iflag)
+               card('I', itoa(indent));
+       if (mailflg)
+               card('M', person);
+       if (format == 't')
+               for (i = 0; i < 4; i++)
+                       if (fonts[i] != NULL)
+                               card('1'+i, fonts[i]);
+       if (width != NULL)
+               card('W', width);
+
+       if (argc == 1)
                copy(0, " ");
                copy(0, " ");
-       else while(--argc) {
-               if(test(arg = *++argv) == -1)   /* file reasonable */
-                       continue;
-
-               if (flag == '+')                /* force copy flag */
-                       goto cf;
-               if (stat(arg, &sbuf) < 0) {
-                       printf("lpr:");
-                       perror(arg);
-                       continue;
-               }
-               if((sbuf.st_mode&04) == 0)
-                       goto cf;
-               if(*arg == '/' && flag != '-') {
-                       for(i=0;i<ncopies;i++) {
-                               if (prflag) {
-                                       if (title)
-                                               card('H', title);
-                                       card('R', arg);
-                               } else
-                                       card('F', arg);
-                               card('N', arg);
-                       }
-                       nact++;
-                       continue;
-               }
-               if(link(arg, lfname) < 0)
-                       goto cf;
-               for(i=0;i<ncopies;i++) {
-                       if (prflag) {
-                               card('H', title ? title : arg);
-                               card('R', lfname);
-                       } else 
-                               card('F', lfname);
+       else while (--argc) {
+               if ((f = test(arg = *++argv)) < 0)
+                       continue;       /* file unreasonable */
+
+               if ((f & 1) && (cp = linked(arg)) != NULL) {
+                       if (format == 'p')
+                               card('T', title ? title : arg);
+                       for (i = 0; i < ncopies; i++)
+                               card(format, &dfname[inchar-2]);
+                       card('U', &dfname[inchar-2]);
+                       if (f & 2)
+                               card('U', cp);
                        card('N', arg);
                        card('N', arg);
+                       dfname[inchar]++;
+                       nact++;
+               } else {
+                       if ((i = open(arg, 0)) < 0) {
+                               printf("%s: cannot open %s\n", name, arg);
+                               continue;
+                       }
+                       copy(i, arg);
+                       (void) close(i);
+                       if ((f & 2) && unlink(arg))
+                               printf("%s: cannot remove %s\n", name, arg);
                }
                }
-               card('U', lfname);
-               lfname[inchar]++;
-               nact++;
-               goto df;
-
-       cf:
-               if((f = open(arg, 0)) < 0) {
-                       printf("%s: cannot open %s\n", name, arg);
-                       continue;
-               }
-               copy(f, arg);
-               close(f);
-
-       df:
-               if(flag == '-' && unlink(arg))
-                       printf("%s: cannot remove %s\n", name, arg);
        }
 
        }
 
-       if(nact) {
+       if (nact) {
                tfname[inchar]--;
                tfname[inchar]--;
-               if(link(tfname, dfname) < 0) {
-                       printf("%s: cannot rename %s\n", name, dfname);
+               if (link(tfname, cfname) < 0) {
+                       printf("%s: cannot rename %s\n", name, cfname);
                        tfname[inchar]++;
                        out();
                }
                unlink(tfname);
                        tfname[inchar]++;
                        out();
                }
                unlink(tfname);
-               if (qflg)               /* just q things up */
+               if (qflag)              /* just q things up */
                        exit(0);
                        exit(0);
-               if (stat(LP, &sbuf) >= 0 && (sbuf.st_mode&0777) == 0) {
-                       printf("job queued, but printer down\n");
+               if (*LP && stat(LP, &stb) >= 0 && (stb.st_mode & 0777) == 0) {
+                       printf("jobs queued, but line printer is down.\n");
                        exit(0);
                }
                        exit(0);
                }
-               for(f = 0; f < NOFILE; close(f++))
-                       ;
-               open("/dev/tty", 0);
-               open("/dev/tty", 1);
-               dup2(1, 2);
-               execl(DN, rindex(DN, '/') ? rindex(DN, '/')+1 : DN, printer, 0);
-               dfname[inchar]++;
+               execl(DN, (arg = rindex(DN, '/')) ? arg+1 : DN, printer, 0);
+               printf("jobs queued, but cannot start daemon.\n");
+               exit(0);
        }
        out();
        }
        out();
+       /*NOTREACHED*/
 }
 
 }
 
+/*
+ * Create the file n and copy from file descriptor f.
+ */
 copy(f, n)
 copy(f, n)
-int f;
-char n[];
+       int f;
+       char n[];
 {
 {
-       int ff, i, nr, nc;
+       register int fd, i, nr, nc;
        char buf[BUFSIZ];
 
        char buf[BUFSIZ];
 
-       for(i=0;i<ncopies;i++) {
-               if (prflag) {
-                       card('H', title ? title : n);
-                       card('R', cfname);
-               } else 
-                       card('F', cfname);
-               card('N', n);
-       }
-       card('U', cfname);
-       ff = nfile(cfname);
+       if (format == 'p')
+               card('T', title ? title : n);
+       for (i = 0; i < ncopies; i++)
+               card(format, &dfname[inchar-2]);
+       card('U', &dfname[inchar-2]);
+       card('N', n);
+       fd = nfile(dfname);
        nr = nc = 0;
        nr = nc = 0;
-       while((i = read(f, buf, BUFSIZ)) > 0) {
-               if (write(ff, buf, i) != i) {
+       while ((i = read(f, buf, BUFSIZ)) > 0) {
+               if (write(fd, buf, i) != i) {
                        printf("%s: %s: temp file write error\n", name, n);
                        break;
                }
                nc += i;
                        printf("%s: %s: temp file write error\n", name, n);
                        break;
                }
                nc += i;
-               if(nc >= BUFSIZ) {
+               if (nc >= BUFSIZ) {
                        nc -= BUFSIZ;
                        nc -= BUFSIZ;
-                       if(nr++ > MX) {
+                       if (nr++ > MX) {
                                printf("%s: %s: copy file is too large\n", name, n);
                                break;
                        }
                }
        }
                                printf("%s: %s: copy file is too large\n", name, n);
                                break;
                        }
                }
        }
-       close(ff);
+       (void) close(fd);
        nact++;
 }
 
        nact++;
 }
 
+/*
+ * Try and link the file to dfname. Return a pointer to the full
+ * path name if successful.
+ */
+char *
+linked(file)
+       register char *file;
+{
+       register char *cp;
+       char buf[BUFSIZ];
+
+       if (*file != '/') {
+               if (getwd(buf) == NULL)
+                       return(NULL);
+               while (file[0] == '.') {
+                       switch (file[1]) {
+                       case '/':
+                               file += 2;
+                               continue;
+                       case '.':
+                               if (file[2] == '/') {
+                                       if ((cp = rindex(buf, '/')) != NULL)
+                                               *cp = '\0';
+                                       file += 3;
+                                       continue;
+                               }
+                       }
+                       break;
+               }
+               strcat(buf, "/");
+               strcat(buf, file);
+               file = buf;
+       }
+       return(symlink(file, dfname) ? NULL : file);
+}
+
+/*
+ * Put a line into the control file.
+ */
 card(c, p2)
 card(c, p2)
-register char c, *p2;
+       register char c, *p2;
 {
        char buf[BUFSIZ];
        register char *p1 = buf;
 {
        char buf[BUFSIZ];
        register char *p1 = buf;
-       int col = 0;
+       register int len = 2;
 
        *p1++ = c;
 
        *p1++ = c;
-       while((c = *p2++) != '\0') {
+       while ((c = *p2++) != '\0') {
                *p1++ = c;
                *p1++ = c;
-               col++;
+               len++;
        }
        *p1++ = '\n';
        }
        *p1++ = '\n';
-       write(tff, buf, col+2);
+       write(tfd, buf, len);
 }
 
 }
 
-ident()
-{
-       extern char *getlogin();
-       extern struct passwd *getpwuid();
-       struct passwd *pw;
-       extern char *itoa();
-
-       if ((person = getlogin()) == NULL) {
-               if ((pw = getpwuid(user)) == NULL)
-                       person = "Unknown User";
-               else
-                       person = pw->pw_name;
-       }
-
-       if (hdr) {
-               card('J',jobname);
-               card('C',class);
-               card('L', person);
-       }
-       if (iflag)
-               card('I', itoa(indent));
-       if (mailflg)
-               card('M', person);
-}
+/*
+ * Create a new file in the spool directory.
+ */
 
 nfile(n)
 
 nfile(n)
-char *n;
+       char *n;
 {
        register f;
 {
        register f;
+       int oldumask = umask(0);                /* should block signals */
 
 
-       if((f = creat(n, FILMOD)) < 0) {
+       f = creat(n, FILMOD);
+       (void) umask(oldumask);
+       if (f < 0) {
                printf("%s: cannot create %s\n", name, n);
                out();
        }
                printf("%s: cannot create %s\n", name, n);
                out();
        }
-       if (chown(n, user, spgroup) < 0) {
+#ifdef BSD41C
+       if (chown(n, userid, -1) < 0) {
+#else
+       if (chown(n, userid, getegid()) < 0) {
+#endif
                unlink(n);
                printf("%s: cannot chown %s\n", name, n);
                out();
                unlink(n);
                printf("%s: cannot chown %s\n", name, n);
                out();
@@ -428,6 +454,9 @@ char *n;
        return(f);
 }
 
        return(f);
 }
 
+/*
+ * Cleanup after interrupts and errors.
+ */
 out()
 {
        register i;
 out()
 {
        register i;
@@ -438,54 +467,54 @@ out()
        signal(SIGTERM, SIG_IGN);
        i = inchar;
        if (tfname)
        signal(SIGTERM, SIG_IGN);
        i = inchar;
        if (tfname)
-               while(tfname[i] != 'A') {
+               while (tfname[i] != 'A') {
                        tfname[i]--;
                        unlink(tfname);
                }
        if (cfname)
                        tfname[i]--;
                        unlink(tfname);
                }
        if (cfname)
-               while(cfname[i] != 'A') {
+               while (cfname[i] != 'A') {
                        cfname[i]--;
                        unlink(cfname);
                }
                        cfname[i]--;
                        unlink(cfname);
                }
-       if (lfname)
-               while(lfname[i] != 'A') {
-                       lfname[i]--;
-                       unlink(lfname);
-               }
        if (dfname)
        if (dfname)
-               while(dfname[i] != 'A') {
+               while (dfname[i] != 'A') {
                        dfname[i]--;
                        unlink(dfname);
                }
        exit();
 }
 
                        dfname[i]--;
                        unlink(dfname);
                }
        exit();
 }
 
+/*
+ * Test to see if this is a printable file.
+ * Return -1 if it is not, 1 if we should try to link and or in 2 if
+ * we should remove it after printing.
+ */
 test(file)
 test(file)
-char *file;
+       char *file;
 {
 {
-       struct exec buf;
-       struct stat mbuf;
-       int fd;
+       struct exec execb;
+       struct stat statb;
+       register int fd;
+       register char *cp;
 
        if (access(file, 4) < 0) {
                printf("%s: cannot access %s\n", name, file);
                return(-1);
        }
 
        if (access(file, 4) < 0) {
                printf("%s: cannot access %s\n", name, file);
                return(-1);
        }
-       if(stat(file, &mbuf) < 0) {
+       if (stat(file, &statb) < 0) {
                printf("%s: cannot stat %s\n", name, file);
                printf("%s: cannot stat %s\n", name, file);
-               return (-1);
+               return(-1);
        }
        }
-       if ((mbuf.st_mode&S_IFMT) == S_IFDIR) {
+       if ((statb.st_mode & S_IFMT) == S_IFDIR) {
                printf("%s: %s is a directory\n", name, file);
                return(-1);
        }
                printf("%s: %s is a directory\n", name, file);
                return(-1);
        }
-
-       if((fd = open(file, 0)) < 0) {
+       if ((fd = open(file, 0)) < 0) {
                printf("%s: cannot open %s\n", name, file);
                return(-1);
        }
                printf("%s: cannot open %s\n", name, file);
                return(-1);
        }
-       if (read(fd, &buf, sizeof(buf)) == sizeof(buf))
-               switch(buf.a_magic) {
+       if (read(fd, &execb, sizeof(execb)) == sizeof(execb))
+               switch(execb.a_magic) {
                case A_MAGIC1:
                case A_MAGIC2:
                case A_MAGIC3:
                case A_MAGIC1:
                case A_MAGIC2:
                case A_MAGIC3:
@@ -499,12 +528,26 @@ char *file;
                        printf("%s: %s is an archive file", name, file);
                        goto error1;
                }
                        printf("%s: %s is an archive file", name, file);
                        goto error1;
                }
+       (void) close(fd);
+       fd = 0;
+       if (lflag && (statb.st_mode & 04))
+               fd |= 1;
+       if (rflag) {
+               if ((cp = rindex(file, '/')) == NULL) {
+                       if (access(".", 2) == 0)
+                               fd |= 2;
+               } else {
+                       *cp = '\0';
+                       if (access(file, 2) == 0)
+                               fd |= 2;
+                       *cp = '/';
+               }
+       }
+       return(fd);
 
 
-       close(fd);
-       return(0);
 error1:
        printf(" and is unprintable\n");
 error1:
        printf(" and is unprintable\n");
-       close(fd);
+       (void) close(fd);
        return(-1);
 }
 
        return(-1);
 }
 
@@ -513,7 +556,7 @@ error1:
  */
 char *
 itoa(i)
  */
 char *
 itoa(i)
-register int i;
+       register int i;
 {
        static char b[10] = "########";
        register char *p;
 {
        static char b[10] = "########";
        register char *p;
@@ -527,10 +570,9 @@ register int i;
 
 /*
  * Perform lookup for printer name or abbreviation --
 
 /*
  * Perform lookup for printer name or abbreviation --
- *   return pointer to daemon structure
  */
 chkprinter(s)
  */
 chkprinter(s)
-register char *s;
+       register char *s;
 {
        static char buf[BUFSIZ/2];
        char b[BUFSIZ];
 {
        static char buf[BUFSIZ/2];
        char b[BUFSIZ];
@@ -538,34 +580,77 @@ register char *s;
        char *bp = buf;
 
        if ((stat = pgetent(b, s)) < 0) {
        char *bp = buf;
 
        if ((stat = pgetent(b, s)) < 0) {
-               fprintf(stderr, "%s: can't open printer description file\n", name);
+               printf("%s: can't open printer description file\n", name);
                exit(3);
        } else if (stat == 0)
                exit(3);
        } else if (stat == 0)
-               return(NULL);
+               return(0);
        if ((DN = pgetstr("dn", &bp)) == NULL)
                DN = DEFDAEMON;
        if ((LP = pgetstr("lp", &bp)) == NULL)
                LP = DEFDEVLP;
        if ((DN = pgetstr("dn", &bp)) == NULL)
                DN = DEFDAEMON;
        if ((LP = pgetstr("lp", &bp)) == NULL)
                LP = DEFDEVLP;
-       if ((SA = pgetstr("sa", &bp)) == NULL)
-               SA = DEFSPOOL;
+       if ((SD = pgetstr("sd", &bp)) == NULL)
+               SD = DEFSPOOL;
        if ((MX = pgetnum("mx")) < 0)
                MX = DEFMX;
        if ((MX = pgetnum("mx")) < 0)
                MX = DEFMX;
+       RM = pgetstr("rm", &bp);
        return(1);
 }
 
 /*
        return(1);
 }
 
 /*
- * Make a temp file
+ * Make the temp files.
+ */
+mktemps()
+{
+       register int c, len;
+       int n;
+       char buf[BUFSIZ], *mktemp();
+       FILE *fp;
+
+       (void) sprintf(buf, "%s/.seq", SD);
+       if ((fp = fopen(buf, "r+")) == NULL) {
+               if ((fp = fopen(buf, "w")) == NULL) {
+                       printf("%s: cannot create %s\n", name, buf);
+                       exit(1);
+               }
+               setbuf(fp, buf);
+               n = 0;
+       } else {
+               setbuf(fp, buf);
+#ifdef BSD41C
+               if (flock(fileno(fp), FEXLOCK)) {
+                       printf("%s: cannot lock %s\n", name, buf);
+                       exit(1);
+               }
+#endif
+               n = 0;
+               while ((c = getc(fp)) >= '0' && c <= '9')
+                       n = n * 10 + (c - '0');
+       }
+       len = strlen(SD) + strlen(host) + 8;
+       tfname = mktemp("tf", n, len);
+       cfname = mktemp("cf", n, len);
+       dfname = mktemp("df", n, len);
+       inchar = strlen(SD) + 3;
+       n = (n + 1) % 1000;
+       (void) fseek(fp, 0L, 0);
+       fprintf(fp, "%d\n", n);
+       (void) fclose(fp);
+}
+
+/*
+ * Make a temp file name.
  */
 char *
  */
 char *
-mktmp(id, pid, n)
-char *id;
+mktemp(id, num, len)
+       char    *id;
+       int     num, len;
 {
        register char *s;
 
 {
        register char *s;
 
-       if ((s = malloc(n)) == NULL) {
-               fprintf(stderr, "%s: out of memory\n", name);
+       if ((s = malloc(len)) == NULL) {
+               printf("%s: out of memory\n", name);
                exit(1);
        }
                exit(1);
        }
-       sprintf(s, "%s/%sA%05d", SA, id, pid);
+       (void) sprintf(s, "%s/%sA%03d%s", SD, id, num, host);
        return(s);
 }
        return(s);
 }