From 538eba61a7959f88d84f4baeab0d6cb53eb6c1fc Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Sat, 25 Aug 1979 17:59:53 -0500 Subject: [PATCH] Research V7 development Work on file usr/src/cmd/lpr/lpd.c Work on file usr/src/cmd/lpr/daemon0.c Work on file usr/src/cmd/lpr/daemon.c Work on file usr/src/cmd/lpr/makefile Work on file usr/src/cmd/lpr/lpr.c Work on file usr/src/cmd/lpr/spool.c Work on file usr/src/cmd/lpr/chrtab.c Work on file usr/man/man8/lpd.8 Co-Authored-By: Dennis Ritchie Synthesized-from: v7 --- usr/man/man8/lpd.8 | 90 ++++++++ usr/src/cmd/lpr/chrtab.c | 98 +++++++++ usr/src/cmd/lpr/daemon.c | 333 +++++++++++++++++++++++++++++ usr/src/cmd/lpr/daemon0.c | 113 ++++++++++ usr/src/cmd/lpr/lpd.c | 219 +++++++++++++++++++ usr/src/cmd/lpr/lpr.c | 104 +++++++++ usr/src/cmd/lpr/makefile | 15 ++ usr/src/cmd/lpr/spool.c | 436 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 1408 insertions(+) create mode 100644 usr/man/man8/lpd.8 create mode 100644 usr/src/cmd/lpr/chrtab.c create mode 100644 usr/src/cmd/lpr/daemon.c create mode 100644 usr/src/cmd/lpr/daemon0.c create mode 100644 usr/src/cmd/lpr/lpd.c create mode 100644 usr/src/cmd/lpr/lpr.c create mode 100644 usr/src/cmd/lpr/makefile create mode 100644 usr/src/cmd/lpr/spool.c diff --git a/usr/man/man8/lpd.8 b/usr/man/man8/lpd.8 new file mode 100644 index 0000000000..aa6ba76969 --- /dev/null +++ b/usr/man/man8/lpd.8 @@ -0,0 +1,90 @@ +.TH LPD 8 +.SH NAME +lpd \- line printer daemon +.SH SYNOPSIS +.B /etc/lpd +.SH DESCRIPTION +.I Lpd +is the daemon for the line printer. +.I Lpd +uses the directory +.IR /usr/spool/lpd . +The file +.I lock +in that directory is used +to prevent two daemons from becoming active. +After the program has successfully set the lock, +it forks and the main path exits, thus +spawning the daemon. +The directory is scanned for files +beginning with +.B df. +Each such file is submitted as a job. +Each line of a job file must begin with a key +character to specify what to do with the remainder +of the line. +.TP 5 +.B L +specifies that the remainder of the line is to +be sent as a literal. +.TP 5 +.B B +specifies that the rest of the line +is a file name. +.TP 5 +.B F +is the same as +.B B +except a form feed is prepended to the file. +.TP 5 +.B U +specifies that the rest of the line +is a file name. +After the job has been transmitted, +the file is unlinked. +.TP 5 +.B M +is followed by a user ID; after the job is sent, +a message is +mailed to the user via the +.IR mail (1) +command +to verify the sending of the job. +.PP +Any error encountered will cause the daemon to +wait and start over. +This means that an improperly constructed +.B df +file may cause the same job to be submitted +repeatedly. +.PP +.I Lpd +is automatically initiated by the line printer command, +.I lpr. +.PP +.PP +To restart +.I lpd +(in the case of hardware or software malfunction), +it is necessary to first kill the old +daemon +(if still alive), +and remove the lock file +before initiating +the new daemon. +This is done automatically when the system is brought up, +by +.I /etc/rc, +in case there were any jobs left in the spooling directory +when the system last went down. +.SH FILES +/usr/spool/lpd/* +spool area for line printer daemon +.br +/etc/passwd +to get the user's name +.br +/dev/lp +line printer device +.SH "SEE ALSO" +lpr(1) diff --git a/usr/src/cmd/lpr/chrtab.c b/usr/src/cmd/lpr/chrtab.c new file mode 100644 index 0000000000..4d8a81acc9 --- /dev/null +++ b/usr/src/cmd/lpr/chrtab.c @@ -0,0 +1,98 @@ +char chrtab[][16] = { +0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, /*, sp, */ +0010,0010,0010,0010,0010,0010,0010,0010,0000,0000,0010,0000,0000,0000,0000,0000, /*, !, */ +0024,0024,0024,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, /*, ", */ +0000,0000,0000,0044,0044,0176,0044,0044,0176,0044,0044,0000,0000,0000,0000,0000, /*, #, */ +0000,0010,0010,0010,0076,0101,0100,0076,0001,0101,0076,0010,0010,0000,0000,0000, /*, $, */ +0000,0000,0000,0141,0142,0004,0010,0010,0020,0043,0103,0000,0000,0000,0000,0000, /*, %, */ +0000,0000,0070,0104,0110,0060,0060,0111,0106,0106,0071,0000,0000,0000,0000,0000, /*, &, */ +0004,0010,0020,0040,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, /*, ', */ +0000,0004,0010,0020,0040,0040,0040,0040,0040,0040,0020,0010,0004,0000,0000,0000, /*, (, */ +0000,0040,0020,0010,0004,0004,0004,0004,0004,0004,0010,0020,0040,0000,0000,0000, /*, ), */ +0000,0000,0000,0010,0111,0052,0034,0177,0034,0052,0111,0010,0000,0000,0000,0000, /*, *, */ +0000,0000,0000,0000,0010,0010,0010,0177,0010,0010,0010,0000,0000,0000,0000,0000, /*, +, */ +0000,0000,0000,0000,0000,0000,0000,0000,0000,0030,0030,0010,0020,0000,0000,0000, /*, ,, */ +0000,0000,0000,0000,0000,0000,0000,0176,0000,0000,0000,0000,0000,0000,0000,0000, /*, -, */ +0000,0000,0000,0000,0000,0000,0000,0000,0000,0030,0030,0000,0000,0000,0000,0000, /*, ., */ +0000,0000,0001,0002,0004,0010,0010,0010,0020,0040,0100,0000,0000,0000,0000,0000, /*, /, */ +0000,0030,0044,0102,0102,0102,0102,0102,0102,0044,0030,0000,0000,0000,0000,0000, /*, 0, */ +0000,0010,0030,0010,0010,0010,0010,0010,0010,0010,0034,0000,0000,0000,0000,0000, /*, 1, */ +0000,0070,0104,0004,0004,0010,0020,0040,0100,0100,0174,0000,0000,0000,0000,0000, /*, 2, */ +0000,0176,0004,0004,0010,0014,0002,0002,0002,0104,0070,0000,0000,0000,0000,0000, /*, 3, */ +0000,0004,0014,0024,0044,0104,0176,0004,0004,0004,0004,0000,0000,0000,0000,0000, /*, 4, */ +0000,0174,0100,0100,0130,0144,0002,0002,0102,0044,0030,0000,0000,0000,0000,0000, /*, 5, */ +0000,0074,0102,0100,0130,0144,0102,0102,0102,0044,0030,0000,0000,0000,0000,0000, /*, 6, */ +0000,0176,0004,0004,0010,0010,0020,0020,0040,0040,0040,0000,0000,0000,0000,0000, /*, 7, */ +0000,0034,0042,0101,0042,0076,0101,0101,0101,0101,0076,0000,0000,0000,0000,0000, /*, 8, */ +0000,0034,0042,0101,0101,0101,0043,0036,0004,0010,0020,0040,0000,0000,0000,0000, /*, 9, */ +0000,0000,0000,0000,0000,0000,0030,0030,0000,0030,0030,0000,0000,0000,0000,0000, /*, :, */ +0000,0000,0000,0000,0000,0000,0030,0030,0000,0030,0030,0020,0040,0000,0000,0000, /*, ;, */ +0002,0004,0010,0020,0040,0100,0040,0020,0010,0004,0002,0000,0000,0000,0000,0000, /*, <, */ +0000,0000,0000,0000,0177,0000,0177,0000,0000,0000,0000,0000,0000,0000,0000,0000, /*, =, */ +0100,0040,0020,0010,0004,0002,0004,0010,0020,0040,0100,0000,0000,0000,0000,0000, /*, >, */ +0000,0030,0044,0102,0001,0002,0004,0010,0010,0000,0010,0000,0000,0000,0000,0000, /*, ?, */ +0000,0074,0102,0101,0115,0123,0121,0121,0121,0111,0046,0000,0000,0000,0000,0000, /*, @, */ +0000,0010,0024,0042,0101,0101,0177,0101,0101,0101,0101,0000,0000,0000,0000,0000, /*, A, */ +0000,0176,0101,0101,0101,0176,0101,0101,0101,0101,0176,0000,0000,0000,0000,0000, /*, B, */ +0000,0076,0101,0100,0100,0100,0100,0100,0100,0101,0076,0000,0000,0000,0000,0000, /*, C, */ +0000,0176,0101,0101,0101,0101,0101,0101,0101,0101,0176,0000,0000,0000,0000,0000, /*, D, */ +0000,0176,0100,0100,0100,0170,0100,0100,0100,0100,0177,0000,0000,0000,0000,0000, /*, E, */ +0000,0177,0100,0100,0100,0174,0100,0100,0100,0100,0100,0000,0000,0000,0000,0000, /*, F, */ +0000,0076,0101,0100,0100,0117,0101,0101,0101,0101,0076,0000,0000,0000,0000,0000, /*, G, */ +0000,0101,0101,0101,0101,0176,0101,0101,0101,0101,0101,0000,0000,0000,0000,0000, /*, H, */ +0000,0034,0010,0010,0010,0010,0010,0010,0010,0010,0034,0000,0000,0000,0000,0000, /*, I, */ +0000,0016,0004,0004,0004,0004,0004,0004,0104,0104,0070,0000,0000,0000,0000,0000, /*, J, */ +0000,0101,0102,0104,0110,0120,0160,0110,0104,0102,0101,0000,0000,0000,0000,0000, /*, K, */ +0000,0100,0100,0100,0100,0100,0100,0100,0100,0100,0177,0000,0000,0000,0000,0000, /*, L, */ +0000,0101,0143,0125,0111,0101,0101,0101,0101,0101,0101,0000,0000,0000,0000,0000, /*, M, */ +0000,0101,0141,0121,0111,0105,0103,0101,0101,0101,0101,0000,0000,0000,0000,0000, /*, N, */ +0000,0076,0101,0101,0101,0101,0101,0101,0101,0101,0076,0000,0000,0000,0000,0000, /*, O, */ +0000,0176,0101,0101,0101,0176,0100,0100,0100,0100,0100,0000,0000,0000,0000,0000, /*, P, */ +0000,0076,0101,0101,0101,0101,0101,0101,0131,0105,0076,0002,0001,0000,0000,0000, /*, Q, */ +0000,0176,0101,0101,0101,0176,0104,0102,0101,0101,0101,0000,0000,0000,0000,0000, /*, R, */ +0000,0076,0101,0100,0100,0076,0001,0001,0001,0101,0076,0000,0000,0000,0000,0000, /*, S, */ +0000,0177,0010,0010,0010,0010,0010,0010,0010,0010,0010,0000,0000,0000,0000,0000, /*, T, */ +0000,0101,0101,0101,0101,0101,0101,0101,0101,0101,0076,0000,0000,0000,0000,0000, /*, U, */ +0000,0101,0101,0101,0101,0101,0101,0101,0042,0024,0010,0000,0000,0000,0000,0000, /*, V, */ +0000,0101,0101,0101,0101,0111,0111,0125,0143,0101,0101,0000,0000,0000,0000,0000, /*, W, */ +0000,0101,0101,0042,0024,0010,0024,0042,0101,0101,0101,0000,0000,0000,0000,0000, /*, X, */ +0000,0101,0042,0024,0010,0010,0010,0010,0010,0010,0010,0000,0000,0000,0000,0000, /*, Y, */ +0000,0177,0001,0002,0004,0010,0020,0040,0100,0100,0177,0000,0000,0000,0000,0000, /*, Z, */ +0000,0034,0020,0020,0020,0020,0020,0020,0020,0020,0020,0034,0000,0000,0000,0000, /*, [, */ +0000,0000,0100,0040,0020,0010,0010,0010,0004,0002,0001,0000,0000,0000,0000,0000, /*, , \, */ +0000,0070,0010,0010,0010,0010,0010,0010,0010,0010,0010,0070,0000,0000,0000,0000, /*, ], */ +0010,0024,0042,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, /*, ^, */ +0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0377,0000,0000, /*, _, */ +0040,0020,0010,0004,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, /*, `, */ +0000,0000,0000,0000,0000,0074,0002,0076,0102,0102,0076,0000,0000,0000,0000,0000, /*, a, */ +0000,0100,0100,0100,0100,0174,0102,0102,0102,0102,0174,0000,0000,0000,0000,0000, /*, b, */ +0000,0000,0000,0000,0000,0074,0102,0100,0100,0102,0074,0000,0000,0000,0000,0000, /*, c, */ +0002,0002,0002,0002,0002,0076,0102,0102,0102,0102,0076,0000,0000,0000,0000,0000, /*, d, */ +0000,0000,0000,0000,0000,0074,0102,0174,0100,0102,0074,0000,0000,0000,0000,0000, /*, e, */ +0000,0016,0020,0020,0020,0176,0020,0020,0020,0020,0020,0000,0000,0000,0000,0000, /*, f, */ +0000,0000,0000,0000,0000,0076,0102,0102,0102,0102,0076,0002,0002,0102,0076,0000, /*, g, */ +0000,0100,0100,0100,0100,0174,0102,0102,0102,0102,0102,0000,0000,0000,0000,0000, /*, h, */ +0000,0000,0000,0010,0000,0030,0010,0010,0010,0010,0034,0000,0000,0000,0000,0000, /*, i, */ +0000,0000,0000,0010,0000,0030,0010,0010,0010,0010,0010,0010,0010,0050,0020,0000, /*, j, */ +0000,0100,0100,0100,0100,0106,0110,0120,0160,0110,0106,0000,0000,0000,0000,0000, /*, k, */ +0000,0030,0010,0010,0010,0010,0010,0010,0010,0010,0034,0000,0000,0000,0000,0000, /*, l, */ +0000,0000,0000,0000,0000,0166,0111,0111,0111,0111,0111,0000,0000,0000,0000,0000, /*, m, */ +0000,0000,0000,0000,0100,0174,0102,0102,0102,0102,0102,0000,0000,0000,0000,0000, /*, n, */ +0000,0000,0000,0000,0000,0074,0102,0102,0102,0102,0074,0000,0000,0000,0000,0000, /*, o, */ +0000,0000,0000,0000,0000,0174,0102,0102,0102,0102,0174,0100,0100,0100,0100,0000, /*, p, */ +0000,0000,0000,0000,0000,0076,0102,0102,0102,0102,0076,0002,0002,0002,0002,0000, /*, q, */ +0000,0000,0000,0000,0000,0134,0142,0100,0100,0100,0100,0000,0000,0000,0000,0000, /*, r, */ +0000,0000,0000,0000,0000,0076,0100,0074,0002,0102,0074,0000,0000,0000,0000,0000, /*, s, */ +0000,0020,0020,0020,0020,0176,0020,0020,0020,0020,0014,0000,0000,0000,0000,0000, /*, t, */ +0000,0000,0000,0000,0000,0102,0102,0102,0102,0102,0075,0000,0000,0000,0000,0000, /*, u, */ +0000,0000,0000,0000,0000,0101,0101,0101,0042,0024,0010,0000,0000,0000,0000,0000, /*, v, */ +0000,0000,0000,0000,0000,0111,0111,0111,0111,0111,0066,0000,0000,0000,0000,0000, /*, w, */ +0000,0000,0000,0000,0000,0102,0044,0030,0030,0044,0102,0000,0000,0000,0000,0000, /*, x, */ +0000,0000,0000,0000,0000,0102,0102,0102,0042,0024,0010,0020,0040,0100,0000,0000, /*, y, */ +0000,0000,0000,0000,0000,0176,0004,0010,0020,0040,0176,0000,0000,0000,0000,0000, /*, z, */ +0000,0014,0020,0020,0020,0020,0040,0020,0020,0020,0020,0014,0000,0000,0000,0000, /*, {, */ +0000,0010,0010,0010,0010,0000,0000,0010,0010,0010,0010,0000,0000,0000,0000,0000, /*, |, */ +0000,0030,0010,0010,0010,0010,0004,0010,0010,0010,0010,0030,0000,0000,0000,0000, /*, }, */ +0020,0052,0004,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, /*, ~, */ +0000,0176,0176,0176,0176,0176,0176,0176,0176,0176,0176,0000,0000,0000,0000,0000, /*, del, */ +}; diff --git a/usr/src/cmd/lpr/daemon.c b/usr/src/cmd/lpr/daemon.c new file mode 100644 index 0000000000..ce1d1928c0 --- /dev/null +++ b/usr/src/cmd/lpr/daemon.c @@ -0,0 +1,333 @@ +/* + * daemon.c -- main control routines for spider and phone dpd daemons, + * and for line printer daemon. + */ + +long snsum = 0; /*number of characters written*/ + +#include "daemon0.c" + +#include +#include + +struct direct dbuf; +int LDIRNAM = 0; /*length of directory name. MRW*/ +int LCHAR = 0; /*length of file name thru 'df'.*/ +int LPID = 0; /*length of file name to process-id.*/ +int retcode = 1; +int nwait = 0; +char *fowner; /*RBB*/ +char baddf[30]; /*name for unsendable df-files.*/ +FILE *popen(); + +#if LPD +int waittm = 10; +#else +int waittm = 60; +#endif + +main() +{ + register char *p1, *p2; + FILE *df; + + dem_setup(); + LDIRNAM = 0; /*calculate length of directory name. MRW*/ + while(dfname[LDIRNAM]) LDIRNAM++; + LCHAR = LDIRNAM + 2; + LPID = LDIRNAM + 3; + +again: + snsum = 0; + if(access(lock, 0) < 0){ + logerr("Lock has disappeared."); + dem_dis(); + exit(1); + } + df = fopen(dpd, "r"); + if (df) { + do { + if(fread((char *)&dbuf, sizeof dbuf, 1, df) < 1){ + dem_dis(); /*disconnect phone line. MRW*/ + unlink(lock); + exit(0); + } + } while (dbuf.d_ino==0 || dbuf.d_name[0]!='d' || dbuf.d_name[1]!='f'); + fclose(df); + } + p1 = dbuf.d_name; + p2 = &dfname[LDIRNAM]; + while (p1 < &dbuf.d_name[DIRSIZ]) + *p2++ = *p1++; + if (trysend() == 0) { + waittm = 60; + nwait = 0; + goto again; + } +#if PHONE + if(nwait > 10){ /*after 3 hours try fresh daemon. MRW*/ + unlink(lock); + execl("/usr/lib/dpd", "dpd", (char *)0); + execl("/etc/dpd", "dpd", (char *)0); + logerr("Can't find dpd."); + exit(1); + } +#endif + sleep(waittm); +#if PHONE || SPIDER +#ifndef DEBUG + if (waittm <= 8*60) + waittm *= 2; + else + nwait++; +#endif +#endif + goto again; +} + +/* + * The remaining part is the device interface, to spider, the dataphone, + * or the line printer. + */ + +#define MXLINE 128 +#define MXMESS 500 + +char *snumb; +char line[MXLINE]; +char message[MXMESS+1]; +char *mesp; +char mailfname[64]; +int linel; +FILE *dfb = NULL; +jmp_buf env; +char ff = '\014'; /*formfeed*/ +char *copline(); + +trysend() +{ + if(retcode != 0) + if(retcode = dem_con()) /*connect phone line.*/ + return(retcode); + retcode = 1; + if(setjmp(env)) + return(retcode); + xtrysend(); + return(0); +} + +xtrysend() +{ + int i; + + dem_open(dfname); /*open spider connection.*/ + if((dfb = fopen(dfname, "r")) == NULL){ + if(LDIRNAM < (i = sizeof(baddf)-1)){ + strncpy(baddf, dfname, i); + baddf[i] = '\0'; + baddf[LDIRNAM] = 'b'; + link(dfname, baddf); + } + unlink(dfname); + retcode = 0; + trouble("Can't read %s.", dfname); + } + getowner(dfname); /*RBB*/ + mesp = message; + *mesp = 0; + while (getline()) switch (line[0]) { + + case 'S': + get_snumb(); /*get snumb for GCOS.*/ + continue; + + case 'B': + if(sascii(0)) + trouble("Can't send %s.", &line[1]); + continue; + + case 'F': + if(sascii(1)) + trouble("Can't send %s.", &line[1]); + continue; + + case 'I': /*mail back $IDENT card. MRW*/ + mesp = copline(&line[1], linel-1, mesp); + + case 'L': + lwrite(); /*write a literal line.*/ + continue; + + case 'M': + continue; + + case 'N': /*mail back file name. MRW*/ + copline(&line[1], linel-1, mailfname); + continue; + + case 'Q': /*additional text to mail back*/ + if(mesp+linel <= message+MXMESS) + mesp = copline(&line[1], linel-1, mesp); + + case 'U': + continue; + } +/* + * Second pass. + * Unlink files and send mail. + */ + alarm(0); + fseek(dfb, (long)0, 0); + while (getline()) switch (line[0]) { + + default: + continue; + + case 'U': + unlink(&line[1]); + continue; + + case 'M': + sendmail(); + continue; + } + FCLOSE(dfb); + dem_close(); /*close connection to spider.*/ + unlink(dfname); + retcode = 0; + trouble("OK: %-5s %-7s %-8s", snumb, fowner, dfname+LDIRNAM); /*RBB*/ +} + +#define LUBM 30 /*length of mail command line.*/ +#define IARG1 5 /*start of arg to mail command.*/ +char mail[LUBM+1] = "mail "; +FILE *pmail; + +sendmail() +{ + register i; + + alarm(0); + i = 0; + while((mail[IARG1+i] = line[i+1]) && (++i < LUBM-IARG1)); + mail[IARG1+i] = 0; + if((pmail = popen(mail, "w")) == NULL){ + logerr("Can't mail: %-5s %-8s",snumb,dfname+LDIRNAM); /*MRW*/ + return; + } + maildname(); + pclose(pmail); +} + +#if LPD == 0 + +maildname() /*break up dfname into command name, and process-id + to send back in the mail. MRW*/ +{ + char c; + char *command; + + fprintf(pmail,"Sent %-5s: file %s%s",snumb,mailfname,message); +/* + c = dfname[LCHAR]; + switch (c){ + case 'A': + case 'a': + command = "dpr"; + break; + + case 'G': + case 'g': + command = "gcat"; + break; + + case 'J': + case 'j': + command = "ibm"; + break; + + case 'N': + case 'n': + command = "fsend"; + break; + + case 'T': + case 't': + command = "fget"; + break; + + default: + command = &dfname[LDIRNAM]; + break; + } + fprintf(pmail, "%s process-id was %s\n", command, &dfname[LPID]); +*/ +} + +#endif + + +getline() +{ + register char *lp; + register c; + + lp = line; + linel = 0; + while ((c = getc(dfb)) != '\n' && linel < MXLINE-2) { + if (c == EOF) + return(0); + if (c=='\t') { + do { + *lp++ = ' '; + linel++; + } while ((linel & 07) != 0); + continue; + } + *lp++ = c; + linel++; + } + *lp++ = 0; + return(1); +} + +char * +copline(ab, n, ml) +char *ab; +int n; +char ml[64]; +{ + register char *b, *p, *eb; + + b = ab; + eb = b+n; + p = ml; + while (bpw_name; +} + +#endif diff --git a/usr/src/cmd/lpr/daemon0.c b/usr/src/cmd/lpr/daemon0.c new file mode 100644 index 0000000000..615972c608 --- /dev/null +++ b/usr/src/cmd/lpr/daemon0.c @@ -0,0 +1,113 @@ +/* + * daemon0.c -- dem_setup() and logerr() routines for spider and + * and dataphone dpd and fget daemons. + */ + +#include +#include +#include +#include +#include + +#define WRMODE 2 + +#define FCLOSE(F) if(F != NULL){ fclose(F); F = NULL;} +#define DAEMUID 1 +#define DAEMNAM "daemon\0\0" + +struct stat statbuf; +struct passwd *getpwuid(); + +unlock() +{ + signal(SIGTERM, SIG_IGN); + dem_dis(); + logerr("Daemon killed."); + unlink(lock); + exit(1); +} + + +dem_setup() +{ + int i; + int of; + + setuid(DAEMUID); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGTERM, unlock); +#ifndef DEBUG + signal(SIGQUIT, SIG_IGN); +/* + * Close all files, open /dev/null as 0, 1, 2 + * to assure standard environment + */ + freopen("/dev/null", "r", stdin); + freopen("/dev/null", "w", stdout); + freopen("/dev/null", "w", stderr); + for (of=3; of<_NFILE; of++) + close(of); +#endif + if ((of=creat(lock, 0)) < 0) + exit(0); + if(fstat(of, &statbuf) < 0 || statbuf.st_mode != 0100000){ + logerr("Bad lock file %s.", lock); + exit(1); + } + close(of); +#ifndef DEBUG + if (i = fork()){ + if(i == -1){ + logerr("Unable to fork."); + unlink(lock); + exit(1); + } + exit(0); + } +#endif + chdir(dpd); +} + + +#if LPD == 0 + +int nlog = 0; + +/* VARARGS */ +logerr(s, a1, a2, a3, a4) +char *s; +int a1, a2, a3, a4; +{ + long static tb; + register i; + FILE *f; + struct passwd *pwp; + + if(access(error, WRMODE) != 0) + return; + if((f = fopen(error, "a")) == NULL) + return; + time(&tb); + fprintf(f, "%.19s:%s:", ctime(&tb), dname); + fprintf(f, s, a1, a2, a3, a4); +#if FGET == 0 + i = snsum/1000; + if(i <= 0){ + i = snsum; + fprintf(f, " %3d bytes", i); + } + else + fprintf(f, " %3dk bytes", i); +#endif + if(!nlog++ && ((pwp = getpwuid(getuid())) != NULL)){ + putc(' ', f); putc(' ', f); + i = 0; + while(pwp->pw_name[i]) + putc(pwp->pw_name[i++], f); + } + putc('\n', f); + fclose(f); +} + +#endif diff --git a/usr/src/cmd/lpr/lpd.c b/usr/src/cmd/lpr/lpd.c new file mode 100644 index 0000000000..764c66ade9 --- /dev/null +++ b/usr/src/cmd/lpr/lpd.c @@ -0,0 +1,219 @@ +# +/* + * lpd -- line printer daemon dispatcher + * + */ + +#include + +#define SPIDER 0 +#define PHONE 0 +#define LPD 1 + +char dpd[] = "/usr/spool/lpd"; +char dfname[30] = "/usr/spool/lpd/"; +char lock[] = "/usr/spool/lpd/lock"; + +#include "daemon.c" + +/* + * The remaining part is the line printer interface. + */ + +char lp[] = "/dev/lp"; +char chrtab[][16]; +FILE *lpf = NULL; + +dem_con() +{ + if((lpf = fopen(lp, "w")) == NULL) + return(-1); + return(0); +} + +dem_dis() +{ + + FCLOSE(lpf); + FCLOSE(dfb); +} + +dem_open(file) +char *file; +{ +} + +dem_close() +{ +} + +get_snumb() +{ +} + +lwrite() +{ + banner(&line[1]); +} + + +FILE *ibuf; + +sascii(fff) +{ + if((ibuf = fopen(&line[1], "r")) == NULL) + return(0); + if(fff) + putc(ff, lpf); + bsopt(); + fflush(lpf); + fclose(ibuf); + return(0); +} + +/* + * Copy file ibuf to lpf arranging that no + * backspaces will appear in the output. Courtesy ARK + */ + +#define BSIZE 256 + +char b1[BSIZE], b2[BSIZE]; +int size1, size2; + +bsopt() +{ + register int cp, c; + + size1 = size2 = cp = 0; + while ((c = getc(ibuf)) != EOF) { + if (isprint (c)) { + if (cp < BSIZE) { + if (cp >= size1 || b1[cp] == ' ') { + while (cp >= size1) + b1[size1++] = ' '; + } else { + if (cp < size2 && b2[cp] != ' ') + pr2(); + while (cp >= size2) + b2[size2++] = ' '; + b2[cp] = b1[cp]; + } + b1[cp++] = c; + } + } else { + switch (c) { + + case ' ': + cp++; + break; + + case '\b': + if (cp) + cp--; + break; + + case '\t': + cp = (cp + 8) & -8; + break; + + case '\r': + cp = 0; + break; + + case '\n': + case '\f': + pr2(); + pr1(); + putc(c, lpf); + size1 = cp = 0; + break; + + } + } + } + pr2(); + pr1(); +} +pr1() +{ + register char *p, *lim; + + p = b1; + lim = p + size1; + while (p < lim) + putc(*p++, lpf); + size1 = 0; +} + +pr2() +{ + register char *p, *lim; + + p = b2; + lim = p + size2; + if (p < lim) { + do + putc(*p++, lpf); + while (p < lim); + putc('\r', lpf); + } + size2 = 0; +} + +/* VARARGS */ +trouble(s, a1, a2, a3, a4) +char *s; +{ + if(retcode != 0){ + dem_dis(); + } + longjmp(env, 1); +} + +/* VARARGS */ +logerr() +{ +} + +getowner() +{ +} + +maildname() +{ + fprintf(pmail, "Your lpr printer job is done.\n"); +} + +banner(s) +char *s; +{ + long timeb; + register char *sp; + int i, j, t, lsw; + + for(lsw=0; s[lsw] && lsw<5; lsw++); + putc(ff, lpf); + fprintf(lpf, "\n\n\n\n\n\n\n\n"); + for (i=0; i<16; i++) { + if(lsw < 5) + fprintf(lpf, " "); + for (sp=s; *sp; sp++) { + if (*sp<=' '|| *sp >'}') + continue; + fprintf(lpf, " "); + t = chrtab[*sp - ' '][i]; + for (j=7; j>=0; j--) + if ((t>>j) & 01) + putc('X', lpf); + else + putc(' ', lpf); + } + putc('\n', lpf); + } + fprintf(lpf, "\n\n\n\n\n\n\n\n"); + time(&timeb); + fprintf(lpf, " "); + fprintf(lpf, ctime(&timeb)); + putc(ff, lpf); +} diff --git a/usr/src/cmd/lpr/lpr.c b/usr/src/cmd/lpr/lpr.c new file mode 100644 index 0000000000..28eb6c9590 --- /dev/null +++ b/usr/src/cmd/lpr/lpr.c @@ -0,0 +1,104 @@ +#include + +/* + * lpr -- on line print to line printer + */ +#ifdef VPR +/* if VPR defined, uses versatek printer via /usr/spool/vpd. */ +#endif + +#define DPR 0 +#define FGET 0 +#define FSEND 0 +#define GCAT 0 +#define LPR 1 + +#ifdef VPR +#define NAME "vpr" +#else +#define NAME "lpr" +#endif + +#define BF 'F' +#define MAXCOPY 204800L +#define FIRSTCHAR 'A'-1 + +#ifdef VPR +char cfname[] = "/usr/spool/vpd/cf@XXXXX"; +char dfname[] = "/usr/spool/vpd/df@XXXXX"; +char lfname[] = "/usr/spool/vpd/lf@XXXXX"; +char tfname[] = "/usr/spool/vpd/tf@XXXXX"; +char zfname[] = "/usr/spool/vpd/zf@XXXXX"; +#else +char cfname[] = "/usr/spool/lpd/cf@XXXXX"; +char dfname[] = "/usr/spool/lpd/df@XXXXX"; +char lfname[] = "/usr/spool/lpd/lf@XXXXX"; +char tfname[] = "/usr/spool/lpd/tf@XXXXX"; +char zfname[] = "/usr/spool/lpd/zf@XXXXX"; +#endif + +#include "spool.c" + +main(agc, agv) +int agc; +char *agv[]; +{ + argc = agc; argv = agv; + pidfn(); + + while (argc>1 && (arg = argv[1])[0]=='-') { + if(!comopt(arg[1])) + switch (arg[1]) { + + default: + fprintf(stderr, "%s: Unrecognized option: %s\n", NAME, arg); + break; + } + argc--; + argv++; + } + + if(debug) + tff = stdout; + else + if((tff = nfile(tfname)) == NULL){ + fprintf(stderr, "%s: Can't create %s.\n", NAME, tfname); + out(); + } + if(ident()) + out(); + + filargs(); /*process file arguments.*/ + + if(debug) + out(); + fclose(tff); + if(nact) { + dfname[INCHAR]++; + if(link(tfname, dfname) < 0){ + fprintf(stderr, "%s: Cannot rename %s\n", NAME, tfname); + out(); + } + unlink(tfname); +#ifdef VPR + execl("/usr/lib/vpd", "vpd", 0); + execl("/etc/vpd", "vpd", 0); +#else + execl("/usr/lib/lpd", "lpd", 0); + execl("/etc/lpd", "lpd", 0); +#endif + fprintf(stderr, "%s: Can't find daemon.\nFiles left in spooling dir.\n", NAME); + exit(1); + } + out(); +} + + +archive() +{ +} + + +nuact() +{ +} diff --git a/usr/src/cmd/lpr/makefile b/usr/src/cmd/lpr/makefile new file mode 100644 index 0000000000..de5c503d91 --- /dev/null +++ b/usr/src/cmd/lpr/makefile @@ -0,0 +1,15 @@ +lpr: lpr.c spool.c + cc -n -s -O lpr.c -o lpr + +lpd: lpd.c daemon.c daemon0.c + cc -n -s -O lpd.c -o lpd + +install: + cp lpr /bin/lpr + cp lpd /usr/lib/lpd + rm lpr + rm lpd + echo make sure /etc/rc contains + echo rm /usr/spool/lpd/lock; /usr/lib/lpd + mkdir /usr/spool + mkdir /usr/spool/lpd diff --git a/usr/src/cmd/lpr/spool.c b/usr/src/cmd/lpr/spool.c new file mode 100644 index 0000000000..2aa9017d9c --- /dev/null +++ b/usr/src/cmd/lpr/spool.c @@ -0,0 +1,436 @@ +#include +#include +#include + +#define ONL 0 +#define TOSS 1 +int INCHAR = 0; /*index of incremented character in + temporary file names. */ + +char version[] = "Version 2/6/79"; + +char grade; +char remote[]= "$ remote **,onl"; +char toss[] = "$ sysout toss"; +int remotsw; /*toss-output flag*/ +char *mailfile = 0; +char wantmail = 0; +char *pp = 0; /*recipient of mail*/ +char *identf = 0; /*ident card info*/ +int uidf = 0; +char gcosid[13]; /*gcos userid*/ +char cpflag = 'l'; /*copy/link flag*/ +int rmflag = 0; /*remove flag*/ +int debug = 0; +int gcdebug = 0; /*GCOS debug switch*/ +int archsw = 0; /*archive switch*/ + +int argc; +char **argv; +char *arg; +char buf[80]; /*used by card */ +int nact = 0; /*number of non-null files to process.*/ +int gsize = 20; /*size of current file in GCOS blocks.*/ +long usize = 20*1200; /*size of current file in bytes.*/ +FILE *tff; /*temporary control card file*/ +FILE *nfile(); +char *getarg(); +char *sprintf(); + + +comopt(o) /*routine to test for common options.*/ +char o; +{ + switch (o){ + + case 'c': + cpflag = 'c'; + break; + + case 'i': + identf = getarg('i'); + break; + + case 'm': + wantmail++; + if(arg[2]) + pp = &arg[2]; + break; + + case 'n': /*new option to suppress mail. MRW*/ + wantmail = 0; + break; + + case 'o': + remotsw = ONL; + break; + + case 'r': + rmflag++; + break; + + case 's': + if(arg[2] < '1' || arg[2] > '3') + goto unknown; + grade = arg[2]; + break; + + case 't': + if(arg[2]) + goto unknown; + remotsw = TOSS; + break; + + case '#': + debug = 1; + break; + + case 'Z': /*GCOS debugging switch*/ + gcdebug = 1; + break; + +unknown: + default: + return(0); + } + return(1); +} + + +#if LPR == 0 + +spool1() /*set up common initial GCOS control cards.*/ +{ + if(debug) + tff = stdout; + else + if((tff = nfile(tfname)) == NULL){ + fprintf(stderr, "%s: Can't create %s.\n", NAME, tfname); + out(); + } + card('S', ""); + card('L', sprintf(buf, "$ sgrade %c %s", grade, version ) ); + if(ident()) + out(); + card('L', remote); + if(remotsw == TOSS) + card('L', toss); +} + + +spool2() /*add final control cards, and spool job.*/ +{ + if(wantmail) + card('N', mailfile); + card('L', "$ endjob"); + if(debug) + out(); + fclose(tff); + if(nact) { + dfname[INCHAR]++; + if(link(tfname, dfname) < 0){ + fprintf(stderr, "%s: Cannot rename %s\n", NAME, tfname); + out(); + } + unlink(tfname); + execl("/usr/lib/dpd", "dpd", 0); + execl("/etc/dpd", "dpd", 0); + fprintf(stderr, "%s: Can't find dpd.\nFiles left in spooling dir.\n", NAME); + exit(1); + } +} + +#endif + + +#if FGET == 0 + +filargs() /*process file arguments for dpr, gcat, fsend, lpr.*/ +{ + int i; + FILE *f; + + if(argc == 1){ + if(mailfile == 0) + mailfile = "pipe.end"; + if(copy(stdin, mailfile, GCAT) == -1) + out(); + if(archsw) + archive(); + } + while(--argc) { + arg = *++argv; + switch(cpflag){ + + case 'l': + if(lfname[INCHAR]++ >= 'z') + cpflag = rmflag ? 'c' : 'n'; + else if(link(arg, lfname) == 0){ + if(size(arg,arg) <= 0) + continue; + nuact(arg); + card(BF, lfname); + card('U', lfname); + break; + } + + case 'n': + if(*arg == '/' && !rmflag){ + if(size(arg,arg) <= 0) + continue; + nuact(arg); + card(BF, arg); + break; + } + + case 'c': + f = fopen(arg, "r"); + if(f == NULL){ + fprintf(stderr, "%s: Cannot open %s\n", NAME, arg); + continue; + } + i = copy(f, arg, GCAT); + fclose(f); + if(i == -1) + continue; + break; + } + if(archsw) + archive(); + if(rmflag){ + if(unlink(arg) < 0) + fprintf(stderr, "%s: Cannot remove %s\n", NAME, arg); + } + if(mailfile == 0) + mailfile = arg; + } +} + +#endif + + +FILE *nfile(name) /*generate a new file name, and open file.*/ +char *name; +{ + FILE *f; + + if(name[INCHAR] >= 'z') + return(NULL); + name[INCHAR]++; + if(!access(name, 0) || (f = fopen(name, "w")) == NULL) + return(NULL); + return(f); +} + +#if FGET == 0 + +copy(f, gname, gcatsw) +FILE *f; +char *gname; +int gcatsw; +{ + int c; + FILE *ff; + long cnt; + + if((ff = nfile(cfname)) == NULL){ + fprintf(stderr, "%s: Too many copy files; %s not copied\n", NAME, gname); + return(-1); + } + cnt = 0; + while((c = getc(f)) != EOF){ + if(gcatsw) + if(c != 0){ + fprintf(stderr, "%s: Bad input from %s.\n", NAME, gname); + out(); + }else gcatsw = 0; + if((putc(c, ff) == EOF) && ferror(ff)){ + fprintf(stderr, "%s: Write error on copy of %s.\n", NAME, gname); + break; + } + cnt++; + if(cnt > MAXCOPY){ + fprintf(stderr, "%s: Copy file %s is too large\n", NAME, gname); + break; + } + } + fclose(ff); + if(size(cfname,gname) <= 0) + return(-1); + nuact(gname); + card(BF, cfname); + card('U', cfname); + return(0); +} + +#endif + +card(c, s) +int c; +char *s; +{ + putc( c, tff ); + + while( (c = *s++) != '\0') putc( c, tff ); + + c = putc( '\n', tff ); + + if(c == EOF){ + fprintf(stderr, "%s: Error writing control file.\n", NAME); + out(); + } +} + +size(file, name) +char *file, *name; +{ + struct stat stbuf; + + if(stat(file,&stbuf) < 0){ + fprintf(stderr, "%s: Cannot open %s\n", NAME, file); + return(-1); + } + if(!stbuf.st_size){ + fprintf(stderr, "%s: File %s is empty.\n", NAME, name); + return(0); + } + usize = stbuf.st_size; + gsize = usize / 1200; + gsize++; + nact++; + return(gsize); +} + + +char * +getarg(c) /*get modifier for complex options -- + from either same or next argument. MRW + e.g. either "-ffile" or "-f file"*/ +char c; +{ + + if(arg[2]) + return(&arg[2]); + else if(--argc>1) + return(arg = (++argv)[1]); + fprintf(stderr, "%s: Incomplete -%c option\n", NAME,c); + out(); +} + +#include +struct passwd *getpwuid(); + +ident() +{ + int c, i, j, n, test, jsave; + struct passwd *b1; + static char b2[100]; + + if((b1 = getpwuid(getuid())) == NULL) { + fprintf(stderr, "%s: Invalid user id\n", NAME); + return(1); + } + j = 0; +#if LPR == 0 + while(c = "$ ident "[j]) + b2[j++] = c; + + i = 0; + if(identf) + while(c = identf[i++]) + b2[j++] = c; + else{ + jsave = j; /*use either usg or pwb-style passwd. MRW*/ + while((c = b1->pw_gecos[i++]) && c != ':') + if(c == ')') + j = jsave; + else + b2[j++] = c; + } + b2[j++] = ','; +#endif + + i = 0; + if(!pp) + pp = &b2[j]; + while(c = b1->pw_name[i++]) + b2[j++] = c; + b2[j] = '\0'; + +#if LPR == 0 + i = 0; + n = 3; + while(--n) { + test = 0; + while((c=b2[i++]) && c != ',') { + if('0' <= c && c <= '9') test += c -'0'; + else test = 0; + } + if(test == 0) { + b2[j] = '\0'; + fprintf(stderr, "%s: Invalid IDENT information - %s\n", NAME, b2); + return (1); + } + } + + if(!uidf) { + n = 0; + while((c = b2[i++]) && c != ',') { + if(n >= 12) break; + gcosid[n++] = c; + } + gcosid[n++] = '\0'; + } +#endif + card('L', b2); + if(wantmail){ + card('M',pp); + if(identf) + card('Q', b2); /*mail back $IDENT card.*/ + } + return (0); +} + +pidfn() /*rewrite using mktemp. MRW*/ +{ + int out(); + + while(tfname[INCHAR] != 'X') + INCHAR++; + INCHAR--; + mktemp(cfname); + mktemp(dfname); + mktemp(lfname); + mktemp(tfname); + mktemp(zfname); + if(signal(SIGHUP, SIG_IGN) != SIG_IGN) + signal(SIGHUP, out); + if(signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, out); + if(signal(SIGQUIT, SIG_IGN) != SIG_IGN) + signal(SIGQUIT, out); + if(signal(SIGTERM, SIG_IGN) != SIG_IGN) + signal(SIGTERM, out); +} + +out() +{ + register i; + + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGTERM, SIG_IGN); + i = INCHAR; + for(; cfname[i] != FIRSTCHAR; cfname[i]--) + unlink(cfname); + if(dfname[i] != FIRSTCHAR) + unlink(dfname); + for(; lfname[i] != FIRSTCHAR; lfname[i]--) + unlink(lfname); + if(tfname[i] != FIRSTCHAR) + unlink(tfname); + for(; zfname[i] != FIRSTCHAR; zfname[i]--) + unlink(zfname); + exit(1); +} -- 2.20.1