📄 cmds.c
字号:
/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * * 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, 1993\n\ The Regents of the University of California. All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)cmds.c 8.1 (Berkeley) 6/6/93";#endif /* not lint *//* * lpc -- line printer control program -- commands: */#include <sys/param.h>#include <sys/time.h>#include <sys/stat.h>#include <signal.h>#include <fcntl.h>#include <errno.h>#include <dirent.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <string.h>#include "lp.h"#include "lp.local.h"#include "lpc.h"#include "extern.h"#include "pathnames.h"static void abortpr __P((int));static void cleanpr __P((void));static void disablepr __P((void));static int doarg __P((char *));static int doselect __P((struct dirent *));static void enablepr __P((void));static void prstat __P((void));static void putmsg __P((int, char **));static int sortq __P((const void *, const void *));static void startpr __P((int));static void stoppr __P((void));static int touch __P((struct queue *));static void unlinkf __P((char *));static void upstat __P((char *));/* * kill an existing daemon and disable printing. */voiddoabort(argc, argv) int argc; char *argv[];{ register int c, status; register char *cp1, *cp2; char prbuf[100]; if (argc == 1) { printf("Usage: abort {all | printer ...}\n"); return; } if (argc == 2 && !strcmp(argv[1], "all")) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; cp2 = bp; while ((c = *cp2++) && c != '|' && c != ':') *cp1++ = c; *cp1 = '\0'; abortpr(1); } return; } while (--argc) { printer = *++argv; if ((status = cgetent(&bp, printcapdb, printer)) == -2) { printf("cannot open printer description file\n"); continue; } else if (status == -1) { printf("unknown printer %s\n", printer); continue; } else if (status == -3) fatal("potential reference loop detected in printcap file"); abortpr(1); }}static voidabortpr(dis) int dis;{ register FILE *fp; struct stat stbuf; int pid, fd; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; (void) sprintf(line, "%s/%s", SD, LO); printf("%s:\n", printer); /* * Turn on the owner execute bit of the lock file to disable printing. */ if (dis) { if (stat(line, &stbuf) >= 0) { if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) printf("\tcannot disable printing\n"); else { upstat("printing disabled\n"); printf("\tprinting disabled\n"); } } else if (errno == ENOENT) { if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) printf("\tcannot create lock file\n"); else { (void) close(fd); upstat("printing disabled\n"); printf("\tprinting disabled\n"); printf("\tno daemon to abort\n"); } return; } else { printf("\tcannot stat lock file\n"); return; } } /* * Kill the current daemon to stop printing now. */ if ((fp = fopen(line, "r")) == NULL) { printf("\tcannot open lock file\n"); return; } if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { (void) fclose(fp); /* unlocks as well */ printf("\tno daemon to abort\n"); return; } (void) fclose(fp); if (kill(pid = atoi(line), SIGTERM) < 0) printf("\tWarning: daemon (pid %d) not killed\n", pid); else printf("\tdaemon (pid %d) killed\n", pid);}/* * Write a message into the status file. */static voidupstat(msg) char *msg;{ register int fd; char statfile[BUFSIZ]; if (cgetstr(bp, "st", &ST) == -1) ST = DEFSTAT; (void) sprintf(statfile, "%s/%s", SD, ST); umask(0); fd = open(statfile, O_WRONLY|O_CREAT, 0664); if (fd < 0 || flock(fd, LOCK_EX) < 0) { printf("\tcannot create status file\n"); return; } (void) ftruncate(fd, 0); if (msg == (char *)NULL) (void) write(fd, "\n", 1); else (void) write(fd, msg, strlen(msg)); (void) close(fd);}/* * Remove all spool files and temporaries from the spooling area. */voidclean(argc, argv) int argc; char *argv[];{ register int c, status; register char *cp1, *cp2; char prbuf[100]; if (argc == 1) { printf("Usage: clean {all | printer ...}\n"); return; } if (argc == 2 && !strcmp(argv[1], "all")) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; cp2 = bp; while ((c = *cp2++) && c != '|' && c != ':') *cp1++ = c; *cp1 = '\0'; cleanpr(); } return; } while (--argc) { printer = *++argv; if ((status = cgetent(&bp, printcapdb, printer)) == -2) { printf("cannot open printer description file\n"); continue; } else if (status == -1) { printf("unknown printer %s\n", printer); continue; } else if (status == -3) fatal("potential reference loop detected in printcap file"); cleanpr(); }}static intdoselect(d) struct dirent *d;{ int c = d->d_name[0]; if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') return(1); return(0);}/* * Comparison routine for scandir. Sort by job number and machine, then * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. */static intsortq(a, b) const void *a, *b;{ struct dirent **d1, **d2; int c1, c2; d1 = (struct dirent **)a; d2 = (struct dirent **)b; if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) return(c1); c1 = (*d1)->d_name[0]; c2 = (*d2)->d_name[0]; if (c1 == c2) return((*d1)->d_name[2] - (*d2)->d_name[2]); if (c1 == 'c') return(-1); if (c1 == 'd' || c2 == 'c') return(1); return(-1);}/* * Remove incomplete jobs from spooling area. */static voidcleanpr(){ register int i, n; register char *cp, *cp1, *lp; struct dirent **queue; int nitems; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; printf("%s:\n", printer); for (lp = line, cp = SD; *lp++ = *cp++; ) ; lp[-1] = '/'; nitems = scandir(SD, &queue, doselect, sortq); if (nitems < 0) { printf("\tcannot examine spool directory\n"); return; } if (nitems == 0) return; i = 0; do { cp = queue[i]->d_name; if (*cp == 'c') { n = 0; while (i + 1 < nitems) { cp1 = queue[i + 1]->d_name; if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) break; i++; n++; } if (n == 0) { strcpy(lp, cp); unlinkf(line); } } else { /* * Must be a df with no cf (otherwise, it would have * been skipped above) or a tf file (which can always * be removed). */ strcpy(lp, cp); unlinkf(line); } } while (++i < nitems);} static voidunlinkf(name) char *name;{ if (unlink(name) < 0) printf("\tcannot remove %s\n", name); else printf("\tremoved %s\n", name);}/* * Enable queuing to the printer (allow lpr's). */voidenable(argc, argv) int argc; char *argv[];{ register int c, status; register char *cp1, *cp2; char prbuf[100]; if (argc == 1) { printf("Usage: enable {all | printer ...}\n"); return; } if (argc == 2 && !strcmp(argv[1], "all")) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; cp2 = bp; while ((c = *cp2++) && c != '|' && c != ':') *cp1++ = c; *cp1 = '\0'; enablepr(); } return; } while (--argc) { printer = *++argv; if ((status = cgetent(&bp, printcapdb, printer)) == -2) { printf("cannot open printer description file\n"); continue; } else if (status == -1) { printf("unknown printer %s\n", printer); continue; } else if (status == -3) fatal("potential reference loop detected in printcap file"); enablepr(); }}static voidenablepr(){ struct stat stbuf; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; (void) sprintf(line, "%s/%s", SD, LO); printf("%s:\n", printer); /* * Turn off the group execute bit of the lock file to enable queuing. */ if (stat(line, &stbuf) >= 0) { if (chmod(line, stbuf.st_mode & 0767) < 0) printf("\tcannot enable queuing\n"); else printf("\tqueuing enabled\n"); }}/* * Disable queuing. */voiddisable(argc, argv) int argc; char *argv[];{ register int c, status; register char *cp1, *cp2; char prbuf[100]; if (argc == 1) { printf("Usage: disable {all | printer ...}\n"); return; } if (argc == 2 && !strcmp(argv[1], "all")) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; cp2 = bp; while ((c = *cp2++) && c != '|' && c != ':') *cp1++ = c; *cp1 = '\0'; disablepr(); } return; } while (--argc) { printer = *++argv; if ((status = cgetent(&bp, printcapdb, printer)) == -2) { printf("cannot open printer description file\n"); continue; } else if (status == -1) { printf("unknown printer %s\n", printer); continue; } else if (status == -3) fatal("potential reference loop detected in printcap file"); disablepr(); }}static voiddisablepr(){ register int fd; struct stat stbuf; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; (void) sprintf(line, "%s/%s", SD, LO); printf("%s:\n", printer); /* * Turn on the group execute bit of the lock file to disable queuing. */ if (stat(line, &stbuf) >= 0) { if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) printf("\tcannot disable queuing\n"); else printf("\tqueuing disabled\n"); } else if (errno == ENOENT) { if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) printf("\tcannot create lock file\n"); else { (void) close(fd); printf("\tqueuing disabled\n"); } return; } else printf("\tcannot stat lock file\n");}/* * Disable queuing and printing and put a message into the status file * (reason for being down). */voiddown(argc, argv) int argc; char *argv[];{ register int c, status; register char *cp1, *cp2; char prbuf[100]; if (argc == 1) { printf("Usage: down {all | printer} [message ...]\n"); return; } if (!strcmp(argv[1], "all")) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; cp2 = bp; while ((c = *cp2++) && c != '|' && c != ':') *cp1++ = c; *cp1 = '\0'; putmsg(argc - 2, argv + 2); } return; } printer = argv[1]; if ((status = cgetent(&bp, printcapdb, printer)) == -2) { printf("cannot open printer description file\n"); return; } else if (status == -1) { printf("unknown printer %s\n", printer); return; } else if (status == -3) fatal("potential reference loop detected in printcap file"); putmsg(argc - 2, argv + 2);}static voidputmsg(argc, argv) int argc; char **argv;{ register int fd; register char *cp1, *cp2; char buf[1024]; struct stat stbuf; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; if (cgetstr(bp, "st", &ST) == -1) ST = DEFSTAT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -