|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 5032 (0x13a8) Types: TextFile Notes: UNIX file Names: »lpr.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─ ⟦this⟧ »cmd/lpr/lpr.c«
/* * Submit a listing to the local line * printer spooler. */ #include <stdio.h> #include <pwd.h> #include <signal.h> #ifndef TYPES_H #include <types.h> #endif /* Schizo is missing so -r doesn't check access privileges */ #define NBAN 6 /* Maximum number of banners */ #define NFNAME 400 /* Longest filename allowed */ char *banners[NBAN]; char tfspace[20]; char cfname[20]; char dfname[20]; char *tfname; /* Control file during lpr */ char *wd; char *myuname; FILE *cfp; /* Control file stream */ char spooldir[] = "/usr/spool/lpd"; char lpd[] = "/usr/lib/lpd"; char tmb[] = "Too many banners, `%s' ignored"; int cflag; /* Generate a copy */ int mflag; /* Send notification */ int rflag; /* Remove when done */ int banno = 4; /* Current banner number */ int myuid; long unique(); char *absname(); char *getwd(); char *ctime(); char *getlogin(); int rmexit(); main(argc, argv) char *argv[]; { register char *ap; register int i, j; signal(SIGINT, rmexit); signal(SIGHUP, rmexit); for (i=1; i<argc; i++) { if (*argv[i] != '-') break; for (ap = &argv[i][1]; *ap != '\0'; ap++) switch (*ap) { case 'b': if (++i >= argc) lperr("Missing banner"); if (banno >= NBAN) fprintf(stderr, tmb, argv[i]); else banners[banno++] = argv[i]; break; case 'c': cflag = 1; break; case 'm': mflag = 1; break; case 'n': mflag = 0; break; case 'r': cflag = rflag = 1; break; default: usage(); } } lprinit(argc, argv); for (j=i; j<argc; j++) if (banno < NBAN) banners[banno++] = argv[j]; else break; for (j=0; j<banno; j++) fprintf(cfp, "L%s\n", banners[j]); if (i == argc) lpr(NULL); else for (; i<argc; i++) lpr(argv[i]); lprterm(); for (i=3; i<_NFILE; i++) close(i); close(0); execl(lpd, lpd, NULL); lperr("Cannot find daemon `%s'", lpd); } /* * Initialise the control file. * Set up the banners. */ lprinit(ac, av) char **av; { time_t time(), xtime; register int i; register struct passwd *pwp; register char *s; myuid = getuid(); wd = getwd(); if (chdir(spooldir) < 0) lperr("bad directory `%s'", spooldir); tfname = tfspace; sprintf(tfname, "tf%D", unique()); strcpy(cfname, tfname); cfname[0] = 'c'; if ((cfp = fopen(tfname, "w")) == NULL) lperr("cannot create control file"); putc('D', cfp); for (i=0; i<ac; i++) fprintf(cfp, "%s%c", av[i], i==ac-1 ? '\n' : ' '); banners[0] = "\35\36\37"; banners[1] = "Coherent"; /* Mark Williams logo */ xtime = time(NULL); s = ctime(&xtime); s[16] = '\0'; banners[2] = s; if ((myuname = getlogin()) == NULL) if ((pwp = getpwuid(myuid))==NULL) myuname = "Guess who?"; if (myuname == NULL) banners[3] = "Guess who?"; else banners[3] = myuname; } /* * Called for each file to put * an entry for it in the control * file and do any copies to the * spool area. * The NULL `file' is stdin. */ lpr(file) char *file; { FILE *ifp; char *abfile; if (file == NULL) ifp = stdin; else { abfile = absname(file); if ((ifp = fopen(abfile, "r")) == NULL) lperr("cannot open %s", file); } if (cflag || file==NULL) { copy(ifp); fprintf(cfp, "A%s\nU%s\n", dfname, dfname); dfname[0] = '\0'; } else fprintf(cfp, "A%s\n", abfile); if (rflag && file!=NULL) { if (unperm(abfile)<0 || unlink(abfile)<0) lperr("Cannot unlink %s", file); } if (file != NULL) fclose(ifp); } /* * Given a file, see if we have permissions to unlink it. */ unperm(np) register char *np; { register char *cp; char name[NFNAME]; cp = name; while ((*cp++=*np++) != '\0') ; while (*--cp != '/') { if (cp == name) { *cp = '.'; break; } } cp[1] = '\0'; return (access(name, 2)); } /* * Clean up and close out * control file. */ lprterm() { if (mflag) if (myuname == NULL) fprintf(cfp, "M%d\n", myuid); else fprintf(cfp, "M%s\n", myuname); fflush(cfp); if (ferror(cfp)) lperr("Control file I/O error"); fclose(cfp); link(tfname, cfname); unlink(tfname); tfname = NULL; } /* * Copy the data to a data file * in the spool directory. */ copy(inf) register FILE *inf; { register int c; register FILE *outf; sprintf(dfname, "df%D", unique()); if ((outf = fopen(dfname, "w")) == NULL) lperr("cannot create data file"); while ((c = getc(inf)) != EOF) putc(c, outf); fflush(outf); if (ferror(outf)) lperr("data file I/O error"); fclose(outf); } /* * Return an absolute pathname * for the given filename. * (Uses the variable `wd' which * contains the process's working * directory.) */ char * absname(fn) char *fn; { static char name[NFNAME]; if (*fn == '/') return (fn); sprintf(name, "%s/%s", wd, fn); return (name); } usage() { lperr("Usage: lpr [-cmrn] [-b banner] [file ...]"); } /* VARARGS */ lperr(x) { fprintf(stderr, "lpr: %r", &x); putc('\n', stderr); rmexit(1); } /* * Exit, removing any files that * are left lying around. */ rmexit(s) { if (tfname != NULL) unlink(tfname); if (dfname[0] != '\0') unlink(dfname); exit(s); }