formatting
[unix-history] / usr / src / usr.sbin / lpr / lpr / lpr.c
index 5848690..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.7     83/01/07        */
+/*     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.
  *
  * Allows multiple printers and printers on remote machines by
  * using information from a printer data base.
@@ -81,7 +80,7 @@ int   nact;                   /* number of jobs to act on */
 int    tfd;                    /* control file descriptor */
 int     mailflg;               /* send mail */
 int    qflag;                  /* q job, but don't exec daemon */
 int    tfd;                    /* control file descriptor */
 int     mailflg;               /* send mail */
 int    qflag;                  /* q job, but don't exec daemon */
-int    prflag;                 /* ``pr'' files */
+char   format = 'f';           /* format char for printing files */
 int    rflag;                  /* remove files upon completion */      
 int    lflag;                  /* link flag */
 char   *person;                /* user name */
 int    rflag;                  /* remove files upon completion */      
 int    lflag;                  /* link flag */
 char   *person;                /* user name */
@@ -95,8 +94,10 @@ char *RM;                    /* remote machine name if no local printer */
 char   *SD;                    /* spool directory */
 int     MX;                    /* maximum size in blocks of a print file */
 int    hdr = 1;                /* print header or not (default is yes) */
 char   *SD;                    /* spool directory */
 int     MX;                    /* maximum size in blocks of a print file */
 int    hdr = 1;                /* print header or not (default is yes) */
-int     user;                  /* user id */
+int     userid;                        /* user id */
 char   *title;                 /* pr'ing title */
 char   *title;                 /* pr'ing title */
+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   host[32];               /* host name */
 char   *class = host;          /* class title on header page */
 char    *jobname;              /* job name on header page */
@@ -106,13 +107,18 @@ char      *pgetstr();
 char   *malloc();
 char   *getenv();
 char   *rindex();
 char   *malloc();
 char   *getenv();
 char   *rindex();
+char   *linked();
 
 /*ARGSUSED*/
 main(argc, argv)
        int argc;
        char *argv[];
 {
 
 /*ARGSUSED*/
 main(argc, argv)
        int argc;
        char *argv[];
 {
-       register char *arg;
+       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;
        int i, f, out();
        char *printer = NULL;
        struct stat stb;
@@ -140,7 +146,6 @@ main(argc, argv)
                signal(SIGTERM, out);
 
        gethostname(host, sizeof (host));
                signal(SIGTERM, out);
 
        gethostname(host, sizeof (host));
-       user = getuid();
        name = argv[0];
 
        while (argc > 1 && (arg = argv[1])[0] == '-') {
        name = argv[0];
 
        while (argc > 1 && (arg = argv[1])[0] == '-') {
@@ -156,7 +161,7 @@ main(argc, argv)
                        hdr++;
                        if (arg[2])
                                class = &arg[2];
                        hdr++;
                        if (arg[2])
                                class = &arg[2];
-                       else if (argc > 0) {
+                       else if (argc > 1) {
                                argc--;
                                class = *++argv;
                        }
                                argc--;
                                class = *++argv;
                        }
@@ -166,7 +171,7 @@ main(argc, argv)
                        hdr++;
                        if (arg[2])
                                jobname = &arg[2];
                        hdr++;
                        if (arg[2])
                                jobname = &arg[2];
-                       else if (argc > 0) {
+                       else if (argc > 1) {
                                argc--;
                                jobname = *++argv;
                        }
                                argc--;
                                jobname = *++argv;
                        }
@@ -175,14 +180,33 @@ main(argc, argv)
                case 'T':               /* pr's title line */
                        if (arg[2])
                                title = &arg[2];
                case 'T':               /* pr's title line */
                        if (arg[2])
                                title = &arg[2];
-                       else if (argc > 0) {
+                       else if (argc > 1) {
                                argc--;
                                title = *++argv;
                        }
                        break;
 
                                argc--;
                                title = *++argv;
                        }
                        break;
 
-               case 'p':               /* use pr to print files */
-                       prflag++;
+               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;
+
+               case '4':               /* troff fonts */
+               case '3':
+               case '2':
+               case '1':
+                       if (argc > 1) {
+                               argc--;
+                               fonts[arg[1] - '1'] = *++argv;
+                               format = 't';
+                       }
+                       break;
+
+               case 'w':               /* versatec page width */
+                       width = arg+2;
                        break;
 
                case 'r':               /* remove file when done */
                        break;
 
                case 'r':               /* remove file when done */
@@ -197,7 +221,7 @@ main(argc, argv)
                        hdr = !hdr;
                        break;
 
                        hdr = !hdr;
                        break;
 
-               case 'l':               /* try to link files */
+               case 's':               /* try to link files */
                        lflag++;
                        break;
 
                        lflag++;
                        break;
 
@@ -210,61 +234,80 @@ main(argc, argv)
                        indent = arg[2] ? atoi(&arg[2]) : 8;
                        break;
 
                        indent = arg[2] ? atoi(&arg[2]) : 8;
                        break;
 
-               default:                /* n copies ? */
-                       if (isdigit(arg[1]))
-                               ncopies = atoi(&arg[1]);
+               case '#':               /* n copies */
+                       if (isdigit(arg[2]))
+                               ncopies = atoi(&arg[2]);
                }
        }
        if (printer == NULL && (printer = getenv("PRINTER")) == NULL)
                printer = DEFLP;
        if (!chkprinter(printer)) {
                }
        }
        if (printer == NULL && (printer = getenv("PRINTER")) == NULL)
                printer = DEFLP;
        if (!chkprinter(printer)) {
-               printf("%s: unknown printer\n", name, printer);
+               printf("%s: unknown printer %s\n", name, printer);
                exit(2);
        }
                exit(2);
        }
+       /*
+        * 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
+                       person = pw->pw_name;
+       } else if ((pw = getpwnam(person)) != NULL)
+               userid = pw->pw_uid;            /* in case of su */
        mktemps();
        tfd = nfile(tfname);
        mktemps();
        tfd = nfile(tfname);
-       if (jobname == NULL) {
-               if (argc == 1)
-                       jobname = &cfname[inchar-2];
-               else
-                       jobname = argv[1];
+       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 (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, " ");
        else while (--argc) {
 
        if (argc == 1)
                copy(0, " ");
        else while (--argc) {
-               if ((i = test(arg = *++argv)) < 0)
+               if ((f = test(arg = *++argv)) < 0)
                        continue;       /* file unreasonable */
 
                        continue;       /* file unreasonable */
 
-               if (i && lflag && linked(arg)) {
-                       if (prflag)
+               if ((f & 1) && (cp = linked(arg)) != NULL) {
+                       if (format == 'p')
                                card('T', title ? title : arg);
                                card('T', title ? title : arg);
-                       for (i = 0;i < ncopies; i++)
-                               card(prflag ? 'R' : 'F', &dfname[inchar-2]);
+                       for (i = 0; i < ncopies; i++)
+                               card(format, &dfname[inchar-2]);
                        card('U', &dfname[inchar-2]);
                        card('U', &dfname[inchar-2]);
+                       if (f & 2)
+                               card('U', cp);
                        card('N', arg);
                        dfname[inchar]++;
                        nact++;
                } else {
                        card('N', arg);
                        dfname[inchar]++;
                        nact++;
                } else {
-                       if ((f = open(arg, 0)) < 0) {
+                       if ((i = open(arg, 0)) < 0) {
                                printf("%s: cannot open %s\n", name, arg);
                                continue;
                        }
                                printf("%s: cannot open %s\n", name, arg);
                                continue;
                        }
-                       copy(f, arg);
-                       (void) close(f);
-               }
-               if (rflag) {
-                       register char *cp;
-
-                       if ((cp = rindex(arg, '/')) == NULL)
-                               f = access(".", 2);
-                       else {
-                               *cp = '\0';
-                               f = access(arg, 2);
-                               *cp = '/';
-                       }
-                       if (f || unlink(arg))
+                       copy(i, arg);
+                       (void) close(i);
+                       if ((f & 2) && unlink(arg))
                                printf("%s: cannot remove %s\n", name, arg);
                }
        }
                                printf("%s: cannot remove %s\n", name, arg);
                }
        }
@@ -283,7 +326,7 @@ main(argc, argv)
                        printf("jobs queued, but line printer is down.\n");
                        exit(0);
                }
                        printf("jobs queued, but line printer is down.\n");
                        exit(0);
                }
-               execl(DN, arg = rindex(DN, "/") ? arg+1 : DN, printer, 0);
+               execl(DN, (arg = rindex(DN, '/')) ? arg+1 : DN, printer, 0);
                printf("jobs queued, but cannot start daemon.\n");
                exit(0);
        }
                printf("jobs queued, but cannot start daemon.\n");
                exit(0);
        }
@@ -301,10 +344,10 @@ copy(f, n)
        register int fd, i, nr, nc;
        char buf[BUFSIZ];
 
        register int fd, i, nr, nc;
        char buf[BUFSIZ];
 
-       if (prflag)
+       if (format == 'p')
                card('T', title ? title : n);
        for (i = 0; i < ncopies; i++)
                card('T', title ? title : n);
        for (i = 0; i < ncopies; i++)
-               card(prflag ? 'R' : 'F', &dfname[inchar-2]);
+               card(format, &dfname[inchar-2]);
        card('U', &dfname[inchar-2]);
        card('N', n);
        fd = nfile(dfname);
        card('U', &dfname[inchar-2]);
        card('N', n);
        fd = nfile(dfname);
@@ -328,19 +371,19 @@ copy(f, n)
 }
 
 /*
 }
 
 /*
- * Try and link the file to dfname. Return true if successful.
+ * 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];
 
 linked(file)
        register char *file;
 {
        register char *cp;
        char buf[BUFSIZ];
 
-       if (link(file, dfname) == 0)
-               return(1);
        if (*file != '/') {
                if (getwd(buf) == NULL)
        if (*file != '/') {
                if (getwd(buf) == NULL)
-                       return(0);
+                       return(NULL);
                while (file[0] == '.') {
                        switch (file[1]) {
                        case '/':
                while (file[0] == '.') {
                        switch (file[1]) {
                        case '/':
@@ -360,7 +403,7 @@ linked(file)
                strcat(buf, file);
                file = buf;
        }
                strcat(buf, file);
                file = buf;
        }
-       return(symlink(file, dfname) == 0);
+       return(symlink(file, dfname) ? NULL : file);
 }
 
 /*
 }
 
 /*
@@ -382,37 +425,6 @@ card(c, p2)
        write(tfd, buf, len);
 }
 
        write(tfd, buf, len);
 }
 
-/*
- * Get the identity of the person doing the lpr and save it in the
- * control file.
- */
-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;
-       }
-
-       card('H', host);
-       card('P', person);
-       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.
  */
 /*
  * Create a new file in the spool directory.
  */
@@ -429,7 +441,11 @@ nfile(n)
                printf("%s: cannot create %s\n", name, n);
                out();
        }
                printf("%s: cannot create %s\n", name, n);
                out();
        }
-       if (chown(n, user, getegid()) < 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();
@@ -470,14 +486,16 @@ out()
 
 /*
  * Test to see if this is a printable file.
 
 /*
  * Test to see if this is a printable file.
- * Return -1 if it is not, 1 if it's publically readable, else 0
+ * 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)
        char *file;
 {
        struct exec execb;
        struct stat statb;
  */
 test(file)
        char *file;
 {
        struct exec execb;
        struct stat statb;
-       int fd;
+       register int fd;
+       register char *cp;
 
        if (access(file, 4) < 0) {
                printf("%s: cannot access %s\n", name, file);
 
        if (access(file, 4) < 0) {
                printf("%s: cannot access %s\n", name, file);
@@ -511,23 +529,21 @@ test(file)
                        goto error1;
                }
        (void) close(fd);
                        goto error1;
                }
        (void) close(fd);
-       if (rflag) {    /* check to make sure user can delete this file */
-               register char   *cp = rindex(file, '/');
-
-               if (cp == NULL)
-                       file = ".";
-               else
+       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';
                        *cp = '\0';
-               if (access(file, 2) < 0) {
+                       if (access(file, 2) == 0)
+                               fd |= 2;
                        *cp = '/';
                        *cp = '/';
-                       printf("%s: cannot remove %s\n", name, file);
-                       return(-1);
                }
                }
-               *cp = '/';
        }
        }
-       if (statb.st_mode & 04)
-               return(1);
-       return(0);
+       return(fd);
 
 error1:
        printf(" and is unprintable\n");
 
 error1:
        printf(" and is unprintable\n");
@@ -592,14 +608,20 @@ mktemps()
 
        (void) sprintf(buf, "%s/.seq", SD);
        if ((fp = fopen(buf, "r+")) == NULL) {
 
        (void) sprintf(buf, "%s/.seq", SD);
        if ((fp = fopen(buf, "r+")) == NULL) {
-               printf("%s: cannot create %s\n", name, buf);
-               exit(1);
+               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);
        } else {
                setbuf(fp, buf);
+#ifdef BSD41C
                if (flock(fileno(fp), FEXLOCK)) {
                        printf("%s: cannot lock %s\n", name, buf);
                        exit(1);
                }
                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');
                n = 0;
                while ((c = getc(fp)) >= '0' && c <= '9')
                        n = n * 10 + (c - '0');