]> arthur.barton.de Git - netatalk.git/blob - etc/papd/main.c
Warning fixes.
[netatalk.git] / etc / papd / main.c
1 /*
2  * $Id: main.c,v 1.8 2001-07-31 19:50:14 srittau Exp $
3  *
4  * Copyright (c) 1990,1995 Regents of The University of Michigan.
5  * All Rights Reserved.  See COPYRIGHT.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif /* HAVE_CONFIG_H */
11
12 #include <sys/param.h>
13 #include <sys/types.h>
14 #include <sys/time.h>
15 #include <sys/uio.h>
16 #if defined( sun ) && defined( __svr4__ )
17 #include </usr/ucbinclude/sys/file.h>
18 #else /* sun && __svr4__ */
19 #include <sys/file.h>
20 #endif /* sun && __svr4__ */
21 #include <sys/socket.h>
22 #include <sys/syslog.h>
23 #include <sys/wait.h>
24 #include <errno.h>
25
26 #include <string.h>
27 #include <signal.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <netdb.h>
31 #include <fcntl.h>
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif /* HAVE_UNISTD_H */
35
36 #include <netatalk/endian.h>
37 #include <netatalk/at.h>
38 #include <atalk/compat.h>
39 #include <atalk/atp.h>
40 #include <atalk/pap.h>
41 #include <atalk/paths.h>
42 #include <atalk/util.h>
43 #include <atalk/nbp.h>
44
45 #include "printer.h"
46 #include "printcap.h"
47 #include "session.h"
48 #include "uam_auth.h"
49
50 #define _PATH_PAPDPPDFILE       ".ppd"
51
52 #define PIPED_STATUS    "status: print spooler processing job"
53
54 struct printer  defprinter;
55 struct printer  *printers = NULL;
56
57 int             debug = 0;
58 char            *conffile = _PATH_PAPDCONF;
59 char            *printcap = _PATH_PAPDPRINTCAP;
60 unsigned char   connid, quantum, sock, oquantum = PAP_MAXQUANTUM;
61 char            *cannedstatus = PIPED_STATUS;
62 struct printer  *printer = NULL;
63 char            *version = VERSION;
64 static char      *pidfile = _PATH_PAPDLOCK;
65
66 char            *uamlist;
67 char            *uampath = _PATH_PAPDUAMPATH;
68
69 /* Prototypes for locally used functions */
70 int getstatus( struct printer *pr, char *buf );
71 int rprintcap( struct printer *pr );
72 void getprinters( char *cf );
73
74
75 /* this only needs to be used by the server process */
76 static void papd_exit(const int i)
77 {
78   server_unlock(pidfile);
79   auth_unload();
80   exit(i);
81 }
82
83 #if !defined( ibm032 ) && !defined( _IBMR2 )
84     void
85 #endif /* ! ibm032 && ! _IBMR2 */
86 die( n )
87     int                 n;
88 {
89     struct printer      *pr;
90     struct at_addr      addr;
91
92     memset(&addr, 0, sizeof(addr));
93
94     for ( pr = printers; pr; pr = pr->p_next ) {
95         if ( pr->p_flags & P_REGISTERED ) {
96             if ( nbp_unrgstr( pr->p_name, pr->p_type, pr->p_zone, &addr ) < 0 ) {
97                 syslog( LOG_ERR, "can't unregister %s:%s@%s\n", pr->p_name,
98                         pr->p_type, pr->p_zone );
99                 papd_exit( n + 1 );
100             }
101             syslog( LOG_ERR, "unregister %s:%s@%s\n", pr->p_name, pr->p_type,
102                     pr->p_zone );
103         }
104     }
105     papd_exit( n );
106 }
107
108 #if !defined( ibm032 ) && !defined( _IBMR2 )
109     void
110 #endif /* ! ibm032 && ! _IBMR2 */
111 reap()
112 {
113     int         status;
114     int         pid;
115
116     while (( pid = wait3( &status, WNOHANG, 0 )) > 0 ) {
117         if ( WIFEXITED( status )) {
118             if ( WEXITSTATUS( status )) {
119                 syslog( LOG_ERR, "child %d exited with %d", pid,
120                         WEXITSTATUS( status ));
121             } else {
122                 syslog( LOG_INFO, "child %d done", pid );
123             }
124         } else {
125             if ( WIFSIGNALED( status )) {
126                 syslog( LOG_ERR, "child %d killed with %d", pid,
127                         WTERMSIG( status ));
128             } else {
129                 syslog( LOG_ERR, "child %d died", pid );
130             }
131         }
132     }
133     return;
134 }
135
136 char            rbuf[ 255 + 1 + 8 ];
137
138 int main( ac, av )
139     int         ac;
140     char        **av;
141 {
142     extern char         *optarg;
143
144     ATP                 atp;
145     struct atp_block    atpb;
146     struct sockaddr_at  sat;
147     struct sigaction    sv;
148     struct iovec        iov;
149     fd_set              fdset;
150     struct printer      *pr;
151     char                *p, hostname[ MAXHOSTNAMELEN ];
152     char                cbuf[ 8 ];
153     int                 c;
154
155     if ( gethostname( hostname, sizeof( hostname )) < 0 ) {
156         perror( "gethostname" );
157         exit( 1 );
158     }
159     if (( p = strchr( hostname, '.' )) != 0 ) {
160         *p = '\0';
161     }
162     if (( defprinter.p_name = (char *)malloc( strlen( hostname ) + 1 ))
163             == NULL ) {
164         perror( "malloc" );
165         exit( 1 );
166     }
167     strcpy( defprinter.p_name, hostname );
168     defprinter.p_type = "LaserWriter";
169     defprinter.p_zone = "*";
170     memset(&defprinter.p_addr, 0, sizeof(defprinter.p_addr));
171     defprinter.p_ppdfile = _PATH_PAPDPPDFILE;
172 #ifdef __svr4__
173     defprinter.p_flags = P_PIPED;
174     defprinter.p_printer = "/usr/bin/lp -T PS";
175 #else /* __svr4__ */
176     defprinter.p_flags = P_SPOOLED;
177     defprinter.p_printer = "lp";
178 #endif /* __svr4__ */
179     defprinter.p_operator = "operator";
180     defprinter.p_spool = _PATH_PAPDSPOOLDIR;
181 #ifdef ABS_PRINT
182     defprinter.p_role = NULL;
183     defprinter.p_srvid = 0;
184 #endif /* ABS_PRINT */
185     defprinter.p_pagecost = 200;                /* default cost */
186     defprinter.p_pagecost_msg = NULL;
187     defprinter.p_lock = "lock";
188
189     while (( c = getopt( ac, av, "adf:p:P:" )) != EOF ) {
190         switch ( c ) {
191         case 'a' :              /* for compatibility with old papd */
192             break;
193
194         case 'd' :              /* debug */
195             debug++;
196             break;
197
198         case 'f' :              /* conffile */
199             conffile = optarg;
200             break;
201
202         case 'p' :              /* printcap */
203             printcap = optarg;
204             break;
205
206         case 'P' :
207             pidfile = optarg;
208             break;
209
210         default :
211             fprintf( stderr,
212                     "Usage:\t%s [ -d ] [ -f conffile ] [ -p printcap ]\n",
213                     *av );
214             exit( 1 );
215         }
216     }
217
218     getprinters( conffile );
219
220     switch (server_lock("papd", pidfile, debug)) {
221     case 0: /* open a couple things again in the child */
222       if ((c = open("/", O_RDONLY)) >= 0) {
223         dup2(c, 1);
224         dup2(c, 2);
225       }
226       break;
227     case -1:
228       exit(1);
229     default:
230       exit(0);
231     }      
232
233     /*
234      * Start logging.
235      */
236     if (( p = strrchr( av[ 0 ], '/' )) == NULL ) {
237         p = av[ 0 ];
238     } else {
239         p++;
240     }
241 #ifdef ultrix
242     openlog( p, LOG_PID );
243 #else /* ultrix */
244     openlog( p, LOG_NDELAY|LOG_PID, LOG_LPR );
245 #endif /* ultrix */
246
247     syslog( LOG_INFO, "restart (%s)", version );
248
249     for ( pr = printers; pr; pr = pr->p_next ) {
250         if (( pr->p_flags & P_SPOOLED ) && rprintcap( pr ) < 0 ) {
251             syslog( LOG_ERR, "printcap problem: %s", pr->p_printer );
252         }
253         if (( pr->p_atp = atp_open( ATADDR_ANYPORT, &pr->p_addr )) == NULL ) {
254             syslog( LOG_ERR, "atp_open: %m" );
255             papd_exit( 1 );
256         }
257         if ( nbp_rgstr( atp_sockaddr( pr->p_atp ), pr->p_name, pr->p_type,
258                 pr->p_zone ) < 0 ) {
259             syslog( LOG_ERR, "can't register %s:%s@%s", pr->p_name, pr->p_type,
260                     pr->p_zone );
261             die( 1 );
262         }
263         if ( pr->p_flags & P_AUTH ) {
264                 syslog( LOG_INFO, "Authentication enabled: %s", pr->p_name );
265         }
266         else {
267                 syslog( LOG_INFO, "Authentication disabled: %s", pr->p_name );
268         }
269         syslog( LOG_INFO, "register %s:%s@%s", pr->p_name, pr->p_type,
270                 pr->p_zone );
271         pr->p_flags |= P_REGISTERED;
272     }
273
274     memset(&sv, 0, sizeof(sv));
275     sv.sa_handler = die;
276     sigemptyset( &sv.sa_mask );
277     sv.sa_flags = SA_RESTART;
278     if ( sigaction( SIGTERM, &sv, 0 ) < 0 ) {
279         syslog( LOG_ERR, "sigaction: %m" );
280         papd_exit( 1 );
281     }
282
283     sv.sa_handler = reap;
284     sigemptyset( &sv.sa_mask );
285     sv.sa_flags = SA_RESTART;
286     if ( sigaction( SIGCHLD, &sv, 0 ) < 0 ) {
287         syslog( LOG_ERR, "sigaction: %m" );
288         papd_exit( 1 );
289     }
290
291     /*
292      * Load UAMS
293      */
294     auth_load(uampath, uamlist);
295
296     /*
297      * Begin accepting connections.
298      */
299     FD_ZERO( &fdset );
300     for (;;) {
301         for ( pr = printers; pr; pr = pr->p_next ) {
302             FD_SET( atp_fileno( pr->p_atp ), &fdset );
303         }
304         if (( c = select( FD_SETSIZE, &fdset, 0, 0, 0 )) < 0 ) {
305             if ( errno == EINTR ) {
306                 continue;
307             }
308             syslog( LOG_ERR, "select: %m" );
309             papd_exit( 1 );
310         }
311
312         for ( pr = printers; pr; pr = pr->p_next ) {
313             if ( FD_ISSET( atp_fileno( pr->p_atp ), &fdset )) {
314                 int             err = 0;
315
316                 bzero( &sat, sizeof( struct sockaddr_at ));
317 #ifdef BSD4_4
318                 sat.sat_len = sizeof( struct sockaddr_at );
319 #endif /* BSD4_4 */
320                 sat.sat_family = AF_APPLETALK;
321                 sat.sat_addr.s_net = ATADDR_ANYNET;
322                 sat.sat_addr.s_node = ATADDR_ANYNODE;
323                 sat.sat_port = ATADDR_ANYPORT;
324                 /* do an atp_rsel(), to prevent hangs */
325                 if (( c = atp_rsel( pr->p_atp, &sat, ATP_TREQ )) != ATP_TREQ ) {
326                     continue;
327                 }
328                 atpb.atp_saddr = &sat;
329                 atpb.atp_rreqdata = cbuf;
330                 atpb.atp_rreqdlen = sizeof( cbuf );
331                 if ( atp_rreq( pr->p_atp, &atpb ) < 0 ) {
332                     syslog( LOG_ERR, "atp_rreq: %m" );
333                     continue;
334                 }
335
336                 /* should check length of req buf */
337
338                 switch( cbuf[ 1 ] ) {
339                 case PAP_OPEN :
340                     connid = (unsigned char)cbuf[ 0 ];
341                     sock = (unsigned char)cbuf[ 4 ];
342                     quantum = (unsigned char)cbuf[ 5 ];
343                     rbuf[ 0 ] = cbuf[ 0 ];
344                     rbuf[ 1 ] = PAP_OPENREPLY;
345                     rbuf[ 2 ] = rbuf[ 3 ] = 0;
346
347                     if (( pr->p_flags & P_SPOOLED ) && rprintcap( pr ) != 0 ) {
348                         syslog( LOG_ERR, "printcap problem: %s",
349                                 pr->p_printer );
350                         rbuf[ 2 ] = rbuf[ 3 ] = 0xff;
351                         err = 1;
352                     }
353
354                     /*
355                      * If this fails, we've run out of sockets. Rather than
356                      * just die(), let's try to continue. Maybe some sockets
357                      * will close, and we can continue;
358                      */
359                     if (( atp = atp_open( ATADDR_ANYPORT, 
360                                           &pr->p_addr)) == NULL ) {
361                         syslog( LOG_ERR, "atp_open: %m" );
362                         rbuf[ 2 ] = rbuf[ 3 ] = 0xff;
363                         err = 1;
364                     }
365                     rbuf[ 4 ] = atp_sockaddr( atp )->sat_port;
366                     rbuf[ 5 ] = oquantum;
367                     rbuf[ 6 ] = rbuf[ 7 ] = 0;
368
369                     iov.iov_base = rbuf;
370                     iov.iov_len = 8 + getstatus( pr, &rbuf[ 8 ] );
371                     atpb.atp_sresiov = &iov;
372                     atpb.atp_sresiovcnt = 1;
373                     /*
374                      * This may error out if we lose a route, so we won't die().
375                      */
376                     if ( atp_sresp( pr->p_atp, &atpb ) < 0 ) {
377                         syslog( LOG_ERR, "atp_sresp: %m" );
378                         continue;
379                     }
380
381                     if ( err ) {
382                         continue;
383                     }
384
385                     switch ( c = fork()) {
386                     case -1 :
387                         syslog( LOG_ERR, "fork: %m" );
388                         continue;
389
390                     case 0 : /* child */
391                         printer = pr;
392
393                         if (( printer->p_flags & P_SPOOLED ) &&
394                                 chdir( printer->p_spool ) < 0 ) {
395                             syslog( LOG_ERR, "chdir %s: %m", printer->p_spool );
396                             exit( 1 );
397                         }
398
399                         sv.sa_handler = SIG_DFL;
400                         sigemptyset( &sv.sa_mask );
401                         sv.sa_flags = SA_RESTART;
402                         if ( sigaction( SIGTERM, &sv, 0 ) < 0 ) {
403                             syslog( LOG_ERR, "sigaction: %m" );
404                             exit( 1 );
405                         }
406
407                         for ( pr = printers; pr; pr = pr->p_next ) {
408                             atp_close( pr->p_atp );
409                         }
410                         sat.sat_port = sock;
411                         if ( session( atp, &sat ) < 0 ) {
412                             syslog( LOG_ERR, "bad session" );
413                             exit( 1 );
414                         }
415                         exit( 0 );
416                         break;
417
418                     default : /* parent */
419                         syslog( LOG_INFO, "child %d for \"%s\" from %u.%u",
420                                 c, pr->p_name, ntohs( sat.sat_addr.s_net ),
421                                 sat.sat_addr.s_node);
422                         atp_close( atp );
423                     }
424                     break;
425
426                 case PAP_SENDSTATUS :
427                     rbuf[ 0 ] = 0;
428                     rbuf[ 1 ] = PAP_STATUS;
429                     rbuf[ 2 ] = rbuf[ 3 ] = 0;
430                     rbuf[ 4 ] = rbuf[ 5 ] = 0;
431                     rbuf[ 6 ] = rbuf[ 7 ] = 0;
432
433                     iov.iov_base = rbuf;
434                     iov.iov_len = 8 + getstatus( pr, &rbuf[ 8 ] );
435                     atpb.atp_sresiov = &iov;
436                     atpb.atp_sresiovcnt = 1;
437                     /*
438                      * This may error out if we lose a route, so we won't die().
439                      */
440                     if ( atp_sresp( pr->p_atp, &atpb ) < 0 ) {
441                         syslog( LOG_ERR, "atp_sresp: %m" );
442                     }
443                     break;
444
445                 default :
446                     syslog( LOG_ERR, "Bad request from %u.%u!",
447                             ntohs( sat.sat_addr.s_net ), sat.sat_addr.s_node );
448                     continue;
449                     break;
450                 }
451
452 #ifdef notdef
453                 /*
454                  * Sometimes the child process will send its first READ
455                  * before the parent has sent the OPEN REPLY.  Moving this
456                  * code into the OPEN/STATUS switch fixes this problem.
457                  */
458                 iov.iov_base = rbuf;
459                 iov.iov_len = 8 + getstatus( pr, &rbuf[ 8 ] );
460                 atpb.atp_sresiov = &iov;
461                 atpb.atp_sresiovcnt = 1;
462                 /*
463                  * This may error out if we lose a route, so we won't die().
464                  */
465                 if ( atp_sresp( pr->p_atp, &atpb ) < 0 ) {
466                     syslog( LOG_ERR, "atp_sresp: %m" );
467                 }
468 #endif /* notdef */
469             }
470         }
471     }
472     return 0;
473 }
474
475 /*
476  * We assume buf is big enough for 255 bytes of data and a length byte.
477  */
478
479 int getstatus( pr, buf )
480     struct printer      *pr;
481     char                *buf;
482 {
483     char                path[ MAXPATHLEN ];
484     int                 fd = -1, rc;
485
486     if ( pr->p_flags & P_SPOOLED && ( pr->p_spool != NULL )) {
487         strcpy( path, pr->p_spool );
488         strcat( path, "/status" );
489         fd = open( path, O_RDONLY);
490     }
491
492     if (( pr->p_flags & P_PIPED ) || ( fd < 0 )) {
493         *buf = strlen( cannedstatus );
494         strncpy( &buf[ 1 ], cannedstatus, *buf );
495         return( *buf + 1 );
496     } else {
497         if (( rc = read( fd, &buf[ 1 ], 255 )) < 0 ) {
498             rc = 0;
499         }
500         close( fd );
501         if ( rc && buf[ rc ] == '\n' ) {        /* remove trailing newline */
502             rc--;
503         }
504         *buf = rc;
505         return( rc + 1 );
506     }
507 }
508
509 char    *pgetstr();
510 char    *getpname();
511
512 void getprinters( cf )
513     char        *cf;
514 {
515     char                buf[ 1024 ], area[ 1024 ], *a, *p, *name, *type, *zone;
516     struct printer      *pr;
517     int                 c;
518
519     while (( c = getprent( cf, buf )) > 0 ) {
520         a = area;
521         /*
522          * Get the printer's nbp name.
523          */
524         if (( p = getpname( &a )) == NULL ) {
525             fprintf( stderr, "No printer name\n" );
526             exit( 1 );
527         }
528
529         if (( pr = (struct printer *)malloc( sizeof( struct printer )))
530                 == NULL ) {
531             perror( "malloc" );
532             exit( 1 );
533         }
534         bzero( pr, sizeof( struct printer ));
535
536         name = defprinter.p_name;
537         type = defprinter.p_type;
538         zone = defprinter.p_zone;
539         if ( nbp_name( p, &name, &type, &zone )) {
540             fprintf( stderr, "Can't parse \"%s\"\n", name );
541             exit( 1 );
542         }
543         if ( name != defprinter.p_name ) {
544             if (( pr->p_name = (char *)malloc( strlen( name ) + 1 )) == NULL ) {
545                 perror( "malloc" );
546                 exit( 1 );
547             }
548             strcpy( pr->p_name, name );
549         } else {
550             pr->p_name = name;
551         }
552         if ( type != defprinter.p_type ) {
553             if (( pr->p_type = (char *)malloc( strlen( type ) + 1 )) == NULL ) {
554                 perror( "malloc" );
555                 exit( 1 );
556             }
557             strcpy( pr->p_type, type );
558         } else {
559             pr->p_type = type;
560         }
561         if ( zone != defprinter.p_zone ) {
562             if (( pr->p_zone = (char *)malloc( strlen( zone ) + 1 )) == NULL ) {
563                 perror( "malloc" );
564                 exit( 1 );
565             }
566             strcpy( pr->p_zone, zone );
567         } else {
568             pr->p_zone = zone;
569         }
570
571         if ( pnchktc( cf ) != 1 ) {
572             fprintf( stderr, "Bad papcap entry\n" );
573             exit( 1 );
574         }
575
576         /*
577          * Get PPD file.
578          */
579         if (( p = pgetstr( "pd", &a )) == NULL ) {
580             pr->p_ppdfile = defprinter.p_ppdfile;
581         } else {
582             if (( pr->p_ppdfile = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
583                 perror( "malloc" );
584                 exit( 1 );
585             }
586             strcpy( pr->p_ppdfile, p );
587         }
588
589         /*
590          * Get lpd printer name.
591          */
592         if (( p = pgetstr( "pr", &a )) == NULL ) {
593             pr->p_printer = defprinter.p_printer;
594             pr->p_flags = defprinter.p_flags;
595         } else {
596             if ( *p == '|' ) {
597                 p++;
598                 pr->p_flags = P_PIPED;
599             } else {
600                 pr->p_flags = P_SPOOLED;
601             }
602             if (( pr->p_printer = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
603                 perror( "malloc" );
604                 exit( 1 );
605             }
606             strcpy( pr->p_printer, p );
607         }
608
609         /*
610          * Do we want authenticated printing?
611          */
612         if ((p = pgetstr( "ca", &a )) != NULL ) {
613             if ((pr->p_authprintdir = (char *)malloc(strlen(p)+1)) == NULL) {
614                 perror( "malloc" );
615                 exit(1);
616             }
617             strcpy( pr->p_authprintdir, p );
618             pr->p_flags |= P_AUTH;
619             pr->p_flags |= P_AUTH_CAP;
620         } else { pr->p_authprintdir = NULL; }
621
622         if ( pgetflag( "sp" ) == 1 ) {
623             pr->p_flags |= P_AUTH;
624             pr->p_flags |= P_AUTH_PSSP;
625         }
626
627         if ((p = pgetstr("am", &a)) != NULL ) {
628                 if ((uamlist = (char *)malloc(strlen(p)+1)) == NULL ) {
629                         perror("malloc");
630                         exit(1);
631                 }
632                 strcpy(uamlist, p);
633         }
634
635         if ( pr->p_flags & P_SPOOLED ) {
636             /*
637              * Get operator name.
638              */
639             if (( p = pgetstr( "op", &a )) == NULL ) {
640                 pr->p_operator = defprinter.p_operator;
641             } else {
642                 if (( pr->p_operator = (char *)malloc( strlen( p ) + 1 ))
643                         == NULL ) {
644                     perror( "malloc" );
645                     exit( 1 );
646                 }
647                 strcpy( pr->p_operator, p );
648             }
649         }
650
651         /* get printer's appletalk address. */
652         if (( p = pgetstr( "pa", &a )) == NULL ) 
653             memcpy(&pr->p_addr, &defprinter.p_addr, sizeof(pr->p_addr));
654         else 
655             atalk_aton(p, &pr->p_addr);
656
657         pr->p_next = printers;
658         printers = pr;
659     }
660     if ( c == 0 ) {
661         endprent();
662     } else {                    /* No capability file, do default */
663         printers = &defprinter;
664     }
665 }
666
667 int rprintcap( pr )
668     struct printer      *pr;
669 {
670     char                buf[ 1024 ], area[ 1024 ], *a, *p;
671     int                 c;
672
673     /*
674      * Spool directory from printcap file.
675      */
676     if ( pr->p_flags & P_SPOOLED ) {
677         if ( pgetent( printcap, buf, pr->p_printer ) != 1 ) {
678             syslog( LOG_ERR, "No such printer: %s", pr->p_printer );
679             return( -1 );
680         }
681
682         /*
683          * Spool directory.
684          */
685         if ( pr->p_spool != NULL && pr->p_spool != defprinter.p_spool ) {
686             free( pr->p_spool );
687         }
688         a = area;
689         if (( p = pgetstr( "sd", &a )) == NULL ) {
690             pr->p_spool = defprinter.p_spool;
691         } else {
692             if (( pr->p_spool = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
693                 syslog( LOG_ERR, "malloc: %m" );
694                 exit( 1 );
695             }
696             strcpy( pr->p_spool, p );
697         }
698
699         /*
700          * Is accounting on?
701          */
702         a = area;
703         if ( pgetstr( "af", &a ) == NULL ) {
704             pr->p_flags &= ~P_ACCOUNT;
705         } else {
706             pr->p_flags |= P_ACCOUNT;
707 #ifdef ABS_PRINT
708             if ( pr->p_role != NULL && pr->p_role != defprinter.p_role ) {
709                 free( pr->p_role );
710             }
711             a = area;
712             if (( p = pgetstr( "ro", &a )) == NULL ) {
713                 pr->p_role = defprinter.p_role;
714             } else {
715                 if (( pr->p_role =
716                         (char *)malloc( strlen( p ) + 1 )) == NULL ) {
717                     syslog( LOG_ERR, "malloc: %m" );
718                     exit( 1 );
719                 }
720                 strcpy( pr->p_role, p );
721             }
722
723             if (( c = pgetnum( "si" )) < 0 ) {
724                 pr->p_srvid = defprinter.p_srvid;
725             } else {
726                 pr->p_srvid = c;
727             }
728 #endif /* ABS_PRINT */
729         }
730
731
732         /*
733          * Cost of printer.
734          */
735         if ( pr->p_pagecost_msg != NULL &&
736                 pr->p_pagecost_msg != defprinter.p_pagecost_msg ) {
737             free( pr->p_pagecost_msg );
738         }
739         a = area;
740         if (( p = pgetstr( "pc", &a )) != NULL ) {
741             if (( pr->p_pagecost_msg =
742                     (char *)malloc( strlen( p ) + 1 )) == NULL ) {
743                 syslog( LOG_ERR, "malloc: %m" );
744                 exit( 1 );
745             }
746             strcpy( pr->p_pagecost_msg, p );
747             pr->p_pagecost = 0;
748         } else if ( pr->p_flags & P_ACCOUNT ) {
749             if (( c = pgetnum( "pc" )) < 0 ) {
750                 pr->p_pagecost = defprinter.p_pagecost;
751             } else {
752                 pr->p_pagecost = c;
753             }
754             pr->p_pagecost_msg = NULL;
755         }
756
757         /*
758          * Get lpd lock file.
759          */
760         if ( pr->p_lock != NULL && pr->p_lock != defprinter.p_lock ) {
761             free( pr->p_lock );
762         }
763         a = area;
764         if (( p = pgetstr( "lo", &a )) == NULL ) {
765             pr->p_lock = defprinter.p_lock;
766         } else {
767             if (( pr->p_lock = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
768                 syslog( LOG_ERR, "malloc: %m" );
769                 exit( 1 );
770             }
771             strcpy( pr->p_lock, p );
772         }
773
774 #ifdef KRB
775         /*
776          * Must Kerberos authenticate?
777          */
778         if ( pgetflag( "ka" ) == 1 ) {
779             pr->p_flags |= P_KRB;
780         } else {
781             pr->p_flags &= ~P_KRB;
782         }
783 #endif /* KRB */
784
785         endprent();
786     }
787
788     return( 0 );
789 }