]> arthur.barton.de Git - netatalk.git/blobdiff - etc/papd/main.c
replace remaining %m printf glibc extension with %s strerror(errno)
[netatalk.git] / etc / papd / main.c
index 4b2239b390e3a03cf7c6292aaa9db9fae17a3b14..de9ca08baf9972069176aebf462d6563549b986b 100644 (file)
@@ -1,29 +1,64 @@
 /*
+ * $Id: main.c,v 1.18.6.2.2.4 2008-11-14 10:04:52 didg Exp $
+ *
  * Copyright (c) 1990,1995 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+
 #include <sys/param.h>
-#include <sys/types.h>
 #include <sys/time.h>
 #include <sys/uio.h>
 #if defined( sun ) && defined( __svr4__ )
 #include </usr/ucbinclude/sys/file.h>
-#else sun __svr4__
+#else /* sun && __svr4__ */
 #include <sys/file.h>
-#endif sun __svr4__
+#endif /* sun && __svr4__ */
 #include <sys/socket.h>
-#include <sys/syslog.h>
+#include <atalk/logger.h>
+
+/* POSIX.1 sys/wait.h check */
+#include <sys/types.h>
+#ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
+#endif /* HAVE_SYS_WAIT_H */
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif /* ! WEXITSTATUS */
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif /* ! WIFEXITED */
+
 #include <errno.h>
 
+/* STDC check */
+#if STDC_HEADERS
 #include <string.h>
+#else /* STDC_HEADERS */
+#ifndef HAVE_STRCHR
+#define strchr index
+#define strrchr index
+#endif /* HAVE_STRCHR */
+char *strchr (), *strrchr ();
+#ifndef HAVE_MEMCPY
+#define memcpy(d,s,n) bcopy ((s), (d), (n))
+#define memmove(d,s,n) bcopy ((s), (d), (n))
+#endif /* ! HAVE_MEMCPY */
+#endif /* STDC_HEADERS */
+
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <netdb.h>
 #include <fcntl.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif /* HAVE_UNISTD_H */
 
 #include <netatalk/endian.h>
 #include <netatalk/at.h>
 #include <atalk/pap.h>
 #include <atalk/paths.h>
 #include <atalk/util.h>
+#include <atalk/nbp.h>
+#include <atalk/unicode.h>
 
 #include "printer.h"
+#include "printcap.h"
+#include "session.h"
+#include "uam_auth.h"
+#include "print_cups.h"
 
 #define _PATH_PAPDPPDFILE      ".ppd"
 
@@ -43,46 +84,66 @@ struct printer      defprinter;
 struct printer *printers = NULL;
 
 int            debug = 0;
-char           *conffile = _PATH_PAPDCONF;
+static char    *conffile = _PATH_PAPDCONF;
 char           *printcap = _PATH_PAPDPRINTCAP;
 unsigned char  connid, quantum, sock, oquantum = PAP_MAXQUANTUM;
 char           *cannedstatus = PIPED_STATUS;
 struct printer *printer = NULL;
 char           *version = VERSION;
-static char      *pidfile = _PATH_PAPDLOCK;
+static char    *pidfile = _PATH_PAPDLOCK;
+
+char           *uamlist;
+char           *uampath = _PATH_PAPDUAMPATH;
+
+/* Prototypes for locally used functions */
+int getstatus( struct printer *pr, char *buf );
+int rprintcap( struct printer *pr );
+static void getprinters( char *cf );
+
 
 /* this only needs to be used by the server process */
 static void papd_exit(const int i)
 {
   server_unlock(pidfile);
+  auth_unload();
   exit(i);
 }
 
 #if !defined( ibm032 ) && !defined( _IBMR2 )
     void
-#endif ibm032 _IBMR2
+#endif /* ! ibm032 && ! _IBMR2 */
 die( n )
     int                        n;
 {
     struct printer     *pr;
+    struct at_addr     addr;
+
+    memset(&addr, 0, sizeof(addr));
 
     for ( pr = printers; pr; pr = pr->p_next ) {
        if ( pr->p_flags & P_REGISTERED ) {
-           if ( nbp_unrgstr( pr->p_name, pr->p_type, pr->p_zone ) < 0 ) {
-               syslog( LOG_ERR, "can't unregister %s:%s@%s\n", pr->p_name,
+           if ( nbp_unrgstr( pr->p_name, pr->p_type, pr->p_zone, &addr ) < 0 ) {
+               LOG(log_error, logtype_papd, "can't unregister %s:%s@%s", pr->p_name,
                        pr->p_type, pr->p_zone );
                papd_exit( n + 1 );
            }
-           syslog( LOG_ERR, "unregister %s:%s@%s\n", pr->p_name, pr->p_type,
+           LOG(log_info, logtype_papd, "unregister %s:%s@%s", pr->p_name, pr->p_type,
                    pr->p_zone );
        }
+#ifdef HAVE_CUPS
+       if ( pr->p_flags & P_SPOOLED && pr->p_flags & P_CUPS_PPD ) {
+               LOG(log_info, logtype_papd, "Deleting CUPS temp PPD file for %s (%s)", pr->p_name, pr->p_ppdfile);
+               unlink (pr->p_ppdfile);
+       }
+#endif /* HAVE_CUPS */
+
     }
     papd_exit( n );
 }
 
 #if !defined( ibm032 ) && !defined( _IBMR2 )
     void
-#endif ibm032 _IBMR2
+#endif /* ! ibm032 && ! _IBMR2 */
 reap()
 {
     int                status;
@@ -91,17 +152,17 @@ reap()
     while (( pid = wait3( &status, WNOHANG, 0 )) > 0 ) {
        if ( WIFEXITED( status )) {
            if ( WEXITSTATUS( status )) {
-               syslog( LOG_ERR, "child %d exited with %d", pid,
+               LOG(log_error, logtype_papd, "child %d exited with %d", pid,
                        WEXITSTATUS( status ));
            } else {
-               syslog( LOG_INFO, "child %d done", pid );
+               LOG(log_info, logtype_papd, "child %d done", pid );
            }
        } else {
            if ( WIFSIGNALED( status )) {
-               syslog( LOG_ERR, "child %d killed with %d", pid,
+               LOG(log_error, logtype_papd, "child %d killed with %d", pid,
                        WTERMSIG( status ));
            } else {
-               syslog( LOG_ERR, "child %d died", pid );
+               LOG(log_error, logtype_papd, "child %d died", pid );
            }
        }
     }
@@ -110,12 +171,11 @@ reap()
 
 char           rbuf[ 255 + 1 + 8 ];
 
-main( ac, av )
+int main( ac, av )
     int                ac;
     char       **av;
 {
     extern char         *optarg;
-    extern int          optind;
 
     ATP                        atp;
     struct atp_block   atpb;
@@ -127,6 +187,7 @@ main( ac, av )
     char               *p, hostname[ MAXHOSTNAMELEN ];
     char               cbuf[ 8 ];
     int                        c;
+    char               *atname;
 
     if ( gethostname( hostname, sizeof( hostname )) < 0 ) {
        perror( "gethostname" );
@@ -148,21 +209,21 @@ main( ac, av )
 #ifdef __svr4__
     defprinter.p_flags = P_PIPED;
     defprinter.p_printer = "/usr/bin/lp -T PS";
-#else
+#else /* __svr4__ */
     defprinter.p_flags = P_SPOOLED;
     defprinter.p_printer = "lp";
-#endif
+#endif /* __svr4__ */
     defprinter.p_operator = "operator";
     defprinter.p_spool = _PATH_PAPDSPOOLDIR;
 #ifdef ABS_PRINT
     defprinter.p_role = NULL;
     defprinter.p_srvid = 0;
-#endif ABS_PRINT
+#endif /* ABS_PRINT */
     defprinter.p_pagecost = 200;               /* default cost */
     defprinter.p_pagecost_msg = NULL;
     defprinter.p_lock = "lock";
 
-    while (( c = getopt( ac, av, "adf:p:P:" )) != EOF ) {
+    while (( c = getopt( ac, av, "adf:p:P:v" )) != EOF ) {
        switch ( c ) {
        case 'a' :              /* for compatibility with old papd */
            break;
@@ -183,6 +244,11 @@ main( ac, av )
            pidfile = optarg;
            break;
 
+       case 'v' :              /* version */
+           printf( "papd (version %s)\n", VERSION );
+           exit ( 1 );
+           break;
+
        default :
            fprintf( stderr,
                    "Usage:\t%s [ -d ] [ -f conffile ] [ -p printcap ]\n",
@@ -191,11 +257,10 @@ main( ac, av )
        }
     }
 
-    getprinters( conffile );
 
     switch (server_lock("papd", pidfile, debug)) {
     case 0: /* open a couple things again in the child */
-      if ((c = open("/", O_RDONLY)) >= 0) {
+      if (!debug && (c = open("/", O_RDONLY)) >= 0) {
        dup2(c, 1);
        dup2(c, 2);
       }
@@ -206,6 +271,10 @@ main( ac, av )
       exit(0);
     }      
 
+#ifdef DEBUG1
+    fault_setup(NULL);
+#endif
+
     /*
      * Start logging.
      */
@@ -216,27 +285,48 @@ main( ac, av )
     }
 #ifdef ultrix
     openlog( p, LOG_PID );
-#else ultrix
-    openlog( p, LOG_NDELAY|LOG_PID, LOG_LPR );
-#endif ultrix
+#else /* ultrix */
+    set_processname(p);
+    syslog_setup(log_debug, logtype_default, logoption_ndelay | logoption_pid |
+               debug ? logoption_perror : 0, logfacility_lpr );
+#endif /* ultrix */
+
+    LOG(log_info, logtype_papd, "restart (%s)", version );
+#ifdef HAVE_CUPS
+    LOG(log_info, logtype_papd, "CUPS support enabled (%s)", CUPS_API_VERSION );
+#endif
 
-    syslog( LOG_INFO, "restart (%s)", version );
+    getprinters( conffile );
 
     for ( pr = printers; pr; pr = pr->p_next ) {
        if (( pr->p_flags & P_SPOOLED ) && rprintcap( pr ) < 0 ) {
-           syslog( LOG_ERR, "printcap problem: %s", pr->p_printer );
+           LOG(log_error, logtype_papd, "printcap problem: %s", pr->p_printer );
        }
+
+       if (!(pr->p_flags & P_CUPS)) {
+               if ((size_t)-1 != convert_string_allocate(CH_UNIX, CH_MAC, pr->p_name, strlen(pr->p_name), &atname)) {
+                       pr->p_u_name = pr->p_name;
+                       pr->p_name = atname;
+               }
+       }
+                       
        if (( pr->p_atp = atp_open( ATADDR_ANYPORT, &pr->p_addr )) == NULL ) {
-           syslog( LOG_ERR, "atp_open: %m" );
+           LOG(log_error, logtype_papd, "atp_open: %s", strerror(errno) );
            papd_exit( 1 );
        }
        if ( nbp_rgstr( atp_sockaddr( pr->p_atp ), pr->p_name, pr->p_type,
                pr->p_zone ) < 0 ) {
-           syslog( LOG_ERR, "can't register %s:%s@%s", pr->p_name, pr->p_type,
+           LOG(log_error, logtype_papd, "can't register %s:%s@%s", pr->p_u_name, pr->p_type,
                    pr->p_zone );
            die( 1 );
        }
-       syslog( LOG_INFO, "register %s:%s@%s", pr->p_name, pr->p_type,
+       if ( pr->p_flags & P_AUTH ) {
+               LOG(log_info, logtype_papd, "Authentication enabled: %s", pr->p_u_name );
+       }
+       else {
+               LOG(log_info, logtype_papd, "Authentication disabled: %s", pr->p_u_name );
+       }
+       LOG(log_info, logtype_papd, "register %s:%s@%s", pr->p_u_name, pr->p_type,
                pr->p_zone );
        pr->p_flags |= P_REGISTERED;
     }
@@ -246,7 +336,7 @@ main( ac, av )
     sigemptyset( &sv.sa_mask );
     sv.sa_flags = SA_RESTART;
     if ( sigaction( SIGTERM, &sv, 0 ) < 0 ) {
-       syslog( LOG_ERR, "sigaction: %m" );
+       LOG(log_error, logtype_papd, "sigaction: %s", strerror(errno) );
        papd_exit( 1 );
     }
 
@@ -254,10 +344,15 @@ main( ac, av )
     sigemptyset( &sv.sa_mask );
     sv.sa_flags = SA_RESTART;
     if ( sigaction( SIGCHLD, &sv, 0 ) < 0 ) {
-       syslog( LOG_ERR, "sigaction: %m" );
+       LOG(log_error, logtype_papd, "sigaction: %s", strerror(errno) );
        papd_exit( 1 );
     }
 
+    /*
+     * Load UAMS
+     */
+    auth_load(uampath, uamlist);
+
     /*
      * Begin accepting connections.
      */
@@ -270,7 +365,7 @@ main( ac, av )
            if ( errno == EINTR ) {
                continue;
            }
-           syslog( LOG_ERR, "select: %m" );
+           LOG(log_error, logtype_papd, "select: %s", strerror(errno) );
            papd_exit( 1 );
        }
 
@@ -278,10 +373,10 @@ main( ac, av )
            if ( FD_ISSET( atp_fileno( pr->p_atp ), &fdset )) {
                int             err = 0;
 
-               bzero( &sat, sizeof( struct sockaddr_at ));
+               memset( &sat, 0, sizeof( struct sockaddr_at ));
 #ifdef BSD4_4
                sat.sat_len = sizeof( struct sockaddr_at );
-#endif BSD4_4
+#endif /* BSD4_4 */
                sat.sat_family = AF_APPLETALK;
                sat.sat_addr.s_net = ATADDR_ANYNET;
                sat.sat_addr.s_node = ATADDR_ANYNODE;
@@ -294,7 +389,7 @@ main( ac, av )
                atpb.atp_rreqdata = cbuf;
                atpb.atp_rreqdlen = sizeof( cbuf );
                if ( atp_rreq( pr->p_atp, &atpb ) < 0 ) {
-                   syslog( LOG_ERR, "atp_rreq: %m" );
+                   LOG(log_error, logtype_papd, "atp_rreq: %s", strerror(errno) );
                    continue;
                }
 
@@ -310,12 +405,28 @@ main( ac, av )
                    rbuf[ 2 ] = rbuf[ 3 ] = 0;
 
                    if (( pr->p_flags & P_SPOOLED ) && rprintcap( pr ) != 0 ) {
-                       syslog( LOG_ERR, "printcap problem: %s",
+                       LOG(log_error, logtype_papd, "printcap problem: %s",
                                pr->p_printer );
                        rbuf[ 2 ] = rbuf[ 3 ] = 0xff;
                        err = 1;
                    }
 
+#ifdef HAVE_CUPS
+                  /*
+                   * If cups is not accepting jobs, we return
+                   * 0xffff to indicate we're busy
+                   */
+#ifdef DEBUG
+                    LOG(log_debug, logtype_papd, "CUPS: PAP_OPEN");
+#endif
+                   if ( (pr->p_flags & P_SPOOLED) && (cups_get_printer_status ( pr ) == 0)) {
+                        LOG(log_error, logtype_papd, "CUPS_PAP_OPEN: %s is not accepting jobs",
+                                pr->p_printer );
+                        rbuf[ 2 ] = rbuf[ 3 ] = 0xff;
+                        err = 1;
+                    }
+#endif /* HAVE_CUPS */
+
                    /*
                     * If this fails, we've run out of sockets. Rather than
                     * just die(), let's try to continue. Maybe some sockets
@@ -323,11 +434,14 @@ main( ac, av )
                     */
                    if (( atp = atp_open( ATADDR_ANYPORT, 
                                          &pr->p_addr)) == NULL ) {
-                       syslog( LOG_ERR, "atp_open: %m" );
-                       rbuf[ 2 ] = rbuf[ 3 ] = 0xff;
+                       LOG(log_error, logtype_papd, "atp_open: %s", strerror(errno) );
+                       rbuf[ 2 ] = rbuf[ 3 ] = 0xff;  /* printer busy */
+                       rbuf[ 4 ] = 0; /* FIXME is it right? */
                        err = 1;
                    }
-                   rbuf[ 4 ] = atp_sockaddr( atp )->sat_port;
+                   else {
+                      rbuf[ 4 ] = atp_sockaddr( atp )->sat_port;
+                    }
                    rbuf[ 5 ] = oquantum;
                    rbuf[ 6 ] = rbuf[ 7 ] = 0;
 
@@ -339,33 +453,46 @@ main( ac, av )
                     * This may error out if we lose a route, so we won't die().
                     */
                    if ( atp_sresp( pr->p_atp, &atpb ) < 0 ) {
-                       syslog( LOG_ERR, "atp_sresp: %m" );
-                       continue;
+                       LOG(log_error, logtype_papd, "atp_sresp: %s", strerror(errno) );
+                       err = 1;
                    }
 
                    if ( err ) {
+                       if (atp) {
+                          atp_close(atp);
+                        }
                        continue;
                    }
 
                    switch ( c = fork()) {
                    case -1 :
-                       syslog( LOG_ERR, "fork: %m" );
+                       LOG(log_error, logtype_papd, "fork: %s", strerror(errno) );
+                        atp_close(atp);
                        continue;
 
                    case 0 : /* child */
                        printer = pr;
 
+                       #ifndef HAVE_CUPS
                        if (( printer->p_flags & P_SPOOLED ) &&
                                chdir( printer->p_spool ) < 0 ) {
-                           syslog( LOG_ERR, "chdir %s: %m", printer->p_spool );
+                           LOG(log_error, logtype_papd, "chdir %s: %s", printer->p_spool, strerror(errno) );
+                           exit( 1 );
+                       }
+                       #else
+                       if (( printer->p_flags & P_SPOOLED ) &&
+                               chdir( SPOOLDIR ) < 0 ) {
+                           LOG(log_error, logtype_papd, "chdir %s: %s", SPOOLDIR, strerror(errno) );
                            exit( 1 );
                        }
 
+                       #endif
+
                        sv.sa_handler = SIG_DFL;
                        sigemptyset( &sv.sa_mask );
                        sv.sa_flags = SA_RESTART;
                        if ( sigaction( SIGTERM, &sv, 0 ) < 0 ) {
-                           syslog( LOG_ERR, "sigaction: %m" );
+                           LOG(log_error, logtype_papd, "sigaction: %s", strerror(errno) );
                            exit( 1 );
                        }
 
@@ -374,14 +501,14 @@ main( ac, av )
                        }
                        sat.sat_port = sock;
                        if ( session( atp, &sat ) < 0 ) {
-                           syslog( LOG_ERR, "bad session" );
+                           LOG(log_error, logtype_papd, "bad session" );
                            exit( 1 );
                        }
                        exit( 0 );
                        break;
 
                    default : /* parent */
-                       syslog( LOG_INFO, "child %d for \"%s\" from %u.%u",
+                       LOG(log_info, logtype_papd, "child %d for \"%s\" from %u.%u",
                                c, pr->p_name, ntohs( sat.sat_addr.s_net ),
                                sat.sat_addr.s_node);
                        atp_close( atp );
@@ -403,12 +530,12 @@ main( ac, av )
                     * This may error out if we lose a route, so we won't die().
                     */
                    if ( atp_sresp( pr->p_atp, &atpb ) < 0 ) {
-                       syslog( LOG_ERR, "atp_sresp: %m" );
+                       LOG(log_error, logtype_papd, "atp_sresp: %s", strerror(errno) );
                    }
                    break;
 
                default :
-                   syslog( LOG_ERR, "Bad request from %u.%u!",
+                   LOG(log_error, logtype_papd, "Bad request from %u.%u!",
                            ntohs( sat.sat_addr.s_net ), sat.sat_addr.s_node );
                    continue;
                    break;
@@ -428,22 +555,37 @@ main( ac, av )
                 * This may error out if we lose a route, so we won't die().
                 */
                if ( atp_sresp( pr->p_atp, &atpb ) < 0 ) {
-                   syslog( LOG_ERR, "atp_sresp: %m" );
+                   LOG(log_error, logtype_papd, "atp_sresp: %s", strerror(errno) );
                }
-#endif notdef
+#endif /* notdef */
            }
        }
     }
+    return 0;
 }
 
 /*
  * We assume buf is big enough for 255 bytes of data and a length byte.
  */
-    int
-getstatus( pr, buf )
+
+int getstatus( pr, buf )
     struct printer     *pr;
     char               *buf;
 {
+
+#ifdef HAVE_CUPS
+    if ( pr->p_flags & P_PIPED ) {
+       *buf = strlen( cannedstatus );
+       strncpy( &buf[ 1 ], cannedstatus, *buf );
+       return( *buf + 1 );
+    } else {
+       cups_get_printer_status( pr );
+       *buf = strlen ( pr->p_status );
+       strncpy ( &buf[1], pr->p_status, *buf);
+       return ( *buf + 1);
+    }
+#else
+
     char               path[ MAXPATHLEN ];
     int                        fd = -1, rc;
 
@@ -468,24 +610,27 @@ getstatus( pr, buf )
        *buf = rc;
        return( rc + 1 );
     }
+#endif /* HAVE_CUPS */
 }
 
 char   *pgetstr();
-char   *getpname();
+char   *getpname(char **area, int bufsize);
+
+#define PF_CONFBUFFER  1024
 
-getprinters( cf )
+static void getprinters( cf )
     char       *cf;
 {
-    char               buf[ 1024 ], area[ 1024 ], *a, *p, *name, *type, *zone;
+    char               buf[ PF_CONFBUFFER ], area[ PF_CONFBUFFER ], *a, *p, *name, *type, *zone;
     struct printer     *pr;
     int                        c;
 
-    while (( c = getprent( cf, buf )) > 0 ) {
+    while (( c = getprent( cf, buf, PF_CONFBUFFER )) > 0 ) {
        a = area;
        /*
         * Get the printer's nbp name.
         */
-       if (( p = getpname( &a )) == NULL ) {
+       if (( p = getpname( &a, PF_CONFBUFFER )) == NULL ) {
            fprintf( stderr, "No printer name\n" );
            exit( 1 );
        }
@@ -495,7 +640,7 @@ getprinters( cf )
            perror( "malloc" );
            exit( 1 );
        }
-       bzero( pr, sizeof( struct printer ));
+       memset( pr, 0, sizeof( struct printer ));
 
        name = defprinter.p_name;
        type = defprinter.p_type;
@@ -570,6 +715,32 @@ getprinters( cf )
            strcpy( pr->p_printer, p );
        }
 
+       /*
+        * Do we want authenticated printing?
+        */
+       if ((p = pgetstr( "ca", &a )) != NULL ) {
+           if ((pr->p_authprintdir = (char *)malloc(strlen(p)+1)) == NULL) {
+               perror( "malloc" );
+               exit(1);
+           }
+           strcpy( pr->p_authprintdir, p );
+           pr->p_flags |= P_AUTH;
+           pr->p_flags |= P_AUTH_CAP;
+       } else { pr->p_authprintdir = NULL; }
+
+       if ( pgetflag( "sp" ) == 1 ) {
+           pr->p_flags |= P_AUTH;
+           pr->p_flags |= P_AUTH_PSSP;
+       }
+
+       if ((p = pgetstr("am", &a)) != NULL ) {
+               if ((uamlist = (char *)malloc(strlen(p)+1)) == NULL ) {
+                       perror("malloc");
+                       exit(1);
+               }
+               strcpy(uamlist, p);
+       }
+
        if ( pr->p_flags & P_SPOOLED ) {
            /*
             * Get operator name.
@@ -592,8 +763,42 @@ getprinters( cf )
        else 
            atalk_aton(p, &pr->p_addr);
 
-       pr->p_next = printers;
-       printers = pr;
+#ifdef HAVE_CUPS
+       if ((p = pgetstr("co", &a)) != NULL ) {
+            pr->p_cupsoptions = strdup(p);
+            LOG (log_error, logtype_papd, "enabling cups-options for %s: %s", pr->p_name, pr->p_cupsoptions);
+       }
+#endif
+
+       /* convert line endings for setup sections.
+           real ugly work around for foomatic deficiencies,
+          need to get rid of this */
+       if ( pgetflag("fo") == 1 ) {
+            pr->p_flags |= P_FOOMATIC_HACK;
+            LOG (log_error, logtype_papd, "enabling foomatic hack for %s", pr->p_name);
+       }
+
+       if (strncasecmp (pr->p_name, "cupsautoadd", 11) == 0)
+       {
+#ifdef HAVE_CUPS
+               pr = cups_autoadd_printers (pr, printers);
+               printers = pr;
+#else
+               LOG (log_error, logtype_papd, "cupsautoadd: Cups support not compiled in");
+#endif /* HAVE_CUPS */
+       }
+       else {
+#ifdef HAVE_CUPS
+               if ( cups_check_printer ( pr, printers, 1) == 0)
+               {
+                       pr->p_next = printers;
+                       printers = pr;
+               }
+#else
+               pr->p_next = printers;
+               printers = pr;
+#endif /* HAVE_CUPS */
+       }
     }
     if ( c == 0 ) {
        endprent();
@@ -602,9 +807,40 @@ getprinters( cf )
     }
 }
 
-rprintcap( pr )
+int rprintcap( pr )
     struct printer     *pr;
 {
+
+#ifdef HAVE_CUPS
+
+    char               *p;
+
+    if ( pr->p_flags & P_SPOOLED && !(pr->p_flags & P_CUPS_AUTOADDED) ) { /* Skip check if autoadded */
+       if ( cups_printername_ok ( pr->p_printer ) != 1) {
+           LOG(log_error, logtype_papd, "No such CUPS printer: '%s'", pr->p_printer );
+           return( -1 );
+       }
+    }
+
+    /*
+     * Check for ppd file, moved here because of cups_autoadd we cannot check at the usual location
+     */
+
+    if ( pr->p_ppdfile == defprinter.p_ppdfile ) {
+       if ( (p = (char *) cups_get_printer_ppd ( pr->p_printer )) != NULL ) {
+           if (( pr->p_ppdfile = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
+               LOG(log_error, logtype_papd, "malloc: %s", strerror(errno) );
+               exit( 1 );
+           }
+           strcpy( pr->p_ppdfile, p );
+           pr->p_flags |= P_CUPS_PPD;
+           /*LOG(log_info, logtype_papd, "PPD File for %s set to %s", pr->p_printer, pr->p_ppdfile );*/
+       }
+    }
+
+
+#else
+
     char               buf[ 1024 ], area[ 1024 ], *a, *p;
     int                        c;
 
@@ -613,7 +849,7 @@ rprintcap( pr )
      */
     if ( pr->p_flags & P_SPOOLED ) {
        if ( pgetent( printcap, buf, pr->p_printer ) != 1 ) {
-           syslog( LOG_ERR, "No such printer: %s", pr->p_printer );
+           LOG(log_error, logtype_papd, "No such printer: %s", pr->p_printer );
            return( -1 );
        }
 
@@ -628,7 +864,7 @@ rprintcap( pr )
            pr->p_spool = defprinter.p_spool;
        } else {
            if (( pr->p_spool = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
-               syslog( LOG_ERR, "malloc: %m" );
+               LOG(log_error, logtype_papd, "malloc: %s", strerror(errno) );
                exit( 1 );
            }
            strcpy( pr->p_spool, p );
@@ -652,7 +888,7 @@ rprintcap( pr )
            } else {
                if (( pr->p_role =
                        (char *)malloc( strlen( p ) + 1 )) == NULL ) {
-                   syslog( LOG_ERR, "malloc: %m" );
+                   LOG(log_error, logtype_papd, "malloc: %s", strerror(errno) );
                    exit( 1 );
                }
                strcpy( pr->p_role, p );
@@ -663,7 +899,7 @@ rprintcap( pr )
            } else {
                pr->p_srvid = c;
            }
-#endif ABS_PRINT
+#endif /* ABS_PRINT */
        }
 
 
@@ -678,7 +914,7 @@ rprintcap( pr )
        if (( p = pgetstr( "pc", &a )) != NULL ) {
            if (( pr->p_pagecost_msg =
                    (char *)malloc( strlen( p ) + 1 )) == NULL ) {
-               syslog( LOG_ERR, "malloc: %m" );
+               LOG(log_error, logtype_papd, "malloc: %s", strerror(errno) );
                exit( 1 );
            }
            strcpy( pr->p_pagecost_msg, p );
@@ -703,7 +939,7 @@ rprintcap( pr )
            pr->p_lock = defprinter.p_lock;
        } else {
            if (( pr->p_lock = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
-               syslog( LOG_ERR, "malloc: %m" );
+               LOG(log_error, logtype_papd, "malloc: %s", strerror(errno) );
                exit( 1 );
            }
            strcpy( pr->p_lock, p );
@@ -714,14 +950,15 @@ rprintcap( pr )
         * Must Kerberos authenticate?
         */
        if ( pgetflag( "ka" ) == 1 ) {
-           pr->p_flags |= P_AUTH;
+           pr->p_flags |= P_KRB;
        } else {
-           pr->p_flags &= ~P_AUTH;
+           pr->p_flags &= ~P_KRB;
        }
-#endif
+#endif /* KRB */
 
        endprent();
     }
+#endif /* HAVE_CUPS */
 
     return( 0 );
 }