Skip site navigation (1)Skip section navigation (2)
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>