diff options
author | gad <gad@FreeBSD.org> | 2002-06-15 22:51:58 +0000 |
---|---|---|
committer | gad <gad@FreeBSD.org> | 2002-06-15 22:51:58 +0000 |
commit | 6bfe5682488b02e59b3b1254657a7bc8b9bb209b (patch) | |
tree | 44f771aaa14debc6dffa2c3c508f7bf1c7c5f7a5 | |
parent | 62289e8461aa01c16367d44b6e2f109737065bfa (diff) | |
download | FreeBSD-src-6bfe5682488b02e59b3b1254657a7bc8b9bb209b.zip FreeBSD-src-6bfe5682488b02e59b3b1254657a7bc8b9bb209b.tar.gz |
Add a new command to 'lpc' called 'setstatus', which would be used to
change the status message of a print queue. This includes some minor
changes to the upstat() routine, so that error messages are not printed
while seteuid(priv-user).
Reviewed by: freebsd-audit and freebsd-print@bostonradio.org
MFC after: 10 days
-rw-r--r-- | usr.sbin/lpr/lpc/cmds.c | 121 | ||||
-rw-r--r-- | usr.sbin/lpr/lpc/cmdtab.c | 7 | ||||
-rw-r--r-- | usr.sbin/lpr/lpc/extern.h | 4 | ||||
-rw-r--r-- | usr.sbin/lpr/lpc/lpc.8 | 19 | ||||
-rw-r--r-- | usr.sbin/lpr/lpc/lpc.c | 12 | ||||
-rw-r--r-- | usr.sbin/lpr/lpc/lpc.h | 5 |
6 files changed, 140 insertions, 28 deletions
diff --git a/usr.sbin/lpr/lpc/cmds.c b/usr.sbin/lpr/lpc/cmds.c index c87915c..8ab39b0 100644 --- a/usr.sbin/lpr/lpc/cmds.c +++ b/usr.sbin/lpr/lpc/cmds.c @@ -79,6 +79,7 @@ static const char rcsid[] = #define KQT_KILLOK 1 static void abortpr(struct printer *_pp, int _dis); +static char *args2line(int argc, char **argv); static int doarg(char *_job); static int doselect(struct dirent *_d); static int kill_qtask(const char *lf); @@ -87,7 +88,7 @@ static int sortq(const void *_a, const void *_b); static void startpr(struct printer *_pp, int _chgenable); static int touch(struct jobqueue *_jq); static void unlinkf(char *_name); -static void upstat(struct printer *_pp, const char *_msg); +static void upstat(struct printer *_pp, const char *_msg, int _notify); static void wrapup_clean(int _laststatus); /* @@ -103,11 +104,12 @@ enum qsel_val { /* how a given ptr was selected */ static enum qsel_val generic_qselect; /* indicates how ptr was selected */ static int generic_initerr; /* result of initrtn processing */ +static char *generic_msg; /* if a -msg was specified */ static char *generic_nullarg; static void (*generic_wrapup)(int _last_status); /* perform rtn wrap-up */ void -generic(void (*specificrtn)(struct printer *_pp), +generic(void (*specificrtn)(struct printer *_pp), int cmdopts, void (*initrtn)(int _argc, char *_argv[]), int argc, char *argv[]) { int cmdstatus, more, targc; @@ -115,7 +117,10 @@ generic(void (*specificrtn)(struct printer *_pp), char **targv; if (argc == 1) { - printf("usage: %s {all | printer ...}\n", argv[0]); + printf("usage: %s {all | printer ...}", argv[0]); + if (cmdopts & LPC_MSGOPT) + printf(" [-msg <text> ...]"); + printf("\n"); return; } @@ -136,6 +141,24 @@ generic(void (*specificrtn)(struct printer *_pp), if (generic_nullarg == NULL) generic_nullarg = strdup(""); + /* + * Some commands accept a -msg argument, which indicates that + * all remaining arguments should be combined into a string. + */ + generic_msg = NULL; + if (cmdopts & LPC_MSGOPT) { + targc = argc; + targv = argv; + while (--targc) { + ++targv; + if (strcmp(*targv, "-msg") == 0) { + argc -= targc; + generic_msg = args2line(targc - 1, targv + 1); + break; + } + } + } + /* call initialization routine, if there is one for this cmd */ if (initrtn != NULL) { generic_initerr = 0; @@ -209,7 +232,34 @@ wrapup: if (generic_wrapup) { (*generic_wrapup)(cmdstatus); } + if (generic_msg) + free(generic_msg); +} +/* + * Convert an argv-array of character strings into a single string. + */ +static char * +args2line(int argc, char **argv) +{ + char *cp1, *cend; + const char *cp2; + char buf[1024]; + + if (argc <= 0) + return strdup("\n"); + + cp1 = buf; + cend = buf + sizeof(buf) - 1; /* save room for '\0' */ + while (--argc >= 0) { + cp2 = *argv++; + while ((cp1 < cend) && (*cp1++ = *cp2++)) + ; + cp1[-1] = ' '; + } + cp1[-1] = '\n'; + *cp1 = '\0'; + return strdup(buf); } /* @@ -242,7 +292,10 @@ abortpr(struct printer *pp, int dis) printf("\tcannot disable printing: %s\n", strerror(errno)); else { - upstat(pp, "printing disabled\n"); + /* ..call newer upstat() in obsolete code.. */ + upstat(pp, "printing disabled\n", 0); + /* ..the new upstat() did a setuid(uid).. */ + seteuid(euid); printf("\tprinting disabled\n"); } } else if (errno == ENOENT) { @@ -252,7 +305,10 @@ abortpr(struct printer *pp, int dis) strerror(errno)); else { (void) close(fd); - upstat(pp, "printing disabled\n"); + /* ..call newer upstat() in obsolete code.. */ + upstat(pp, "printing disabled\n", 0); + /* ..the new upstat() did a setuid(uid).. */ + seteuid(euid); printf("\tprinting disabled\n"); printf("\tno daemon to abort\n"); } @@ -377,14 +433,16 @@ killdone: * Write a message into the status file. */ static void -upstat(struct printer *pp, const char *msg) +upstat(struct printer *pp, const char *msg, int notifyuser) { - register int fd; + int fd; char statfile[MAXPATHLEN]; status_file_name(pp, statfile, sizeof statfile); umask(0); + seteuid(euid); fd = open(statfile, O_WRONLY|O_CREAT|O_EXLOCK, STAT_FILE_MODE); + seteuid(uid); if (fd < 0) { printf("\tcannot create status file: %s\n", strerror(errno)); return; @@ -395,6 +453,12 @@ upstat(struct printer *pp, const char *msg) else (void) write(fd, msg, strlen(msg)); (void) close(fd); + if (notifyuser) { + if ((msg == (char *)NULL) || (strcmp(msg, "\n") == 0)) + printf("\tstatus message is now set to nothing.\n"); + else + printf("\tstatus message is now: %s", msg); + } } /* @@ -442,11 +506,8 @@ abort_q(struct printer *pp) break; } - if (setres >= 0) { - seteuid(euid); - upstat(pp, "printing disabled\n"); - seteuid(uid); - } + if (setres >= 0) + upstat(pp, "printing disabled\n", 0); } /* @@ -1133,6 +1194,31 @@ restart_q(struct printer *pp) } /* + * Set the status message of each queue listed. Requires a "-msg" + * parameter to indicate the end of the queue list and start of msg text. + */ +void +setstatus_gi(int argc __unused, char *argv[] __unused) +{ + + if (generic_msg == NULL) { + printf("You must specify '-msg' before the text of the new status message.\n"); + generic_initerr = 1; + } +} + +void +setstatus_q(struct printer *pp) +{ + char lf[MAXPATHLEN]; + + lock_file_name(pp, lf, sizeof lf); + printf("%s:\n", pp->printer); + + upstat(pp, generic_msg, 1); +} + +/* * Enable printing on the specified printer and startup the daemon. */ void @@ -1279,7 +1365,7 @@ stop(struct printer *pp) printf("\tcannot disable printing: %s\n", strerror(errno)); else { - upstat(pp, "printing disabled\n"); + upstat(pp, "printing disabled\n", 0); printf("\tprinting disabled\n"); } } else if (errno == ENOENT) { @@ -1289,7 +1375,7 @@ stop(struct printer *pp) strerror(errno)); else { (void) close(fd); - upstat(pp, "printing disabled\n"); + upstat(pp, "printing disabled\n", 0); printf("\tprinting disabled\n"); } } else @@ -1312,11 +1398,8 @@ stop_q(struct printer *pp) setres = set_qstate(SQS_STOPP, lf); - if (setres >= 0) { - seteuid(euid); - upstat(pp, "printing disabled\n"); - seteuid(uid); - } + if (setres >= 0) + upstat(pp, "printing disabled\n", 0); } struct jobqueue **queue; diff --git a/usr.sbin/lpr/lpc/cmdtab.c b/usr.sbin/lpr/lpc/cmdtab.c index acae213..570c5fb 100644 --- a/usr.sbin/lpr/lpc/cmdtab.c +++ b/usr.sbin/lpr/lpc/cmdtab.c @@ -55,6 +55,8 @@ char downhelp[] = "do a 'stop' followed by 'disable' and put a message in status char helphelp[] = "get help on commands"; char quithelp[] = "exit lpc"; char restarthelp[] = "kill (if possible) and restart a spooling daemon"; +char setstatushelp[] = "set the status message of a queue, requires\n" + "\t\t\"-msg\" before the text of the new message"; char starthelp[] = "enable printing and start a spooling daemon"; char statushelp[] = "show status of daemon and queue"; char stophelp[] = "stop a spooling daemon after current job completes and disable printing"; @@ -62,7 +64,9 @@ char tcleanhelp[] = "test to see what files a clean cmd would remove"; char topqhelp[] = "put job at top of printer queue"; char uphelp[] = "enable everything and restart spooling daemon"; -#define PR 1 /* a privileged command */ +/* Use some abbreviations so entries won't need to wrap */ +#define PR LPC_PRIVCMD +#define M LPC_MSGOPT struct cmd cmdtab[] = { { "abort", aborthelp, PR, 0, abort_q }, @@ -76,6 +80,7 @@ struct cmd cmdtab[] = { { "restart", restarthelp, 0, 0, restart_q }, { "start", starthelp, PR, 0, start_q }, { "status", statushelp, 0, 0, status }, + { "setstatus", setstatushelp, PR|M, setstatus_gi, setstatus_q }, { "stop", stophelp, PR, 0, stop_q }, { "tclean", tcleanhelp, 0, init_tclean, clean_q }, { "topq", topqhelp, PR, topq, 0 }, diff --git a/usr.sbin/lpr/lpc/extern.h b/usr.sbin/lpr/lpc/extern.h index dc9fe9d..211f115 100644 --- a/usr.sbin/lpr/lpc/extern.h +++ b/usr.sbin/lpr/lpc/extern.h @@ -47,7 +47,7 @@ void clean_q(struct printer *_pp); void disable_q(struct printer *_pp); void down(int _argc, char *_argv[]); void enable_q(struct printer *_pp); -void generic(void (*_specificrtn)(struct printer *_pp), +void generic(void (*_specificrtn)(struct printer *_pp), int _cmdopts, void (*_initcmd)(int _argc, char *_argv[]), int _argc, char *_argv[]); void help(int _argc, char *_argv[]); @@ -55,6 +55,8 @@ void init_clean(int _argc, char *_argv[]); void init_tclean(int _argc, char *_argv[]); void quit(int _argc, char *_argv[]); void restart_q(struct printer *_pp); +void setstatus_gi(int _argc, char *_argv[]); +void setstatus_q(struct printer *_pp); void start_q(struct printer *_pp); void status(struct printer *_pp); void stop_q(struct printer *_pp); diff --git a/usr.sbin/lpr/lpc/lpc.8 b/usr.sbin/lpr/lpc/lpc.8 index d993a83..039a4a2 100644 --- a/usr.sbin/lpr/lpc/lpc.8 +++ b/usr.sbin/lpr/lpc/lpc.8 @@ -32,7 +32,7 @@ .\" @(#)lpc.8 8.5 (Berkeley) 4/28/95 .\" $FreeBSD$ .\" -.Dd June 20, 2001 +.Dd June 15, 2002 .Dt LPC 8 .Os .Sh NAME @@ -58,7 +58,11 @@ disable or enable a printer's spooling queue, rearrange the order of jobs in a spooling queue, .It find the status of printers, and their associated -spooling queues and printer daemons. +spooling queues and printer daemons, +.It +change the status message for printer queues (the status message +may be seen by users as part of the output of the +.Xr lpq 1 utility). .El .Pp Without any arguments, @@ -139,6 +143,17 @@ will report that there is no daemon present when this condition occurs. If the user is the super-user, try to abort the current daemon first (i.e., kill and restart a stuck daemon). .Pp +.It Ic setstatus Bro Cm all | Ar printer Brc Cm -msg Ar message ... +Set the status message for the specified printers. +The +.Ic -msg +argument is required to separate the list of printers from the text +that will be the new status message. +This is normally used to change the status message when the printer +queue is no longer active after printing has been disabled, and you +want to change what users will see in the output of the +.Xr lpq 1 utility. +.Pp .It Ic start Brq Cm all | Ar printer Enable printing and start a spooling daemon for the listed printers. .Pp diff --git a/usr.sbin/lpr/lpc/lpc.c b/usr.sbin/lpr/lpc/lpc.c index 457ad70..357e4ad 100644 --- a/usr.sbin/lpr/lpc/lpc.c +++ b/usr.sbin/lpr/lpc/lpc.c @@ -110,12 +110,14 @@ main(int argc, char *argv[]) printf("?Invalid command\n"); exit(1); } - if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) { + if ((c->c_opts & LPC_PRIVCMD) && getuid() && + ingroup(LPR_OPER) == 0) { printf("?Privileged command\n"); exit(1); } if (c->c_generic != 0) - generic(c->c_generic, c->c_handler, argc, argv); + generic(c->c_generic, c->c_opts, c->c_handler, + argc, argv); else (*c->c_handler)(argc, argv); exit(0); @@ -210,7 +212,8 @@ cmdscanner(void) printf("?Invalid command\n"); continue; } - if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) { + if ((c->c_opts & LPC_PRIVCMD) && getuid() && + ingroup(LPR_OPER) == 0) { printf("?Privileged command\n"); continue; } @@ -223,7 +226,8 @@ cmdscanner(void) * initial parameter processing. */ if (c->c_generic != 0) - generic(c->c_generic, c->c_handler, margc, margv); + generic(c->c_generic, c->c_opts, c->c_handler, + margc, margv); else (*c->c_handler)(margc, margv); } diff --git a/usr.sbin/lpr/lpc/lpc.h b/usr.sbin/lpr/lpc/lpc.h index 9511c24..73e4cc5 100644 --- a/usr.sbin/lpr/lpc/lpc.h +++ b/usr.sbin/lpr/lpc/lpc.h @@ -40,10 +40,13 @@ */ struct printer; +#define LPC_PRIVCMD 0x0001 /* a privileged command */ +#define LPC_MSGOPT 0x0002 /* command recognizes -msg option */ + struct cmd { const char *c_name; /* command name */ const char *c_help; /* help message */ - const int c_priv; /* privileged command */ + const int c_opts; /* flags (eg: privileged command) */ /* routine to do all the work for plain cmds, or * initialization work for generic-printer cmds: */ void (*c_handler)(int, char *[]); |