/* * 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); }