void rmjob(const char *printer) { register int i, nitems; int assassinated = 0; struct dirent **files; char *cp; struct printer myprinter, *pp = &myprinter; init_printer(pp); if ((i = getprintcap(printer, pp)) < 0) fatal(pp, "getprintcap: %s", pcaperr(i)); if ((cp = checkremote(pp))) { printf("Warning: %s\n", cp); free(cp); } /* * If the format was `lprm -' and the user isn't the super-user, * then fake things to look like he said `lprm user'. */ if (users < 0) { if (getuid() == 0) all = 1; /* all files in local queue */ else { user[0] = person; users = 1; } } if (!strcmp(person, "-all")) { if (from_host == local_host) fatal(pp, "The login name \"-all\" is reserved"); all = 1; /* all those from 'from_host' */ person = root; } seteuid(euid); if (chdir(pp->spool_dir) < 0) fatal(pp, "cannot chdir to spool directory"); if ((nitems = scandir(".", &files, iscf, NULL)) < 0) fatal(pp, "cannot access spool directory"); seteuid(uid); if (nitems) { /* * Check for an active printer daemon (in which case we * kill it if it is reading our file) then remove stuff * (after which we have to restart the daemon). */ if (lockchk(pp, pp->lock_file) && chk(current)) { seteuid(euid); assassinated = kill(cur_daemon, SIGINT) == 0; seteuid(uid); if (!assassinated) fatal(pp, "cannot kill printer daemon"); } /* * process the files */ for (i = 0; i < nitems; i++) process(pp, files[i]->d_name); } rmremote(pp); /* * Restart the printer daemon if it was killed */ if (assassinated && !startdaemon(pp)) fatal(pp, "cannot restart printer daemon\n"); exit(0); }
void rmjob(void) { int i, nitems; int assassinated = 0; struct dirent **files; char *cp; if ((i = cgetent(&bp, printcapdb, printer)) == -2) fatal("can't open printer description file"); else if (i == -1) fatal("unknown printer"); else if (i == -3) fatal("potential reference loop detected in printcap file"); if (cgetstr(bp, DEFLP, &LP) < 0) LP = _PATH_DEFDEVLP; if (cgetstr(bp, "rp", &RP) < 0) RP = DEFLP; if (cgetstr(bp, "sd", &SD) < 0) SD = _PATH_DEFSPOOL; if (cgetstr(bp,"lo", &LO) < 0) LO = DEFLOCK; cgetstr(bp, "rm", &RM); if ((cp = checkremote()) != NULL) printf("Warning: %s\n", cp); /* * If the format was `lprm -' and the user isn't the super-user, * then fake things to look like he said `lprm user'. */ if (users < 0) { if (getuid() == 0) all = 1; /* all files in local queue */ else { user[0] = person; users = 1; } } if (!strcmp(person, "-all")) { if (from == host) fatal("The login name \"-all\" is reserved"); all = 1; /* all those from 'from' */ person = root; } PRIV_START; if (chdir(SD) < 0) fatal("cannot chdir to spool directory"); if ((nitems = scandir(".", &files, iscf, NULL)) < 0) fatal("cannot access spool directory"); PRIV_END; if (nitems) { /* * Check for an active printer daemon. If one is running * and it is reading our file, kill it, then remove stuff. * Lastly, restart the daemon if it is not (or no longer) * running. */ if (lockchk(LO) && chk(current)) { PRIV_START; assassinated = kill(cur_daemon, SIGINT) == 0; PRIV_END; if (!assassinated) fatal("cannot kill printer daemon"); } /* * process the files */ for (i = 0; i < nitems; i++) process(files[i]->d_name); } rmremote(); /* * Restart the printer daemon if it was killed */ if (assassinated && !startdaemon(printer)) fatal("cannot restart printer daemon"); exit(0); }
/* * Display the current state of the queue. Format = 1 if long format. */ void displayq(struct printer *pp, int format) { register struct jobqueue *q; register int i, nitems, fd, ret; char *cp, *endp; struct jobqueue **queue; struct stat statb; FILE *fp; void (*savealrm)(int); lflag = format; totsize = 0; rank = -1; if ((cp = checkremote(pp))) { printf("Warning: %s\n", cp); free(cp); } /* * Print out local queue * Find all the control files in the spooling directory */ PRIV_START if (chdir(pp->spool_dir) < 0) fatal(pp, "cannot chdir to spooling directory: %s", strerror(errno)); PRIV_END if ((nitems = getq(pp, &queue)) < 0) fatal(pp, "cannot examine spooling area\n"); PRIV_START ret = stat(pp->lock_file, &statb); PRIV_END if (ret >= 0) { if (statb.st_mode & LFM_PRINT_DIS) { if (pp->remote) printf("%s: ", local_host); printf("Warning: %s is down: ", pp->printer); PRIV_START fd = open(pp->status_file, O_RDONLY|O_SHLOCK); PRIV_END if (fd >= 0) { while ((i = read(fd, line, sizeof(line))) > 0) (void) fwrite(line, 1, i, stdout); (void) close(fd); /* unlocks as well */ } else putchar('\n'); } if (statb.st_mode & LFM_QUEUE_DIS) { if (pp->remote) printf("%s: ", local_host); printf("Warning: %s queue is turned off\n", pp->printer); } } if (nitems) { PRIV_START fp = fopen(pp->lock_file, "r"); PRIV_END if (fp == NULL) daemonwarn(pp); else { /* get daemon pid */ cp = current; endp = cp + sizeof(current) - 1; while ((i = getc(fp)) != EOF && i != '\n') { if (cp < endp) *cp++ = i; } *cp = '\0'; i = atoi(current); if (i <= 0) { ret = -1; } else { PRIV_START ret = kill(i, 0); PRIV_END } if (ret < 0) { daemonwarn(pp); } else { /* read current file name */ cp = current; endp = cp + sizeof(current) - 1; while ((i = getc(fp)) != EOF && i != '\n') { if (cp < endp) *cp++ = i; } *cp = '\0'; /* * Print the status file. */ if (pp->remote) printf("%s: ", local_host); PRIV_START fd = open(pp->status_file, O_RDONLY|O_SHLOCK); PRIV_END if (fd >= 0) { while ((i = read(fd, line, sizeof(line))) > 0) fwrite(line, 1, i, stdout); close(fd); /* unlocks as well */ } else putchar('\n'); } (void) fclose(fp); } /* * Now, examine the control files and print out the jobs to * be done for each user. */ if (!lflag) header(); for (i = 0; i < nitems; i++) { q = queue[i]; inform(pp, q->job_cfname); free(q); } free(queue); } if (!pp->remote) { if (nitems == 0) puts("no entries"); return; } /* * Print foreign queue * Note that a file in transit may show up in either queue. */ if (nitems) putchar('\n'); (void) snprintf(line, sizeof(line), "%c%s", format ? '\4' : '\3', pp->remote_queue); cp = line; for (i = 0; i < requests && cp-line+10 < sizeof(line) - 1; i++) { cp += strlen(cp); (void) sprintf(cp, " %d", requ[i]); } for (i = 0; i < users && cp - line + 1 + strlen(user[i]) < sizeof(line) - 1; i++) { cp += strlen(cp); *cp++ = ' '; (void) strcpy(cp, user[i]); } strcat(line, "\n"); savealrm = signal(SIGALRM, alarmhandler); alarm(pp->conn_timeout); fd = getport(pp, pp->remote_host, 0); alarm(0); (void)signal(SIGALRM, savealrm); if (fd < 0) { if (from_host != local_host) printf("%s: ", local_host); printf("connection to %s is down\n", pp->remote_host); } else { i = strlen(line); if (write(fd, line, i) != i) fatal(pp, "Lost connection"); while ((i = read(fd, line, sizeof(line))) > 0) filtered_write(line, i, stdout); filtered_write(NULL, -1, stdout); (void) close(fd); } }
/* * Display the current state of the queue. Format = 1 if long format. */ void displayq(int format) { struct queue *q; int i, rank, nitems, fd, ret, len; char *cp, *ecp, *p; struct queue **queue; struct winsize win; struct stat statb; FILE *fp; termwidth = 80; if (isatty(STDOUT_FILENO)) { if ((p = getenv("COLUMNS")) != NULL) termwidth = atoi(p); else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 && win.ws_col > 0) termwidth = win.ws_col; } if (termwidth < 60) termwidth = 60; lflag = format; totsize = 0; if ((i = cgetent(&bp, printcapdb, printer)) == -2) fatal("can't open printer description file"); else if (i == -1) fatal("unknown printer"); else if (i == -3) fatal("potential reference loop detected in printcap file"); if (cgetstr(bp, DEFLP, &LP) < 0) LP = _PATH_DEFDEVLP; if (cgetstr(bp, "rp", &RP) < 0) RP = DEFLP; if (cgetstr(bp, "sd", &SD) < 0) SD = _PATH_DEFSPOOL; if (cgetstr(bp,"lo", &LO) < 0) LO = DEFLOCK; if (cgetstr(bp, "st", &ST) < 0) ST = DEFSTAT; cgetstr(bp, "rm", &RM); if ((cp = checkremote()) != NULL) printf("Warning: %s\n", cp); /* * Print out local queue * Find all the control files in the spooling directory */ PRIV_START; if (chdir(SD) < 0) fatal("cannot chdir to spooling directory"); PRIV_END; if ((nitems = getq(&queue)) < 0) fatal("cannot examine spooling area"); PRIV_START; ret = stat(LO, &statb); PRIV_END; if (ret >= 0) { if (statb.st_mode & S_IXUSR) { if (remote) printf("%s: ", host); printf("Warning: %s is down: ", printer); PRIV_START; fd = safe_open(ST, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd >= 0 && flock(fd, LOCK_SH) == 0) { while ((i = read(fd, line, sizeof(line))) > 0) (void)fwrite(line, 1, i, stdout); (void)close(fd); /* unlocks as well */ } else putchar('\n'); } if (statb.st_mode & S_IXGRP) { if (remote) printf("%s: ", host); printf("Warning: %s queue is turned off\n", printer); } } if (nitems) { PRIV_START; fd = safe_open(LO, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd < 0 || (fp = fdopen(fd, "r")) == NULL) { if (fd >= 0) close(fd); nodaemon(); } else { /* get daemon pid */ cp = current; ecp = cp + sizeof(current) - 1; while ((i = getc(fp)) != EOF && i != '\n') { if (cp < ecp) *cp++ = i; } *cp = '\0'; i = atoi(current); if (i <= 0) { ret = -1; } else { PRIV_START; ret = kill(i, 0); PRIV_END; } if (ret < 0 && errno != EPERM) { nodaemon(); } else { /* read current file name */ cp = current; ecp = cp + sizeof(current) - 1; while ((i = getc(fp)) != EOF && i != '\n') { if (cp < ecp) *cp++ = i; } *cp = '\0'; /* * Print the status file. */ if (remote) printf("%s: ", host); PRIV_START; fd = safe_open(ST, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd >= 0 && flock(fd, LOCK_SH) == 0) { while ((i = read(fd, line, sizeof(line))) > 0) (void)fwrite(line, 1, i, stdout); (void)close(fd); /* unlocks as well */ } else putchar('\n'); } (void)fclose(fp); } /* * Now, examine the control files and print out the jobs to * be done for each user. */ if (!lflag) header(); /* The currently printed job is treated specially. */ if (!remote && current[0] != '\0') inform(current, 0); for (i = 0, rank = 1; i < nitems; i++) { q = queue[i]; if (remote || strcmp(current, q->q_name) != 0) inform(q->q_name, rank++); free(q); } } free(queue); if (!remote) { if (nitems == 0) puts("no entries"); return; } /* * Print foreign queue * Note that a file in transit may show up in either queue. */ if (nitems) putchar('\n'); (void)snprintf(line, sizeof(line), "%c%s", format + '\3', RP); cp = line; cp += strlen(cp); for (i = 0; i < requests && cp - line < sizeof(line) - 1; i++) { len = line + sizeof(line) - cp; if (snprintf(cp, len, " %d", requ[i]) >= len) { cp += strlen(cp); break; } cp += strlen(cp); } for (i = 0; i < users && cp - line < sizeof(line) - 1; i++) { len = line + sizeof(line) - cp; if (snprintf(cp, len, " %s", user[i]) >= len) { cp += strlen(cp); break; } } if (cp-line < sizeof(line) - 1) strlcat(line, "\n", sizeof(line)); else line[sizeof(line) - 2] = '\n'; fd = getport(RM, 0); if (fd < 0) { if (from != host) printf("%s: ", host); (void)printf("connection to %s is down\n", RM); } else { struct sigaction osa, nsa; char *visline; int n = 0; i = strlen(line); if (write(fd, line, i) != i) fatal("Lost connection"); memset(&nsa, 0, sizeof(nsa)); nsa.sa_handler = alarmer; sigemptyset(&nsa.sa_mask); nsa.sa_flags = 0; (void)sigaction(SIGALRM, &nsa, &osa); alarm(wait_time); if ((visline = (char *)malloc(4 * sizeof(line) + 1)) == NULL) fatal("Out of memory"); while ((i = read(fd, line, sizeof(line))) > 0) { n = strvisx(visline, line, i, VIS_SAFE|VIS_NOSLASH); (void)fwrite(visline, 1, n, stdout); alarm(wait_time); } /* XXX some LPR implementations may not end stream with '\n' */ if (n > 0 && visline[n-1] != '\n') putchar('\n'); alarm(0); (void)sigaction(SIGALRM, &osa, NULL); free(visline); (void)close(fd); } }