diff options
author | wollman <wollman@FreeBSD.org> | 1997-12-02 20:46:22 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1997-12-02 20:46:22 +0000 |
commit | bf21e6b4e0e85ae08cb5d1f2335da248f52e2d26 (patch) | |
tree | 041fd28f30eaadf848820e6ceed6899636d31478 /usr.sbin/lpr/common_source/rmjob.c | |
parent | fa82bf4e17d3b6422eb922374e04631e08af93ef (diff) | |
download | FreeBSD-src-bf21e6b4e0e85ae08cb5d1f2335da248f52e2d26.zip FreeBSD-src-bf21e6b4e0e85ae08cb5d1f2335da248f52e2d26.tar.gz |
Mega lpd/lpd upgrade, part I:
- Get rid of a lot of the static variables which were shared by
many routines and programs in the suite.
- Create an abstract interface to the printcap database, so that
other retrieval and iteration mechanisms could be developed
(e.g., YP, Hesiod, or automatic retrieval from a trusted server).
- Give each capability a human-readable name in addition to the historic
two-character one.
- Otherwise generally clean up a lot of dark corners. Many still remain.
- When submitting jobs, use the official login name record (from getlogin())
if there is one, rather than reverse-mapping the uid.
More to come...
Diffstat (limited to 'usr.sbin/lpr/common_source/rmjob.c')
-rw-r--r-- | usr.sbin/lpr/common_source/rmjob.c | 139 |
1 files changed, 80 insertions, 59 deletions
diff --git a/usr.sbin/lpr/common_source/rmjob.c b/usr.sbin/lpr/common_source/rmjob.c index 256da3f..e2406b9 100644 --- a/usr.sbin/lpr/common_source/rmjob.c +++ b/usr.sbin/lpr/common_source/rmjob.c @@ -36,19 +36,25 @@ static char sccsid[] = "@(#)rmjob.c 8.2 (Berkeley) 4/28/95"; #endif static const char rcsid[] = - "$Id: rmjob.c,v 1.9 1997/09/24 06:47:31 charnier Exp $"; + "$Id: rmjob.c,v 1.10 1997/10/14 16:00:37 joerg Exp $"; #endif /* not lint */ #include <sys/param.h> +#include <sys/uio.h> -#include <signal.h> -#include <errno.h> +#include <ctype.h> #include <dirent.h> -#include <unistd.h> -#include <stdlib.h> +#include <errno.h> +#include <signal.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> -#include <ctype.h> +#define psignal foil_gcc_psignal +#define sys_siglist foil_gcc_siglist +#include <unistd.h> +#undef psignal +#undef sys_siglist + #include "lp.h" #include "lp.local.h" #include "pathnames.h" @@ -71,32 +77,22 @@ static void alarmhandler __P((int)); static void do_unlink __P((char *)); void -rmjob() +rmjob(printer) + const char *printer; { register int i, nitems; int assasinated = 0; struct dirent **files; char *cp; + struct printer myprinter, *pp = &myprinter; - 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, "lp", &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 (cgetnum(bp, "ct", &CT) < 0) - CT = DEFTIMEOUT; - cgetstr(bp, "rm", &RM); - if ((cp = checkremote())) + 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, @@ -112,16 +108,16 @@ rmjob() } if (!strcmp(person, "-all")) { if (from == host) - fatal("The login name \"-all\" is reserved"); + fatal(pp, "The login name \"-all\" is reserved"); all = 1; /* all those from 'from' */ person = root; } seteuid(euid); - if (chdir(SD) < 0) - fatal("cannot chdir to spool directory"); + if (chdir(pp->spool_dir) < 0) + fatal(pp, "cannot chdir to spool directory"); if ((nitems = scandir(".", &files, iscf, NULL)) < 0) - fatal("cannot access spool directory"); + fatal(pp, "cannot access spool directory"); seteuid(uid); if (nitems) { @@ -130,25 +126,25 @@ rmjob() * kill it if it is reading our file) then remove stuff * (after which we have to restart the daemon). */ - if (lockchk(LO) && chk(current)) { + if (lockchk(pp, pp->lock_file) && chk(current)) { seteuid(euid); assasinated = kill(cur_daemon, SIGINT) == 0; seteuid(uid); if (!assasinated) - fatal("cannot kill printer daemon"); + fatal(pp, "cannot kill printer daemon"); } /* * process the files */ for (i = 0; i < nitems; i++) - process(files[i]->d_name); + process(pp, files[i]->d_name); } - rmremote(); + rmremote(pp); /* * Restart the printer daemon if it was killed */ - if (assasinated && !startdaemon(printer)) - fatal("cannot restart printer daemon\n"); + if (assasinated && !startdaemon(pp)) + fatal(pp, "cannot restart printer daemon\n"); exit(0); } @@ -158,7 +154,8 @@ rmjob() * Return boolean indicating existence of a lock file. */ int -lockchk(s) +lockchk(pp, s) + struct printer *pp; char *s; { register FILE *fp; @@ -167,7 +164,7 @@ lockchk(s) seteuid(euid); if ((fp = fopen(s, "r")) == NULL) { if (errno == EACCES) - fatal("can't access lock file"); + fatal(pp, "%s: %s", s, strerror(errno)); else return(0); } @@ -197,7 +194,8 @@ lockchk(s) * Process a control file. */ void -process(file) +process(pp, file) + const struct printer *pp; char *file; { FILE *cfp; @@ -206,7 +204,7 @@ process(file) return; seteuid(euid); if ((cfp = fopen(file, "r")) == NULL) - fatal("cannot open %s", file); + fatal(pp, "cannot open %s", file); seteuid(uid); while (getline(cfp)) { switch (line[0]) { @@ -315,14 +313,15 @@ isowner(owner, file) * then try removing files on the remote machine. */ void -rmremote() +rmremote(pp) + const struct printer *pp; { - register char *cp; - register int i, rem; + int i, rem, niov, totlen; char buf[BUFSIZ]; void (*savealrm)(int); + struct iovec *iov; - if (!remote) + if (!pp->remote) return; /* not sending to a remote machine */ /* @@ -331,34 +330,55 @@ rmremote() */ fflush(stdout); - (void)snprintf(buf, sizeof(buf), "\5%s %s", RP, all ? "-all" : person); - cp = buf; - for (i = 0; i < users && cp-buf+1+strlen(user[i]) < sizeof(buf); i++) { - cp += strlen(cp); - *cp++ = ' '; - strcpy(cp, user[i]); + /* + * Counting: + * 4 == "\5" + remote_queue + " " + person + * 2 * users == " " + user[i] for each user + * requests == asprintf results for each request + * 1 == "\n" + * Although laborious, doing it this way makes it possible for + * us to process requests of indeterminate length without + * applying an arbitrary limit. Arbitrary Limits Are Bad (tm). + */ + niov = 4 + 2 * users + requests + 1; + iov = malloc(niov * sizeof *iov); + if (iov == 0) + fatal(pp, "out of memory"); + iov[0].iov_base = "\5"; + iov[1].iov_base = pp->remote_queue; + iov[2].iov_base = " "; + iov[3].iov_base = all ? "-all" : person; + for (i = 0; i < users; i++) { + iov[4 + 2 * i].iov_base = " "; + iov[4 + 2 * i + 1].iov_base = user[i]; } - for (i = 0; i < requests && cp-buf+10 < sizeof(buf) - 1; i++) { - cp += strlen(cp); - (void) sprintf(cp, " %d", requ[i]); + for (i = 0; i < requests; i++) { + asprintf(&iov[4 + 2 * users + i].iov_base, " %d", requ[i]); + if (iov[4 + 2 * users + i].iov_base == 0) + fatal(pp, "out of memory"); } - strcat(cp, "\n"); + iov[4 + 2 * users + requests].iov_base = "\n"; + for (totlen = i = 0; i < niov; i++) + totlen += (iov[i].iov_len = strlen(iov[i].iov_base)); + savealrm = signal(SIGALRM, alarmhandler); - alarm(CT); - rem = getport(RM, 0); + alarm(pp->conn_timeout); + rem = getport(pp, pp->remote_host, 0); (void)signal(SIGALRM, savealrm); if (rem < 0) { if (from != host) printf("%s: ", host); - printf("connection to %s is down\n", RM); + printf("connection to %s is down\n", pp->remote_host); } else { - i = strlen(buf); - if (write(rem, buf, i) != i) - fatal("Lost connection"); + if (writev(rem, iov, niov) != totlen) + fatal(pp, "Lost connection"); while ((i = read(rem, buf, sizeof(buf))) > 0) (void) fwrite(buf, 1, i, stdout); (void) close(rem); } + for (i = 0; i < requests; i++) + free(iov[4 + 2 * users + i].iov_base); + free(iov); } /* @@ -373,6 +393,7 @@ iscf(d) void alarmhandler(signo) + int signo; { /* ignored */ } |