Date: Mon, 10 Jun 2002 22:37:46 -0400 From: Garance A Drosihn <drosih@rpi.edu> To: freebsd-print@bostonradio.org Cc: freebsd-audit@freebsd.org Subject: New 'setmsg' (or 'setstatus') command for lpc Message-ID: <p05111744b92b0eaf61f9@[128.113.24.47]>
next in thread | raw e-mail | index | archive | help
Here's the next update in the series. This one adds a new command to lpc which can be used to set the status message for one or more printers. It includes some changes to the upstat() routine, to make that handle seteuid() calls instead of assuming the caller handled them. You'll notice two places where I added seteuid() after a call to upstat(). That looks weird, but that's in the X-version of the abort command, and that whole routine will disappear soon anyway. When this was originally implemented at RPI, it was called 'setstatus'. I noticed lpc in LPRng has a 'msg' command which does about the same thing, but I don't quite like 'msg' as a command. So, I added 'setmsg' instead. As I look at this, I'm thinking that maybe I should just stick with 'setstatus' instead of having two commands that do the same thing. This patch assumes the previous patch has been applied. The latest version of *that* patch (which rewrote of much of lpc/cmds.c) is at http://people.freebsd.org/~gad/lpr/lpc-cmds.diff There are only a few cosmetic changes to that patch, but this new patch probably assumes those cosmetic changes are in place. This new patch is also at: http://people.freebsd.org/~gad/lpr/lpc-setmsg.diff This patch is in a slightly different format, because it is a 'diff' between two directories, instead of a 'cvs diff' from current. I'm not sure how usable that is, but at least it's readable. I would like to commit this to -current next weekend, but it can certainly wait a bit longer if people want more time to think about it. =================================================================== diff -u -r fbsd-rel5.orig/lpc/cmds.c fbsd-rel5/lpc/cmds.c --- fbsd-rel5.orig/lpc/cmds.c Sun Jun 9 18:56:53 2002 +++ fbsd-rel5/lpc/cmds.c Mon Jun 10 21:12:32 2002 @@ -79,6 +79,7 @@ #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 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 @@ 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 @@ 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,21 @@ if (generic_nullarg == NULL) generic_nullarg = strdup(""); + /* Some commands accept a -msg argument */ + 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 +229,34 @@ 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); + while (--argc >= 0) { + cp2 = *argv++; + while ((cp1 < cend) && (*cp2 != '\0')) + *cp1++ = *cp2++; + *cp1++ = ' '; + } + cp1[-1] = '\n'; + *cp1 = '\0'; + return strdup(buf); } /* @@ -242,7 +289,9 @@ printf("\tcannot disable printing: %s\n", strerror(errno)); else { - upstat(pp, "printing disabled\n"); + upstat(pp, "printing disabled\n", 0); + /* ...new upstat() did a setuid(uid)... */ + seteuid(euid); printf("\tprinting disabled\n"); } } else if (errno == ENOENT) { @@ -252,7 +301,9 @@ strerror(errno)); else { (void) close(fd); - upstat(pp, "printing disabled\n"); + upstat(pp, "printing disabled\n", 0); + /* ...new upstat() did a setuid(uid)... */ + seteuid(euid); printf("\tprinting disabled\n"); printf("\tno daemon to abort\n"); } @@ -377,14 +428,16 @@ * 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 +448,12 @@ 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 +501,8 @@ break; } - if (setres >= 0) { - seteuid(euid); - upstat(pp, "printing disabled\n"); - seteuid(uid); - } + if (setres >= 0) + upstat(pp, "printing disabled\n", 0); } /* @@ -1133,6 +1189,31 @@ } /* + * 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 +setmsg_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 +setmsg_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 +1360,7 @@ 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 +1370,7 @@ strerror(errno)); else { (void) close(fd); - upstat(pp, "printing disabled\n"); + upstat(pp, "printing disabled\n", 0); printf("\tprinting disabled\n"); } } else @@ -1312,11 +1393,8 @@ 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 -u -r fbsd-rel5.orig/lpc/cmdtab.c fbsd-rel5/lpc/cmdtab.c --- fbsd-rel5.orig/lpc/cmdtab.c Mon Jun 10 16:48:00 2002 +++ fbsd-rel5/lpc/cmdtab.c Mon Jun 10 20:02:18 2002 @@ -55,6 +55,7 @@ char helphelp[] = "get help on commands"; char quithelp[] = "exit lpc"; char restarthelp[] = "kill (if possible) and restart a spooling daemon"; +char setmsghelp[] = "set the status message, requires \"-msg\" before the msg"; 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 +63,9 @@ 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 }, @@ -74,6 +77,8 @@ { "help", helphelp, 0, help, 0 }, { "quit", quithelp, 0, quit, 0 }, { "restart", restarthelp, 0, 0, restart_q }, + { "setmsg", setmsghelp, PR|M, setmsg_gi, setmsg_q }, + { "setstatus", setmsghelp, PR|M, setmsg_gi, setmsg_q }, { "start", starthelp, PR, 0, start_q }, { "status", statushelp, 0, 0, status }, { "stop", stophelp, PR, 0, stop_q }, =================================================================== diff -u -r fbsd-rel5.orig/lpc/extern.h fbsd-rel5/lpc/extern.h --- fbsd-rel5.orig/lpc/extern.h Mon Jun 10 12:56:06 2002 +++ fbsd-rel5/lpc/extern.h Mon Jun 10 20:43:46 2002 @@ -47,7 +47,7 @@ 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_tclean(int _argc, char *_argv[]); void quit(int _argc, char *_argv[]); void restart_q(struct printer *_pp); +void setmsg_gi(int _argc, char *_argv[]); +void setmsg_q(struct printer *_pp); void start_q(struct printer *_pp); void status(struct printer *_pp); void stop_q(struct printer *_pp); =================================================================== diff -u -r fbsd-rel5.orig/lpc/extern_lpc.h fbsd-rel5/lpc/extern_lpc.h --- fbsd-rel5.orig/lpc/extern_lpc.h Mon Jun 10 12:56:06 2002 +++ fbsd-rel5/lpc/extern_lpc.h Mon Jun 10 20:43:46 2002 @@ -47,7 +47,7 @@ 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_tclean(int _argc, char *_argv[]); void quit(int _argc, char *_argv[]); void restart_q(struct printer *_pp); +void setmsg_gi(int _argc, char *_argv[]); +void setmsg_q(struct printer *_pp); void start_q(struct printer *_pp); void status(struct printer *_pp); void stop_q(struct printer *_pp); =================================================================== diff -u -r fbsd-rel5.orig/lpc/lpc.c fbsd-rel5/lpc/lpc.c --- fbsd-rel5.orig/lpc/lpc.c Mon Oct 1 04:46:45 2001 +++ fbsd-rel5/lpc/lpc.c Mon Jun 10 21:08:02 2002 @@ -110,12 +110,14 @@ 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 @@ 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 @@ * 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 -u -r fbsd-rel5.orig/lpc/lpc.h fbsd-rel5/lpc/lpc.h --- fbsd-rel5.orig/lpc/lpc.h Sun Jun 24 22:05:03 2001 +++ fbsd-rel5/lpc/lpc.h Mon Jun 10 19:59:11 2002 @@ -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 *[]); -- Garance Alistair Drosehn = gad@gilead.netel.rpi.edu Senior Systems Programmer or gad@freebsd.org Rensselaer Polytechnic Institute or drosih@rpi.edu To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?p05111744b92b0eaf61f9>