don't fork off an output filter if it won't ever be used
[unix-history] / usr / src / usr.sbin / lpr / lpd / printjob.c
index 9ae3ead..347c2eb 100644 (file)
@@ -1,6 +1,23 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)printjob.c 4.16 (Berkeley) %G%";
-#endif
+static char sccsid[] = "@(#)printjob.c 5.11 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
  * printjob -- print jobs in the queue.
 
 /*
  * printjob -- print jobs in the queue.
@@ -10,33 +27,46 @@ static char sccsid[] = "@(#)printjob.c      4.16 (Berkeley) %G%";
  */
 
 #include "lp.h"
  */
 
 #include "lp.h"
+#include "pathnames.h"
 
 
-#define DORETURN       0               /* absorb fork error */
-#define DOABORT                1               /* abort if dofork fails */
-
-static char    title[80];              /* ``pr'' title */
-static FILE    *cfp;                   /* control file */
-static int     pfd;                    /* printer file descriptor */
-static int     ofd;                    /* output filter file descriptor */
-static int     lfd;                    /* lock file descriptor */
-static int     pid;                    /* pid of lpd process */
-static int     prchild;                /* id of pr process */
-static int     child;                  /* id of any filters */
-static int     ofilter;                /* id of output filter, if any */
-static int     tof;                    /* true if at top of form */
-static int     count;                  /* Number of files actually printed */
-static int     remote;                 /* true if sending files to remote */
-
-static char    fromhost[32];           /* user's host machine */
-static char    logname[32];            /* user's login name */
-static char    jobname[100];           /* job or file name */
-static char    class[32];              /* classification field */
-static char    width[10] = "-w";       /* page width in characters */
-static char    length[10] = "-l";      /* page length in lines */
-static char    pxwidth[10] = "-x";     /* page width in pixels */
-static char    pxlength[10] = "-y";    /* page length in pixels */
-static char    indent[10] = "-i0";     /* indentation size in characters */
-static char    tmpfile[] = "errsXXXXXX"; /* file name for filter output */
+#define DORETURN       0       /* absorb fork error */
+#define DOABORT                1       /* abort if dofork fails */
+
+/*
+ * Error tokens
+ */
+#define REPRINT                -2
+#define ERROR          -1
+#define        OK              0
+#define        FATALERR        1
+#define        NOACCT          2
+#define        FILTERERR       3
+#define        ACCESS          4
+
+char   title[80];              /* ``pr'' title */
+FILE   *cfp;                   /* control file */
+int    pfd;                    /* printer file descriptor */
+int    ofd;                    /* output filter file descriptor */
+int    lfd;                    /* lock file descriptor */
+int    pid;                    /* pid of lpd process */
+int    prchild;                /* id of pr process */
+int    child;                  /* id of any filters */
+int    ofilter;                /* id of output filter, if any */
+int    tof;                    /* true if at top of form */
+int    remote;                 /* true if sending files to remote */
+dev_t  fdev;                   /* device of file pointed to by symlink */
+ino_t  fino;                   /* inode of file pointed to by symlink */
+
+char   fromhost[32];           /* user's host machine */
+char   logname[32];            /* user's login name */
+char   jobname[100];           /* job or file name */
+char   class[32];              /* classification field */
+char   width[10] = "-w";       /* page width in characters */
+char   length[10] = "-l";      /* page length in lines */
+char   pxwidth[10] = "-x";     /* page width in pixels */
+char   pxlength[10] = "-y";    /* page length in pixels */
+char   indent[10] = "-i0";     /* indentation size in characters */
+char   tempfile[] = "errsXXXXXX"; /* file name for filter output */
 
 printjob()
 {
 
 printjob()
 {
@@ -45,42 +75,44 @@ printjob()
        struct queue **queue;
        register int i, nitems;
        long pidoff;
        struct queue **queue;
        register int i, nitems;
        long pidoff;
-       extern int onintr();
+       int count = 0;
+       extern int abortpr();
 
        init();                                 /* set up capabilities */
        (void) write(1, "", 1);                 /* ack that daemon is started */
 
        init();                                 /* set up capabilities */
        (void) write(1, "", 1);                 /* ack that daemon is started */
-       (void) close(1);                        /* set up log file */
-       (void) close(2);
-       if (open(LF, O_WRONLY|O_APPEND) < 0)
-               (void) open("/dev/null", O_WRONLY);
-       dup(1);
+       (void) close(2);                        /* set up log file */
+       if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) {
+               syslog(LOG_ERR, "%s: %m", LF);
+               (void) open(_PATH_DEVNULL, O_WRONLY);
+       }
+       setgid(getegid());
        pid = getpid();                         /* for use with lprm */
        setpgrp(0, pid);
        pid = getpid();                         /* for use with lprm */
        setpgrp(0, pid);
-       signal(SIGHUP, onintr);
-       signal(SIGINT, onintr);
-       signal(SIGQUIT, onintr);
-       signal(SIGTERM, onintr);
+       signal(SIGHUP, abortpr);
+       signal(SIGINT, abortpr);
+       signal(SIGQUIT, abortpr);
+       signal(SIGTERM, abortpr);
 
 
-       (void) mktemp(tmpfile);
+       (void) mktemp(tempfile);
 
        /*
         * uses short form file names
         */
        if (chdir(SD) < 0) {
 
        /*
         * uses short form file names
         */
        if (chdir(SD) < 0) {
-               log("cannot chdir to %s", SD);
+               syslog(LOG_ERR, "%s: %m", SD);
                exit(1);
        }
        if (stat(LO, &stb) == 0 && (stb.st_mode & 0100))
                exit(0);                /* printing disabled */
        lfd = open(LO, O_WRONLY|O_CREAT, 0644);
        if (lfd < 0) {
                exit(1);
        }
        if (stat(LO, &stb) == 0 && (stb.st_mode & 0100))
                exit(0);                /* printing disabled */
        lfd = open(LO, O_WRONLY|O_CREAT, 0644);
        if (lfd < 0) {
-               log("cannot create %s", LO);
+               syslog(LOG_ERR, "%s: %s: %m", printer, LO);
                exit(1);
        }
        if (flock(lfd, LOCK_EX|LOCK_NB) < 0) {
                if (errno == EWOULDBLOCK)       /* active deamon present */
                        exit(0);
                exit(1);
        }
        if (flock(lfd, LOCK_EX|LOCK_NB) < 0) {
                if (errno == EWOULDBLOCK)       /* active deamon present */
                        exit(0);
-               log("cannot lock %s", LO);
+               syslog(LOG_ERR, "%s: %s: %m", printer, LO);
                exit(1);
        }
        ftruncate(lfd, 0);
                exit(1);
        }
        ftruncate(lfd, 0);
@@ -90,21 +122,21 @@ printjob()
        sprintf(line, "%u\n", pid);
        pidoff = i = strlen(line);
        if (write(lfd, line, i) != i) {
        sprintf(line, "%u\n", pid);
        pidoff = i = strlen(line);
        if (write(lfd, line, i) != i) {
-               log("cannot write daemon pid");
+               syslog(LOG_ERR, "%s: %s: %m", printer, LO);
                exit(1);
        }
        /*
         * search the spool directory for work and sort by queue order.
         */
        if ((nitems = getq(&queue)) < 0) {
                exit(1);
        }
        /*
         * search the spool directory for work and sort by queue order.
         */
        if ((nitems = getq(&queue)) < 0) {
-               log("can't scan spool directory %s", SD);
+               syslog(LOG_ERR, "%s: can't scan %s", printer, SD);
                exit(1);
        }
        if (nitems == 0)                /* no work to do */
                exit(0);
        if (stb.st_mode & 01) {         /* reset queue flag */
                if (fchmod(lfd, stb.st_mode & 0776) < 0)
                exit(1);
        }
        if (nitems == 0)                /* no work to do */
                exit(0);
        if (stb.st_mode & 01) {         /* reset queue flag */
                if (fchmod(lfd, stb.st_mode & 0776) < 0)
-                       log("cannot chmod %s", LO);
+                       syslog(LOG_ERR, "%s: %s: %m", printer, LO);
        }
        openpr();                       /* open printer or remote */
 again:
        }
        openpr();                       /* open printer or remote */
 again:
@@ -122,7 +154,7 @@ again:
                (void) sprintf(line, "%s\n", q->q_name);
                i = strlen(line);
                if (write(lfd, line, i) != i)
                (void) sprintf(line, "%s\n", q->q_name);
                i = strlen(line);
                if (write(lfd, line, i) != i)
-                       log("can't write (%d) control file name", errno);
+                       syslog(LOG_ERR, "%s: %s: %m", printer, LO);
                if (!remote)
                        i = printit(q->q_name);
                else
                if (!remote)
                        i = printit(q->q_name);
                else
@@ -132,20 +164,23 @@ again:
                 * if we are to rebuild the queue.
                 */
                if (fstat(lfd, &stb) == 0) {
                 * if we are to rebuild the queue.
                 */
                if (fstat(lfd, &stb) == 0) {
+                       /* stop printing before starting next job? */
                        if (stb.st_mode & 0100)
                                goto done;
                        if (stb.st_mode & 0100)
                                goto done;
+                       /* rebuild queue (after lpc topq) */
                        if (stb.st_mode & 01) {
                                for (free((char *) q); nitems--; free((char *) q))
                                        q = *qp++;
                                if (fchmod(lfd, stb.st_mode & 0776) < 0)
                        if (stb.st_mode & 01) {
                                for (free((char *) q); nitems--; free((char *) q))
                                        q = *qp++;
                                if (fchmod(lfd, stb.st_mode & 0776) < 0)
-                                       log("cannot chmod %s", LO);
+                                       syslog(LOG_WARNING, "%s: %s: %m",
+                                               printer, LO);
                                break;
                        }
                }
                                break;
                        }
                }
-               if (i == 0)             /* file ok and printed */
+               if (i == OK)            /* file ok and printed */
                        count++;
                        count++;
-               else if (i > 0) {       /* try reprinting the job */
-                       log("restarting");
+               else if (i == REPRINT) { /* try reprinting the job */
+                       syslog(LOG_INFO, "restarting %s", printer);
                        if (ofilter > 0) {
                                kill(ofilter, SIGCONT); /* to be sure */
                                (void) close(ofd);
                        if (ofilter > 0) {
                                kill(ofilter, SIGCONT); /* to be sure */
                                (void) close(ofd);
@@ -155,7 +190,7 @@ again:
                        }
                        (void) close(pfd);      /* close printer */
                        if (ftruncate(lfd, pidoff) < 0)
                        }
                        (void) close(pfd);      /* close printer */
                        if (ftruncate(lfd, pidoff) < 0)
-                               log("can't truncate lock file (%d)", errno);
+                               syslog(LOG_WARNING, "%s: %s: %m", printer, LO);
                        openpr();               /* try to reopen printer */
                        goto restart;
                }
                        openpr();               /* try to reopen printer */
                        goto restart;
                }
@@ -165,7 +200,7 @@ again:
         * search the spool directory for more work.
         */
        if ((nitems = getq(&queue)) < 0) {
         * search the spool directory for more work.
         */
        if ((nitems = getq(&queue)) < 0) {
-               log("can't scan spool directory %s", SD);
+               syslog(LOG_ERR, "%s: can't scan %s", printer, SD);
                exit(1);
        }
        if (nitems == 0) {              /* no more work to do */
                exit(1);
        }
        if (nitems == 0) {              /* no more work to do */
@@ -176,7 +211,7 @@ again:
                        if (TR != NULL)         /* output trailer */
                                (void) write(ofd, TR, strlen(TR));
                }
                        if (TR != NULL)         /* output trailer */
                                (void) write(ofd, TR, strlen(TR));
                }
-               (void) unlink(tmpfile);
+               (void) unlink(tempfile);
                exit(0);
        }
        goto again;
                exit(0);
        }
        goto again;
@@ -184,38 +219,38 @@ again:
 
 char   fonts[4][50];   /* fonts for troff */
 
 
 char   fonts[4][50];   /* fonts for troff */
 
-static char ifonts[4][18] = {
-       "/usr/lib/vfont/R",
-       "/usr/lib/vfont/I",
-       "/usr/lib/vfont/B",
-       "/usr/lib/vfont/S"
+char ifonts[4][40] = {
+       _PATH_VFONTR,
+       _PATH_VFONTI,
+       _PATH_VFONTB,
+       _PATH_VFONTS,
 };
 
 /*
  * The remaining part is the reading of the control file (cf)
  * and performing the various actions.
 };
 
 /*
  * The remaining part is the reading of the control file (cf)
  * and performing the various actions.
- * Returns 0 if everthing was OK, 1 if we should try to reprint the job and
- * -1 if a non-recoverable error occured.
  */
  */
-static
 printit(file)
        char *file;
 {
        register int i;
 printit(file)
        char *file;
 {
        register int i;
-       int bombed = 0;
+       char *cp;
+       int bombed = OK;
 
        /*
 
        /*
-        * open control file
+        * open control file; ignore if no longer there.
         */
        if ((cfp = fopen(file, "r")) == NULL) {
         */
        if ((cfp = fopen(file, "r")) == NULL) {
-               log("control file (%s) open failure <errno = %d>", file, errno);
-               return(0);
+               syslog(LOG_INFO, "%s: %s: %m", printer, file);
+               return(OK);
        }
        /*
         * Reset troff fonts.
         */
        for (i = 0; i < 4; i++)
                strcpy(fonts[i], ifonts[i]);
        }
        /*
         * Reset troff fonts.
         */
        for (i = 0; i < 4; i++)
                strcpy(fonts[i], ifonts[i]);
+       strcpy(width+2, "0");
+       strcpy(indent+2, "0");
 
        /*
         *      read the control file for work to do
 
        /*
         *      read the control file for work to do
@@ -224,6 +259,7 @@ printit(file)
         *      rest of the line is the argument.
         *      valid commands are:
         *
         *      rest of the line is the argument.
         *      valid commands are:
         *
+        *              S -- "stat info" for symbolic link protection
         *              J -- "job name" on banner page
         *              C -- "class name" on banner page
         *              L -- "literal" user's name to print on banner
         *              J -- "job name" on banner page
         *              C -- "class name" on banner page
         *              L -- "literal" user's name to print on banner
@@ -266,13 +302,26 @@ printit(file)
                        strncpy(logname, line+1, sizeof(logname)-1);
                        if (RS) {                       /* restricted */
                                if (getpwnam(logname) == (struct passwd *)0) {
                        strncpy(logname, line+1, sizeof(logname)-1);
                        if (RS) {                       /* restricted */
                                if (getpwnam(logname) == (struct passwd *)0) {
-                                       bombed = 2;
+                                       bombed = NOACCT;
                                        sendmail(line+1, bombed);
                                        goto pass2;
                                }
                        }
                        continue;
 
                                        sendmail(line+1, bombed);
                                        goto pass2;
                                }
                        }
                        continue;
 
+               case 'S':
+                       cp = line+1;
+                       i = 0;
+                       while (*cp >= '0' && *cp <= '9')
+                               i = i * 10 + (*cp++ - '0');
+                       fdev = i;
+                       cp++;
+                       i = 0;
+                       while (*cp >= '0' && *cp <= '9')
+                               i = i * 10 + (*cp++ - '0');
+                       fino = i;
+                       continue;
+
                case 'J':
                        if (line[1] != '\0')
                                strncpy(jobname, line+1, sizeof(jobname)-1);
                case 'J':
                        if (line[1] != '\0')
                                strncpy(jobname, line+1, sizeof(jobname)-1);
@@ -292,7 +341,7 @@ printit(file)
                        continue;
 
                case 'L':       /* identification line */
                        continue;
 
                case 'L':       /* identification line */
-                       if (!SH)
+                       if (!SH && !HL)
                                banner(line+1, jobname);
                        continue;
 
                                banner(line+1, jobname);
                        continue;
 
@@ -314,15 +363,16 @@ printit(file)
 
                default:        /* some file to print */
                        switch (i = print(line[0], line+1)) {
 
                default:        /* some file to print */
                        switch (i = print(line[0], line+1)) {
-                       case -1:
-                               if (!bombed)
-                                       bombed = 1;
+                       case ERROR:
+                               if (bombed == OK)
+                                       bombed = FATALERR;
                                break;
                                break;
-                       case 1:
+                       case REPRINT:
                                (void) fclose(cfp);
                                (void) fclose(cfp);
-                               return(1);
-                       case 2:
-                               bombed = 3;
+                               return(REPRINT);
+                       case FILTERERR:
+                       case ACCESS:
+                               bombed = i;
                                sendmail(logname, bombed);
                        }
                        title[0] = '\0';
                                sendmail(logname, bombed);
                        }
                        title[0] = '\0';
@@ -340,8 +390,13 @@ pass2:
        fseek(cfp, 0L, 0);
        while (getline(cfp))
                switch (line[0]) {
        fseek(cfp, 0L, 0);
        while (getline(cfp))
                switch (line[0]) {
+               case 'L':       /* identification line */
+                       if (!SH && HL)
+                               banner(line+1, jobname);
+                       continue;
+
                case 'M':
                case 'M':
-                       if (bombed < 2)         /* already sent if >= 2 */
+                       if (bombed < NOACCT)    /* already sent if >= NOACCT */
                                sendmail(line+1, bombed);
                        continue;
 
                                sendmail(line+1, bombed);
                        continue;
 
@@ -353,7 +408,7 @@ pass2:
         */
        (void) fclose(cfp);
        (void) unlink(file);
         */
        (void) fclose(cfp);
        (void) unlink(file);
-       return(bombed ? -1 : 0);
+       return(bombed == OK ? OK : ERROR);
 }
 
 /*
 }
 
 /*
@@ -366,7 +421,6 @@ pass2:
  * Note: all filters take stdin as the file, stdout as the printer,
  * stderr as the log file, and must not ignore SIGINT.
  */
  * Note: all filters take stdin as the file, stdout as the printer,
  * stderr as the log file, and must not ignore SIGINT.
  */
-static
 print(format, file)
        int format;
        char *file;
 print(format, file)
        int format;
        char *file;
@@ -374,14 +428,22 @@ print(format, file)
        register int n;
        register char *prog;
        int fi, fo;
        register int n;
        register char *prog;
        int fi, fo;
+       FILE *fp;
        char *av[15], buf[BUFSIZ];
        int pid, p[2], stopped = 0;
        union wait status;
        char *av[15], buf[BUFSIZ];
        int pid, p[2], stopped = 0;
        union wait status;
+       struct stat stb;
 
 
-       if ((fi = open(file, O_RDONLY)) < 0) {
-               log("%s: open failure <errno = %d>", file, errno);
-               return(-1);
-       }
+       if (lstat(file, &stb) < 0 || (fi = open(file, O_RDONLY)) < 0)
+               return(ERROR);
+       /*
+        * Check to see if data file is a symbolic link. If so, it should
+        * still point to the same file or someone is trying to print
+        * something he shouldn't.
+        */
+       if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(fi, &stb) == 0 &&
+           (stb.st_dev != fdev || stb.st_ino != fino))
+               return(ACCESS);
        if (!SF && !tof) {              /* start on a fresh page */
                (void) write(ofd, FF, strlen(FF));
                tof = 1;
        if (!SF && !tof) {              /* start on a fresh page */
                (void) write(ofd, FF, strlen(FF));
                tof = 1;
@@ -391,15 +453,15 @@ print(format, file)
                while ((n = read(fi, buf, BUFSIZ)) > 0)
                        if (write(ofd, buf, n) != n) {
                                (void) close(fi);
                while ((n = read(fi, buf, BUFSIZ)) > 0)
                        if (write(ofd, buf, n) != n) {
                                (void) close(fi);
-                               return(1);
+                               return(REPRINT);
                        }
                (void) close(fi);
                        }
                (void) close(fi);
-               return(0);
+               return(OK);
        }
        switch (format) {
        case 'p':       /* print file using 'pr' */
                if (IF == NULL) {       /* use output filter */
        }
        switch (format) {
        case 'p':       /* print file using 'pr' */
                if (IF == NULL) {       /* use output filter */
-                       prog = PR;
+                       prog = _PATH_PR;
                        av[0] = "pr";
                        av[1] = width;
                        av[2] = length;
                        av[0] = "pr";
                        av[1] = width;
                        av[2] = length;
@@ -415,8 +477,9 @@ print(format, file)
                        dup2(p[1], 1);          /* pipe is stdout */
                        for (n = 3; n < NOFILE; n++)
                                (void) close(n);
                        dup2(p[1], 1);          /* pipe is stdout */
                        for (n = 3; n < NOFILE; n++)
                                (void) close(n);
-                       execl(PR, "pr", width, length, "-h", *title ? title : " ", 0);
-                       log("cannot execl %s", PR);
+                       execl(_PATH_PR, "pr", width, length,
+                           "-h", *title ? title : " ", 0);
+                       syslog(LOG_ERR, "cannot execl %s", _PATH_PR);
                        exit(2);
                }
                (void) close(p[1]);             /* close output side */
                        exit(2);
                }
                (void) close(p[1]);             /* close output side */
@@ -424,7 +487,7 @@ print(format, file)
                if (prchild < 0) {
                        prchild = 0;
                        (void) close(p[0]);
                if (prchild < 0) {
                        prchild = 0;
                        (void) close(p[0]);
-                       return(-1);
+                       return(ERROR);
                }
                fi = p[0];                      /* use pipe for input */
        case 'f':       /* print plain text file */
                }
                fi = p[0];                      /* use pipe for input */
        case 'f':       /* print plain text file */
@@ -453,12 +516,12 @@ print(format, file)
        case 'd':       /* print tex output */
                (void) unlink(".railmag");
                if ((fo = creat(".railmag", FILMOD)) < 0) {
        case 'd':       /* print tex output */
                (void) unlink(".railmag");
                if ((fo = creat(".railmag", FILMOD)) < 0) {
-                       log("cannot create .railmag");
+                       syslog(LOG_ERR, "%s: cannot create .railmag", printer);
                        (void) unlink(".railmag");
                } else {
                        for (n = 0; n < 4; n++) {
                                if (fonts[n][0] != '/')
                        (void) unlink(".railmag");
                } else {
                        for (n = 0; n < 4; n++) {
                                if (fonts[n][0] != '/')
-                                       (void) write(fo, "/usr/lib/vfont/", 15);
+                                       (void) write(fo, _PATH_VFONT, 15);
                                (void) write(fo, fonts[n], strlen(fonts[n]));
                                (void) write(fo, "\n", 1);
                        }
                                (void) write(fo, fonts[n], strlen(fonts[n]));
                                (void) write(fo, "\n", 1);
                        }
@@ -489,8 +552,9 @@ print(format, file)
                break;
        default:
                (void) close(fi);
                break;
        default:
                (void) close(fi);
-               log("illegal format character '%c'", format);
-               return(-1);
+               syslog(LOG_ERR, "%s: illegal format character '%c'",
+                       printer, format);
+               return(ERROR);
        }
        if ((av[0] = rindex(prog, '/')) != NULL)
                av[0]++;
        }
        if ((av[0] = rindex(prog, '/')) != NULL)
                av[0]++;
@@ -509,8 +573,9 @@ print(format, file)
                        ;
                if (status.w_stopval != WSTOPPED) {
                        (void) close(fi);
                        ;
                if (status.w_stopval != WSTOPPED) {
                        (void) close(fi);
-                       log("output filter died (%d)", status.w_retcode);
-                       return(1);
+                       syslog(LOG_WARNING, "%s: output filter died (%d)",
+                               printer, status.w_retcode);
+                       return(REPRINT);
                }
                stopped++;
        }
                }
                stopped++;
        }
@@ -518,13 +583,13 @@ start:
        if ((child = dofork(DORETURN)) == 0) {  /* child */
                dup2(fi, 0);
                dup2(fo, 1);
        if ((child = dofork(DORETURN)) == 0) {  /* child */
                dup2(fi, 0);
                dup2(fo, 1);
-               n = open(tmpfile, O_WRONLY|O_CREAT, 0664);
+               n = open(tempfile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
                if (n >= 0)
                        dup2(n, 2);
                for (n = 3; n < NOFILE; n++)
                        (void) close(n);
                execv(prog, av);
                if (n >= 0)
                        dup2(n, 2);
                for (n = 3; n < NOFILE; n++)
                        (void) close(n);
                execv(prog, av);
-               log("cannot execl %s", prog);
+               syslog(LOG_ERR, "cannot execv %s", prog);
                exit(2);
        }
        (void) close(fi);
                exit(2);
        }
        (void) close(fi);
@@ -537,20 +602,38 @@ start:
        prchild = 0;
        if (stopped) {          /* restart output filter */
                if (kill(ofilter, SIGCONT) < 0) {
        prchild = 0;
        if (stopped) {          /* restart output filter */
                if (kill(ofilter, SIGCONT) < 0) {
-                       log("cannot restart output filter");
+                       syslog(LOG_ERR, "cannot restart output filter");
                        exit(1);
                }
        }
        tof = 0;
                        exit(1);
                }
        }
        tof = 0;
+
+       /* Copy filter output to "lf" logfile */
+       if (fp = fopen(tempfile, "r")) {
+               char tbuf[512];
+
+               while (fgets(buf, sizeof(buf), fp))
+                       fputs(buf, stderr);
+               close(fp);
+       }
+
        if (!WIFEXITED(status)) {
        if (!WIFEXITED(status)) {
-               log("Daemon filter '%c' terminated (%d)", format, status.w_termsig);
-               return(-1);
-       } else if (status.w_retcode > 2) {
-               log("Daemon filter '%c' exited (%d)", format, status.w_retcode);
-               return(-1);
-       } else if (status.w_retcode == 0)
+               syslog(LOG_WARNING, "%s: Daemon filter '%c' terminated (%d)",
+                       printer, format, status.w_termsig);
+               return(ERROR);
+       }
+       switch (status.w_retcode) {
+       case 0:
                tof = 1;
                tof = 1;
-       return(status.w_retcode);
+               return(OK);
+       case 1:
+               return(REPRINT);
+       default:
+               syslog(LOG_WARNING, "%s: Daemon filter '%c' exited (%d)",
+                       printer, format, status.w_retcode);
+       case 2:
+               return(ERROR);
+       }
 }
 
 /*
 }
 
 /*
@@ -558,20 +641,17 @@ start:
  * Return -1 if a non-recoverable error occured, 1 if a recoverable error and
  * 0 if all is well.
  */
  * Return -1 if a non-recoverable error occured, 1 if a recoverable error and
  * 0 if all is well.
  */
-static
 sendit(file)
        char *file;
 {
 sendit(file)
        char *file;
 {
-       register int linelen, err = 0;
-       char last[132];
+       register int i, err = OK;
+       char *cp, last[BUFSIZ];
 
        /*
         * open control file
         */
 
        /*
         * open control file
         */
-       if ((cfp = fopen(file, "r")) == NULL) {
-               log("control file (%s) open failure <errno = %d>", file, errno);
-               return(0);
-       }
+       if ((cfp = fopen(file, "r")) == NULL)
+               return(OK);
        /*
         *      read the control file for work to do
         *
        /*
         *      read the control file for work to do
         *
@@ -589,24 +669,43 @@ sendit(file)
         */
        while (getline(cfp)) {
        again:
         */
        while (getline(cfp)) {
        again:
+               if (line[0] == 'S') {
+                       cp = line+1;
+                       i = 0;
+                       while (*cp >= '0' && *cp <= '9')
+                               i = i * 10 + (*cp++ - '0');
+                       fdev = i;
+                       cp++;
+                       i = 0;
+                       while (*cp >= '0' && *cp <= '9')
+                               i = i * 10 + (*cp++ - '0');
+                       fino = i;
+                       continue;
+               }
                if (line[0] >= 'a' && line[0] <= 'z') {
                        strcpy(last, line);
                if (line[0] >= 'a' && line[0] <= 'z') {
                        strcpy(last, line);
-                       while (linelen = getline(cfp))
+                       while (i = getline(cfp))
                                if (strcmp(last, line))
                                        break;
                                if (strcmp(last, line))
                                        break;
-                       if ((err = sendfile('\3', last+1)) > 0) {
-                               (void) fclose(cfp);
-                               return(1);
-                       } else if (err)
+                       switch (sendfile('\3', last+1)) {
+                       case OK:
+                               if (i)
+                                       goto again;
                                break;
                                break;
-                       if (linelen)
-                               goto again;
+                       case REPRINT:
+                               (void) fclose(cfp);
+                               return(REPRINT);
+                       case ACCESS:
+                               sendmail(logname, ACCESS);
+                       case ERROR:
+                               err = ERROR;
+                       }
                        break;
                }
        }
                        break;
                }
        }
-       if (!err && sendfile('\2', file) > 0) {
+       if (err == OK && sendfile('\2', file) > 0) {
                (void) fclose(cfp);
                (void) fclose(cfp);
-               return(1);
+               return(REPRINT);
        }
        /*
         * pass 2
        }
        /*
         * pass 2
@@ -616,40 +715,53 @@ sendit(file)
                if (line[0] == 'U')
                        (void) unlink(line+1);
        /*
                if (line[0] == 'U')
                        (void) unlink(line+1);
        /*
-        * clean-up incase another control file exists
+        * clean-up in case another control file exists
         */
        (void) fclose(cfp);
        (void) unlink(file);
         */
        (void) fclose(cfp);
        (void) unlink(file);
-       return(0);
+       return(err);
 }
 
 /*
  * Send a data file to the remote machine and spool it.
  * Return positive if we should try resending.
  */
 }
 
 /*
  * Send a data file to the remote machine and spool it.
  * Return positive if we should try resending.
  */
-static
 sendfile(type, file)
        char type, *file;
 {
        register int f, i, amt;
        struct stat stb;
        char buf[BUFSIZ];
 sendfile(type, file)
        char type, *file;
 {
        register int f, i, amt;
        struct stat stb;
        char buf[BUFSIZ];
-       int sizerr;
+       int sizerr, resp;
 
 
-       if ((f = open(file, O_RDONLY)) < 0 || fstat(f, &stb) < 0) {
-               log("file (%s) open failure <errno = %d>", file, errno);
-               return(-1);
-       }
+       if (lstat(file, &stb) < 0 || (f = open(file, O_RDONLY)) < 0)
+               return(ERROR);
+       /*
+        * Check to see if data file is a symbolic link. If so, it should
+        * still point to the same file or someone is trying to print something
+        * he shouldn't.
+        */
+       if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(f, &stb) == 0 &&
+           (stb.st_dev != fdev || stb.st_ino != fino))
+               return(ACCESS);
        (void) sprintf(buf, "%c%d %s\n", type, stb.st_size, file);
        amt = strlen(buf);
        (void) sprintf(buf, "%c%d %s\n", type, stb.st_size, file);
        amt = strlen(buf);
-       if (write(pfd, buf, amt) != amt) {
-               (void) close(f);
-               return(1);
-       }
-       if (noresponse()) {
-               (void) close(f);
-               return(1);
+       for (i = 0;  ; i++) {
+               if (write(pfd, buf, amt) != amt ||
+                   (resp = response()) < 0 || resp == '\1') {
+                       (void) close(f);
+                       return(REPRINT);
+               } else if (resp == '\0')
+                       break;
+               if (i == 0)
+                       status("no space on remote; waiting for queue to drain");
+               if (i == 10)
+                       syslog(LOG_ALERT, "%s: can't send to %s; queue full",
+                               printer, RM);
+               sleep(5 * 60);
        }
        }
+       if (i)
+               status("sending to %s", RM);
        sizerr = 0;
        for (i = 0; i < stb.st_size; i += BUFSIZ) {
                amt = BUFSIZ;
        sizerr = 0;
        for (i = 0; i < stb.st_size; i += BUFSIZ) {
                amt = BUFSIZ;
@@ -659,20 +771,19 @@ sendfile(type, file)
                        sizerr = 1;
                if (write(pfd, buf, amt) != amt) {
                        (void) close(f);
                        sizerr = 1;
                if (write(pfd, buf, amt) != amt) {
                        (void) close(f);
-                       return(1);
+                       return(REPRINT);
                }
        }
        (void) close(f);
        if (sizerr) {
                }
        }
        (void) close(f);
        if (sizerr) {
-               log("%s: changed size", file);
-               (void) write(pfd, "\1", 1);  /* tell recvjob to ignore this file */
-               return(-1);
+               syslog(LOG_INFO, "%s: %s: changed size", printer, file);
+               /* tell recvjob to ignore this file */
+               (void) write(pfd, "\1", 1);
+               return(ERROR);
        }
        }
-       if (write(pfd, "", 1) != 1)
-               return(1);
-       if (noresponse())
-               return(1);
-       return(0);
+       if (write(pfd, "", 1) != 1 || response())
+               return(REPRINT);
+       return(OK);
 }
 
 /*
 }
 
 /*
@@ -680,22 +791,20 @@ sendfile(type, file)
  * are in sync with eachother.
  * Return non-zero if the connection was lost.
  */
  * are in sync with eachother.
  * Return non-zero if the connection was lost.
  */
-static
-noresponse()
+response()
 {
        char resp;
 
 {
        char resp;
 
-       if (read(pfd, &resp, 1) != 1 || resp != '\0') {
-               log("lost connection or error in recvjob");
-               return(1);
+       if (read(pfd, &resp, 1) != 1) {
+               syslog(LOG_INFO, "%s: lost connection", printer);
+               return(-1);
        }
        }
-       return(0);
+       return(resp);
 }
 
 /*
  * Banner printing stuff
  */
 }
 
 /*
  * Banner printing stuff
  */
-static
 banner(name1, name2)
        char *name1, *name2;
 {
 banner(name1, name2)
        char *name1, *name2;
 {
@@ -736,7 +845,7 @@ banner(name1, name2)
        tof = 1;
 }
 
        tof = 1;
 }
 
-static char *
+char *
 scnline(key, p, c)
        register char key, *p;
        char c;
 scnline(key, p, c)
        register char key, *p;
        char c;
@@ -752,7 +861,6 @@ scnline(key, p, c)
 
 #define TRC(q) (((q)-' ')&0177)
 
 
 #define TRC(q) (((q)-' ')&0177)
 
-static
 scan_out(scfd, scsp, dlm)
        int scfd;
        char *scsp, dlm;
 scan_out(scfd, scsp, dlm)
        int scfd;
        char *scsp, dlm;
@@ -786,7 +894,6 @@ scan_out(scfd, scsp, dlm)
        }
 }
 
        }
 }
 
-static
 dropit(c)
        char c;
 {
 dropit(c)
        char c;
 {
@@ -811,7 +918,6 @@ dropit(c)
  * sendmail ---
  *   tell people about job completion
  */
  * sendmail ---
  *   tell people about job completion
  */
-static
 sendmail(user, bombed)
        char *user;
        int bombed;
 sendmail(user, bombed)
        char *user;
        int bombed;
@@ -828,12 +934,12 @@ sendmail(user, bombed)
                dup2(p[0], 0);
                for (i = 3; i < NOFILE; i++)
                        (void) close(i);
                dup2(p[0], 0);
                for (i = 3; i < NOFILE; i++)
                        (void) close(i);
-               if ((cp = rindex(MAIL, '/')) != NULL)
+               if ((cp = rindex(_PATH_SENDMAIL, '/')) != NULL)
                        cp++;
                else
                        cp++;
                else
-                       cp = MAIL;
+                       cp = _PATH_SENDMAIL;
                sprintf(buf, "%s@%s", user, fromhost);
                sprintf(buf, "%s@%s", user, fromhost);
-               execl(MAIL, cp, buf, 0);
+               execl(_PATH_SENDMAIL, cp, buf, 0);
                exit(0);
        } else if (s > 0) {                             /* parent */
                dup2(p[1], 1);
                exit(0);
        } else if (s > 0) {                             /* parent */
                dup2(p[1], 1);
@@ -843,19 +949,19 @@ sendmail(user, bombed)
                if (*jobname)
                        printf("(%s) ", jobname);
                switch (bombed) {
                if (*jobname)
                        printf("(%s) ", jobname);
                switch (bombed) {
-               case 0:
+               case OK:
                        printf("\ncompleted successfully\n");
                        break;
                default:
                        printf("\ncompleted successfully\n");
                        break;
                default:
-               case 1:
+               case FATALERR:
                        printf("\ncould not be printed\n");
                        break;
                        printf("\ncould not be printed\n");
                        break;
-               case 2:
+               case NOACCT:
                        printf("\ncould not be printed without an account on %s\n", host);
                        break;
                        printf("\ncould not be printed without an account on %s\n", host);
                        break;
-               case 3:
-                       if (stat(tmpfile, &stb) < 0 || stb.st_size == 0 ||
-                           (fp = fopen(tmpfile, "r")) == NULL) {
+               case FILTERERR:
+                       if (stat(tempfile, &stb) < 0 || stb.st_size == 0 ||
+                           (fp = fopen(tempfile, "r")) == NULL) {
                                printf("\nwas printed but had some errors\n");
                                break;
                        }
                                printf("\nwas printed but had some errors\n");
                                break;
                        }
@@ -863,6 +969,9 @@ sendmail(user, bombed)
                        while ((i = getc(fp)) != EOF)
                                putchar(i);
                        (void) fclose(fp);
                        while ((i = getc(fp)) != EOF)
                                putchar(i);
                        (void) fclose(fp);
+                       break;
+               case ACCESS:
+                       printf("\nwas not printed because it was not linked to the original file\n");
                }
                fflush(stdout);
                (void) close(1);
                }
                fflush(stdout);
                (void) close(1);
@@ -875,7 +984,6 @@ sendmail(user, bombed)
 /*
  * dofork - fork with retries on failure
  */
 /*
  * dofork - fork with retries on failure
  */
-static
 dofork(action)
        int action;
 {
 dofork(action)
        int action;
 {
@@ -893,13 +1001,13 @@ dofork(action)
                        setuid(DU);
                return(pid);
        }
                        setuid(DU);
                return(pid);
        }
-       log("can't fork");
+       syslog(LOG_ERR, "can't fork");
 
        switch (action) {
        case DORETURN:
                return (-1);
        default:
 
        switch (action) {
        case DORETURN:
                return (-1);
        default:
-               log("bad action (%d) to dofork", action);
+               syslog(LOG_ERR, "bad action (%d) to dofork", action);
                /*FALL THRU*/
        case DOABORT:
                exit(1);
                /*FALL THRU*/
        case DOABORT:
                exit(1);
@@ -908,12 +1016,11 @@ dofork(action)
 }
 
 /*
 }
 
 /*
- * Cleanup child processes when a signal is caught.
+ * Kill child processes to abort current job.
  */
  */
-static
-onintr()
+abortpr()
 {
 {
-       (void) unlink(tmpfile);
+       (void) unlink(tempfile);
        kill(0, SIGINT);
        if (ofilter > 0)
                kill(ofilter, SIGCONT);
        kill(0, SIGINT);
        if (ofilter > 0)
                kill(ofilter, SIGCONT);
@@ -922,17 +1029,20 @@ onintr()
        exit(0);
 }
 
        exit(0);
 }
 
-static
 init()
 {
        int status;
 init()
 {
        int status;
+       char *s;
 
 
-       if ((status = pgetent(line, printer)) < 0)
-               fatal("can't open printer description file");
-       else if (status == 0)
-               fatal("unknown printer");
+       if ((status = pgetent(line, printer)) < 0) {
+               syslog(LOG_ERR, "can't open printer description file");
+               exit(1);
+       } else if (status == 0) {
+               syslog(LOG_ERR, "unknown printer: %s", printer);
+               exit(1);
+       }
        if ((LP = pgetstr("lp", &bp)) == NULL)
        if ((LP = pgetstr("lp", &bp)) == NULL)
-               LP = DEFDEVLP;
+               LP = _PATH_DEFDEVLP;
        if ((RP = pgetstr("rp", &bp)) == NULL)
                RP = DEFLP;
        if ((LO = pgetstr("lo", &bp)) == NULL)
        if ((RP = pgetstr("rp", &bp)) == NULL)
                RP = DEFLP;
        if ((LO = pgetstr("lo", &bp)) == NULL)
@@ -940,9 +1050,9 @@ init()
        if ((ST = pgetstr("st", &bp)) == NULL)
                ST = DEFSTAT;
        if ((LF = pgetstr("lf", &bp)) == NULL)
        if ((ST = pgetstr("st", &bp)) == NULL)
                ST = DEFSTAT;
        if ((LF = pgetstr("lf", &bp)) == NULL)
-               LF = DEFLOGF;
+               LF = _PATH_CONSOLE;
        if ((SD = pgetstr("sd", &bp)) == NULL)
        if ((SD = pgetstr("sd", &bp)) == NULL)
-               SD = DEFSPOOL;
+               SD = _PATH_DEFSPOOL;
        if ((DU = pgetnum("du")) < 0)
                DU = DEFUID;
        if ((FF = pgetstr("ff", &bp)) == NULL)
        if ((DU = pgetnum("du")) < 0)
                DU = DEFUID;
        if ((FF = pgetstr("ff", &bp)) == NULL)
@@ -960,6 +1070,9 @@ init()
                PY = 0;
        sprintf(&pxlength[2], "%d", PY);
        RM = pgetstr("rm", &bp);
                PY = 0;
        sprintf(&pxlength[2], "%d", PY);
        RM = pgetstr("rm", &bp);
+       if (s = checkremote())
+               syslog(LOG_WARNING, s);
+
        AF = pgetstr("af", &bp);
        OF = pgetstr("of", &bp);
        IF = pgetstr("if", &bp);
        AF = pgetstr("af", &bp);
        OF = pgetstr("of", &bp);
        IF = pgetstr("if", &bp);
@@ -975,6 +1088,7 @@ init()
        SF = pgetflag("sf");
        SH = pgetflag("sh");
        SB = pgetflag("sb");
        SF = pgetflag("sf");
        SH = pgetflag("sh");
        SB = pgetflag("sb");
+       HL = pgetflag("hl");
        RW = pgetflag("rw");
        BR = pgetnum("br");
        if ((FC = pgetnum("fc")) < 0)
        RW = pgetflag("rw");
        BR = pgetnum("br");
        if ((FC = pgetnum("fc")) < 0)
@@ -991,18 +1105,18 @@ init()
 /*
  * Acquire line printer or remote connection.
  */
 /*
  * Acquire line printer or remote connection.
  */
-static
 openpr()
 {
        register int i, n;
 openpr()
 {
        register int i, n;
+       int resp;
 
 
-       if (*LP) {
+       if (!sendtorem && *LP) {
                for (i = 1; ; i = i < 32 ? i << 1 : i) {
                        pfd = open(LP, RW ? O_RDWR : O_WRONLY);
                        if (pfd >= 0)
                                break;
                        if (errno == ENOENT) {
                for (i = 1; ; i = i < 32 ? i << 1 : i) {
                        pfd = open(LP, RW ? O_RDWR : O_WRONLY);
                        if (pfd >= 0)
                                break;
                        if (errno == ENOENT) {
-                               log("cannot open %s", LP);
+                               syslog(LOG_ERR, "%s: %m", LP);
                                exit(1);
                        }
                        if (i == 1)
                                exit(1);
                        }
                        if (i == 1)
@@ -1013,32 +1127,38 @@ openpr()
                        setty();
                status("%s is ready and printing", printer);
        } else if (RM != NULL) {
                        setty();
                status("%s is ready and printing", printer);
        } else if (RM != NULL) {
-               for (i = 1; ; i = i < 512 ? i << 1 : i) {
+               for (i = 1; ; i = i < 256 ? i << 1 : i) {
+                       resp = -1;
                        pfd = getport(RM);
                        if (pfd >= 0) {
                                (void) sprintf(line, "\2%s\n", RP);
                                n = strlen(line);
                        pfd = getport(RM);
                        if (pfd >= 0) {
                                (void) sprintf(line, "\2%s\n", RP);
                                n = strlen(line);
-                               if (write(pfd, line, n) != n)
-                                       break;
-                               if (noresponse())
-                                       (void) close(pfd);
-                               else
+                               if (write(pfd, line, n) == n &&
+                                   (resp = response()) == '\0')
                                        break;
                                        break;
+                               (void) close(pfd);
+                       }
+                       if (i == 1) {
+                               if (resp < 0)
+                                       status("waiting for %s to come up", RM);
+                               else {
+                                       status("waiting for queue to be enabled on %s", RM);
+                                       i = 256;
+                               }
                        }
                        }
-                       if (i == 1)
-                               status("waiting for %s to come up", RM);
                        sleep(i);
                }
                status("sending to %s", RM);
                remote = 1;
        } else {
                        sleep(i);
                }
                status("sending to %s", RM);
                remote = 1;
        } else {
-               log("no line printer device or remote machine name");
+               syslog(LOG_ERR, "%s: no line printer device or host name",
+                       printer);
                exit(1);
        }
        /*
         * Start up an output filter, if needed.
         */
                exit(1);
        }
        /*
         * Start up an output filter, if needed.
         */
-       if (OF) {
+       if (!remote && OF) {
                int p[2];
                char *cp;
 
                int p[2];
                char *cp;
 
@@ -1053,7 +1173,7 @@ openpr()
                        else
                                cp++;
                        execl(OF, cp, width, length, 0);
                        else
                                cp++;
                        execl(OF, cp, width, length, 0);
-                       log("can't execl output filter %s", OF);
+                       syslog(LOG_ERR, "%s: %s: %m", printer, OF);
                        exit(1);
                }
                (void) close(p[0]);             /* close input side */
                        exit(1);
                }
                (void) close(p[0]);             /* close input side */
@@ -1089,18 +1209,17 @@ struct bauds {
 /*
  * setup tty lines.
  */
 /*
  * setup tty lines.
  */
-static
 setty()
 {
        struct sgttyb ttybuf;
        register struct bauds *bp;
 
        if (ioctl(pfd, TIOCEXCL, (char *)0) < 0) {
 setty()
 {
        struct sgttyb ttybuf;
        register struct bauds *bp;
 
        if (ioctl(pfd, TIOCEXCL, (char *)0) < 0) {
-               log("cannot set exclusive-use");
+               syslog(LOG_ERR, "%s: ioctl(TIOCEXCL): %m", printer);
                exit(1);
        }
        if (ioctl(pfd, TIOCGETP, (char *)&ttybuf) < 0) {
                exit(1);
        }
        if (ioctl(pfd, TIOCGETP, (char *)&ttybuf) < 0) {
-               log("cannot get tty parameters");
+               syslog(LOG_ERR, "%s: ioctl(TIOCGETP): %m", printer);
                exit(1);
        }
        if (BR > 0) {
                exit(1);
        }
        if (BR > 0) {
@@ -1108,7 +1227,7 @@ setty()
                        if (BR == bp->baud)
                                break;
                if (!bp->baud) {
                        if (BR == bp->baud)
                                break;
                if (!bp->baud) {
-                       log("illegal baud rate %d", BR);
+                       syslog(LOG_ERR, "%s: illegal baud rate %d", printer, BR);
                        exit(1);
                }
                ttybuf.sg_ispeed = ttybuf.sg_ospeed = bp->speed;
                        exit(1);
                }
                ttybuf.sg_ispeed = ttybuf.sg_ospeed = bp->speed;
@@ -1116,25 +1235,24 @@ setty()
        ttybuf.sg_flags &= ~FC;
        ttybuf.sg_flags |= FS;
        if (ioctl(pfd, TIOCSETP, (char *)&ttybuf) < 0) {
        ttybuf.sg_flags &= ~FC;
        ttybuf.sg_flags |= FS;
        if (ioctl(pfd, TIOCSETP, (char *)&ttybuf) < 0) {
-               log("cannot set tty parameters");
+               syslog(LOG_ERR, "%s: ioctl(TIOCSETP): %m", printer);
                exit(1);
        }
        if (XC) {
                if (ioctl(pfd, TIOCLBIC, &XC) < 0) {
                exit(1);
        }
        if (XC) {
                if (ioctl(pfd, TIOCLBIC, &XC) < 0) {
-                       log("cannot set local tty parameters");
+                       syslog(LOG_ERR, "%s: ioctl(TIOCLBIC): %m", printer);
                        exit(1);
                }
        }
        if (XS) {
                if (ioctl(pfd, TIOCLBIS, &XS) < 0) {
                        exit(1);
                }
        }
        if (XS) {
                if (ioctl(pfd, TIOCLBIS, &XS) < 0) {
-                       log("cannot set local tty parameters");
+                       syslog(LOG_ERR, "%s: ioctl(TIOCLBIS): %m", printer);
                        exit(1);
                }
        }
 }
 
 /*VARARGS1*/
                        exit(1);
                }
        }
 }
 
 /*VARARGS1*/
-static
 status(msg, a1, a2, a3)
        char *msg;
 {
 status(msg, a1, a2, a3)
        char *msg;
 {
@@ -1143,8 +1261,10 @@ status(msg, a1, a2, a3)
 
        umask(0);
        fd = open(ST, O_WRONLY|O_CREAT, 0664);
 
        umask(0);
        fd = open(ST, O_WRONLY|O_CREAT, 0664);
-       if (fd < 0 || flock(fd, LOCK_EX) < 0)
-               fatal("cannot create status file");
+       if (fd < 0 || flock(fd, LOCK_EX) < 0) {
+               syslog(LOG_ERR, "%s: %s: %m", printer, ST);
+               exit(1);
+       }
        ftruncate(fd, 0);
        sprintf(buf, msg, a1, a2, a3);
        strcat(buf, "\n");
        ftruncate(fd, 0);
        sprintf(buf, msg, a1, a2, a3);
        strcat(buf, "\n");