Subject: papd and LPRng ... not working ...

From: "Michael Rothwell" <[email-masked]>
Date: Tue, 1 Jul 1997 13:38:03 -0400

Hello, everyone!

I like netatalk. It's much better then NT.

HOWEVER,

I'm having a problem getting my Netatalk 1.4b2 installation on Linux 2.0.29
(Slackware 3.2 + patches) using LPRng. I keep getting the following
message:

Jul  1 13:26:21 earth papd[2061]: lp_conn_unix connect /dev/printer:
Connection refused
Jul  1 13:26:21 earth papd[2061]: lp_print: lp_conn_unix: Connection
refused 

Great. Fine. But I never refer to /dev/printer anywhere, at all, on my
system. It's /dev/lp1. Samba prints fine, catting PS files to /dev/lp1
works, cat xxx.ps | lpr works... but papd doesn't work.

Anyone got any suggestions?

Michael Rothwell
Director
Network Services Department
CyberGrafx
[email-masked]
Voice: (919) 851-7777
Fax  : (919) 851-6767
http://www.cybergrafx.com/

---

From: "Jonathan I. Kamens" <[email-masked]>
Date: Tue, 1 Jul 1997 17:49:01 -0400

LPRng doesn't queue the same was BSD LPR does.  I modified netatalk to
use support LPRng by using "lpr" to queue jobs rather than trying to
insert them directly into the queue directory.  I submitted my patches
(against netatalk-1.4b2) to the folks who maintain netatalk, but I
don't know if they've integrated them into the current beta release.
If not, I suppose it's because either (a) they're very busy working on
other functionality, or (b) we had some philosophical differences over
how I implemented my changes, so they decided they wanted to do it
differently, but haven't gotten around to it.

In any case, I've appended the patch below.  Apply it to
etc/papd/lp.c, and then define LPRNG when compiling papd (perhaps in
sys/linux/Makefile), and you should be all set.

  jik

--- lp.c	1997/04/08 02:22:50	1.1
+++ lp.c	1997/07/01 21:47:21
@@ -64,6 +64,15 @@
 #include <netdb.h>
 #include <fcntl.h>
 
+#ifdef LPRNG
+#include <sys/wait.h>
+#include <signal.h>
+
+#ifndef LPR
+#define LPR "/usr/bin/lpr"
+#endif
+#endif /* LPRNG */
+
 #include "printer.h"
 #include "file.h"
 
@@ -167,9 +176,11 @@
 lp_init( out )
     struct papfile	*out;
 {
+#ifndef LPRNG
     int		fd, n, len;
     char	*cp, buf[ BUFSIZ ];
     struct stat	st;
+#endif
 #ifdef ABS_PRINT
     char	cost[ 22 ];
     char	balance[ 22 ];
@@ -207,6 +218,7 @@
     lp.lp_letter = 'A';
 
     if ( printer->p_flags & P_SPOOLED ) {
+#ifndef LPRNG
 	/* check if queuing is enabled: mode & 010 on lock file */
 	if ( stat( printer->p_lock, &st ) < 0 ) {
 	    syslog( LOG_ERR, "lp_init: %s: %m", printer->p_lock );
@@ -252,6 +264,7 @@
 	lseek( fd, 0L, 0 );
 	write( fd, buf, strlen( buf ));
 	close( fd );
+#endif
     } else {
 	lp.lp_flags |= LP_PIPE;
 	lp.lp_seq = getpid();
@@ -283,9 +296,19 @@
 	    return( -1 );
 	}
     } else {
+#ifdef LPRNG
+	sprintf( name, "%spapd.%d%c", _PATH_VARTMP, getpid(), lp.lp_letter++ );
+#else
 	sprintf( name, "df%c%03d%s", lp.lp_letter++, lp.lp_seq, hostname );
+#endif
 
-	if (( fd = open( name, O_WRONLY|O_CREAT|O_EXCL, 0660 )) < 0 ) {
+	if (( fd = open( name, O_WRONLY|O_CREAT|O_EXCL,
+#ifdef LPRNG
+			 0600
+#else
+			 0660
+#endif
+			 )) < 0 ) {
 	    syslog( LOG_ERR, "lp_open %s: %m", name );
 	    spoolerror( out, NULL );
 	    return( -1 );
@@ -340,8 +363,13 @@
 	lp_close();
     }
 
+    
     for ( letter = 'A'; letter < lp.lp_letter; letter++ ) {
+#ifdef LPRNG
+	sprintf( name, "%spapd.%d%c", _PATH_VARTMP, getpid(), letter );
+#else
 	sprintf( name, "df%c%03d%s", letter, lp.lp_seq, hostname );
+#endif
 	if ( unlink( name ) < 0 ) {
 	    syslog( LOG_ERR, "lp_cancel unlink %s: %m", name );
 	}
@@ -371,6 +399,73 @@
     lp_close();
 
     if ( printer->p_flags & P_SPOOLED ) {
+	char *job, *person;
+#ifdef LPRNG
+	char **argv, **ptr, **fileptr;
+	pid_t pid;
+#endif
+
+	job = (lp.lp_job && *lp.lp_job) ? lp.lp_job : "Mac Job";
+	person = lp.lp_person ? lp.lp_person : printer->p_operator;
+
+#ifdef LPRNG
+	if (! ((ptr = argv = (char **) malloc(sizeof(*argv) *
+					      (6 + (lp.lp_letter - 'A')))) &&
+	       (*ptr++ = (char *) malloc(sizeof("lpr"))) &&
+	       (*ptr++ = (char *) malloc(strlen(printer->p_printer) + 3)) &&/* -P */
+	       (*ptr++ = (char *) malloc(strlen(job) + 3)) &&		    /* -J */
+	       (*ptr++ = (char *) malloc(strlen(job) + 3)) &&		    /* -T */
+	       (*ptr++ = (char *) malloc(strlen(person) + 3)))) {	    /* -U */
+	    syslog( LOG_ERR, "malloc: %m" );
+	    exit( 1 );
+	}
+
+	for ( letter = 'A'; letter < lp.lp_letter; letter++ ) {
+	    if (! (*ptr++ = (char *) malloc( strlen(_PATH_VARTMP) + 20 ))) {
+		syslog( LOG_ERR, "malloc: %m" );
+		exit( 1 );
+	    }
+	}
+
+	ptr = argv;
+
+	(void) sprintf( *ptr++, "lpr" );
+	(void) sprintf( *ptr++, "-P%s", printer->p_printer );
+	(void) sprintf( *ptr++, "-J%s", job );
+	(void) sprintf( *ptr++, "-T%s", job );
+	(void) sprintf( *ptr++, "-U%s", person );
+
+	fileptr = ptr;
+
+	for ( letter = 'A'; letter < lp.lp_letter; letter++ )
+	  (void) sprintf( *ptr++, "%spapd.%d%c", _PATH_VARTMP, getpid(), letter );
+
+	*ptr = NULL;
+
+	signal( SIGCHLD, SIG_DFL );
+
+	switch (( pid = fork() )) {
+	case 0:
+	  (void) execv( LPR, argv );
+	  syslog( LOG_ERR, "execvp(%s): %m", LPR );
+	  exit( 1 );
+	case -1:
+	  syslog( LOG_ERR, "fork: %m" );
+	  exit( 1 );
+	default: {
+	      int status;
+
+	      pid = waitpid( pid, &status, 0 );
+	      if ( WIFEXITED(status) && WEXITSTATUS(status) )
+		  syslog( LOG_ERR, "lp_print: child exited with status %d",
+			  WEXITSTATUS(status) );
+	      while ( *fileptr )
+		  (void) unlink( *fileptr++ );
+	      for ( ptr = argv; *ptr; ptr++ )
+		  (void) free( *ptr );
+	  }
+	}
+#else
 	sprintf( tfname, "tfA%03d%s", lp.lp_seq, hostname );
 	if (( fd = open( tfname, O_WRONLY|O_EXCL|O_CREAT, 0660 )) < 0 ) {
 	    syslog( LOG_ERR, "lp_print %s: %m", tfname );
@@ -382,38 +477,21 @@
 	}
 	fprintf( cfile, "H%s\n", hostname );	/* XXX lp_host? */
 
-	if ( lp.lp_person ) {
-	    fprintf( cfile, "P%s\n", lp.lp_person );
-	} else {
-	    fprintf( cfile, "P%s\n", printer->p_operator );
-	}
+	fprintf( cfile, "P%s\n", person );
 
-	if ( lp.lp_job && *lp.lp_job ) {
-	    fprintf( cfile, "J%s\n", lp.lp_job );
-	    fprintf( cfile, "T%s\n", lp.lp_job );
-	} else {
-	    fprintf( cfile, "JMac Job\n" );
-	    fprintf( cfile, "TMac Job\n" );
-	}
+	fprintf( cfile, "J%s\n", job );
+	fprintf( cfile, "T%s\n", job );
 
 	fprintf( cfile, "C%s\n", hostname );	/* XXX lp_host? */
 
-	if ( lp.lp_person ) {
-	    fprintf( cfile, "L%s\n", lp.lp_person );
-	} else {
-	    fprintf( cfile, "L%s\n", printer->p_operator );
-	}
+	fprintf( cfile, "L%s\n", person );
 
 	for ( letter = 'A'; letter < lp.lp_letter; letter++ ) {
 	    fprintf( cfile, "fdf%c%03d%s\n", letter, lp.lp_seq, hostname );
 	    fprintf( cfile, "Udf%c%03d%s\n", letter, lp.lp_seq, hostname );
 	}
 
-	if ( lp.lp_job && *lp.lp_job ) {
-	    fprintf( cfile, "N%s\n", lp.lp_job );
-	} else {
-	    fprintf( cfile, "NMac Job\n" );
-	}
+	fprintf( cfile, "N%s\n", job );
 	fclose( cfile );
 
 	sprintf( cfname, "cfA%03d%s", lp.lp_seq, hostname );
@@ -446,6 +524,7 @@
 	    syslog( LOG_ERR, "lp_print lpd said %c: %m", buf[ 0 ] );
 	    return;
 	}
+#endif
     }
     syslog( LOG_INFO, "lp_print queued" );
     return;
@@ -530,6 +609,9 @@
 lp_rmjob( job )
     int		job;
 {
+#ifdef LPRNG
+    return( -1 );
+#else
     char	buf[ 1024 ];
     int		n, s;
 
@@ -555,6 +637,7 @@
 
     lp_disconn_inet( s );
     return( 0 );
+#endif
 }
 
 char	*kw_rank = "Rank";
@@ -570,6 +653,9 @@
 lp_queue( out )
     struct papfile	*out;
 {
+#ifdef LPRNG
+    return( -1 );
+#else
     char			buf[ 1024 ], *start, *stop, *p, *q;
     static struct papfile	pf;
     int				n, len, s;
@@ -714,4 +800,5 @@
 	    return( 0 );
 	}
     }
+#endif
 }

---

From: Edan Idzerda <[email-masked]>
Date: Wed, 2 Jul 1997 11:22:50 -0400 (EDT)

> insert them directly into the queue directory.  I submitted my patches

Err, I didn't look closely at your code to see if it would work 
better, but you can already do

	:pr=|lpr:

To get papd to use lpr instead of queueing directly.  This appears
to be the The One Truth I Know About Netatalk Printing.

- edan

--
Edan Idzerda	<[email-masked]>
System Administrator --  Michigan Technological University, Houghton MI USA

---

From: "Jonathan I. Kamens" <[email-masked]>
Date: Wed, 2 Jul 1997 11:34:06 -0400

>  Date: Wed, 2 Jul 1997 11:22:50 -0400 (EDT)
>  From: Edan Idzerda <[email-masked]>
>  
>  To get papd to use lpr instead of queueing directly.

Yes, I know you can do that, and yes, my code "would work better" than
that.  Read the patch.

  jik