|
|
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 - metrics - 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);
}