Bug 7593 - making lpd work with MacOS LaserWriter 8.7 client
Summary: making lpd work with MacOS LaserWriter 8.7 client
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: lpr
Version: 6.1
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Bernhard Rosenkraenzer
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 1999-12-05 05:16 UTC by Jonathan Kamens
Modified: 2008-05-01 15:37 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2000-02-10 14:53:47 UTC
Embargoed:


Attachments (Terms of Use)
new patch for lpr-0.50 (1.68 KB, patch)
2000-02-10 14:45 UTC, Jonathan Kamens
no flags Details | Diff

Description Jonathan Kamens 1999-12-05 05:16:56 UTC
The lpd included in the RedHat "lpr" package cannot accept jobs from
Macintosh computers using the "LaserWriter" extension which supports the
lpr protocol.  There are two problems which prevent it from accepting these
files; one of them is a bug in the LaserWriter extension (which I've
already reported to Apple), and another is a bug in lpd.

The patch below fixes the bug in lpd, introduces a workaround for the bug
in the LaserWriter extension, and fixes an additional bug.  In particular:

1) In lpd.c, set the SO_REUSEADDR socket option on the lpd socket before
binding it, so that it's possible to run lpd immediately after "kill -9"ing
it.  There's really no good reason why any TCP/IP application server
shouldn't set SO_REUSEADDR.  This is the "additional bug" mentioned above.
I discovered it while debugging the other problems.

2) In recvjob.c, detect when we receive a null immediately after receiving
a file from the client, and if that happens, discard it.  This is necessary
because the LPR protocol specifies that the client should send a null
immediately after sending the contents of a control or data file.  I can
only assume that other lpr clients don't bother to send the null (i.e.,
they are not compliant with the RFC), otherwise lpd would have run into
this problem with other clients besides the LaserWriter extension.  In any
case, this change is backward compatible to clients that don't send the
null.

3) In recvjob.c, notice if the client sends the print queue name twice, and
if so, discard the second one.  For some reason, the LaserWriter extension
sends the "receive job" command twice.  I've reported this to Apple as a
bug, but in the meantime, this workaround will make lpd accept jobs despite
the duplicate command.

Only in lpr-0.46.new/lpd: TAGS
diff -ur lpr-0.46/lpd/lpd.c lpr-0.46.new/lpd/lpd.c
--- lpr-0.46/lpd/lpd.c	Fri Oct 22 16:44:35 1999
+++ lpr-0.46.new/lpd/lpd.c	Sat Dec  4 23:27:59 1999
@@ -167,6 +167,10 @@
 	finet = socket(AF_INET, SOCK_STREAM, 0);
 	if (finet >= 0) {
 		struct servent *sp;
+		int val = 1;
+
+		(void) setsockopt(finet, SOL_SOCKET, SO_REUSEADDR, &val,
+				  sizeof(val));

 		if (options & SO_DEBUG)
 			if (setsockopt(finet, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) {
diff -ur lpr-0.46/lpd/recvjob.c lpr-0.46.new/lpd/recvjob.c
--- lpr-0.46/lpd/recvjob.c	Sat Oct 23 01:50:39 1999
+++ lpr-0.46.new/lpd/recvjob.c	Sun Dec  5 00:05:36 1999
@@ -118,6 +118,7 @@
 	struct passwd *user;
 	struct group *lpgrp;
 	FILE *cfile;
+	int gotfile = 0; /* Did we just receive a control or data file? */

 	lpgrp = getgrnam("lp");
 	ack();
@@ -141,12 +142,26 @@
 		} while (*cp++ != '\n' && (cp - line + 1) < sizeof(line));
 		*--cp = '\0';
 		cp = line;
+		if (gotfile && (*cp == '\0')) {
+			/* The protocol says that data files should be
+			   terminated by a null octet. */
+			cp++;
+		}
+		gotfile = 0;
 		switch (*cp++) {
 		case '\1':	/* cleanup because data sent was bad */
 			rcleanup();
 			continue;

 		case '\2':	/* read cf file */
+			if (! strcmp(cp, printer)) {
+			  	/* MacOS LaserWriter 8.7 lpr client
+				   sends the  printer "recvjob" command
+				   twice. */
+				ack();
+				continue;
+			}
+			gotfile = 1;
 			user = getpwnam("lp");
 			size = 0;
 			while (*cp >= '0' && *cp <= '9')
@@ -201,6 +216,7 @@
 			continue;

 		case '\3':	/* read df file */
+			gotfile = 1;
 			size = 0;
 			while (*cp >= '0' && *cp <= '9')
 				size = size * 10 + (*cp++ - '0');

Comment 1 Jonathan Kamens 2000-02-10 14:45:59 UTC
Created attachment 108 [details]
new patch for lpr-0.50

Comment 2 Bernhard Rosenkraenzer 2000-02-10 14:53:59 UTC
Thanks - I've added it to the lpr cvs tree for the next base version (0.51).


Note You need to log in before you can comment on or make changes to this bug.