Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Apr 2002 03:21:37 -0400
From:      Garance A Drosihn <drosih@rpi.edu>
To:        freebsd-audit@freebsd.org
Cc:        freebsd-print@bostonradio.org
Subject:   Re: New option 'rc' for 'remote.resendcopies'
Message-ID:  <p05111701b8e9664df7ae@[128.113.24.47]>
In-Reply-To: <p05101574b8b5f34fdfe9@[128.113.24.47]>
References:  <p05101574b8b5f34fdfe9@[128.113.24.47]>

next in thread | previous in thread | raw e-mail | index | archive | help
On 3/14/02, Garance A Drosihn wrote to freebsd-print:
>While many printers support 'lpr protocols', they often do not
>concern themselves with getting some of the details correct.
>In particular, some printers do not pay attention to everything
>in the 'cf' file, and will print the 'df' file exactly one time
>as it is transferred.  This means that if a user requests
>multiple jobs via lpr -#, they will only get one copy.
>
>I was thinking about adding a new boolean option for a printcap
>entry, called 'rs' or 'remote.resendcopies'.  'rc' does not seem
>to be used by netbsd, openbsd, or lprng.  The idea is that lpd
>would handle multiple copies of a file by sending the file to
>the printer multiple times.

Well, after other updates which reorganized the sendfile() routine,
here is the update I plan to commit to implement this new option.
My intent is to commit it to current later this week (after a little
more testing on my own part), and then hopefully MFC it in time to
beat the code freeze for Release 4.6 (ie, May 1st).  This will only
apply to pretty recent versions of lpr, as it depends on the updates
that I MFC'ed just last week.

This is also at:
http://people.freebsd.org/~gad/lpr/lpd-rc-cur.diff

in case my email client garbles it up.


Index: common_source/lp.h
===================================================================
RCS file: /home/ncvs/src/usr.sbin/lpr/common_source/lp.h,v
retrieving revision 1.19
diff -u -r1.19 lp.h
--- common_source/lp.h	15 Jul 2001 00:57:18 -0000	1.19
+++ common_source/lp.h	22 Apr 2002 06:29:00 -0000
@@ -72,6 +72,7 @@
  	long	 page_width;	/* PW: page width */
  	long	 page_pwidth;	/* PX: page width in pixels */
  	long	 page_plength;	/* PY: page length in pixels */
+	long	 resend_copies;	/* RC: resend copies to remote host */
  	char	*restrict_grp;	/* RG: restricted group */
  	char	*remote_host;	/* RM: remote machine name */
  	char	*remote_queue;	/* RP: remote printer name */
Index: common_source/printcap.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/lpr/common_source/printcap.c,v
retrieving revision 1.8
diff -u -r1.8 printcap.c
--- common_source/printcap.c	12 Jun 2001 16:38:16 -0000	1.8
+++ common_source/printcap.c	22 Apr 2002 06:29:00 -0000
@@ -257,6 +257,7 @@
  			    &pp->status_file));
  	CHK(capdb_getaltstr(bp, "tr", "job.trailer", 0, &pp->trailer));

+	pp->resend_copies = capdb_getaltlog(bp, "rc", "remote.resend_copies");
  	pp->restricted = capdb_getaltlog(bp, "rs", "daemon.restricted");
  	pp->short_banner = capdb_getaltlog(bp, "sb", "banner.short");
  	pp->no_copies = capdb_getaltlog(bp, "sc", "job.no_copies");
Index: lpd/printjob.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/lpr/lpd/printjob.c,v
retrieving revision 1.50
diff -u -r1.50 printjob.c
--- lpd/printjob.c	19 Apr 2002 18:46:10 -0000	1.50
+++ lpd/printjob.c	22 Apr 2002 06:29:01 -0000
@@ -146,7 +146,7 @@
  		    int _dlm);
  static char	*scnline(int _key, char *_p, int _c);
  static int	 sendfile(struct printer *_pp, int _type, char *_file,
-		    char _format);
+		    char _format, int _copyreq);
  static int	 sendit(struct printer *_pp, char *_file);
  static void	 sendmail(struct printer *_pp, char *_userid, int _bombed);
  static void	 setty(const struct printer *_pp);
@@ -868,7 +868,7 @@
  static int
  sendit(struct printer *pp, char *file)
  {
-	register int i, err = OK;
+	int dfcopies, err, i;
  	char *cp, last[BUFSIZ];

  	/*
@@ -895,6 +895,7 @@
  	/*
  	 * pass 1
  	 */
+	err = OK;
  	while (getline(cfp)) {
  	again:
  		if (line[0] == 'S') {
@@ -925,11 +926,14 @@
  		} else if (line[0] == 'I') {
  			strlcpy(indent+2, line + 1, sizeof(indent) - 2);
  		} else if (line[0] >= 'a' && line[0] <= 'z') {
+			dfcopies = 1;
  			strcpy(last, line);
-			while ((i = getline(cfp)) != 0)
-				if (strcmp(last, line))
+			while ((i = getline(cfp)) != 0) {
+				if (strcmp(last, line) != 0)
  					break;
-			switch (sendfile(pp, '\3', last+1, *last)) {
+				dfcopies++;
+			}
+			switch (sendfile(pp, '\3', last+1, *last, dfcopies)) {
  			case OK:
  				if (i)
  					goto again;
@@ -945,7 +949,7 @@
  			break;
  		}
  	}
-	if (err == OK && sendfile(pp, '\2', file, '\0') > 0) {
+	if (err == OK && sendfile(pp, '\2', file, '\0', 1) > 0) {
  		(void) fclose(cfp);
  		return(REPRINT);
  	}
@@ -969,13 +973,13 @@
   * Return positive if we should try resending.
   */
  static int
-sendfile(struct printer *pp, int type, char *file, char format)
+sendfile(struct printer *pp, int type, char *file, char format, int copyreq)
  {
  	int i, amt;
  	struct stat stb;
  	char *av[15], *filtcmd;
  	char buf[BUFSIZ], opt_c[4], opt_h[4], opt_n[4];
-	int filtstat, narg, resp, sfd, sfres, sizerr, statrc;
+	int copycnt, filtstat, narg, resp, sfd, sfres, sizerr, statrc;

  	statrc = lstat(file, &stb);
  	if (statrc < 0) {
@@ -1102,7 +1106,15 @@
  		lseek(sfd, 0, SEEK_SET);
  	}

-	(void) sprintf(buf, "%c%qd %s\n", type, stb.st_size, file);
+	copycnt = 0;
+sendagain:
+	copycnt++;
+
+	if (copycnt < 2)
+		(void) sprintf(buf, "%c%qd %s\n", type, stb.st_size, file);
+	else
+		(void) sprintf(buf, "%c%qd %s_c%d\n", type, stb.st_size,
+		    file, copycnt);
  	amt = strlen(buf);
  	for (i = 0;  ; i++) {
  		if (write(pfd, buf, amt) != amt ||
@@ -1121,6 +1133,10 @@
  	}
  	if (i)
  		pstatus(pp, "sending to %s", pp->remote_host);
+	/*
+	 * XXX - we should change trstat_init()/trstat_write() to include
+	 *	 the copycnt in the statistics record it may write.
+	 */
  	if (type == '\3')
  		trstat_init(pp, file, job_dfcnt);
  	for (i = 0; i < stb.st_size; i += BUFSIZ) {
@@ -1146,9 +1162,30 @@
  		sfres = REPRINT;
  		goto return_sfres;
  	}
-	if (type == '\3')
+	if (type == '\3') {
  		trstat_write(pp, TR_SENDING, stb.st_size, logname,
-				 pp->remote_host, origin_host);
+		    pp->remote_host, origin_host);
+		/*
+		 * Usually we only need to send one copy of a datafile,
+		 * because the control-file will simply print the same
+		 * file multiple times.  However, some printers ignore
+		 * the control file, and simply print each data file as
+		 * it arrives.  For such "remote hosts", we need to
+		 * transfer the same data file multiple times.  Such a
+		 * a host is indicated by adding 'rc' to the printcap
+		 * entry.
+		 * XXX - Right now this ONLY works for remote hosts which
+		 *	do ignore the name of the data file, because
+		 *	this sends the file multiple times with slight
+		 *	changes to the filename.  To do this right would
+		 *	require that we also rewrite the control file
+		 *	to match those filenames.
+		 */
+		if (pp->resend_copies && (copycnt < copyreq)) {
+			lseek(sfd, 0, SEEK_SET);
+			goto sendagain;
+		}
+	}
  	sfres = OK;

  return_sfres:
Index: lpr/printcap.5
===================================================================
RCS file: /home/ncvs/src/usr.sbin/lpr/lpr/printcap.5,v
retrieving revision 1.26
diff -u -r1.26 printcap.5
--- lpr/printcap.5	22 Apr 2002 01:09:24 -0000	1.26
+++ lpr/printcap.5	22 Apr 2002 06:29:01 -0000
@@ -109,6 +109,7 @@
  .It "pw	num	132	page width (in characters)"
  .It "px	num	0	page width in pixels (horizontal)"
  .It "py	num	0	page length in pixels (vertical)"
+.It "rc	bool	false	when sending to a remote host, resend 
copies (see below)"
  .It "rf	str" Ta Dv NULL Ta No "filter for printing"
  .Tn FORTRAN
  style text files
@@ -157,6 +158,7 @@
  .It "pw	page.width"
  .It "px	page.pwidth"
  .It "py	page.plength"
+.It "rc	remote.resend_copies"
  .It "rf	filt.fortran"
  .It "rg	daemon.restrictgrp"
  .It "rm	remote.host"
@@ -324,6 +326,24 @@
  will therefore happen before
  .Xr pr 1
  is executed rather than afterwards.
+.Pp
+There are some models of network printers which accept jobs from
+.Xr lpd 8 , but they ignore the control file for a job and simply print
+each data file as it arrives at the printer.
+One side-effect of this behavior is that the printer will ignore any request
+for multiple copies as given with the
+.Fl #
+flag on the
+.Xr lpr 1 command.
+The
+.Cm rc
+entry will cause
+.Xr lpd 8 to resend each data file for each copy that the user
+originally requested.
+Note that the
+.Cm rc
+entry should only be specified on hosts which send jobs directly to
+the printer.
  .Pp
  If
  .Cm lp

-- 
Garance Alistair Drosehn            =   gad@eclipse.acs.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?p05111701b8e9664df7ae>