📄 lpr.c
字号:
/* * Copyright (c) 1983, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1983, 1989, 1993\n\ The Regents of the University of California. All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)lpr.c 8.3 (Berkeley) 3/30/94";#endif /* not lint *//* * lpr -- off line print * * Allows multiple printers and printers on remote machines by * using information from a printer data base. */#include <sys/param.h>#include <sys/stat.h>#include <dirent.h>#include <fcntl.h>#include <a.out.h>#include <signal.h>#include <syslog.h>#include <pwd.h>#include <grp.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <string.h>#include "lp.h"#include "lp.local.h"#include "pathnames.h"static char *cfname; /* daemon control files, linked from tf's */static char *class = host; /* class title on header page */static char *dfname; /* data files */static char *fonts[4]; /* troff font names */static char format = 'f'; /* format char for printing files */static int hdr = 1; /* print header or not (default is yes) */static int iflag; /* indentation wanted */static int inchar; /* location to increment char in file names */static int indent; /* amount to indent */static char *jobname; /* job name on header page */static int mailflg; /* send mail */static int nact; /* number of jobs to act on */static int ncopies = 1; /* # of copies to make */static char *person; /* user name */static int qflag; /* q job, but don't exec daemon */static int rflag; /* remove files upon completion */ static int sflag; /* symbolic link flag */static int tfd; /* control file descriptor */static char *tfname; /* tmp copy of cf before linking */static char *title; /* pr'ing title */static int userid; /* user id */static char *width; /* width for versatec printing */static struct stat statb;static void card __P((int, char *));static void chkprinter __P((char *));static void cleanup __P((int));static void copy __P((int, char []));static void fatal2 __P((const char *, ...));static char *itoa __P((int));static char *linked __P((char *));static char *lmktemp __P((char *, int, int));static void mktemps __P((void));static int nfile __P((char *));static int test __P((char *));voidmain(argc, argv) int argc; char *argv[];{ struct passwd *pw; struct group *gptr; extern char *itoa(); register char *arg, *cp; char buf[BUFSIZ]; int i, f; struct stat stb; if (signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, cleanup); if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, cleanup); if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, cleanup); if (signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, cleanup); name = argv[0]; gethostname(host, sizeof (host)); openlog("lpd", 0, LOG_LPR); while (argc > 1 && argv[1][0] == '-') { argc--; arg = *++argv; switch (arg[1]) { case 'P': /* specifiy printer name */ if (arg[2]) printer = &arg[2]; else if (argc > 1) { argc--; printer = *++argv; } break; case 'C': /* classification spec */ hdr++; if (arg[2]) class = &arg[2]; else if (argc > 1) { argc--; class = *++argv; } break; case 'U': /* user name */ hdr++; if (arg[2]) person = &arg[2]; else if (argc > 1) { argc--; person = *++argv; } break; case 'J': /* job name */ hdr++; if (arg[2]) jobname = &arg[2]; else if (argc > 1) { argc--; jobname = *++argv; } break; case 'T': /* pr's title line */ if (arg[2]) title = &arg[2]; else if (argc > 1) { argc--; title = *++argv; } break; case 'l': /* literal output */ case 'p': /* print using ``pr'' */ case 't': /* print troff output (cat files) */ case 'n': /* print ditroff output */ case 'd': /* print tex output (dvi files) */ case 'g': /* print graph(1G) output */ case 'c': /* print cifplot output */ case 'v': /* print vplot output */ format = arg[1]; break; case 'f': /* print fortran output */ format = 'r'; break; case '4': /* troff fonts */ case '3': case '2': case '1': if (argc > 1) { argc--; fonts[arg[1] - '1'] = *++argv; } break; case 'w': /* versatec page width */ width = arg+2; break; case 'r': /* remove file when done */ rflag++; break; case 'm': /* send mail when done */ mailflg++; break; case 'h': /* toggle want of header page */ hdr = !hdr; break; case 's': /* try to link files */ sflag++; break; case 'q': /* just q job */ qflag++; break; case 'i': /* indent output */ iflag++; indent = arg[2] ? atoi(&arg[2]) : 8; break; case '#': /* n copies */ if (isdigit(arg[2])) { i = atoi(&arg[2]); if (i > 0) ncopies = i; } } } if (printer == NULL && (printer = getenv("PRINTER")) == NULL) printer = DEFLP; chkprinter(printer); if (SC && ncopies > 1) fatal2("multiple copies are not allowed"); if (MC > 0 && ncopies > MC) fatal2("only %d copies are allowed", MC); /* * Get the identity of the person doing the lpr using the same * algorithm as lprm. */ userid = getuid(); if (userid != DU || person == 0) { if ((pw = getpwuid(userid)) == NULL) fatal2("Who are you?"); person = pw->pw_name; } /* * Check for restricted group access. */ if (RG != NULL && userid != DU) { if ((gptr = getgrnam(RG)) == NULL) fatal2("Restricted group specified incorrectly"); if (gptr->gr_gid != getgid()) { while (*gptr->gr_mem != NULL) { if ((strcmp(person, *gptr->gr_mem)) == 0) break; gptr->gr_mem++; } if (*gptr->gr_mem == NULL) fatal2("Not a member of the restricted group"); } } /* * Check to make sure queuing is enabled if userid is not root. */ (void) sprintf(buf, "%s/%s", SD, LO); if (userid && stat(buf, &stb) == 0 && (stb.st_mode & 010)) fatal2("Printer queue is disabled"); /* * Initialize the control file. */ mktemps(); tfd = nfile(tfname); (void) fchown(tfd, DU, -1); /* owned by daemon for protection */ card('H', host); card('P', person); if (hdr) { if (jobname == NULL) { if (argc == 1) jobname = "stdin"; else jobname = (arg = rindex(argv[1], '/')) ? arg+1 : argv[1]; } card('J', jobname); card('C', class); card('L', person); } if (iflag) card('I', itoa(indent)); if (mailflg) card('M', person); if (format == 't' || format == 'n' || format == 'd') for (i = 0; i < 4; i++) if (fonts[i] != NULL) card('1'+i, fonts[i]); if (width != NULL) card('W', width); /* * Read the files and spool them. */ if (argc == 1) copy(0, " "); else while (--argc) { if ((f = test(arg = *++argv)) < 0) continue; /* file unreasonable */ if (sflag && (cp = linked(arg)) != NULL) { (void) sprintf(buf, "%d %d", statb.st_dev, statb.st_ino); card('S', buf); if (format == 'p') card('T', title ? title : arg); for (i = 0; i < ncopies; i++) card(format, &dfname[inchar-2]); card('U', &dfname[inchar-2]); if (f) card('U', cp); card('N', arg); dfname[inchar]++; nact++; continue; } if (sflag) printf("%s: %s: not linked, copying instead\n", name, arg); if ((i = open(arg, O_RDONLY)) < 0) { printf("%s: cannot open %s\n", name, arg); continue; } copy(i, arg); (void) close(i); if (f && unlink(arg) < 0) printf("%s: %s: not removed\n", name, arg); } if (nact) { (void) close(tfd); tfname[inchar]--; /* * Touch the control file to fix position in the queue. */ if ((tfd = open(tfname, O_RDWR)) >= 0) { char c; if (read(tfd, &c, 1) == 1 && lseek(tfd, (off_t)0, 0) == 0 && write(tfd, &c, 1) != 1) { printf("%s: cannot touch %s\n", name, tfname); tfname[inchar]++; cleanup(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -