2 * Copyright (c) 1990,1995 Regents of The University of Michigan.
3 * All Rights Reserved. See COPYRIGHT.
10 #include <sys/param.h>
11 #include <sys/types.h>
14 #if defined( sun ) && defined( __svr4__ )
15 #include </usr/ucbinclude/sys/file.h>
19 #include <sys/socket.h>
20 #include <sys/syslog.h>
32 #include <netatalk/endian.h>
33 #include <netatalk/at.h>
34 #include <atalk/compat.h>
35 #include <atalk/atp.h>
36 #include <atalk/pap.h>
37 #include <atalk/paths.h>
38 #include <atalk/util.h>
39 #include <atalk/nbp.h>
46 #define _PATH_PAPDPPDFILE ".ppd"
48 #define PIPED_STATUS "status: print spooler processing job"
50 struct printer defprinter;
51 struct printer *printers = NULL;
54 char *conffile = _PATH_PAPDCONF;
55 char *printcap = _PATH_PAPDPRINTCAP;
56 unsigned char connid, quantum, sock, oquantum = PAP_MAXQUANTUM;
57 char *cannedstatus = PIPED_STATUS;
58 struct printer *printer = NULL;
59 char *version = VERSION;
60 static char *pidfile = _PATH_PAPDLOCK;
63 char *uampath = _PATH_PAPDUAMPATH;
65 /* Prototypes for locally used functions */
66 int getstatus( struct printer *pr, char *buf );
67 int rprintcap( struct printer *pr );
68 void getprinters( char *cf );
71 /* this only needs to be used by the server process */
72 static void papd_exit(const int i)
74 server_unlock(pidfile);
79 #if !defined( ibm032 ) && !defined( _IBMR2 )
88 memset(&addr, 0, sizeof(addr));
90 for ( pr = printers; pr; pr = pr->p_next ) {
91 if ( pr->p_flags & P_REGISTERED ) {
92 if ( nbp_unrgstr( pr->p_name, pr->p_type, pr->p_zone, &addr ) < 0 ) {
93 syslog( LOG_ERR, "can't unregister %s:%s@%s\n", pr->p_name,
94 pr->p_type, pr->p_zone );
97 syslog( LOG_ERR, "unregister %s:%s@%s\n", pr->p_name, pr->p_type,
104 #if !defined( ibm032 ) && !defined( _IBMR2 )
112 while (( pid = wait3( &status, WNOHANG, 0 )) > 0 ) {
113 if ( WIFEXITED( status )) {
114 if ( WEXITSTATUS( status )) {
115 syslog( LOG_ERR, "child %d exited with %d", pid,
116 WEXITSTATUS( status ));
118 syslog( LOG_INFO, "child %d done", pid );
121 if ( WIFSIGNALED( status )) {
122 syslog( LOG_ERR, "child %d killed with %d", pid,
125 syslog( LOG_ERR, "child %d died", pid );
132 char rbuf[ 255 + 1 + 8 ];
142 struct atp_block atpb;
143 struct sockaddr_at sat;
148 char *p, hostname[ MAXHOSTNAMELEN ];
152 if ( gethostname( hostname, sizeof( hostname )) < 0 ) {
153 perror( "gethostname" );
156 if (( p = strchr( hostname, '.' )) != 0 ) {
159 if (( defprinter.p_name = (char *)malloc( strlen( hostname ) + 1 ))
164 strcpy( defprinter.p_name, hostname );
165 defprinter.p_type = "LaserWriter";
166 defprinter.p_zone = "*";
167 memset(&defprinter.p_addr, 0, sizeof(defprinter.p_addr));
168 defprinter.p_ppdfile = _PATH_PAPDPPDFILE;
170 defprinter.p_flags = P_PIPED;
171 defprinter.p_printer = "/usr/bin/lp -T PS";
173 defprinter.p_flags = P_SPOOLED;
174 defprinter.p_printer = "lp";
176 defprinter.p_operator = "operator";
177 defprinter.p_spool = _PATH_PAPDSPOOLDIR;
179 defprinter.p_role = NULL;
180 defprinter.p_srvid = 0;
182 defprinter.p_pagecost = 200; /* default cost */
183 defprinter.p_pagecost_msg = NULL;
184 defprinter.p_lock = "lock";
186 while (( c = getopt( ac, av, "adf:p:P:" )) != EOF ) {
188 case 'a' : /* for compatibility with old papd */
191 case 'd' : /* debug */
195 case 'f' : /* conffile */
199 case 'p' : /* printcap */
209 "Usage:\t%s [ -d ] [ -f conffile ] [ -p printcap ]\n",
215 getprinters( conffile );
217 switch (server_lock("papd", pidfile, debug)) {
218 case 0: /* open a couple things again in the child */
219 if ((c = open("/", O_RDONLY)) >= 0) {
233 if (( p = strrchr( av[ 0 ], '/' )) == NULL ) {
239 openlog( p, LOG_PID );
241 openlog( p, LOG_NDELAY|LOG_PID, LOG_LPR );
244 syslog( LOG_INFO, "restart (%s)", version );
246 for ( pr = printers; pr; pr = pr->p_next ) {
247 if (( pr->p_flags & P_SPOOLED ) && rprintcap( pr ) < 0 ) {
248 syslog( LOG_ERR, "printcap problem: %s", pr->p_printer );
250 if (( pr->p_atp = atp_open( ATADDR_ANYPORT, &pr->p_addr )) == NULL ) {
251 syslog( LOG_ERR, "atp_open: %m" );
254 if ( nbp_rgstr( atp_sockaddr( pr->p_atp ), pr->p_name, pr->p_type,
256 syslog( LOG_ERR, "can't register %s:%s@%s", pr->p_name, pr->p_type,
260 if ( pr->p_flags & P_AUTH ) {
261 syslog( LOG_INFO, "Authentication enabled: %s", pr->p_name );
264 syslog( LOG_INFO, "Authentication disabled: %s", pr->p_name );
266 syslog( LOG_INFO, "register %s:%s@%s", pr->p_name, pr->p_type,
268 pr->p_flags |= P_REGISTERED;
271 memset(&sv, 0, sizeof(sv));
273 sigemptyset( &sv.sa_mask );
274 sv.sa_flags = SA_RESTART;
275 if ( sigaction( SIGTERM, &sv, 0 ) < 0 ) {
276 syslog( LOG_ERR, "sigaction: %m" );
280 sv.sa_handler = reap;
281 sigemptyset( &sv.sa_mask );
282 sv.sa_flags = SA_RESTART;
283 if ( sigaction( SIGCHLD, &sv, 0 ) < 0 ) {
284 syslog( LOG_ERR, "sigaction: %m" );
291 auth_load(uampath, uamlist);
294 * Begin accepting connections.
298 for ( pr = printers; pr; pr = pr->p_next ) {
299 FD_SET( atp_fileno( pr->p_atp ), &fdset );
301 if (( c = select( FD_SETSIZE, &fdset, 0, 0, 0 )) < 0 ) {
302 if ( errno == EINTR ) {
305 syslog( LOG_ERR, "select: %m" );
309 for ( pr = printers; pr; pr = pr->p_next ) {
310 if ( FD_ISSET( atp_fileno( pr->p_atp ), &fdset )) {
313 bzero( &sat, sizeof( struct sockaddr_at ));
315 sat.sat_len = sizeof( struct sockaddr_at );
317 sat.sat_family = AF_APPLETALK;
318 sat.sat_addr.s_net = ATADDR_ANYNET;
319 sat.sat_addr.s_node = ATADDR_ANYNODE;
320 sat.sat_port = ATADDR_ANYPORT;
321 /* do an atp_rsel(), to prevent hangs */
322 if (( c = atp_rsel( pr->p_atp, &sat, ATP_TREQ )) != ATP_TREQ ) {
325 atpb.atp_saddr = &sat;
326 atpb.atp_rreqdata = cbuf;
327 atpb.atp_rreqdlen = sizeof( cbuf );
328 if ( atp_rreq( pr->p_atp, &atpb ) < 0 ) {
329 syslog( LOG_ERR, "atp_rreq: %m" );
333 /* should check length of req buf */
335 switch( cbuf[ 1 ] ) {
337 connid = (unsigned char)cbuf[ 0 ];
338 sock = (unsigned char)cbuf[ 4 ];
339 quantum = (unsigned char)cbuf[ 5 ];
340 rbuf[ 0 ] = cbuf[ 0 ];
341 rbuf[ 1 ] = PAP_OPENREPLY;
342 rbuf[ 2 ] = rbuf[ 3 ] = 0;
344 if (( pr->p_flags & P_SPOOLED ) && rprintcap( pr ) != 0 ) {
345 syslog( LOG_ERR, "printcap problem: %s",
347 rbuf[ 2 ] = rbuf[ 3 ] = 0xff;
352 * If this fails, we've run out of sockets. Rather than
353 * just die(), let's try to continue. Maybe some sockets
354 * will close, and we can continue;
356 if (( atp = atp_open( ATADDR_ANYPORT,
357 &pr->p_addr)) == NULL ) {
358 syslog( LOG_ERR, "atp_open: %m" );
359 rbuf[ 2 ] = rbuf[ 3 ] = 0xff;
362 rbuf[ 4 ] = atp_sockaddr( atp )->sat_port;
363 rbuf[ 5 ] = oquantum;
364 rbuf[ 6 ] = rbuf[ 7 ] = 0;
367 iov.iov_len = 8 + getstatus( pr, &rbuf[ 8 ] );
368 atpb.atp_sresiov = &iov;
369 atpb.atp_sresiovcnt = 1;
371 * This may error out if we lose a route, so we won't die().
373 if ( atp_sresp( pr->p_atp, &atpb ) < 0 ) {
374 syslog( LOG_ERR, "atp_sresp: %m" );
382 switch ( c = fork()) {
384 syslog( LOG_ERR, "fork: %m" );
390 if (( printer->p_flags & P_SPOOLED ) &&
391 chdir( printer->p_spool ) < 0 ) {
392 syslog( LOG_ERR, "chdir %s: %m", printer->p_spool );
396 sv.sa_handler = SIG_DFL;
397 sigemptyset( &sv.sa_mask );
398 sv.sa_flags = SA_RESTART;
399 if ( sigaction( SIGTERM, &sv, 0 ) < 0 ) {
400 syslog( LOG_ERR, "sigaction: %m" );
404 for ( pr = printers; pr; pr = pr->p_next ) {
405 atp_close( pr->p_atp );
408 if ( session( atp, &sat ) < 0 ) {
409 syslog( LOG_ERR, "bad session" );
415 default : /* parent */
416 syslog( LOG_INFO, "child %d for \"%s\" from %u.%u",
417 c, pr->p_name, ntohs( sat.sat_addr.s_net ),
418 sat.sat_addr.s_node);
423 case PAP_SENDSTATUS :
425 rbuf[ 1 ] = PAP_STATUS;
426 rbuf[ 2 ] = rbuf[ 3 ] = 0;
427 rbuf[ 4 ] = rbuf[ 5 ] = 0;
428 rbuf[ 6 ] = rbuf[ 7 ] = 0;
431 iov.iov_len = 8 + getstatus( pr, &rbuf[ 8 ] );
432 atpb.atp_sresiov = &iov;
433 atpb.atp_sresiovcnt = 1;
435 * This may error out if we lose a route, so we won't die().
437 if ( atp_sresp( pr->p_atp, &atpb ) < 0 ) {
438 syslog( LOG_ERR, "atp_sresp: %m" );
443 syslog( LOG_ERR, "Bad request from %u.%u!",
444 ntohs( sat.sat_addr.s_net ), sat.sat_addr.s_node );
451 * Sometimes the child process will send its first READ
452 * before the parent has sent the OPEN REPLY. Moving this
453 * code into the OPEN/STATUS switch fixes this problem.
456 iov.iov_len = 8 + getstatus( pr, &rbuf[ 8 ] );
457 atpb.atp_sresiov = &iov;
458 atpb.atp_sresiovcnt = 1;
460 * This may error out if we lose a route, so we won't die().
462 if ( atp_sresp( pr->p_atp, &atpb ) < 0 ) {
463 syslog( LOG_ERR, "atp_sresp: %m" );
473 * We assume buf is big enough for 255 bytes of data and a length byte.
476 int getstatus( pr, buf )
480 char path[ MAXPATHLEN ];
483 if ( pr->p_flags & P_SPOOLED && ( pr->p_spool != NULL )) {
484 strcpy( path, pr->p_spool );
485 strcat( path, "/status" );
486 fd = open( path, O_RDONLY);
489 if (( pr->p_flags & P_PIPED ) || ( fd < 0 )) {
490 *buf = strlen( cannedstatus );
491 strncpy( &buf[ 1 ], cannedstatus, *buf );
494 if (( rc = read( fd, &buf[ 1 ], 255 )) < 0 ) {
498 if ( rc && buf[ rc ] == '\n' ) { /* remove trailing newline */
509 void getprinters( cf )
512 char buf[ 1024 ], area[ 1024 ], *a, *p, *name, *type, *zone;
516 while (( c = getprent( cf, buf )) > 0 ) {
519 * Get the printer's nbp name.
521 if (( p = getpname( &a )) == NULL ) {
522 fprintf( stderr, "No printer name\n" );
526 if (( pr = (struct printer *)malloc( sizeof( struct printer )))
531 bzero( pr, sizeof( struct printer ));
533 name = defprinter.p_name;
534 type = defprinter.p_type;
535 zone = defprinter.p_zone;
536 if ( nbp_name( p, &name, &type, &zone )) {
537 fprintf( stderr, "Can't parse \"%s\"\n", name );
540 if ( name != defprinter.p_name ) {
541 if (( pr->p_name = (char *)malloc( strlen( name ) + 1 )) == NULL ) {
545 strcpy( pr->p_name, name );
549 if ( type != defprinter.p_type ) {
550 if (( pr->p_type = (char *)malloc( strlen( type ) + 1 )) == NULL ) {
554 strcpy( pr->p_type, type );
558 if ( zone != defprinter.p_zone ) {
559 if (( pr->p_zone = (char *)malloc( strlen( zone ) + 1 )) == NULL ) {
563 strcpy( pr->p_zone, zone );
568 if ( pnchktc( cf ) != 1 ) {
569 fprintf( stderr, "Bad papcap entry\n" );
576 if (( p = pgetstr( "pd", &a )) == NULL ) {
577 pr->p_ppdfile = defprinter.p_ppdfile;
579 if (( pr->p_ppdfile = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
583 strcpy( pr->p_ppdfile, p );
587 * Get lpd printer name.
589 if (( p = pgetstr( "pr", &a )) == NULL ) {
590 pr->p_printer = defprinter.p_printer;
591 pr->p_flags = defprinter.p_flags;
595 pr->p_flags = P_PIPED;
597 pr->p_flags = P_SPOOLED;
599 if (( pr->p_printer = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
603 strcpy( pr->p_printer, p );
607 * Do we want authenticated printing?
609 if ((p = pgetstr( "ca", &a )) != NULL ) {
610 if ((pr->p_authprintdir = (char *)malloc(strlen(p)+1)) == NULL) {
614 strcpy( pr->p_authprintdir, p );
615 pr->p_flags |= P_AUTH;
616 pr->p_flags |= P_AUTH_CAP;
617 } else { pr->p_authprintdir = NULL; }
619 if ( pgetflag( "sp" ) == 1 ) {
620 pr->p_flags |= P_AUTH;
621 pr->p_flags |= P_AUTH_PSSP;
624 if ((p = pgetstr("am", &a)) != NULL ) {
625 if ((uamlist = (char *)malloc(strlen(p)+1)) == NULL ) {
632 if ( pr->p_flags & P_SPOOLED ) {
636 if (( p = pgetstr( "op", &a )) == NULL ) {
637 pr->p_operator = defprinter.p_operator;
639 if (( pr->p_operator = (char *)malloc( strlen( p ) + 1 ))
644 strcpy( pr->p_operator, p );
648 /* get printer's appletalk address. */
649 if (( p = pgetstr( "pa", &a )) == NULL )
650 memcpy(&pr->p_addr, &defprinter.p_addr, sizeof(pr->p_addr));
652 atalk_aton(p, &pr->p_addr);
654 pr->p_next = printers;
659 } else { /* No capability file, do default */
660 printers = &defprinter;
667 char buf[ 1024 ], area[ 1024 ], *a, *p;
671 * Spool directory from printcap file.
673 if ( pr->p_flags & P_SPOOLED ) {
674 if ( pgetent( printcap, buf, pr->p_printer ) != 1 ) {
675 syslog( LOG_ERR, "No such printer: %s", pr->p_printer );
682 if ( pr->p_spool != NULL && pr->p_spool != defprinter.p_spool ) {
686 if (( p = pgetstr( "sd", &a )) == NULL ) {
687 pr->p_spool = defprinter.p_spool;
689 if (( pr->p_spool = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
690 syslog( LOG_ERR, "malloc: %m" );
693 strcpy( pr->p_spool, p );
700 if ( pgetstr( "af", &a ) == NULL ) {
701 pr->p_flags &= ~P_ACCOUNT;
703 pr->p_flags |= P_ACCOUNT;
705 if ( pr->p_role != NULL && pr->p_role != defprinter.p_role ) {
709 if (( p = pgetstr( "ro", &a )) == NULL ) {
710 pr->p_role = defprinter.p_role;
713 (char *)malloc( strlen( p ) + 1 )) == NULL ) {
714 syslog( LOG_ERR, "malloc: %m" );
717 strcpy( pr->p_role, p );
720 if (( c = pgetnum( "si" )) < 0 ) {
721 pr->p_srvid = defprinter.p_srvid;
732 if ( pr->p_pagecost_msg != NULL &&
733 pr->p_pagecost_msg != defprinter.p_pagecost_msg ) {
734 free( pr->p_pagecost_msg );
737 if (( p = pgetstr( "pc", &a )) != NULL ) {
738 if (( pr->p_pagecost_msg =
739 (char *)malloc( strlen( p ) + 1 )) == NULL ) {
740 syslog( LOG_ERR, "malloc: %m" );
743 strcpy( pr->p_pagecost_msg, p );
745 } else if ( pr->p_flags & P_ACCOUNT ) {
746 if (( c = pgetnum( "pc" )) < 0 ) {
747 pr->p_pagecost = defprinter.p_pagecost;
751 pr->p_pagecost_msg = NULL;
757 if ( pr->p_lock != NULL && pr->p_lock != defprinter.p_lock ) {
761 if (( p = pgetstr( "lo", &a )) == NULL ) {
762 pr->p_lock = defprinter.p_lock;
764 if (( pr->p_lock = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
765 syslog( LOG_ERR, "malloc: %m" );
768 strcpy( pr->p_lock, p );
773 * Must Kerberos authenticate?
775 if ( pgetflag( "ka" ) == 1 ) {
776 pr->p_flags |= P_KRB;
778 pr->p_flags &= ~P_KRB;