Bug 49023 - [patch] to lpd(8) (printjob.c) to pass source filename to input filters
Summary: [patch] to lpd(8) (printjob.c) to pass source filename to input filters
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 4.7-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: Garance A Drosehn
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2003-03-07 23:40 UTC by jimd
Modified: 2022-10-17 12:39 UTC (History)
0 users

See Also:


Attachments
file.diff (2.08 KB, patch)
2003-03-07 23:40 UTC, jimd
no flags Details | Diff
printjob.c.diffs (2.32 KB, patch)
2003-03-10 23:46 UTC, jimd
no flags Details | Diff
printjob.c.diffs (4.27 KB, patch)
2004-02-22 07:02 UTC, User1001
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description jimd 2003-03-07 23:40:01 UTC
	Add small section to PRINTJOB.C in /usr/src/usr.sbin/lpr/lpd to extract the
	source file name from the (LPD) control file and pass it to the input filter,
	along with another "identifying" parameter, at the end of the current/normal
	parameter string. The last two parameters below are what get added to the
	input filter parameter list:
	
	-w132 -l66 -i0 -n xxxx -h xxxx /var/account/lp.printacct -fn .cshrc
	
	This will allow remote LPD's to do special actions on print files based on
	their original source file name, and is really intended for use in an input
	filter so it can achieve specialization without having to use other, external,
	methods to derive meaningful identifying information about the file waiting
	for it on STDIN.
Comment 1 jimd 2003-03-10 23:46:46 UTC
Slightly modifed PRINTJOB.C.DIFFS to insert new parameters in input 
filter list only when original filename is found in the control file.
Comment 2 dwmalone freebsd_committer freebsd_triage 2003-03-12 13:42:27 UTC
Responsible Changed
From-To: freebsd-bugs->gad

One for the lpd maintainer.
Comment 3 jimd 2003-04-21 20:10:07 UTC
***************
*** 780,785 ****
--- 803,813 ----
         av[n++] = "-h";
         av[n++] = origin_host;
         av[n++] = pp->acct_file;
+       /* added 20 Feb, 21 Apr 2003 - JD */
+       if ((strcmp(ofilename, " ") != 0)&&(strcmp(ofilename, "") != 0)) {
+         av[n++] = "-fn";
+         av[n++] = ofilename;
+       }  /*  JD  */
         av[n] = 0;
         fo = pfd;
         if (of_pid > 0) {               /* stop output filter */
Comment 4 Garance A Drosehn freebsd_committer freebsd_triage 2003-04-21 20:58:05 UTC
Oops.  I thought I had already replied to this PR.

It is not a good idea to add one more parameter to the parameters given 
to the filters run by lpd.  The problem is that "you" (the generic you) 
have no control over all the different filters that everyone else will 
write and use.  Some filters will break if you add any new parameter to 
them.  I know this, as I added one simple parameter at RPI only to find 
out that it broke the print queue for someone like the dean of 
engineering.  We (RPI) have only three or four different filters that 
we run, and my simple change managed to break at least one of them.  I 
was in a bit of hot water over that (well, for about 24 hours...), and 
I am not eager to repeat that by inflicting the same mistake on 
everyone who runs freebsd.

A better way to do this kind of thing is with environment variables.  
That way it is very very unlikely that you'll break any existing script.

I have some other ideas which pertain to what you're trying to do, but 
I haven't had the time to implement them all yet.

-- 
Garance Alistair Drosehn     =      gad@gilead.netel.rpi.edu
Senior Systems Programmer               or   gad@FreeBSD.org
Rensselaer Polytechnic Institute;             Troy, NY;  USA
Comment 5 J.D. 2003-05-17 13:14:02 UTC
Patch to use environment variables instead of modifying the filter parameter list:

*** printjob.c.orig     Wed Apr 30 11:41:47 2003
--- printjob.c  Wed Apr 30 11:41:52 2003
***************
*** 114,119 ****
--- 114,122 ----
                                /* indentation size in static characters */
  static char   indent[10] = "-i0";
  static char   jobname[100];           /* job or file name */
+ static char   LPD_FILENAME[100];      /* name of (source) file to print - JD*/+ static char   LPD_FILENAME_VAR[12] = "LPD_FILENAME"; /* new env var - JD */
+ static long   origfpos = 0L;          /* original cfp file position - JD */
  static char   length[10] = "-l";      /* page length in lines */
  static char   logname[32];            /* user's login name */
  static char   pxlength[10] = "-y";    /* page length in pixels */
***************
*** 645,650 ****
--- 648,678 ----
                (void) close(fi);
                return (OK);
        }
+
+       /*
+        * reset pointer to config file, parse cf for filename,
+        * reset pointer again to where it was before we got here
+        *
+        * JD 06 March 2003, 30 April 2003
+        *
+        */
+       origfpos = ftell(cfp); /* get previous file position */
+       fseek(cfp, 0L, 0);     /* set file position to beginning of file */
+       strlcpy(LPD_FILENAME, "undefined", sizeof(LPD_FILENAME)); /* initialize
variable */
+       while (getline(cfp))
+         switch (line[0]){
+             case 'N':
+               if (line[1] != '\0') {
+                 strlcpy(LPD_FILENAME, line + 1, sizeof(LPD_FILENAME));
+                 if (strncmp(LPD_FILENAME, " ", sizeof(LPD_FILENAME)) == 0)
+                    strlcpy(LPD_FILENAME, "undefined", sizeof(LPD_FILENAME));
+               }
+                 continue;
+           default: continue;
+       }
+       fseek(cfp, origfpos, 0);  /* reset file pointer */
+       /*-------------------- JD */
+
        switch (format) {
        case 'p':       /* print file using 'pr' */
                if (pp->filters[LPF_INPUT] == NULL) {   /* use output filter */
***************
*** 780,785 ****
--- 808,822 ----
        av[n++] = "-h";
        av[n++] = origin_host;
        av[n++] = pp->acct_file;
+       /* added 20 Feb, 21 Apr 2003 - JD */
+       unsetenv(LPD_FILENAME); errno = 0;
+       if (setenv(LPD_FILENAME_VAR, LPD_FILENAME, 1) < 0) {
+           if (errno == ENOMEM)
+           syslog(LOG_ERR, "Not enough memory to set LPD_FILENAME environment variable");
+         else
+           syslog(LOG_ERR, "Unknown setenv error attempting to set LPD_FILENAME environment variable");
+       }
+       /*  JD  */
        av[n] = 0;
        fo = pfd;
        if (of_pid > 0) {               /* stop output filter */
Comment 6 User1001 2004-02-22 07:02:47 UTC
Attached is an updated patch for "printjob.c" which includes the same 
environment variable setting for a file to be sent to a remote printer, 
but processed by an input filter first using a printcap entry such as 
the following where "ps49...." is a print server similar to an HP Deskjet.

djpsbw_duplex:\
         :lf=/var/log/lpd-errs:mx#0:sh:\
         :af=/var/account/lp.printacct:\
         :if=/usr/libexec/lpr/a2psBWdupprt.sh:\
         :rm=ps49cef5.localnet10:\
         :rp=lpt1:sd=/var/spool/lpd/djpsbw_duplex:
Comment 7 User1001 2004-05-15 05:20:02 UTC
Slight correction to setenv/unsetenv code and variables to 1) better follow
example of setenv/unsetenv calls (with pointer variables) and 2) to fix a
strange setenv/unsetenv call that produced a "LPD_FILENAME-s63" variable
name.

The code has been tested and verified in both FreeBSD-5.2.1 and FreeBSD-4.8.


*** printjob.c.orig	Wed Aug 20 22:43:48 2003
--- printjob.c	Fri May 14 03:18:43 2004
***************
*** 119,124 ****
--- 119,129 ----
  				/* indentation size in static characters */
  static char	indent[10] = "-i0";
  static char	jobname[100];		/* job or file name */
+ static char	LPD_FILENAME[100];	/* name of (source) file to print - JD*/
+ static char	*LPD_FILENAME_VALUE = LPD_FILENAME;
+ static char	LPD_FILENAME_VARNAME[13] = "LPD_FILENAME\0";/* new env var - JD */
+ static char	*LPD_FILENAME_VAR = LPD_FILENAME_VARNAME;
+ static long	origfpos = 0L;		/* original cfp file position - JD */
  static char	length[10] = "-l";	/* page length in lines */
  static char	logname[32];		/* user's login name */
  static char	pxlength[10] = "-y";	/* page length in pixels */
***************
*** 385,390 ****
--- 390,396 ----
  
  	bombed = OK;
  	didignorehdr = 0;
+ 
  	/*
  	 * open control file; ignore if no longer there.
  	 */
***************
*** 444,450 ****
  	 */
  
  	/* pass 1 */
- 
  	while (getline(cfp))
  		switch (line[0]) {
  		case 'H':
--- 450,455 ----
***************
*** 650,655 ****
--- 655,685 ----
  		(void) close(fi);
  		return (OK);
  	}
+ 
+ 	/*
+ 	 * reset pointer to config file, parse cf for filename,
+ 	 * reset pointer again to where it was before we got here
+ 	 *
+ 	 * JD 06 March 2003, 30 April 2003
+ 	 *
+ 	 */
+ 	origfpos = ftell(cfp); /* get previous file position */
+ 	fseek(cfp, 0L, 0);     /* set file position to beginning of file */
+ 	strlcpy(LPD_FILENAME, "undefined", sizeof(LPD_FILENAME)); /* init var */
+ 	while (getline(cfp)){
+ 	  switch (line[0]){
+             case 'N':
+ 		if (line[1] != '\0') {
+ 		  strlcpy(LPD_FILENAME, line + 1, sizeof(LPD_FILENAME));
+     		  if (strncmp(LPD_FILENAME, " ", sizeof(LPD_FILENAME)) == 0)
+          	     strlcpy(LPD_FILENAME, "undefined", sizeof(LPD_FILENAME));
+ 		}
+                 continue;
+ 	    default: continue;
+ 	}}
+ 	fseek(cfp, origfpos, 0);  /* reset file pointer */
+ 	/*-------------------- JD */
+ 
  	switch (format) {
  	case 'p':	/* print file using 'pr' */
  		if (pp->filters[LPF_INPUT] == NULL) {	/* use output filter */
***************
*** 785,790 ****
--- 815,829 ----
  	av[n++] = "-h";
  	av[n++] = origin_host;
  	av[n++] = pp->acct_file;
+ 	/* added 20 Feb 2003, 21 Apr 2003, May 13 2004 - JD */
+ 	unsetenv(LPD_FILENAME_VAR); errno = 0;
+ 	if (setenv(LPD_FILENAME_VAR, LPD_FILENAME_VALUE, 1) != 0) { 
+           if (errno == ENOMEM)
+ 	    syslog(LOG_ERR, "Not enough memory to set LPD_FILENAME environment variable");
+ 	  else
+ 	    syslog(LOG_ERR, "Unknown setenv error attempting to set LPD_FILENAME environment variable");
+ 	}
+ 	/*  JD  */
  	av[n] = 0;
  	fo = pfd;
  	if (of_pid > 0) {		/* stop output filter */
***************
*** 949,954 ****
--- 988,1013 ----
  					break;
  				dfcopies++;
  			}
+ 			/*
+ 			   JD - 22 Feb 2004: extract spool file name and
+ 			   assign it to environment variable for later use
+ 			   by (local) input filter
+ 			*/
+ 			origfpos = ftell(cfp); /* get previous file position */
+ 			fseek(cfp, 0L, 0);     /* set file position to beginning of file */
+ 			strlcpy(LPD_FILENAME, "undefined", sizeof(LPD_FILENAME)); /* initialize variable */
+ 			while (getline(cfp)){
+ 				switch (line[0]){
+ 				case 'N':
+ 			  	  if (line[1] != '\0') {
+ 				    strlcpy(LPD_FILENAME, line + 1, sizeof(LPD_FILENAME));
+ 				    if (strncmp(LPD_FILENAME, " ", sizeof(LPD_FILENAME)) == 0)
+ 				      strlcpy(LPD_FILENAME, "undefined", sizeof(LPD_FILENAME));
+ 				    }
+ continue;
+ 				default: continue;
+ 			}}
+ 			/* JD */
  			switch (sendfile(pp, '\3', last+1, *last, dfcopies)) {
  			case OK:
  				if (i)
***************
*** 1065,1070 ****
--- 1124,1138 ----
  			av[++narg] = origin_host;
  			av[++narg] = pp->acct_file;
  			av[++narg] = NULL;
+                         /* added 21 Feb 2004, May 14 2004 - JD */
+                         unsetenv(LPD_FILENAME_VAR); errno = 0;
+                         if (setenv(LPD_FILENAME_VAR, LPD_FILENAME_VALUE, 1) != 0) {
+                           if (errno == ENOMEM)
+                             syslog(LOG_ERR, "Not enough memory to set LPD_FILENAME environment variable");
+                           else
+                             syslog(LOG_ERR, "Unknown setenv error attempting to set LPD_FILENAME environment variable");
+                        }
+                        /*  JD  */
  		} else if (pp->filters[LPF_OUTPUT]) {
  			filtcmd = pp->filters[LPF_OUTPUT];
  			av[0] = filtcmd;
Comment 8 User1001 2004-05-22 09:27:59 UTC
Last, hopefully, change to LPD (printjob.c) to allow a user to use the lpr
'-p -T ...' parameter sequence to "pass" a filename to LPD when printing a
file which is being piped to LPD. For example,

	man strlcpy | lpr -p -T 'strlcpy.man' -P djpsbw_duplex

will set the TITLE variable and the modified code will use that value when it
determines that the FILENAME variable is empty/null, thus allowing remote LPD
and/or input filter scripts to obtain either a real filename, or a pseudo
filename for their use.

Also - reduced size of extra variables as 100 characters would obviously not
fit on one (8.5 x 11, portrait) print line. Where the output is printed in
landscape, there may be more room for a longer filename, but 50 characters
should be sufficient to properly identify the "source" file. Otherwise, more
code would be needed to determine the best-fit-substring for printing
orientation which might be difficult and/or clumsy to achieve. 50 characters
should be good enough.



*** printjob.c.orig	Wed Aug 20 22:43:48 2003
--- printjob.c	Sat May 22 03:22:59 2004
***************
*** 119,124 ****
--- 119,130 ----
  				/* indentation size in static characters */
  static char	indent[10] = "-i0";
  static char	jobname[100];		/* job or file name */
+ static char	LPD_FILENAME[50] = "\0";  /* name of (source) file to print - JD*/
+ static char	*LPD_FILENAME_VALUE = LPD_FILENAME;
+ static char	LPD_FILENAME_VARNAME[13] = "LPD_FILENAME\0";/* new env var - JD */
+ static char	*LPD_FILENAME_VAR = LPD_FILENAME_VARNAME;
+ static char	LPD_PRTITLE[50] = "\0"; /* additional copy of pr TITLE - JD */
+ static long	origfpos = 0L;		/* original cfp file position - JD */
  static char	length[10] = "-l";	/* page length in lines */
  static char	logname[32];		/* user's login name */
  static char	pxlength[10] = "-y";	/* page length in pixels */
***************
*** 650,655 ****
--- 656,709 ----
  		(void) close(fi);
  		return (OK);
  	}
+ 
+ 	/*
+ 	 * Reset pointer to config file, parse cf for filename
+ 	 *
+ 	 * Also keep a secondary copy of Jobname and/or Title 
+ 	 * in case fileName is missing, in which case LPD_FILENAME
+ 	 * will be set to (non-null) pr TITLE, if "-p -T ..." is
+ 	 * included with lpr command when printing, say,
+ 	 * a MANual page piped to LPR
+ 	 *
+ 	 * Reset pointer again to where it was before we got here
+ 	 *
+ 	 * JD 06 March 2003, 30 April 2003, 22 May 2004
+ 	 *
+ 	 */
+ 	origfpos = ftell(cfp); /* get previous file position */
+ 	fseek(cfp, 0L, 0);     /* set file position to beginning of file */
+ 	strlcpy(LPD_FILENAME, "undefined\0", sizeof(LPD_FILENAME)); /* init var */
+ 	strlcpy(LPD_PRTITLE, "\0", sizeof(LPD_PRTITLE));
+ 	while (getline(cfp)){
+ 	  switch (line[0]){
+             case 'N':
+ 		if (line[1] != '\0') {
+ 		  strlcpy(LPD_FILENAME, line + 1, sizeof(LPD_FILENAME));
+     		  if (strncmp(LPD_FILENAME, " ", sizeof(LPD_FILENAME)) == 0)
+          	     strlcpy(LPD_FILENAME, "undefined\0", sizeof(LPD_FILENAME));
+ 		}
+                 continue;
+             case 'T':
+ 	        if (line[1] != '\0') {
+                    strlcpy(LPD_PRTITLE, line + 1, sizeof(LPD_PRTITLE));
+                 }
+ 		continue;
+ 	    default: continue;
+ 	}}
+ 	fseek(cfp, origfpos, 0);  /* reset file pointer */
+ 	/*
+ 	   if no filename in cfg file, "steal" filename from pr TITLE
+ 	   if it is non-null/empty
+         */
+ 	if (strncmp(LPD_FILENAME, "undefined", sizeof(LPD_FILENAME)) == 0) {
+ 	  if (LPD_PRTITLE[1] != '\0') {
+ 	    strlcpy(LPD_FILENAME, LPD_PRTITLE, sizeof(LPD_FILENAME));
+             strlcpy(LPD_PRTITLE, "\0", sizeof(LPD_PRTITLE));
+           }
+ 	}
+ 	/*-------------------- JD */
+ 
  	switch (format) {
  	case 'p':	/* print file using 'pr' */
  		if (pp->filters[LPF_INPUT] == NULL) {	/* use output filter */
***************
*** 785,790 ****
--- 839,853 ----
  	av[n++] = "-h";
  	av[n++] = origin_host;
  	av[n++] = pp->acct_file;
+ 	/* added 20 Feb 2003, 21 Apr 2003, May 13 2004 - JD */
+ 	unsetenv(LPD_FILENAME_VAR); errno = 0;
+ 	if (setenv(LPD_FILENAME_VAR, LPD_FILENAME_VALUE, 1) != 0) { 
+           if (errno == ENOMEM)
+ 	    syslog(LOG_ERR, "Not enough memory to set LPD_FILENAME environment variable");
+ 	  else
+ 	    syslog(LOG_ERR, "Unknown setenv error attempting to set LPD_FILENAME environment variable");
+ 	}
+ 	/*  JD  */
  	av[n] = 0;
  	fo = pfd;
  	if (of_pid > 0) {		/* stop output filter */
***************
*** 949,954 ****
--- 1012,1065 ----
  					break;
  				dfcopies++;
  			}
+ 
+ 			/*
+ 			 * Reset pointer to config file, parse cf for filename
+ 			 *
+ 			 * Also keep a secondary copy of Jobname and/or Title 
+ 			 * in case fileName is missing, in which case LPD_FILENAME
+ 			 * will be set to (non-null) pr TITLE, if "-p -T ..." is 
+ 			 * included with lpr command when printing, say,
+ 			 * a MANual page piped to LPR
+ 			 *
+ 			 * Reset pointer again to where it was before we got here
+ 			 *
+ 			 * JD 06 March 2003, 30 April 2003, 22 May 2004
+ 			 *
+ 			 */
+ 			origfpos = ftell(cfp); /* get previous file position */
+ 			fseek(cfp, 0L, 0);     /* set file position to beginning of file */
+ 			strlcpy(LPD_FILENAME, "undefined\0", sizeof(LPD_FILENAME)); /* init var */
+ 			strlcpy(LPD_PRTITLE, "\0", sizeof(LPD_PRTITLE));
+ 			while (getline(cfp)){
+ 			  switch (line[0]){
+ 		            case 'N':
+ 				if (line[1] != '\0') {
+ 				  strlcpy(LPD_FILENAME, line + 1, sizeof(LPD_FILENAME));
+ 		    		  if (strncmp(LPD_FILENAME, " ", sizeof(LPD_FILENAME)) == 0)
+ 		         	     strlcpy(LPD_FILENAME, "undefined\0", sizeof(LPD_FILENAME));
+ 				}
+ 		                continue;
+ 		            case 'T':
+ 			        if (line[1] != '\0') {
+ 		                   strlcpy(LPD_PRTITLE, line + 1, sizeof(LPD_PRTITLE));
+ 		                }
+ 				continue;
+ 			    default: continue;
+ 			}}
+ 			fseek(cfp, origfpos, 0);  /* reset file pointer */
+ 			/*
+ 			   if no filename in cfg file, "steal" filename from 'pr' TITLE
+ 			   if it is non-null/empty
+ 		        */
+ 			if (strncmp(LPD_FILENAME, "undefined", sizeof(LPD_FILENAME)) == 0) {
+ 			  if (LPD_PRTITLE[1] != '\0') {
+ 			    strlcpy(LPD_FILENAME, LPD_PRTITLE, sizeof(LPD_FILENAME));
+                             strlcpy(LPD_PRTITLE, "\0", sizeof(LPD_PRTITLE));
+ 		          }
+ 			}
+ 			/*-------------------- JD */
+ 
  			switch (sendfile(pp, '\3', last+1, *last, dfcopies)) {
  			case OK:
  				if (i)
***************
*** 1065,1070 ****
--- 1176,1190 ----
  			av[++narg] = origin_host;
  			av[++narg] = pp->acct_file;
  			av[++narg] = NULL;
+                         /* added 21 Feb 2004, May 14 2004 - JD */
+                         unsetenv(LPD_FILENAME_VAR); errno = 0;
+                         if (setenv(LPD_FILENAME_VAR, LPD_FILENAME_VALUE, 1) != 0) {
+                           if (errno == ENOMEM)
+                             syslog(LOG_ERR, "Not enough memory to set LPD_FILENAME environment variable");
+                           else
+                             syslog(LOG_ERR, "Unknown setenv error attempting to set LPD_FILENAME environment variable");
+                        }
+                        /*  JD  */
  		} else if (pp->filters[LPF_OUTPUT]) {
  			filtcmd = pp->filters[LPF_OUTPUT];
  			av[0] = filtcmd;
Comment 9 Garance A Drosehn freebsd_committer freebsd_triage 2004-05-22 09:38:25 UTC
I just thought I would note that I do plan to get back to this PR, as 
soon as I catch up with a few other side-projects that I am in the 
middle of...  Sorry for the delays!

-- 
Garance Alistair Drosehn     =      gad@gilead.netel.rpi.edu
Senior Systems Programmer               or   gad@FreeBSD.org
Rensselaer Polytechnic Institute;             Troy, NY;  USA
Comment 10 Mark Linimon freebsd_committer freebsd_triage 2005-10-24 00:50:31 UTC
State Changed
From-To: open->analyzed

Mark as 'analyzed' because it has been at least looked at.
Comment 11 Eitan Adler freebsd_committer freebsd_triage 2018-05-28 19:47:49 UTC
batch change:

For bugs that match the following
-  Status Is In progress 
AND
- Untouched since 2018-01-01.
AND
- Affects Base System OR Documentation

DO:

Reset to open status.


Note:
I did a quick pass but if you are getting this email it might be worthwhile to double check to see if this bug ought to be closed.
Comment 12 Graham Perrin freebsd_committer freebsd_triage 2022-10-17 12:39:20 UTC
Keyword: 

    patch
or  patch-ready

– in lieu of summary line prefix: 

    [patch]

* bulk change for the keyword
* summary lines may be edited manually (not in bulk). 

Keyword descriptions and search interface: 

    <https://bugs.freebsd.org/bugzilla/describekeywords.cgi>