📄 lpr.c
字号:
/* assumes args will fit int buf/*****************************************************************/static int card(c, p2) register char c, *p2;{ register char *p1 = buf; register int len = 2; /* allow for char at start and NULL at end */ *p1++ = c; while ((c = *p2++) != '\0') { *p1++ = c; len++; } *p1++ = '\n'; (void) write(tfd, buf, len);}/************************************************************************//* Create the data file dfname in the spool directory with format letter fmt/* and copy file named n into it using file descriptor f /* add file specific entries to control file *//************************************************************************/static int copy(f, n, fmt) int f; char n[]; char fmt;{ register int fd, i, nr, nc; for (i = 0; i < ncopies; i++) card(fmt, &dfname[inchar-2]); card('N', n); card('U', &dfname[inchar-2]); fd = nfile(dfname); nr = nc = 0; while ((i = read(f, buf, BUFSIZ)) > 0) { /* copy to tmp file in spool dir */ if (write(fd, buf, i) != i) { warn("%s temp file write error - file truncated to %d bytes", n, nr * BUFSIZ + nc); break; } nc += i; if (nc >= BUFSIZ) { nc -= BUFSIZ; nr++; if (MX > 0 && nr > MX) {/* check buffer max */ warn("%s file too large - truncated to %d bytes", n, nr * BUFSIZ); break; } } } (void) close(fd); if (nc==0 && nr==0) warn("%s empty input file", f ? n : "stdin"); else nact++;}/*****************************************************************//* Try and link the file to dfname. Return a pointer to the full *//* path name if successful. *//*****************************************************************/static char * linked(file) register char *file;{ register char *cp; static char buf[BUFSIZ]; if (*file != '/') { /* relative path name */ if (getwd(buf) == NULL) return(NULL); while (file[0] == '.') { switch (file[1]) { case '/': /* ignore './' */ file += 2; continue; case '.': /* '../' so strip top level off dir */ if (file[2] == '/') { if ((cp = rindex(buf, '/')) != NULL) *cp = '\0'; file += 3; continue; } } break; } (void) strcat(buf, "/"); (void) strcat(buf, file); file = buf; } return(symlink(file, dfname) ? NULL : file);}/*****************************************************************//* Create a new file in the spool directory. *//*****************************************************************/static int nfile(n) char *n;{ register f; int oldumask = umask(0); /* should block signals */ f = creat(n, FILMOD); (void) umask(oldumask); if (f < 0) { fatal("cannot create %s", n); } if (fchown(f, userid, -1) < 0) { fatal("cannot chown %s", n); } nextname(n); return(f);}/*****************************************************************//* Create the next name in a family. *//*****************************************************************/static void nextname(n) char *n;{ if (++n[inchar] > 'z') { if (++n[inchar-2] == 't') { /* this is a tmp file */ fatal("too many files - break up the job"); } n[inchar] = 'A'; } else if (n[inchar] == '[') /* char after 'Z' */ n[inchar] = 'a';}/*****************************************************************//* Test to see if this is a printable file. *//* Return -1 if it is not, 0 if it is *//*****************************************************************/static int test(file) char *file;{ struct exec execb; register int fd; if (access(file, R_OK) < 0) { warn("cannot access file %s", file); return(-1); } if (stat(file, &statb) < 0) { warn("cannot stat file %s", file); return(-1); } if ((statb.st_mode & S_IFMT) == S_IFDIR) { warn("%s is a directory", file); return(-1); } if (statb.st_size == 0) { warn("%s is an empty file", file); return(-1); } if ((fd = open(file, O_RDONLY)) < 0) { warn("cannot open file %s", file); return(-1); } if (read(fd, (char *) &execb, sizeof(execb)) == sizeof(execb)) switch(execb.a_magic) { case A_MAGIC1: case A_MAGIC2: case A_MAGIC3:#ifdef A_MAGIC4 case A_MAGIC4:#endif warn("%s is an executable program and is unprintable", file); (void) close(fd); return(-1); case ARMAG: warn("%s is an archive file and is unprintable", file); (void) close(fd); return(-1); } (void) close(fd); return(0);}/*****************************************************************//* Perform lookup for printer name or abbreviation -- *//*****************************************************************/static void chkprinter(s) char *s;{ int status; static char pbuf[BUFSIZ/2]; char *bp = pbuf; extern char *pgetstr(); if ((status = pgetent(buf, s)) < 0) fatal("cannot open printer description file"); else if (status == 0) fatal("unknown printer %s", s); if ((SD = pgetstr("sd", &bp)) == NULL) SD = DEFSPOOL; if ((LO = pgetstr("lo", &bp)) == NULL) LO = DEFLOCK; if ((MX = pgetnum("mx")) < 0) MX = DEFMX; if ((MC = pgetnum("mc")) < 0) MC = DEFMAXCOPIES; if ((DU = pgetnum("du")) < 0) DU = DEFUID; SC = pgetflag("sc");}/*****************************************************************//* Assemble the spool file names using the contents of .seq *//*****************************************************************/static void mktemps(){ register int len, fd, n; register char *cp; char *mktemp(); (void) sprintf(buf, "%s/.seq", SD); if ((fd = open(buf, O_RDWR|O_CREAT, 0661)) < 0) { fatal("cannot create %s", buf); } if (flock(fd, LOCK_EX)) { fatal("cannot lock %s", buf); } n = 0; if ((len = read(fd, buf, sizeof(buf))) > 0) { /* read .seq and convert to int */ for (cp = buf; len--; ) { if (*cp < '0' || *cp > '9') break; n = n * 10 + (*cp++ - '0'); } } len = strlen(SD) + strlen(host) + 8; tfname = mktemp("tf", n, len); cfname = mktemp("cf", n, len); dfname = mktemp("df", n, len); inchar = strlen(SD) + 3; n = (n + 1) % 1000; /* inc n and write back to .seq */ (void) lseek(fd, 0L, 0); (void) sprintf(buf, "%03d\n", n); (void) write(fd, buf, strlen(buf)); (void) close(fd); /* unlocks as well */}/*****************************************************************//* Make a temp file name of lenght len/*****************************************************************/static char * mktemp(id, num, len) char *id; int num; int len; { register char *s; if ((s = malloc((unsigned)len)) == NULL) fatal("out of memory"); (void) sprintf(s, "%s/%sA%03d%s", SD, id, num, host); return(s);}/*****************************************************************//* itoa - integer to string conversion *//*****************************************************************/static char * itoa(i) register int i;{ static char b[10] = "########"; register char *p; p = &b[8]; do *p-- = i%10 + '0'; while (i /= 10); return(++p);}/*****************************************************************//* Print usage message on stderr and exit/*****************************************************************/static void usage(){ (void) fprintf(stderr,"Usage: %s %s%s%s%s%s%s%s", name, "[-Pprinter] [-#num] [-Cclass] [-Jjob] [-Ttitle]\n", " [-inum] [-1234font] [-wnum] [-znum] [-Ddata_type]\n", " [-Iinput_tray] [-ooutput_tray] [-Oorientation]\n", " [-Fpage_size] [-Z[lo_page_lim][,hi_page_lim]\n", " [-Xsheet_count] [-Ssheet_size] [-Mmessage]\n", " [-Nnumber_up] [-Llayup_definition] [-Ksides]\n", " [-cdfghlmnprstvx] [filename...]\n"); exit (2);}/*****************************************************************//* Cleanup after interrupts and errors. *//*****************************************************************/static void cleanup(){ register i; (void) signal(SIGHUP, SIG_IGN); /* ignore further interrupts */ (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); (void) signal(SIGTERM, SIG_IGN); i = inchar; if (tfname) /* remove files from spool dir */ do (void) unlink(tfname); while (tfname[i]-- != 'A'); if (cfname) do (void) unlink(cfname); while (cfname[i]-- != 'A'); if (dfname) do { do (void) unlink(dfname); while (dfname[i]-- != 'A'); dfname[i] = 'z'; } while (dfname[i-2]-- != 'd'); exit(1);}/*****************************************************************//* invalid argument - print error messege + valid args and exit *//*****************************************************************/#define linewidth 30static void invalid_arg(opt, opt_num)char *opt;int opt_num;{ struct arg_pair *arg_list; int width=0; get_args(opt_num,&arg_list); warn("invalid argument for %s - must be one of:", opt); (void) fprintf(stderr," "); while (arg_list->arg) { (void) fprintf(stderr, "%s ", arg_list->arg); width += strlen(arg_list->arg); if (width > linewidth){ /* throw newline */ (void) fprintf(stderr, "\n "); width = 0; } arg_list++; } (void) fputc('\n', stderr); exit(1);} /*****************************************************************//* non-fatal error - print warning message on stderr/*****************************************************************//*VARARGS1*/static void warn(msg, a1, a2, a3)char *msg;{ (void) fprintf(stderr, "%s: ", name); (void) fprintf(stderr, msg, a1, a2, a3); (void) fputc('\n', stderr);}/*****************************************************************//* fatal error - print message on stderr cleanup spool dir and exit/*****************************************************************//*VARARGS1*/static void fatal(msg, a1, a2, a3)char *msg;{ (void) fprintf(stderr, "%s: ", name); (void) fprintf(stderr, msg, a1, a2, a3); (void) fputc('\n',stderr); cleanup();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -