BSD 3 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Sun, 25 Nov 1979 08:24:08 +0000 (00:24 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Sun, 25 Nov 1979 08:24:08 +0000 (00:24 -0800)
Work on file usr/src/cmd/lpr/lpd.c

Synthesized-from: 3bsd

usr/src/cmd/lpr/lpd.c [new file with mode: 0755]

diff --git a/usr/src/cmd/lpr/lpd.c b/usr/src/cmd/lpr/lpd.c
new file mode 100755 (executable)
index 0000000..effd466
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Line-printer daemon
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <dir.h>
+#include <signal.h>
+#include <stat.h>
+#include <sgtty.h>
+
+char   line[128];
+char   banbuf[64];
+int    linel;
+FILE   *dfb;
+char   dfname[26] = "/usr/spool/lpd/";
+int    waittm  = 60;
+struct dir dbuf;
+int    onalrm();
+
+main(argc, argv)
+{
+       register char *p1, *p2;
+       register int df;
+       register FILE *dp;
+       struct stat stb;
+
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+       signal(SIGTERM, SIG_IGN);
+/*
+ * Close all files, open root as 0, 1, 2
+ * to assure standard environment
+ */
+       for (df=0; df<=15; df++)
+               close(df);
+       open("/", 0);
+       dup(0);
+       dup(0);
+       if (stat("/usr/spool/lpd/lock", &stb) >= 0)
+               exit(0);
+       if ((df=creat("/usr/spool/lpd/lock", 0)) < 0)
+               exit(0);
+       close(df);
+       if (fork())
+               exit(0);
+again:
+       dp = fopen("/usr/spool/lpd", "r");
+       do {
+               if (fread(&dbuf, sizeof dbuf, 1, dp) != 1) {
+                       feedpage();
+                       unlink("/usr/spool/lpd/lock");
+                       exit(0);
+               }
+       } while (dbuf.d_ino==0 || dbuf.d_name[0]!='d' || dbuf.d_name[1]!='f');
+       fclose(dp);
+       strcpy(dfname, "/usr/spool/lpd/");
+       strcatn(dfname, dbuf.d_name, DIRSIZ);
+       if (trysend(dfname) == 0)
+               goto again;
+       sleep(waittm);
+       goto again;
+}
+
+trysend(file)
+       char *file;
+{
+       register char *p1, *p2;
+       register int i;
+       extern int badexit();
+
+       dfb = fopen(file, "r");
+       if (dfb == NULL)
+               return(0);
+       banbuf[0] = 0;
+       while (getline()) switch (line[0]) {
+       case 'L':
+               p1 = line+1;
+               p2 = banbuf;
+               while (*p2++ = *p1++);
+               continue;
+
+       case 'F':
+               if (send())
+                       return(1);
+               continue;
+
+       case 'U':
+               continue;
+
+       case 'M':
+               continue;
+       }
+/*
+ * Second pass.
+ * Unlink files and send mail.
+ */
+       fseek(dfb, 0L, 0);
+       while (getline()) switch (line[0]) {
+
+       default:
+               continue;
+
+       case 'U':
+               unlink(&line[1]);
+               continue;
+
+       case 'M':
+               sendmail();
+               continue;
+       }
+       fclose(dfb);
+       unlink(file);
+}
+
+sendmail()
+{
+       static int p[2];
+       register i;
+       int stat;
+
+       pipe(p);
+       if (fork()==0) {
+               alarm(0);
+               if (p[0] != 0) {
+                       close(0);
+                       dup(p[0]);
+                       close(p[0]);
+               }
+               close(p[1]);
+               for (i=3; i<=15; i++)
+                       close(i);
+               execl("/bin/mail", "mail", &line[1], 0);
+               exit(0);
+       }
+       write(p[1], "Your printer job is done\n", 25);
+       close(p[0]);
+       close(p[1]);
+       wait(&stat);
+}
+
+getline()
+{
+       register char *lp;
+       register int c;
+
+       lp = line;
+       linel = 0;
+       while ((c = getc(dfb)) != '\n') {
+               if (c<0)
+                       return(0);
+               if (c=='\t') {
+                       do {
+                               *lp++ = ' ';
+                               linel++;
+                       } while ((linel & 07) != 0);
+                       continue;
+               }
+               *lp++ = c;
+               linel++;
+       }
+       *lp++ = 0;
+       return(1);
+}
+
+int    pid;
+
+send()
+{
+       int p;
+
+       if (pid = fork()) {
+               if (pid == -1)
+                       return(1);
+               setexit();
+               signal(SIGALRM, onalrm);
+               alarm(30);
+               wait(&p);
+               alarm(0);
+               return(p);
+       }
+       if (banbuf[0]) {
+               execl("/usr/lib/lpf", "lpf", "-b", banbuf, line+1, 0);
+               return(1);
+       }
+       execl("/usr/lib/lpf", "lpf", line, 0);
+       return(1);
+}
+
+onalrm()
+{
+       struct stat stb;
+
+       signal(SIGALRM, onalrm);
+       if (stat(dfname, &stb) < 0)
+               kill(pid, SIGEMT);
+       reset();
+}
+
+struct sgttyb ttyb = {
+       B9600, B9600,
+       0, 0,
+       XTABS|ANYP|ECHO
+};
+
+feedpage()
+{
+       register int i = 66;
+       FILE *lp;
+
+       lp = fopen("/dev/lp", "w");
+       if (lp == NULL)
+               return;
+       stty(fileno(lp), &ttyb);
+       while (i > 0)
+               fprintf(lp, "\n"), i--;
+       fclose(lp);
+}