Research V7 development origin/Research-V7-Snapshot-Development
authorKen Thompson <ken@research.uucp>
Sat, 25 Aug 1979 22:59:53 +0000 (17:59 -0500)
committerKen Thompson <ken@research.uucp>
Sat, 25 Aug 1979 22:59:53 +0000 (17:59 -0500)
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 <dmr@research.uucp>
Synthesized-from: v7

usr/man/man8/lpd.8 [new file with mode: 0644]
usr/src/cmd/lpr/chrtab.c [new file with mode: 0644]
usr/src/cmd/lpr/daemon.c [new file with mode: 0644]
usr/src/cmd/lpr/daemon0.c [new file with mode: 0644]
usr/src/cmd/lpr/lpd.c [new file with mode: 0644]
usr/src/cmd/lpr/lpr.c [new file with mode: 0644]
usr/src/cmd/lpr/makefile [new file with mode: 0644]
usr/src/cmd/lpr/spool.c [new file with mode: 0644]

diff --git a/usr/man/man8/lpd.8 b/usr/man/man8/lpd.8
new file mode 100644 (file)
index 0000000..aa6ba76
--- /dev/null
@@ -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 (file)
index 0000000..4d8a81a
--- /dev/null
@@ -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 (file)
index 0000000..ce1d192
--- /dev/null
@@ -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       <setjmp.h>
+#include       <sys/dir.h>
+
+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 (b<eb && p < &ml[63])
+               *p++ = *b++;
+       *p++ = '\n';
+       *p = 0;                 /*RBB*/
+       return(p);
+}
+
+#if LPD == 0
+
+/*
+ * the following code determines who the file's owner is.
+ *                     /*RBB*/
+
+struct passwd *getpwuid();
+
+getowner(file)
+char   *file;
+{
+       struct passwd *f;
+
+       if(stat(file, &statbuf) < 0)
+               return;
+       if((f = getpwuid(statbuf.st_uid)) == NULL)
+               fowner = "";
+       else
+               fowner = f->pw_name;
+}
+
+#endif
diff --git a/usr/src/cmd/lpr/daemon0.c b/usr/src/cmd/lpr/daemon0.c
new file mode 100644 (file)
index 0000000..615972c
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *  daemon0.c -- dem_setup() and logerr() routines for spider and
+ *                     and dataphone dpd and fget daemons.
+ */
+
+#include       <stdio.h>
+#include       <sys/types.h>
+#include       <sys/stat.h>
+#include       <pwd.h>
+#include       <signal.h>
+
+#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 (file)
index 0000000..764c66a
--- /dev/null
@@ -0,0 +1,219 @@
+#
+/*
+ * lpd -- line printer daemon dispatcher
+ *
+ */
+
+#include       <ctype.h>
+
+#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 (file)
index 0000000..28eb6c9
--- /dev/null
@@ -0,0 +1,104 @@
+#include       <stdio.h>
+
+/*
+ *  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 (file)
index 0000000..de5c503
--- /dev/null
@@ -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 (file)
index 0000000..2aa9017
--- /dev/null
@@ -0,0 +1,436 @@
+#include       <signal.h>
+#include       <sys/types.h>
+#include       <sys/stat.h>
+
+#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       <pwd.h>
+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);
+}