]> arthur.barton.de Git - netatalk.git/commitdiff
add CUPS support to papd
authorbfernhomberg <bfernhomberg>
Wed, 9 Jun 2004 01:25:52 +0000 (01:25 +0000)
committerbfernhomberg <bfernhomberg>
Wed, 9 Jun 2004 01:25:52 +0000 (01:25 +0000)
15 files changed:
configure.in
etc/papd/.cvsignore
etc/papd/Makefile.am
etc/papd/file.h
etc/papd/headers.c
etc/papd/lp.c
etc/papd/lp.h
etc/papd/magics.c
etc/papd/main.c
etc/papd/ppd.c
etc/papd/print_cups.c [new file with mode: 0644]
etc/papd/print_cups.h [new file with mode: 0644]
etc/papd/printer.h
etc/papd/queries.c
etc/papd/showppd.c

index 88eec162d25c331e1294a3dc2d3dcf7f225d20e7..b79e630fab4e8d759102fa4f4b9b75b23839bc4d 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: configure.in,v 1.179.2.3.2.28 2004-05-18 23:42:30 bfernhomberg Exp $
+dnl $Id: configure.in,v 1.179.2.3.2.29 2004-06-09 01:25:52 bfernhomberg Exp $
 dnl configure.in for netatalk
 
 AC_INIT(etc/afpd/main.c)
@@ -546,6 +546,8 @@ AC_ARG_WITH(uams-path,
        ]
 )
 
+NETATALK_AC_CUPS
+
 dnl --------------------------------------------------------------------------
 dnl FHS stuff has to be done last because it overrides other defaults
 dnl --------------------------------------------------------------------------
index a625c60e03a140cbe5f5a4009e831d67458155ff..dda2bffb2f6003daeb8c518892b01dc0e2e07ee8 100644 (file)
@@ -1,5 +1,6 @@
 Makefile
 Makefile.in
 papd
+showppd
 .deps
 .libs
index b7573266e5009bba68d67025d3affd18f21ce4cd..e3f68270c3520d5fc591eecf899a33176f6b379e 100644 (file)
@@ -1,17 +1,20 @@
 # Makefile.am for etc/papd/
 
 pkgconfdir = @PKGCONFDIR@
+spooldir = @SPOOLDIR@
 
 sbin_PROGRAMS = papd
-#bin_PROGRAMS = showppd
+bin_PROGRAMS = showppd
 
 papd_SOURCES = main.c printcap.c session.c file.c comment.c lp.c ppd.c \
-       magics.c headers.c queries.c auth.c uam.c
-papd_LDADD = $(top_builddir)/libatalk/libatalk.la
-papd_LDFLAGS = -export-dynamic
+              magics.c headers.c queries.c auth.c uam.c print_cups.c
 
-#showppd_SOURCES = showppd.c ppd.c
-#showppd_LDADD = $(top_builddir)/libatalk/libatalk.la
+papd_LDADD = $(top_builddir)/libatalk/libatalk.la @PAM_LIBS@ @CUPS_LIBS@
+papd_LDFLAGS = -export-dynamic @CUPS_LDFLAGS@
+
+showppd_SOURCES = showppd.c ppd.c
+showppd_CFLAGS = @CFLAGS@ -DSHOWPPD
+showppd_LDADD = $(top_builddir)/libatalk/libatalk.la
 
 noinst_HEADERS =       \
        comment.h       \
@@ -21,12 +24,19 @@ noinst_HEADERS =    \
        printcap.h      \
        printer.h       \
        session.h       \
+       print_cups.h    \
        uam_auth.h
 
 CFLAGS = \
        -I$(top_srcdir)/include -I$(top_srcdir)/sys \
        @CFLAGS@ \
        -D_PATH_PAPDCONF=\"$(pkgconfdir)/papd.conf\" \
-       -D_PATH_PAPDUAMPATH=\"$(UAMS_PATH)/\"
+       -D_PATH_PAPDUAMPATH=\"$(UAMS_PATH)/\" \
+       -DSPOOLDIR=\"$(spooldir)/\"
 
-#LIBS = @PAM_LIBS@
+if USE_SPOOLDIR
+install-exec-hook:
+       echo "Creating SPOOLDIR $(spooldir)..."
+       $(mkinstalldirs) $(spooldir)
+       chmod 0777 $(spooldir)
+endif
index c5fb435c3e43c337b2be80ce10c8c6a4e137e5d2..11936b84e182756cd822b016150cd34028589f43 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.h,v 1.6 2001-06-25 20:13:45 rufustfirefly Exp $
+ * $Id: file.h,v 1.6.14.1 2004-06-09 01:25:53 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -17,11 +17,14 @@ struct papfile {
     int                        pf_datalen;
     char               *pf_buf;
     char               *pf_data;
+    int                origin;
 };
 
 #define PF_BOT         (1<<0)
 #define PF_EOF         (1<<1)
 #define PF_QUERY       (1<<2)
+#define PF_STW         (1<<3)
+#define PF_TRANSLATE   (1<<4)
 
 #define CONSUME( pf, len )  {   (pf)->pf_data += (len); \
                                (pf)->pf_datalen -= (len); \
index e6ac1ec022906039e18f5933312530fabfcd8528..04f16471f238b023ae84651c562783024560ec23 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: headers.c,v 1.9 2002-01-04 04:45:47 sibaz Exp $
+ * $Id: headers.c,v 1.9.10.1 2004-06-09 01:25:53 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -9,17 +9,69 @@
 #include "config.h" 
 #endif /* HAVE_CONFIG_H */
 
-#include <atalk/logger.h>
 #include <sys/param.h>
+#include <string.h>
 #include <stdio.h>
 
 #include <netatalk/at.h>
+#include <atalk/logger.h>
 
 #include "file.h"
 #include "comment.h"
 #include "lp.h"
 
 int ch_title( struct papfile *, struct papfile * );
+int ch_for( struct papfile *, struct papfile * );
+
+
+int ch_for( in, out )
+       struct papfile  *in, *out;
+{
+    char                *start, *stop, *p, *q, c;
+    int                 linelength, crlflength;
+
+    switch ( markline( in, &start, &linelength, &crlflength )) {
+    case 0 :
+        return( 0 );
+
+    case -1 :
+        return( CH_MORE );
+    }
+
+    stop = start + linelength;
+    for ( p = start; p < stop; p++ ) {
+        if ( *p == ':' ) {
+            break;
+        }
+    }
+
+    for ( ; p < stop; p++ ) {
+        if ( *p == '(' ) {
+            break;
+        }
+    }
+
+    for ( q = p; q < stop; q++ ) {
+        if ( *q == ')' ) {
+            break;
+        }
+    }
+
+    if ( q < stop && p < stop ) {
+        p++;
+        c = *q;
+        *q = '\0';
+       lp_for ( p );
+        *q = c;
+    }
+
+    in->pf_state |= PF_TRANSLATE;
+    lp_write( in, start, linelength + crlflength );
+    in->pf_state &= ~PF_TRANSLATE;
+    compop();
+    CONSUME( in, linelength + crlflength );
+    return( CH_DONE );
+}
 
 int ch_title( in, out )
     struct papfile     *in, *out;
@@ -35,6 +87,10 @@ int ch_title( in, out )
        return( CH_MORE );
     }
 
+#ifdef DEBUG
+    LOG(log_debug, logtype_papd, "Parsing %%Title");
+#endif
+
     stop = start + linelength;
     for ( p = start; p < stop; p++ ) {
        if ( *p == ':' ) {
@@ -62,16 +118,203 @@ int ch_title( in, out )
        *q = c;
     }
 
-    lp_write( start, linelength + crlflength );
+    in->pf_state |= PF_TRANSLATE;
+    lp_write( in, start, linelength + crlflength );
+    in->pf_state &= ~PF_TRANSLATE;
     compop();
     CONSUME( in, linelength + crlflength );
     return( CH_DONE );
 }
 
+static int guess_creator ( char *creator )
+{
+       if (strstr(creator, "LaserWriter"))
+               return 1;
+       if (strstr(creator, "cgpdftops"))
+               return 2;
+
+       return 0;
+}
+
+
+int ch_creator( in, out )
+    struct papfile     *in, *out;
+{
+    char               *start, *stop, *p, *q, c;
+    int                        linelength, crlflength;
+
+    switch ( markline( in, &start, &linelength, &crlflength )) {
+    case 0 :
+       return( 0 );
+
+    case -1 :
+       return( CH_MORE );
+    }
+
+    stop = start + linelength;
+    for ( p = start; p < stop; p++ ) {
+       if ( *p == ':' ) {
+           break;
+       }
+    }
+
+    for ( ; p < stop; p++ ) {
+       if ( *p == '(' ) {
+           break;
+       }
+    }
+
+    for ( q = p; q < stop; q++ ) {
+       if ( *q == ')' ) {
+           break;
+       }
+    }
+
+    if ( q < stop && p < stop ) {
+       p++;
+       c = *q;
+       *q = '\0';
+       in->origin = guess_creator ( p );
+       lp_origin(in->origin);
+       *q = c;
+    }
+
+    in->pf_state |= PF_TRANSLATE;
+    lp_write( in, start, linelength + crlflength );
+    in->pf_state &= ~PF_TRANSLATE;
+    compop();
+    CONSUME( in, linelength + crlflength );
+    return( CH_DONE );
+}
+
+int ch_endcomm( in, out )
+    struct papfile     *in, *out;
+{
+    char                *start;
+    int                 linelength, crlflength;
+
+#ifdef DEBUG
+    LOG(log_debug, logtype_papd, "End Comment");
+#endif
+    in->pf_state |= PF_STW;
+
+    switch ( markline( in, &start, &linelength, &crlflength )) {
+    case 0 :
+       return( 0 );
+
+    case -1 :
+       return( CH_MORE );
+    }
+
+    in->pf_state |= PF_TRANSLATE;
+    lp_write( in, start, linelength + crlflength );
+    in->pf_state &= ~PF_TRANSLATE;
+    compop();
+    CONSUME( in, linelength + crlflength );
+    return ( CH_DONE);
+}
+
+int ch_starttranslate(in,out)
+    struct papfile      *in, *out;
+{
+    char                *start;
+    int                 linelength, crlflength;
+
+#ifdef DEBUG
+    LOG(log_debug, logtype_papd, "Start translate");
+#endif
+
+    switch ( markline( in, &start, &linelength, &crlflength )) {
+    case 0 :
+        return( 0 );
+
+    case -1 :
+        return( CH_MORE );
+    }
+
+    in->pf_state |= PF_TRANSLATE;
+    lp_write( in, start, linelength + crlflength );
+    compop();
+    CONSUME( in, linelength + crlflength );
+    return ( CH_DONE);
+}
+
+int ch_endtranslate(in,out)
+    struct papfile      *in, *out;
+{
+    char                *start;
+    int                 linelength, crlflength;
+
+#ifdef DEBUG
+    LOG(log_debug, logtype_papd, "EndTranslate");
+#endif
+
+    switch ( markline( in, &start, &linelength, &crlflength )) {
+    case 0 :
+        return( 0 );
+
+    case -1 :
+        return( CH_MORE );
+    }
+
+    lp_write( in, start, linelength + crlflength );
+    in->pf_state &= ~PF_TRANSLATE;
+    compop();
+    CONSUME( in, linelength + crlflength );
+    return ( CH_DONE);
+}
+
+int ch_translateone(in,out)
+    struct papfile      *in, *out;
+{
+    char                *start;
+    int                 linelength, crlflength;
+
+#ifdef DEBUG
+    LOG(log_debug, logtype_papd, "TranslateOne");
+#endif
+
+    switch ( markline( in, &start, &linelength, &crlflength )) {
+    case 0 :
+        return( 0 );
+
+    case -1 :
+        return( CH_MORE );
+    }
+
+    in->pf_state |= PF_TRANSLATE;
+    lp_write( in, start, linelength + crlflength );
+    in->pf_state &= ~PF_TRANSLATE;
+    compop();
+    CONSUME( in, linelength + crlflength );
+    return ( CH_DONE);
+}
+
+
+
+
 /*
  * "Header" comments.
  */
 struct papd_comment    headers[] = {
     { "%%Title:",                      0,              ch_title,       0 },
+    { "%%For:",                                0,              ch_for,         0 },
+    { "%%Creator:",                    0,              ch_creator,     0 },
+    { "%%EndComments",                 0,              ch_endcomm,     0 },
+    { "%%BeginFeature",                        0,              ch_starttranslate,  0 },
+    { "%%EndFeature",                  0,              ch_endtranslate,  0 },
+    { "%%BeginPageSetup",              0,              ch_starttranslate, 0 },
+    { "%%EndPageSetup",                        0,              ch_endtranslate, 0 },
+#if 0
+    { "%%BeginSetup",                  0,              ch_translateone,  0 },
+    { "%%EndSetup",                    0,              ch_translateone,  0 },
+    { "%%BeginProlog",                 0,              ch_translateone,  0 },
+    { "%%EndProlog",                   0,              ch_translateone,  0 },
+    { "%%Page:",                       0,              ch_translateone, 0 },
+    { "%%PageTrailer",                 0,              ch_translateone, 0 },
+    { "%%Trailer",                     0,              ch_translateone, 0 },
+    { "%%EOF",                         0,              ch_translateone, 0 },
+#endif
+    { "%%",                            0,              ch_translateone, 0 },
     { 0 },
 };
index bddc605d04635e93adf45d6887dca37de2add916..6f978a1409904727102b046ddad053a1838f88ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: lp.c,v 1.14.8.2 2004-05-12 21:21:49 didg Exp $
+ * $Id: lp.c,v 1.14.8.3 2004-06-09 01:25:53 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -46,7 +46,6 @@
 #endif /* HAVE_CONFIG_H */
 
 #include <sys/param.h>
-#include <atalk/logger.h>
 #include <sys/time.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/un.h>
 #include <netinet/in.h>
 #undef s_net
-#include <netatalk/at.h>
-#include <atalk/atp.h>
-#include <atalk/paths.h>
 
 #ifdef ABS_PRINT
 #include <math.h>
 #endif /* ABS_PRINT */
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #endif /* HAVE_FCNTL_H */
 #include <pwd.h>
 
+#include <atalk/logger.h>
+#include <netatalk/at.h>
+#include <atalk/atp.h>
+#include <atalk/paths.h>
+#include <atalk/unicode.h>
+
 #include "printer.h"
 #include "file.h"
 #include "lp.h"
 
+#ifdef HAVE_CUPS
+#include  "print_cups.h"
+#endif
+
+
 /* These functions aren't used outside of lp.c */
 int lp_conn_inet();
 int lp_disconn_inet( int );
@@ -98,16 +104,173 @@ struct lp {
     int                        lp_flags;
     FILE               *lp_stream;
     int                        lp_seq;
+    int                lp_origin;
     char               lp_letter;
     char               *lp_person;
+    char               *lp_created_for; /* Holds the content of the Postscript %%For Comment if available */
     char               *lp_host;
     char               *lp_job;
+    char               *lp_spoolfile;
 } lp;
 #define LP_INIT                (1<<0)
 #define LP_OPEN                (1<<1)
 #define LP_PIPE                (1<<2)
 #define LP_CONNECT     (1<<3)
 #define LP_QUEUE       (1<<4)
+#define LP_JOBPENDING  (1<<5)
+
+void lp_origin (int origin)
+{
+    lp.lp_origin = origin;
+}
+
+/* the converted string should always be shorter, but ... FIXME! */
+static void convert_octal (char *string, charset_t dest)
+{
+    unsigned char *p, *q;
+    char temp[4];
+    long int ch;
+
+    q=p=string;
+    while ( *p != '\0' ) {
+        ch = 0;
+        if ( *p == '\\' ) {
+            p++;
+            if (dest && isdigit(*p) && isdigit(*(p+1)) && isdigit(*(p+2)) ) {
+                temp[0] = *p;
+                temp[1] = *(p+1);
+                temp[2] = *(p+2);
+                temp[3] = 0;
+                ch = strtol( temp, NULL, 8);
+                if ( ch && ch < 0xff)
+                    *q = ch;
+               else
+                    *q = '.';
+                p += 2;
+            }
+                   else 
+                *q = '.';
+       }
+       else {
+           *q = *p;
+       }
+           p++;
+           q++;
+    }
+    *q = 0;
+}
+
+
+static void translate(charset_t from, charset_t dest, char **option)
+{
+    char *translated;
+
+    if (*option != NULL) {
+        convert_octal(*option, from);
+        if (from) {
+             if ((size_t) -1 != (convert_string_allocate(from, dest, *option, strlen(*option), &translated)) ) {
+                 free (*option);
+                 *option = translated;
+             }
+        }
+    }
+}
+
+
+static void lp_setup_comments (charset_t dest)
+{
+    charset_t from=0;
+
+    switch (lp.lp_origin) {
+       case 1:
+               from=CH_MAC;
+               break;
+       case 2:
+               from=CH_UTF8_MAC;
+               break;
+    }
+
+    if (lp.lp_job) {
+#ifdef DEBUG1
+        LOG(log_debug, logtype_papd, "job: %s", lp.lp_job );
+#endif
+        translate(from, dest, &lp.lp_job);
+    }
+    if (lp.lp_created_for) {
+#ifdef DEBUG1
+        LOG(log_debug, logtype_papd, "for: %s", lp.lp_created_for );
+#endif
+        translate(from, dest, &lp.lp_created_for);
+    }
+    if (lp.lp_person) {
+#ifdef DEBUG1
+       LOG(log_debug, logtype_papd, "person: %s", lp.lp_person );
+#endif
+       translate(from, dest, &lp.lp_person);
+    }
+}
+
+#define is_var(a, b) (strncmp((a), (b), 2) == 0)
+
+static char* pipexlate(char *src)
+{
+    char *p, *q, *dest; 
+    static char destbuf[MAXPATHLEN];
+    size_t destlen = MAXPATHLEN;
+    int len = 0;
+   
+    dest = destbuf; 
+
+    if (!src)
+       return NULL;
+
+    strncpy(dest, src, MAXPATHLEN);
+    if ((p = strchr(src, '%')) == NULL) /* nothing to do */
+        return destbuf;
+
+    /* first part of the path. just forward to the next variable. */
+    len = MIN((size_t)(p - src), destlen);
+    if (len > 0) {
+        destlen -= len;
+        dest += len;
+    }
+
+    while (p && destlen > 0) {
+        /* now figure out what the variable is */
+        q = NULL;
+        if (is_var(p, "%U")) {
+           q = lp.lp_person;
+        } else if (is_var(p, "%C") || is_var(p, "%J") ) {
+            q = lp.lp_job;
+        } else if (is_var(p, "%F")) {
+            q =  lp.lp_created_for;
+        } else if (is_var(p, "%%")) {
+            q = "%";
+        } else
+            q = p;
+
+        /* copy the stuff over. if we don't understand something that we
+         * should, just skip it over. */
+        if (q) {
+            len = MIN(p == q ? 2 : strlen(q), destlen);
+            strncpy(dest, q, len);
+            dest += len;
+            destlen -= len;
+        }
+
+        /* stuff up to next $ */
+        src = p + 2;
+        p = strchr(src, '$');
+        len = p ? MIN((size_t)(p - src), destlen) : destlen;
+        if (len > 0) {
+            strncpy(dest, src, len);
+            dest += len;
+            destlen -= len;
+        }
+    }
+    return destbuf;
+}
+
 
 void lp_person( person )
     char       *person;
@@ -151,38 +314,49 @@ void lp_host( host )
        exit( 1 );
     }
     strcpy( lp.lp_host, host );
+    LOG(log_debug, logtype_papd, "host: %s", lp.lp_host );
 }
 
+/* Currently lp_job and lp_for will not handle the
+ * conversion of macroman chars > 0x7f correctly
+ * This should be added.
+ */
+
 void lp_job( job )
     char       *job;
 {
-    char       *p, *q;
-
     if ( lp.lp_job != NULL ) {
        free( lp.lp_job );
     }
-    if (( lp.lp_job = (char *)malloc( strlen( job ) + 1 )) == NULL ) {
-       LOG(log_error, logtype_papd, "malloc: %m" );
-       exit( 1 );
-    }
-    for ( p = job, q = lp.lp_job; *p != '\0'; p++, q++ ) {
-       if ( !isascii( *p ) || !isprint( *p ) || *p == '\\' ) {
-           *q = '.';
-       } else {
-           *q = *p;
-       }
+
+    lp.lp_job = strdup(job);
+#ifdef DEBUG
+    LOG(log_debug, logtype_papd, "job: %s", lp.lp_job );
+#endif
+    
+}
+
+void lp_for ( lpfor )
+       char    *lpfor;
+{
+    if ( lp.lp_created_for != NULL ) {
+       free( lp.lp_created_for );
     }
-    *q = '\0';
+
+    lp.lp_created_for = strdup(lpfor);
 }
 
+
 int lp_init( out, sat )
     struct papfile     *out;
     struct sockaddr_at *sat;
 {
+    int                authenticated = 0;
+#ifndef HAVE_CUPS
     int                fd, n, len;
     char       *cp, buf[ BUFSIZ ];
     struct stat        st;
-    int                authenticated = 0;
+#endif /* HAVE_CUPS */
 #ifdef ABS_PRINT
     char       cost[ 22 ];
     char       balance[ 22 ];
@@ -270,6 +444,8 @@ int lp_init( out, sat )
     lp.lp_letter = 'A';
 
     if ( printer->p_flags & P_SPOOLED ) {
+
+#ifndef HAVE_CUPS
        /* check if queuing is enabled: mode & 010 on lock file */
        if ( stat( printer->p_lock, &st ) < 0 ) {
            LOG(log_error, logtype_papd, "lp_init: %s: %m", printer->p_lock );
@@ -288,7 +464,7 @@ int lp_init( out, sat )
            return( -1 );
        }
 
-#ifndef SOLARIS /* flock is unsupported, I doubt this stuff work anyway with newer solaris so ignore for now */
+#ifndef SOLARIS /* flock is unsupported, I doubt this stuff works anyway with newer solaris so ignore for now */
        if ( flock( fd, LOCK_EX ) < 0 ) {
            LOG(log_error, logtype_papd, "lp_init: can't lock .seq" );
            spoolerror( out, NULL );
@@ -317,6 +493,16 @@ int lp_init( out, sat )
        lseek( fd, 0L, 0 );
        write( fd, buf, strlen( buf ));
        close( fd );
+#else
+
+       if (cups_get_printer_status ( printer ) == 0)
+       {
+           spoolerror( out, "Queuing is disabled." );
+           return( -1 );
+       }
+
+       lp.lp_seq = getpid();
+#endif /* HAVE CUPS */
     } else {
        lp.lp_flags |= LP_PIPE;
        lp.lp_seq = getpid();
@@ -334,15 +520,25 @@ int lp_open( out, sat )
     int                fd;
     struct passwd      *pwent;
 
+#ifdef DEBUG
+    LOG (log_debug, logtype_papd, "lp_open");
+#endif
+
+    if ( lp.lp_flags & LP_JOBPENDING ) {
+       lp_print();
+    }
+
     if (( lp.lp_flags & LP_INIT ) == 0 && lp_init( out, sat ) != 0 ) {
        return( -1 );
     }
     if ( lp.lp_flags & LP_OPEN ) {
-       LOG(log_error, logtype_papd, "lp_open already open" );
-       abort();
+       /* LOG(log_error, logtype_papd, "lp_open already open" ); */
+       /* abort(); */
+       return (-1);
     }
 
     if ( lp.lp_flags & LP_PIPE ) {
+
        /* go right to program */
        if (lp.lp_person != NULL) {
            if((pwent = getpwnam(lp.lp_person)) != NULL) {
@@ -353,11 +549,14 @@ int lp_open( out, sat )
                LOG(log_info, logtype_papd, "Error getting username (%s)", lp.lp_person);
            }
        }
-       if (( lp.lp_stream = popen( printer->p_printer, "w" )) == NULL ) {
+
+       lp_setup_comments(CH_UNIX);
+       if (( lp.lp_stream = popen( pipexlate(printer->p_printer), "w" )) == NULL ) {
            LOG(log_error, logtype_papd, "lp_open popen %s: %m", printer->p_printer );
            spoolerror( out, NULL );
            return( -1 );
        }
+        LOG(log_debug, logtype_papd, "lp_open: opened %s",  pipexlate(printer->p_printer) );
     } else {
        sprintf( name, "df%c%03d%s", lp.lp_letter++, lp.lp_seq, hostname );
 
@@ -367,6 +566,12 @@ int lp_open( out, sat )
            return( -1 );
        }
 
+       if ( NULL == (lp.lp_spoolfile = (char *) malloc (strlen (name) +1)) ) {
+           LOG(log_error, logtype_papd, "malloc: %m");
+           exit(1);
+       }
+       strcpy ( lp.lp_spoolfile, name);        
+
        if (lp.lp_person != NULL) {
            if ((pwent = getpwnam(lp.lp_person)) == NULL) {
                LOG(log_error, logtype_papd, "getpwnam %s: no such user", lp.lp_person);
@@ -392,9 +597,11 @@ int lp_open( out, sat )
            spoolerror( out, NULL );
            return( -1 );
        }
+#ifdef DEBUG        
+        LOG(log_debug, logtype_papd, "lp_open: opened %s", name );
+#endif 
     }
     lp.lp_flags |= LP_OPEN;
-
     return( 0 );
 }
 
@@ -406,18 +613,92 @@ int lp_close()
     fclose( lp.lp_stream );
     lp.lp_stream = NULL;
     lp.lp_flags &= ~LP_OPEN;
+    lp.lp_flags |= LP_JOBPENDING;
     return 0;
 }
 
-int lp_write( buf, len )
+
+
+int lp_write(in, buf, len )
+    struct papfile *in;
     char       *buf;
-    int                len;
+    size_t     len;
 {
+#define BUFSIZE 32768
+    static char tempbuf[BUFSIZE];
+    static char tempbuf2[BUFSIZE];
+    static size_t bufpos = 0;
+    static int last_line_translated = 1; /* if 0, append a \n a the start */
+    char *tbuf = buf;
+
+    /* Before we write out anything check for a pending job, e.g. cover page */
+    if (lp.lp_flags & LP_JOBPENDING)
+       lp_print();
+
+    /* foomatic doesn't handle mac line endings, so we convert them for 
+     * the Postscript headers
+     * REALLY ugly hack, remove ASAP again */
+    if ((printer->p_flags & P_FOOMATIC_HACK) && (in->pf_state & PF_TRANSLATE) && 
+        (buf[len-1] != '\n') ) {
+        if (len <= BUFSIZE) {
+           if (!last_line_translated) {
+               tempbuf2[0] = '\n';
+               memcpy(tempbuf2+1, buf, len++);
+           }
+           else
+               memcpy(tempbuf2, buf, len);
+               
+            if (tempbuf2[len-1] == '\r')
+               tempbuf2[len-1] = '\n';
+            tempbuf2[len] = 0;
+            tbuf = tempbuf2;
+            last_line_translated = 1;
+#ifdef DEBUG
+            LOG(log_debug, logtype_papd, "lp_write: %s", tbuf );
+#endif
+        }
+        else {
+            LOG(log_error, logtype_papd, "lp_write: conversion buffer too small" );
+            abort();
+        }
+    }
+    else {
+        if (printer->p_flags & P_FOOMATIC_HACK && buf[len-1] == '\n') {
+            last_line_translated = 1;
+       }
+        else
+           last_line_translated = 0;
+    }
+
+    /* To be able to do commandline substitutions on piped printers
+     * we store the start of the print job in a buffer.
+     * %%EndComment triggers writing to file */
     if (( lp.lp_flags & LP_OPEN ) == 0 ) {
-       return( -1 );
+#ifdef DEBUG
+        LOG(log_debug, logtype_papd, "lp_write: writing to temporary buffer" );
+#endif
+       if ((bufpos+len) > BUFSIZE) {
+            LOG(log_error, logtype_papd, "lp_write: temporary buffer too small" );
+            /* FIXME: call lp_open here? abort isn't nice... */
+            abort();
+        }
+       else {
+            memcpy(tempbuf + bufpos, tbuf, len);
+            bufpos += len;
+            if (bufpos > BUFSIZE/2)
+                in->pf_state |= PF_STW; /* we used half of the buffer, start writing */
+            return(0);
+       }
+    }
+    else if ( bufpos) {
+        if ( fwrite( tempbuf, 1, bufpos, lp.lp_stream ) != bufpos ) {
+            LOG(log_error, logtype_papd, "lp_write: %m" );
+            abort();
+        }
+        bufpos=0;
     }
 
-    if ( fwrite( buf, 1, len, lp.lp_stream ) != len ) {
+    if ( fwrite( tbuf, 1, len, lp.lp_stream ) != len ) {
        LOG(log_error, logtype_papd, "lp_write: %m" );
        abort();
     }
@@ -455,19 +736,23 @@ int lp_cancel()
  */
 int lp_print()
 {
+#ifndef HAVE_CUPS
     char               buf[ MAXPATHLEN ];
     char               tfname[ MAXPATHLEN ];
     char               cfname[ MAXPATHLEN ];
     char               letter;
     int                        fd, n, s;
     FILE               *cfile;
+#endif /* HAVE_CUPS */
 
     if (( lp.lp_flags & LP_INIT ) == 0 || lp.lp_letter == 'A' ) {
        return 0;
     }
     lp_close();
+    lp.lp_flags &= ~LP_JOBPENDING;
 
     if ( printer->p_flags & P_SPOOLED ) {
+#ifndef HAVE_CUPS
        sprintf( tfname, "tfA%03d%s", lp.lp_seq, hostname );
        if (( fd = open( tfname, O_WRONLY|O_EXCL|O_CREAT, 0660 )) < 0 ) {
            LOG(log_error, logtype_papd, "lp_print %s: %m", tfname );
@@ -543,11 +828,31 @@ int lp_print()
            LOG(log_error, logtype_papd, "lp_print lpd said %c: %m", buf[ 0 ] );
            return 0;
        }
+#else
+        if ( ! (lp.lp_job && *lp.lp_job) ) {
+            lp.lp_job = strdup("Mac Job");
+        }
+
+        lp_setup_comments(add_charset(cups_get_language ()));
+
+        if (lp.lp_person != NULL) {
+           cups_print_job ( printer->p_printer, lp.lp_spoolfile, lp.lp_job, lp.lp_person, printer->p_cupsoptions);
+        } else if (lp.lp_created_for != NULL) {
+            cups_print_job ( printer->p_printer, lp.lp_spoolfile, lp.lp_job, lp.lp_created_for, printer->p_cupsoptions);
+        } else {
+            cups_print_job ( printer->p_printer, lp.lp_spoolfile, lp.lp_job, printer->p_operator, printer->p_cupsoptions);
+        }
+
+       /*LOG(log_info, logtype_papd, "lp_print unlink %s", lp.lp_spoolfile );*/
+        //unlink ( lp.lp_spoolfile );
+       return 0;
+#endif /* HAVE_CUPS*/
     }
     LOG(log_info, logtype_papd, "lp_print queued" );
     return 0;
 }
 
+#ifndef HAVE_CUPS
 int lp_disconn_unix( fd )
 {
     return( close( fd ));
@@ -814,3 +1119,4 @@ int lp_queue( out )
        }
     }
 }
+#endif /* HAVE_CUPS */
index 4d74f2a0aff84db1bebc8c2fd5120dcf83fc2e37..d63314172d2720ac81b9138030fce10aef20f8c0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: lp.h,v 1.3 2001-06-25 20:13:45 rufustfirefly Exp $
+ * $Id: lp.h,v 1.3.14.1 2004-06-09 01:25:53 bfernhomberg Exp $
  */
 
 #ifndef PAPD_LP_H
@@ -13,6 +13,8 @@ void lp_person __P(( char * ));
 int lp_pagecost __P(( void ));
 void lp_host __P(( char * ));
 void lp_job __P(( char * ));
+void lp_for __P(( char * ));
+void lp_origin __P(( int ));
 int lp_rmjob __P(( int ));
 int lp_queue __P(( struct papfile * ));
 
@@ -25,7 +27,7 @@ int lp_print __P(( void ));
 /* open a file for spooling */
 int lp_open __P(( struct papfile *, struct sockaddr_at * ));
 /* open a buffer to the current open file */
-int lp_write __P(( char *, int ));
+int lp_write __P(( struct papfile *,char *, size_t ));
 /* close current spooling file */
 int lp_close __P(( void ));
 
index 800c1854271097d95de6be8e03969d3f2a8766a8..73c07deb091daf0277d6c17a7ff42b5ba6e31d99 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: magics.c,v 1.11 2003-02-17 01:34:35 srittau Exp $
+ * $Id: magics.c,v 1.11.6.1 2004-06-09 01:25:53 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -21,6 +21,8 @@
 #include "comment.h"
 #include "lp.h"
 
+static int state=0;
+
 int ps( infile, outfile, sat )
     struct papfile     *infile, *outfile;
     struct sockaddr_at *sat;
@@ -30,6 +32,15 @@ int ps( infile, outfile, sat )
     struct papd_comment                *comment;
 
     for (;;) {
+        if ( infile->pf_state & PF_STW ) {
+               infile->pf_state &= ~PF_STW;
+               /* set up spool file */
+               if ( lp_open( outfile, sat ) < 0 && !state) {
+                   LOG(log_error, logtype_papd, "lp_open failed" );
+                   spoolerror( outfile, "Ignoring job." );
+               }
+               state = 1;
+       }       
        if ( (comment = compeek()) ) {
            switch( (*comment->c_handler)( infile, outfile, sat )) {
            case CH_DONE :
@@ -41,7 +52,6 @@ int ps( infile, outfile, sat )
            default :
                return( CH_ERROR );
            }
-
        } else {
            switch ( markline( infile, &start, &linelength, &crlflength )) {
            case 0 :
@@ -69,7 +79,7 @@ int ps( infile, outfile, sat )
            }
 
            /* write to file */
-           lp_write( start, linelength + crlflength );
+           lp_write( infile, start, linelength + crlflength );
            CONSUME( infile, linelength + crlflength );
        }
     }
@@ -127,13 +137,14 @@ int cm_psadobe( in, out, sat )
        case -1 :
            return( CH_MORE );
        }
-
        if ( in->pf_state & PF_BOT ) {
            in->pf_state &= ~PF_BOT;
+#if 0
            if ( lp_open( out, sat ) < 0 ) {
                LOG(log_error, logtype_papd, "lp_open failed" );
                spoolerror( out, "Ignoring job." );
            }
+#endif
        } else {
            if (( comment = commatch( start, start + linelength, headers )) != NULL ) {
                compush( comment );
@@ -141,7 +152,7 @@ int cm_psadobe( in, out, sat )
            }
        }
 
-       lp_write( start, linelength + crlflength );
+       lp_write( in, start, linelength + crlflength );
        CONSUME( in, linelength + crlflength );
     }
 }
@@ -193,6 +204,7 @@ int cm_psswitch( in, out, sat )
     return( CH_DONE );
 }
 
+
 struct papd_comment    magics[] = {
     { "%!PS-Adobe-3.0 Query",  0,                      cm_psquery, C_FULL },
     { "%!PS-Adobe-3.0",                0,                      cm_psadobe, C_FULL },
index 4283510c8496217a84eb98c211cd76cca08c29ec..f02744e5e0c4a43c0d5d9cd999b680f4240ec249 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: main.c,v 1.18.6.1 2004-05-12 21:21:49 didg Exp $
+ * $Id: main.c,v 1.18.6.2 2004-06-09 01:25:53 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1995 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -68,11 +68,13 @@ char *strchr (), *strrchr ();
 #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"
 
@@ -125,9 +127,16 @@ die( n )
                        pr->p_type, pr->p_zone );
                papd_exit( n + 1 );
            }
-           LOG(log_error, logtype_papd, "unregister %s:%s@%s", 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 );
 }
@@ -178,6 +187,7 @@ int main( ac, av )
     char               *p, hostname[ MAXHOSTNAMELEN ];
     char               cbuf[ 8 ];
     int                        c;
+    char               *atname;
 
     if ( gethostname( hostname, sizeof( hostname )) < 0 ) {
        perror( "gethostname" );
@@ -247,7 +257,6 @@ int main( ac, av )
        }
     }
 
-    getprinters( conffile );
 
     switch (server_lock("papd", pidfile, debug)) {
     case 0: /* open a couple things again in the child */
@@ -262,6 +271,10 @@ int main( ac, av )
       exit(0);
     }      
 
+#ifdef DEBUG1
+    fault_setup(NULL);
+#endif
+
     /*
      * Start logging.
      */
@@ -278,28 +291,41 @@ int main( ac, av )
 #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
+
+    getprinters( conffile );
 
     for ( pr = printers; pr; pr = pr->p_next ) {
        if (( pr->p_flags & P_SPOOLED ) && rprintcap( pr ) < 0 ) {
            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 ) {
            LOG(log_error, logtype_papd, "atp_open: %m" );
            papd_exit( 1 );
        }
        if ( nbp_rgstr( atp_sockaddr( pr->p_atp ), pr->p_name, pr->p_type,
                pr->p_zone ) < 0 ) {
-           LOG(log_error, logtype_papd, "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 );
        }
        if ( pr->p_flags & P_AUTH ) {
-               LOG(log_info, logtype_papd, "Authentication enabled: %s", pr->p_name );
+               LOG(log_info, logtype_papd, "Authentication enabled: %s", pr->p_u_name );
        }
        else {
-               LOG(log_info, logtype_papd, "Authentication disabled: %s", pr->p_name );
+               LOG(log_info, logtype_papd, "Authentication disabled: %s", pr->p_u_name );
        }
-       LOG(log_info, logtype_papd, "register %s:%s@%s", pr->p_name, pr->p_type,
+       LOG(log_info, logtype_papd, "register %s:%s@%s", pr->p_u_name, pr->p_type,
                pr->p_zone );
        pr->p_flags |= P_REGISTERED;
     }
@@ -384,6 +410,23 @@ int main( ac, av )
                        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
@@ -423,11 +466,20 @@ int main( ac, av )
                    case 0 : /* child */
                        printer = pr;
 
+                       #ifndef HAVE_CUPS
                        if (( printer->p_flags & P_SPOOLED ) &&
                                chdir( printer->p_spool ) < 0 ) {
                            LOG(log_error, logtype_papd, "chdir %s: %m", printer->p_spool );
                            exit( 1 );
                        }
+                       #else
+                       if (( printer->p_flags & P_SPOOLED ) &&
+                               chdir( SPOOLDIR ) < 0 ) {
+                           LOG(log_error, logtype_papd, "chdir %s: %m", SPOOLDIR );
+                           exit( 1 );
+                       }
+
+                       #endif
 
                        sv.sa_handler = SIG_DFL;
                        sigemptyset( &sv.sa_mask );
@@ -513,6 +565,20 @@ 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;
 
@@ -537,6 +603,7 @@ int getstatus( pr, buf )
        *buf = rc;
        return( rc + 1 );
     }
+#endif /* HAVE_CUPS */
 }
 
 char   *pgetstr();
@@ -689,8 +756,42 @@ static void 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();
@@ -702,6 +803,37 @@ static void getprinters( cf )
 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: %m" );
+               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;
 
@@ -819,6 +951,7 @@ int rprintcap( pr )
 
        endprent();
     }
+#endif /* HAVE_CUPS */
 
     return( 0 );
 }
index dcaea66fc91f8bc8b25868cb1959dd9741b194a4..eeb604031d3e0b4e44040f490641942452296ad5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ppd.c,v 1.9 2002-09-29 23:29:14 sibaz Exp $
+ * $Id: ppd.c,v 1.9.8.1 2004-06-09 01:25:54 bfernhomberg Exp $
  *
  * Copyright (c) 1995 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -27,7 +27,11 @@ struct ppd_font              *ppd_fonts = NULL;
 struct ppd_feature     ppd_features[] = {
     { "*LanguageLevel",        0 },
     { "*PSVersion",    0 },
+#ifdef HAVE_CUPS
+    { "*FreeVM",       "33554432" },
+#else
     { "*FreeVM",       0 },
+#endif
     { "*Product",      0 },
     { "*PCFileName",   0 },
     { "*ModelName",    0 },
@@ -59,6 +63,35 @@ int ppd_init()
 }
 #endif /* SHOWPPD */
 
+
+/* quick and ugly hack to be able to read
+   ppd files with Mac line ending */
+static char* my_fgets(buf, bufsize, stream) 
+    char   *buf;
+    size_t bufsize;
+    FILE   *stream;
+{
+    char p;
+    size_t count = 0;
+    while (count < bufsize && EOF != (p=fgetc(stream))) {
+        buf[count] = p;
+        count++;
+        if ( p == '\r' || p == '\n')
+           break;
+    }
+
+    if (p == EOF && count == 0)
+        return NULL;
+
+    /* translate line endings */
+    if ( buf[count - 1] == '\r')
+        buf[count - 1] = '\n';
+
+    buf[count] = 0;
+    return buf;
+}
+
 struct ppdent *getppdent( stream )
     FILE       *stream;
 {
@@ -69,11 +102,11 @@ struct ppdent *getppdent( stream )
     ppdent.pe_main = ppdent.pe_option = ppdent.pe_translation =
            ppdent.pe_value = NULL;
 
-    while (( p = fgets( buf, sizeof( buf ), stream )) != NULL ) {
+    while (( p = my_fgets( buf, sizeof( buf ), stream )) != NULL ) {
        if ( *p != '*' ) {      /* main key word */
            continue;
        }
-       if ( p[ strlen( p ) - 1 ] != '\n' ) {
+       if ( p[ strlen( p ) - 1 ] != '\n' && p[ strlen( p ) - 1 ] != '\r') {
            LOG(log_error, logtype_papd, "getppdent: line too long" );
            continue;
        }
@@ -204,7 +237,7 @@ int read_ppd( file, fcnt )
                break;
            }
        }
-       if ( pfe->pd_name && (pfe->pd_value == NULL) ) {
+       if ( pfe->pd_name ) { /*&& (pfe->pd_value == NULL) ) { */
            if (( pfe->pd_value =
                    (char *)malloc( strlen( pe->pe_value ) + 1 )) == NULL ) {
                LOG(log_error, logtype_papd, "malloc: %m" );
diff --git a/etc/papd/print_cups.c b/etc/papd/print_cups.c
new file mode 100644 (file)
index 0000000..dbc9115
--- /dev/null
@@ -0,0 +1,646 @@
+/*
+ * $Id: print_cups.c,v 1.1.2.1 2004-06-09 01:25:54 bfernhomberg Exp $
+ *
+ * Copyright 2004 Bjoern Fernhomberg.
+ *
+ * Some code copied or adapted from print_cups.c for samba
+ * Copyright 1999-2003 by Michael R Sweet.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <sys/types.h>
+#include <sys/param.h>
+#include <errno.h>
+
+
+#ifdef HAVE_CUPS
+
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <atalk/unicode.h>
+#include <atalk/logger.h>
+#include <atalk/atp.h>
+#include <atalk/pap.h>
+#include <atalk/util.h>
+
+#include "printer.h"
+#include "print_cups.h"
+
+#define MAXCHOOSERLEN 31
+#define HTTP_MAX_URI 1024
+
+static const char* cups_status_msg[] = {
+        "status: busy; info: \"%s\" is rejecting jobs; ",
+        "status: idle; info: \"%s\" is stopped, accepting jobs ;",
+        "status: idle; info: \"%s\" is ready ; ",
+};
+
+/* Local functions */
+static int     convert_to_mac_name ( char *encoding, char * inptr, char * outptr, size_t outlen);
+static size_t  to_ascii ( char *inbuf, char **outbuf);
+static int     cups_mangle_printer_name ( struct printer *pr, struct printer *printers);
+static void     cups_free_printer ( struct printer *pr);
+
+
+char * cups_get_language ()
+{
+        cups_lang_t *language;
+
+        language = cupsLangDefault();           /* needed for conversion */
+        return cupsLangEncoding(language);
+}
+
+/*
+ * 'cups_passwd_cb()' - The CUPS password callback...
+ */
+
+static const char *                            /* O - Password or NULL */
+cups_passwd_cb(const char *prompt)      /* I - Prompt */
+{
+ /*
+  * Always return NULL to indicate that no password is available...
+  */
+  return (NULL);
+}
+
+
+/*
+ * 'cups_printername_ok()' - Verify supplied printer name is a valid cups printer
+ */
+
+int                                     /* O - 1 if printer name OK */
+cups_printername_ok(char *name)         /* I - Name of printer */
+{
+        http_t          *http;          /* HTTP connection to server */
+        ipp_t           *request,       /* IPP Request */
+                        *response;      /* IPP Response */
+        cups_lang_t     *language;      /* Default language */
+        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
+
+       /*
+        * Make sure we don't ask for passwords...
+        */
+
+        cupsSetPasswordCB(cups_passwd_cb);
+
+       /*
+        * Try to connect to the server...
+        */
+
+        if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
+        {
+               LOG(log_error, logtype_papd, "Unable to connect to CUPS server %s - %s\n",
+                         cupsServer(), strerror(errno));
+                return (0);
+        }
+
+
+       /*
+        * Build an IPP_GET_PRINTER_ATTRS request, which requires the following
+        * attributes:
+        *
+        *    attributes-charset
+        *    attributes-natural-language
+        *    requested-attributes
+        *    printer-uri
+        */
+
+        request = ippNew();
+
+        request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+        request->request.op.request_id   = 1;
+
+        language = cupsLangDefault();
+
+        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+                     "attributes-charset", NULL, cupsLangEncoding(language));
+
+        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+                     "attributes-natural-language", NULL, language->language);
+
+        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+                     "requested-attributes", NULL, "printer-uri");
+
+        sprintf(uri, "ipp://localhost/printers/%s", name);
+
+        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+                     "printer-uri", NULL, uri);
+
+       /*
+        * Do the request and get back a response...
+        */
+
+        if ((response = cupsDoRequest(http, request, "/")) == NULL)
+        {
+               LOG(log_error, logtype_papd, "Unable to get printer status for %s - %s\n", name,
+                         ippErrorString(cupsLastError()));
+                httpClose(http);
+                return (0);
+        }
+
+        httpClose(http);
+
+        if (response->request.status.status_code >= IPP_OK_CONFLICT)
+        {
+               LOG(log_error, logtype_papd, "Unable to get printer status for %s - %s\n", name,
+                         ippErrorString(response->request.status.status_code));
+                ippDelete(response);
+                return (0);
+        }
+        else
+        {
+                ippDelete(response);
+                return (1);
+        }
+
+       return (0);
+}
+
+const char * 
+cups_get_printer_ppd ( char * name)
+{
+       cupsSetPasswordCB(cups_passwd_cb);
+       return cupsGetPPD( name );
+}
+
+int
+cups_get_printer_status (struct printer *pr)
+{
+
+        http_t          *http;          /* HTTP connection to server */
+        ipp_t           *request,       /* IPP Request */
+                        *response;      /* IPP Response */
+        ipp_attribute_t *attr;          /* Current attribute */
+        cups_lang_t     *language;      /* Default language */
+        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
+       int             status = -1;
+
+        static const char *pattrs[] =   /* Requested printer attributes */
+                        {
+                          "printer-state",
+                          "printer-state-message",
+                         "printer-is-accepting-jobs"
+                        };
+
+       /*
+        * Make sure we don't ask for passwords...
+        */
+
+        cupsSetPasswordCB(cups_passwd_cb);
+
+       /*
+        * Try to connect to the server...
+        */
+
+        if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
+        {
+               LOG(log_error, logtype_papd, "Unable to connect to CUPS server %s - %s\n",
+                         cupsServer(), strerror(errno));
+                return (0);
+        }
+
+       /*
+        * Generate the printer URI...
+        */
+
+        sprintf(uri, "ipp://localhost/printers/%s", pr->p_printer);
+
+
+
+       /*
+        * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
+        * following attributes:
+        *
+        *    attributes-charset
+        *    attributes-natural-language
+        *    requested-attributes
+        *    printer-uri
+        */
+
+        request = ippNew();
+
+        request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+        request->request.op.request_id   = 1;
+
+        language = cupsLangDefault();
+
+        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+                     "attributes-charset", NULL, cupsLangEncoding(language));
+
+        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+                     "attributes-natural-language", NULL, language->language);
+
+        ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+                      "requested-attributes",
+                      (sizeof(pattrs) / sizeof(pattrs[0])),
+                      NULL, pattrs);
+
+        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+                     "printer-uri", NULL, uri);
+
+       /*
+        * Do the request and get back a response...
+        */
+
+        if ((response = cupsDoRequest(http, request, "/")) == NULL)
+        {
+               LOG(log_error, logtype_papd, "Unable to get printer status for %s - %s\n", pr->p_printer,
+                         ippErrorString(cupsLastError()));
+                httpClose(http);
+                return (0);
+        }
+
+        if (response->request.status.status_code >= IPP_OK_CONFLICT)
+        {
+               LOG(log_error, logtype_papd, "Unable to get printer status for %s - %s\n", pr->p_printer,
+                         ippErrorString(response->request.status.status_code));
+                ippDelete(response);
+                httpClose(http);
+                return (0);
+        }
+
+       /*
+        * Get the current printer status and convert it to the status values.
+        */
+
+       memset ( pr->p_status, 0 ,sizeof(pr->p_status));
+
+        if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
+        {
+                if (attr->values[0].integer == IPP_PRINTER_STOPPED)
+                       status = 1;
+                else if (attr->values[0].integer == IPP_NOT_ACCEPTING)
+                       status = 0;
+               else
+                       status = 2;
+        }
+
+       if ((attr = ippFindAttribute(response, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN)) != NULL)
+       {
+               if ( attr->values[0].integer == 0 ) 
+                       status = 0;
+       }
+               
+       snprintf ( pr->p_status, 255, cups_status_msg[status], pr->p_printer );
+
+        if ((attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT)) != NULL)
+               strncat ( pr->p_status, attr->values[0].string.text, 255-strlen(pr->p_status));
+
+        ippDelete(response);
+
+       /*
+        * Return the print status ...
+        */
+
+        httpClose(http);
+
+       return (status);
+}
+
+
+/*------------------------------------------------------------------------*/
+
+/* pass the job to cups */
+
+int cups_print_job ( char * name, char *filename, char *job, char *username, char * cupsoptions )
+{
+       int             jobid;
+       char            filepath[MAXPATHLEN];
+       int             num_options;
+       cups_option_t   *options;
+
+       /* Initialize the options array */
+       num_options = 0;
+       options     = (cups_option_t *)0;
+
+        cupsSetPasswordCB(cups_passwd_cb);
+
+       if ( username != NULL )
+       {
+               /* Add options using cupsAddOption() */
+               num_options = cupsAddOption("job-originating-user-name", username, num_options, &options);
+               num_options = cupsAddOption("originating-user-name", username, num_options, &options);
+               cupsSetUser ( username );
+       }
+
+       if (cupsoptions != NULL)
+       {
+              num_options = cupsParseOptions(cupsoptions, num_options, &options);
+       }
+       
+       strlcpy ( filepath, SPOOLDIR, sizeof(filepath));
+       strlcat ( filepath , "/", sizeof(filepath));
+       strlcat ( filepath , filename, sizeof(filepath));
+       
+       if ((jobid = cupsPrintFile( name, filepath, job, 0, options)) == 0)
+               LOG(log_error, logtype_papd, "Unable to print job '%s' (%s) to printer '%s' for user '%s' - CUPS error : '%s'\n", job, filepath, name, username, ippErrorString(cupsLastError()));
+       else 
+               LOG(log_info, logtype_papd, "Job '%s' queued to printer '%s' with id '%d'", job, name, jobid);
+
+       cupsFreeOptions(num_options, options);
+       return (jobid);
+}
+
+
+/*------------------------------------------------------------------------*/
+
+struct printer *
+cups_autoadd_printers ( struct printer *defprinter, struct printer *printers)
+{
+       struct printer  *pr;
+        int            num_dests,i;
+       int             ret;
+        cups_dest_t    *dests;
+        cups_lang_t    *language;
+       char            name[MAXCHOOSERLEN+1], *p;
+
+        language  = cupsLangDefault();         /* needed for conversion */
+        num_dests = cupsGetDests(&dests);      /* get the available destination from CUPS */
+
+        for  (i=0; i< num_dests; i++)
+        {
+               if (( pr = (struct printer *)malloc( sizeof( struct printer ))) == NULL ) {
+                       LOG(log_error, logtype_papd, "malloc: %m" );
+                       exit( 1 );
+               }
+       
+               memcpy( pr, defprinter, sizeof( struct printer ) );
+
+               /* convert from CUPS to local encoding */
+                convert_string_allocate( add_charset(cupsLangEncoding(language)), CH_UNIX, 
+                                         dests[i].name, strlen(dests[i].name), &pr->p_u_name);
+
+               /* convert CUPS name to Mac charset */
+               if ( convert_to_mac_name ( cupsLangEncoding(language), dests[i].name, name, sizeof(name)) <= 0)
+               {
+                       LOG (log_error, logtype_papd, "Conversion from CUPS to MAC name failed for %s", dests[i].name);
+                       free (pr);
+                       continue;
+               }
+
+               if (( pr->p_name = (char *)malloc( strlen( name ) + 1 )) == NULL ) {
+                       LOG(log_error, logtype_papd, "malloc: %m" );
+                       exit( 1 );
+               }
+               strcpy( pr->p_name, name );
+
+               /* set printer flags */
+               pr->p_flags &= ~P_PIPED;
+               pr->p_flags |= P_SPOOLED;
+               pr->p_flags |= P_CUPS;
+               pr->p_flags |= P_CUPS_AUTOADDED;
+                       
+               if (( pr->p_printer = (char *)malloc( strlen( dests[i].name ) + 1 )) == NULL ) {
+                       LOG(log_error, logtype_papd, "malloc: %m" );
+                               exit( 1 );
+               }
+               strcpy( pr->p_printer, dests[i].name );                 
+
+               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: %m" );
+                                       exit( 1 );
+                       }
+                       strcpy( pr->p_ppdfile, p );
+                       pr->p_flags |= P_CUPS_PPD;
+               }
+
+               if ( (ret = cups_check_printer ( pr, printers, 0)) == -1) 
+                       ret = cups_mangle_printer_name ( pr, printers );
+
+               if (ret) {
+                       cups_free_printer (pr);
+                       LOG(log_info, logtype_papd, "Printer %s not added: reason %d", name, ret);
+               }
+               else {
+                       pr->p_next = printers;
+                       printers = pr;
+               }
+       }
+        cupsFreeDests(num_dests, dests);
+        cupsLangFree(language);
+
+       return printers;
+}
+
+
+/*------------------------------------------------------------------------*/
+
+/* cups_mangle_printer_name
+ *    Mangles the printer name if two CUPS printer provide the same Chooser Name
+ *    Append '#nn' to the chooser name, if it is longer than 28 char we overwrite the last three chars
+ * Returns: 0 on Success, 2 on Error
+ */
+
+static int cups_mangle_printer_name ( struct printer *pr, struct printer *printers)
+{
+       size_t  count, name_len;
+       char    name[MAXCHOOSERLEN];
+
+       count = 1;
+       name_len = strlen (pr->p_name);
+       strncpy ( name, pr->p_name, MAXCHOOSERLEN-3);
+       
+       /* Reallocate necessary space */
+       (name_len >= MAXCHOOSERLEN-3) ? (name_len = MAXCHOOSERLEN+1) : (name_len = name_len + 4);
+       pr->p_name = (char *) realloc (pr->p_name, name_len );
+               
+       while ( ( cups_check_printer ( pr, printers, 0 )) && count < 100)
+       {
+               memset ( pr->p_name, 0, name_len);
+               strncpy ( pr->p_name, name, MAXCHOOSERLEN-3);
+               sprintf ( pr->p_name, "%s#%2.2u", pr->p_name, count++);
+       }
+
+       if ( count > 99) 
+               return (2);
+       
+       return (0);
+}      
+
+/*------------------------------------------------------------------------*/
+
+/* fallback ASCII conversion */
+
+static size_t
+to_ascii ( char  *inptr, char **outptr)
+{
+       char *out, *osav;
+
+       if ( NULL == (out = (char*) malloc ( strlen ( inptr) + 1 )) ) {
+               LOG(log_error, logtype_papd, "malloc: %m" );
+               exit (1);
+       }
+
+       osav = out;
+
+       while ( *inptr != '\0' ) {
+               if ( *inptr & 0x80 ) {
+                       *out = '_';
+                       out++;
+                       inptr++;
+               }
+               else
+                       *out++ = *inptr++;
+       }
+       *out = '\0';
+       *outptr = osav;
+       return ( strlen (osav) );
+}
+
+
+/*------------------------------------------------------------------------*/
+
+/* convert_to_mac_name
+ *     1) Convert from encoding to MacRoman
+ *     2) Shorten to MAXCHOOSERLEN (31)
+ *      3) Replace @ and _ as they are illegal
+ * Returns: -1 on failure, length of name on success; outpr contains name in MacRoman
+ */
+
+static int convert_to_mac_name ( char * encoding, char * inptr, char * outptr, size_t outlen)
+{
+       char    *outbuf;
+       char    *soptr;
+       size_t  name_len = 0;
+       size_t  i;
+       charset_t chCups;
+
+       /* Change the encoding */
+       if ((charset_t)-1 != (chCups = add_charset(encoding))) {
+               name_len = convert_string_allocate( chCups, CH_MAC, inptr, strlen(inptr), &outbuf);
+       }
+
+       if (name_len == 0 || name_len == (size_t)-1) {
+               /* charset conversion failed, use ascii fallback */
+               name_len = to_ascii ( inptr, &outbuf );
+       }
+       
+       soptr = outptr;
+
+       for ( i=0; i< name_len && i < outlen-1 ; i++)
+       {
+               if ( outbuf[i] == '_' ) 
+                       *soptr = ' '; /* Replace '_' with a space (just for the looks) */
+               else if ( outbuf[i] == '@' || outbuf[i] == ':' ) 
+                       *soptr = '_'; /* Replace @ and : with '_' as they are illegal chars */
+               else
+                       *soptr = outbuf[i];
+               soptr++;
+       }
+       *soptr = '\0';
+       free (outbuf);
+       return (i);
+}
+
+
+/*------------------------------------------------------------------------*/
+
+/*
+ * cups_check_printer:
+ * check if a printer with this name already exists.
+ * if yes, and replace = 1 the existing printer is replaced with
+ * the new one. This allows to overwrite printer settings
+ * created by cupsautoadd. It also used by cups_mangle_printer.
+ */
+
+int cups_check_printer ( struct printer *pr, struct printer *printers, int replace)
+{
+       struct printer *listptr, *listprev;
+
+       listptr = printers;
+       listprev = NULL;
+
+       while ( listptr != NULL) {
+               if ( strcasecmp (pr->p_name, listptr->p_name) == 0) {
+                       if ( pr->p_flags & P_CUPS_AUTOADDED ) {  /* Check if printer has been autoadded */
+                               if ( listptr->p_flags & P_CUPS_AUTOADDED )
+                                       return (-1);             /* Conflicting Cups Auto Printer (mangling issue?) */
+                               else
+                                       return (1);              /* Never replace a hand edited printer with auto one */
+                       }
+
+                       if ( replace ) {
+                               /* Replace printer */
+                               if ( listprev != NULL) {
+                                       pr->p_next = listptr->p_next;
+                                       listprev->p_next = pr;
+                                       cups_free_printer (listptr);
+                               }
+                               else {
+                                       printers = pr;
+                                       printers->p_next = listptr->p_next;
+                                       cups_free_printer (listptr);
+                               }
+                       }
+                       return (1);  /* Conflicting Printers */
+               }
+               listprev = listptr;
+               listptr = listptr->p_next;
+       }       
+       return (0);     /* No conflict */
+}
+
+
+/*------------------------------------------------------------------------*/
+
+
+void
+cups_free_printer ( struct printer *pr)
+{
+       if ( pr->p_name != NULL)
+               free (pr->p_name);
+       if ( pr->p_printer != NULL)
+               free (pr->p_printer);
+       if ( pr->p_ppdfile != NULL)
+               free (pr->p_ppdfile);
+       
+       /* CUPS autoadded printers share the other informations
+        * so if the printer is autoadded we won't free them.
+        * We might leak some bytes here though.
+        */
+       if ( pr->p_flags & P_CUPS_AUTOADDED ) {
+               free (pr);
+               return;
+       }
+
+       if ( pr->p_operator != NULL )
+               free (pr->p_operator);
+       if ( pr->p_zone != NULL )
+               free (pr->p_zone);
+       if ( pr->p_type != NULL )
+               free (pr->p_type);
+       if ( pr->p_authprintdir != NULL )
+               free (pr->p_authprintdir);
+       
+       free ( pr );
+       return;
+       
+}
+       
+#endif /* HAVE_CUPS*/
diff --git a/etc/papd/print_cups.h b/etc/papd/print_cups.h
new file mode 100644 (file)
index 0000000..2811a84
--- /dev/null
@@ -0,0 +1,21 @@
+\r
+#ifndef PAPD_CUPS_H\r
+#define PAPD_CUPS_H 1\r
+\r
+#ifdef HAVE_CUPS\r
+#include <sys/cdefs.h>\r
+\r
+struct cups_status {\r
+       int     pr_status;\r
+       char *  status_message;\r
+};\r
+\r
+int            cups_printername_ok __P((char * ));\r
+const char *   cups_get_printer_ppd __P(( char * ));\r
+int            cups_get_printer_status __P((struct printer *pr));\r
+int            cups_print_job __P(( char *, char *, char *, char *, char *));\r
+struct printer * cups_autoadd_printers __P(( struct printer *, struct printer *));\r
+int            cups_check_printer __P(( struct printer *, struct printer *, int));\r
+char           *cups_get_language __P(());\r
+#endif /* HAVE_CUPS */\r
+#endif /* PAPD_CUPS_H */\r
index 49ed104b9c245887f6693e665b65e47f99fd1a5f..2085c9a81a894052a5c4dff52b625b1b1e2a677d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: printer.h,v 1.5 2001-06-25 20:13:45 rufustfirefly Exp $
+ * $Id: printer.h,v 1.5.14.1 2004-06-09 01:25:54 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1995 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -9,11 +9,13 @@ struct printer {
     char               *p_name;
     char               *p_type;
     char               *p_zone;
+    char               *p_u_name;
 #ifdef notdef
     char               *p_fonts;
     char               *p_psetdir;
 #endif /* notdef */
     char               *p_ppdfile;
+    char               p_status[255];
     char               *p_authprintdir;
     int                        p_flags;
     struct at_addr      p_addr;
@@ -34,6 +36,9 @@ struct printer {
        char            *pu_cmd;
     } p_un;
     ATP                        p_atp;
+#ifdef HAVE_CUPS
+    char               *p_cupsoptions;
+#endif
     struct printer     *p_next;
 };
 #define p_cmd          p_un.pu_cmd
@@ -57,5 +62,9 @@ struct printer {
 #define P_AUTH         (1<<5)
 #define P_AUTH_PSSP    (1<<6)
 #define P_AUTH_CAP     (1<<7)
+#define P_CUPS         (1<<8)
+#define P_CUPS_PPD     (1<<9)
+#define P_CUPS_AUTOADDED (1<<10)
+#define P_FOOMATIC_HACK (1<<11)
 
 extern struct printer  *printer;
index e7586d5b44f7c8deb1f942034146356166fe3e50..5c056823911166ef6fa80483dd3a376f0aecd44e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: queries.c,v 1.16.2.1 2003-09-03 20:40:50 didg Exp $
+ * $Id: queries.c,v 1.16.2.1.2.1 2004-06-09 01:25:54 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -50,8 +50,10 @@ int cq_font( struct papfile *, struct papfile * );
 int cq_feature( struct papfile *, struct papfile * );
 int cq_printer( struct papfile *, struct papfile * );
 int cq_rmjob( struct papfile *, struct papfile * );
+#ifndef HAVE_CUPS
 int cq_listq( struct papfile *, struct papfile * );
 int cq_rbilogin( struct papfile *, struct papfile * );
+#endif  /* HAVE_CUPS */
 
 
 
@@ -600,6 +602,8 @@ int cq_printer( in, out )
     }
 }
 
+#ifndef HAVE_CUPS
+
 static const char      *rmjobfailed = "Failed\n";
 static const char      *rmjobok = "Ok\n";
 
@@ -666,6 +670,7 @@ int cq_listq( in, out )
     CONSUME( in, linelength + crlflength );
     return( CH_DONE );
 }
+#endif /* HAVE_CUPS */
 
 
 /*
@@ -747,8 +752,10 @@ struct papd_comment        queries[] = {
     { "%%Login: UMICHKerberosIV", 0,                   cq_k4login,     0 },
     { "%%?BeginUAMethodsQuery",        "%%?EndUAMethodsQuery:", cq_uameth, C_FULL },
 #endif /* KRB */
+#ifndef HAVE_CUPS
     { "%UMICHListQueue", 0,                            cq_listq, C_FULL },
     { "%UMICHDeleteJob", 0,                            cq_rmjob,       0 },
+#endif /* HAVE_CUPS */
     { "%%?BeginQuery: RBILogin ", "%%?EndQuery",       cq_rbilogin,    0 },
     { "%%?BeginQuery",         "%%?EndQuery",          cq_query,       0 },
     { "%%?BeginFeatureQuery",  "%%?EndFeatureQuery",   cq_feature,     0 },
index 968f48362e9d65f7924dbf2e64f58584b02e47b7..689189b76ccf16fa784cdee86f66c63269682e67 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: showppd.c,v 1.5 2002-01-04 04:45:48 sibaz Exp $
+ * $Id: showppd.c,v 1.5.10.1 2004-06-09 01:25:54 bfernhomberg Exp $
  *
  * Copyright (c) 1995 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -26,7 +26,7 @@ extern struct ppd_font                *ppd_fonts;
 extern struct ppd_feature      ppd_features[];
 
 
-main( ac, av )
+int main( ac, av )
     int                ac;
     char       **av;
 {
@@ -43,8 +43,8 @@ main( ac, av )
        printf( "Font: %s\n", pfo->pd_font );
     }
     for ( pfe = ppd_features; pfe->pd_name; pfe++ ) {
-       printf( "Feature: %s %s\n", pfe->pd_name, pfe->pd_value );
+       printf( "Feature: %s %s\n", pfe->pd_name, (pfe->pd_value)?pfe->pd_value:"NULL" );
     }
 
-    exit( 0 );
+    exit ( 0 );
 }