X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fpapd%2Flp.c;h=3b817b9f4d3c7d1cdca4d496ad517b9dafcdf377;hb=5f5367aa2eedd7e8538566a83d163cc549c9d68f;hp=60ae548c8aedf73680f6dc4da6bab0ddeaddf796;hpb=33cdcb8d9746a9594df782e5a4f200f4ab61585f;p=netatalk.git diff --git a/etc/papd/lp.c b/etc/papd/lp.c index 60ae548c..3b817b9f 100644 --- a/etc/papd/lp.c +++ b/etc/papd/lp.c @@ -1,4 +1,6 @@ /* + * $Id: lp.c,v 1.31 2009-10-22 13:40:11 franklahm Exp $ + * * Copyright (c) 1990,1994 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. * @@ -39,82 +41,284 @@ * Interface to lpr system. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + #include -#include #include #include #include -#if defined( sun ) && defined( __svr4__ ) -#include -#else sun __svr4__ +#include +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ + #include -#endif sun __svr4__ #include #include #undef s_net -#include -#include -#include #ifdef ABS_PRINT #include -#endif ABS_PRINT - +#endif /* ABS_PRINT */ #include #include #include #include +#ifdef HAVE_FCNTL_H #include +#endif /* HAVE_FCNTL_H */ +#include + +#include +#include +#include +#include +#include #include "printer.h" #include "file.h" +#include "lp.h" -char hostname[ MAXHOSTNAMELEN ]; +#ifdef HAVE_CUPS +#include "print_cups.h" +#endif -/* initialize printing interface */ -int lp_init(); -/* cancel current job */ -int lp_cancel(); -/* print current job */ -int lp_print(); -/* open a file for spooling */ -int lp_open(); -/* open a buffer to the current open file */ -int lp_write(); -/* close current spooling file */ -int lp_close(); +/* These functions aren't used outside of lp.c */ +int lp_conn_inet(); +int lp_disconn_inet( int ); +int lp_conn_unix(); +int lp_disconn_unix( int ); -struct lp { +static char hostname[ MAXHOSTNAMELEN ]; + +extern struct sockaddr_at *sat; + +static 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=(unsigned char *)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) + +#if 0 +/* removed, it's not used and a pain to get it right from a security POV */ +static size_t quote(char *dest, char *src, const size_t bsize, size_t len) +{ +size_t used = 0; + + while (len && used < bsize ) { + switch (*src) { + case '$': + case '\\': + case '"': + case '`': + if (used + 2 > bsize ) + return used; + *dest = '\\'; + dest++; + used++; + break; + } + *dest = *src; + src++; + dest++; + len--; + used++; + } + return used; +} + +static char* pipexlate(char *src) +{ + char *p, *q, *dest; + static char destbuf[MAXPATHLEN +1]; + size_t destlen = MAXPATHLEN; + int len = 0; + + dest = destbuf; + + if (!src) + return NULL; + + memset(dest, 0, MAXPATHLEN +1); + if ((p = strchr(src, '%')) == NULL) { /* nothing to do */ + strncpy(dest, src, MAXPATHLEN); + return destbuf; + } + /* first part of the path. copy and forward to the next variable. */ + len = MIN((size_t)(p - src), destlen); + if (len > 0) { + strncpy(dest, src, len); + destlen -= len; + dest += len; + } -lp_person( person ) - char *person; + 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 = "%"; + } + + /* copy the stuff over. if we don't understand something that we + * should, just skip it over. */ + if (q) { + len = MIN(strlen(q), destlen); + len = quote(dest, q, destlen, len); + } + else { + len = MIN(2, 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; + } + } + if (!destlen) { + /* reach end of buffer, maybe prematurely, give up */ + return NULL; + } + return destbuf; +} +#endif + +void lp_person(char *person) { if ( lp.lp_person != NULL ) { free( lp.lp_person ); } if (( lp.lp_person = (char *)malloc( strlen( person ) + 1 )) == NULL ) { - syslog( LOG_ERR, "malloc: %m" ); + LOG(log_error, logtype_papd, "malloc: %s", strerror(errno) ); exit( 1 ); } strcpy( lp.lp_person, person ); } #ifdef ABS_PRINT -lp_pagecost() +int lp_pagecost(void) { char cost[ 22 ]; char balance[ 22 ]; @@ -129,78 +333,136 @@ lp_pagecost() printer->p_balance = atof( balance ) + atof( cost ); return( err < 0 ? -1 : 0 ); } -#endif ABS_PRINT +#endif /* ABS_PRINT */ -lp_host( host ) - char *host; +void lp_host( char *host) { if ( lp.lp_host != NULL ) { free( lp.lp_host ); } if (( lp.lp_host = (char *)malloc( strlen( host ) + 1 )) == NULL ) { - syslog( LOG_ERR, "malloc: %m" ); + LOG(log_error, logtype_papd, "malloc: %s", strerror(errno) ); exit( 1 ); } strcpy( lp.lp_host, host ); + LOG(log_debug, logtype_papd, "host: %s", lp.lp_host ); } -lp_job( job ) - char *job; -{ - char *p, *q; +/* Currently lp_job and lp_for will not handle the + * conversion of macroman chars > 0x7f correctly + * This should be added. + */ +void lp_job(char *job) +{ if ( lp.lp_job != NULL ) { free( lp.lp_job ); } - if (( lp.lp_job = (char *)malloc( strlen( job ) + 1 )) == NULL ) { - syslog( LOG_ERR, "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 (char *lpfor) +{ + if ( lp.lp_created_for != NULL ) { + free( lp.lp_created_for ); } - *q = '\0'; + + lp.lp_created_for = strdup(lpfor); } -lp_init( out ) - struct papfile *out; + +static int lp_init(struct papfile *out, struct sockaddr_at *sat) { + int authenticated = 0; +#ifndef HAVE_CUPS int fd, n, len; char *cp, buf[ BUFSIZ ]; struct stat st; +#endif /* HAVE_CUPS */ #ifdef ABS_PRINT char cost[ 22 ]; char balance[ 22 ]; -#endif ABS_PRINT +#endif /* ABS_PRINT */ if ( printer->p_flags & P_AUTH ) { - if ( lp.lp_person == NULL ) { - syslog( LOG_ERR, "lp_init: must authenticate" ); + authenticated = 0; + + /* cap style "log on to afp server before printing" authentication */ + + if ( printer->p_authprintdir && (printer->p_flags & P_AUTH_CAP) ) { + int addr_net = ntohs( sat->sat_addr.s_net ); + int addr_node = sat->sat_addr.s_node; + char addr_filename[256]; + char auth_string[256]; + char *username, *afpdpid; + struct stat cap_st; + FILE *cap_file; + + memset( auth_string, 0, 256 ); + sprintf(addr_filename, "%s/net%d.%dnode%d", + printer->p_authprintdir, addr_net/256, addr_net%256, + addr_node); + if (stat(addr_filename, &cap_st) == 0) { + if ((cap_file = fopen(addr_filename, "r")) != NULL) { + if (fgets(auth_string, 256, cap_file) != NULL) { + username = auth_string; + if ((afpdpid = strrchr( auth_string, ':' )) != NULL) { + *afpdpid = '\0'; + afpdpid++; + } + if (getpwnam(username) != NULL ) { + LOG(log_info, logtype_papd, "CAP authenticated %s", username); + lp_person(username); + authenticated = 1; + } else { + LOG(log_info, logtype_papd, "CAP error: invalid username: '%s'", username); + } + } else { + LOG(log_info, logtype_papd, "CAP error: could not read username"); + } + } else { + LOG(log_info, logtype_papd, "CAP error: %s", strerror(errno)); + } + } else { + LOG(log_info, logtype_papd, "CAP error: %s", strerror(errno)); + } + } + + if ( printer->p_flags & P_AUTH_PSSP ) { + if ( lp.lp_person != NULL ) { + authenticated = 1; + } + } + + if ( authenticated == 0 ) { + LOG(log_error, logtype_papd, "lp_init: must authenticate" ); spoolerror( out, "Authentication required." ); return( -1 ); } + #ifdef ABS_PRINT if (( printer->p_flags & P_ACCOUNT ) && printer->p_pagecost > 0 && ! ABS_canprint( lp.lp_person, printer->p_role, printer->p_srvid, cost, balance )) { - syslog( LOG_ERR, "lp_init: no ABS funds" ); + LOG(log_error, logtype_papd, "lp_init: no ABS funds" ); spoolerror( out, "No ABS funds available." ); return( -1 ); } -#endif ABS_PRINT +#endif /* ABS_PRINT */ } if ( gethostname( hostname, sizeof( hostname )) < 0 ) { - syslog( LOG_ERR, "gethostname: %m" ); + LOG(log_error, logtype_papd, "gethostname: %s", strerror(errno) ); exit( 1 ); } if ( lp.lp_flags & LP_INIT ) { - syslog( LOG_ERR, "lp_init: already inited, die!" ); + LOG(log_error, logtype_papd, "lp_init: already inited, die!" ); abort(); } @@ -209,33 +471,37 @@ lp_init( out ) 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 ) { - syslog( LOG_ERR, "lp_init: %s: %m", printer->p_lock ); + LOG(log_error, logtype_papd, "lp_init: %s: %s", printer->p_lock, strerror(errno) ); spoolerror( out, NULL ); return( -1 ); } if ( st.st_mode & 010 ) { - syslog( LOG_INFO, "lp_init: queuing is disabled" ); + LOG(log_info, logtype_papd, "lp_init: queuing is disabled" ); spoolerror( out, "Queuing is disabled." ); return( -1 ); } if (( fd = open( ".seq", O_RDWR|O_CREAT, 0661 )) < 0 ) { - syslog( LOG_ERR, "lp_init: can't create .seq" ); + LOG(log_error, logtype_papd, "lp_init: can't create .seq" ); spoolerror( out, NULL ); return( -1 ); } +#ifndef SOLARIS /* flock is unsupported, I doubt this stuff works anyway with newer solaris so ignore for now */ if ( flock( fd, LOCK_EX ) < 0 ) { - syslog( LOG_ERR, "lp_init: can't lock .seq" ); + LOG(log_error, logtype_papd, "lp_init: can't lock .seq" ); spoolerror( out, NULL ); return( -1 ); } +#endif n = 0; if (( len = read( fd, buf, sizeof( buf ))) < 0 ) { - syslog( LOG_ERR, "lp_init read: %m" ); + LOG(log_error, logtype_papd, "lp_init read: %s", strerror(errno) ); spoolerror( out, NULL ); return( -1 ); } @@ -254,6 +520,16 @@ lp_init( out ) 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(); @@ -263,79 +539,210 @@ lp_init( out ) return( 0 ); } -lp_open( out ) - struct papfile *out; +int lp_open(struct papfile *out, struct sockaddr_at *sat) { char name[ MAXPATHLEN ]; int fd; + struct passwd *pwent; + +#ifdef DEBUG + LOG (log_debug, logtype_papd, "lp_open"); +#endif - if (( lp.lp_flags & LP_INIT ) == 0 && lp_init( out ) != 0 ) { + 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 ) { - syslog( LOG_ERR, "lp_open already open" ); - abort(); + /* LOG(log_error, logtype_papd, "lp_open already open" ); */ + /* abort(); */ + return (-1); } if ( lp.lp_flags & LP_PIPE ) { + char *pipe_cmd; + /* go right to program */ - if (( lp.lp_stream = popen( printer->p_printer, "w" )) == NULL ) { - syslog( LOG_ERR, "lp_open popen %s: %m", printer->p_printer ); + if (lp.lp_person != NULL) { + if((pwent = getpwnam(lp.lp_person)) != NULL) { + if(setreuid(pwent->pw_uid, pwent->pw_uid) != 0) { + LOG(log_error, logtype_papd, "setreuid error: %s", strerror(errno)); + exit(1); + } + } else { + LOG(log_error, logtype_papd, "Error getting username (%s)", lp.lp_person); + exit(1); + } + } + + lp_setup_comments(CH_UNIX); + pipe_cmd = printer->p_printer; + if (!pipe_cmd) { + LOG(log_error, logtype_papd, "lp_open: no pipe cmd" ); + spoolerror( out, NULL ); + return( -1 ); + } + if (( lp.lp_stream = popen(pipe_cmd, "w" )) == NULL ) { + LOG(log_error, logtype_papd, "lp_open popen %s: %s", printer->p_printer, strerror(errno) ); spoolerror( out, NULL ); return( -1 ); } + LOG(log_debug, logtype_papd, "lp_open: opened %s", pipe_cmd ); } else { sprintf( name, "df%c%03d%s", lp.lp_letter++, lp.lp_seq, hostname ); if (( fd = open( name, O_WRONLY|O_CREAT|O_EXCL, 0660 )) < 0 ) { - syslog( LOG_ERR, "lp_open %s: %m", name ); + LOG(log_error, logtype_papd, "lp_open %s: %s", name, strerror(errno) ); spoolerror( out, NULL ); return( -1 ); } + + if ( NULL == (lp.lp_spoolfile = (char *) malloc (strlen (name) +1)) ) { + LOG(log_error, logtype_papd, "malloc: %s", strerror(errno)); + 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); + spoolerror( out, NULL ); + return( -1 ); + } + } else { + if ((pwent = getpwnam(printer->p_operator)) == NULL) { + LOG(log_error, logtype_papd, "getpwnam %s: no such user", printer->p_operator); + spoolerror( out, NULL ); + return( -1 ); + } + } + + if (fchown(fd, pwent->pw_uid, -1) < 0) { + LOG(log_error, logtype_papd, "chown %s %s: %s", pwent->pw_name, name, strerror(errno)); + spoolerror( out, NULL ); + return( -1 ); + } + if (( lp.lp_stream = fdopen( fd, "w" )) == NULL ) { - syslog( LOG_ERR, "lp_open fdopen: %m" ); + LOG(log_error, logtype_papd, "lp_open fdopen: %s", strerror(errno) ); 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 ); } -lp_close() +int lp_close(void) { if (( lp.lp_flags & LP_INIT ) == 0 || ( lp.lp_flags & LP_OPEN ) == 0 ) { - return; + return 0; } fclose( lp.lp_stream ); lp.lp_stream = NULL; lp.lp_flags &= ~LP_OPEN; - return; + lp.lp_flags |= LP_JOBPENDING; + return 0; } -lp_write( buf, len ) - char *buf; - int len; + + +int lp_write(struct papfile *in, char *buf, 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: %s", strerror(errno) ); + abort(); + } + bufpos=0; } - if ( fwrite( buf, 1, len, lp.lp_stream ) != len ) { - syslog( LOG_ERR, "lp_write: %m" ); + if ( fwrite( tbuf, 1, len, lp.lp_stream ) != len ) { + LOG(log_error, logtype_papd, "lp_write: %s", strerror(errno) ); abort(); } return( 0 ); } -lp_cancel() +int lp_cancel(void) { char name[ MAXPATHLEN ]; char letter; if (( lp.lp_flags & LP_INIT ) == 0 || lp.lp_letter == 'A' ) { - return; + return 0; } if ( lp.lp_flags & LP_OPEN ) { @@ -345,11 +752,11 @@ lp_cancel() for ( letter = 'A'; letter < lp.lp_letter; letter++ ) { sprintf( name, "df%c%03d%s", letter, lp.lp_seq, hostname ); if ( unlink( name ) < 0 ) { - syslog( LOG_ERR, "lp_cancel unlink %s: %m", name ); + LOG(log_error, logtype_papd, "lp_cancel unlink %s: %s", name, strerror(errno) ); } } - return; + return 0; } /* @@ -358,29 +765,33 @@ lp_cancel() * * XXX piped? */ -lp_print() +int lp_print(void) { +#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; + 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 ) { - syslog( LOG_ERR, "lp_print %s: %m", tfname ); - return; + LOG(log_error, logtype_papd, "lp_print %s: %s", tfname, strerror(errno) ); + return 0; } if (( cfile = fdopen( fd, "w" )) == NULL ) { - syslog( LOG_ERR, "lp_print %s: %m", tfname ); - return; + LOG(log_error, logtype_papd, "lp_print %s: %s", tfname, strerror(errno) ); + return 0; } fprintf( cfile, "H%s\n", hostname ); /* XXX lp_host? */ @@ -420,59 +831,79 @@ lp_print() sprintf( cfname, "cfA%03d%s", lp.lp_seq, hostname ); if ( link( tfname, cfname ) < 0 ) { - syslog( LOG_ERR, "lp_print can't link %s to %s: %m", cfname, - tfname ); - return; + LOG(log_error, logtype_papd, "lp_print can't link %s to %s: %s", cfname, + tfname, strerror(errno) ); + return 0; } unlink( tfname ); if (( s = lp_conn_unix()) < 0 ) { - syslog( LOG_ERR, "lp_print: lp_conn_unix: %m" ); - return; + LOG(log_error, logtype_papd, "lp_print: lp_conn_unix: %s", strerror(errno) ); + return 0; } sprintf( buf, "\1%s\n", printer->p_printer ); n = strlen( buf ); if ( write( s, buf, n ) != n ) { - syslog( LOG_ERR, "lp_print write: %m" ); - return; + LOG(log_error, logtype_papd, "lp_print write: %s" , strerror(errno)); + return 0; } if ( read( s, buf, 1 ) != 1 ) { - syslog( LOG_ERR, "lp_print read: %m" ); - return; + LOG(log_error, logtype_papd, "lp_print read: %s" , strerror(errno)); + return 0; } lp_disconn_unix( s ); if ( buf[ 0 ] != '\0' ) { - syslog( LOG_ERR, "lp_print lpd said %c: %m", buf[ 0 ] ); - return; + LOG(log_error, logtype_papd, "lp_print lpd said %c: %s", buf[ 0 ], strerror(errno) ); + 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*/ } - syslog( LOG_INFO, "lp_print queued" ); - return; + LOG(log_info, logtype_papd, "lp_print queued" ); + return 0; } -lp_disconn_unix( fd ) +#ifndef HAVE_CUPS +int lp_disconn_unix( int fd ) { return( close( fd )); } -lp_conn_unix() +int lp_conn_unix(void) { int s; struct sockaddr_un saun; if (( s = socket( AF_UNIX, SOCK_STREAM, 0 )) < 0 ) { - syslog( LOG_ERR, "lp_conn_unix socket: %m" ); + LOG(log_error, logtype_papd, "lp_conn_unix socket: %s", strerror(errno) ); return( -1 ); } - bzero( &saun, sizeof( struct sockaddr_un )); + memset( &saun, 0, sizeof( struct sockaddr_un )); saun.sun_family = AF_UNIX; strcpy( saun.sun_path, _PATH_DEVPRINTER ); if ( connect( s, (struct sockaddr *)&saun, strlen( saun.sun_path ) + 2 ) < 0 ) { - syslog( LOG_ERR, "lp_conn_unix connect %s: %m", saun.sun_path ); + LOG(log_error, logtype_papd, "lp_conn_unix connect %s: %s", saun.sun_path, strerror(errno) ); close( s ); return( -1 ); } @@ -480,12 +911,12 @@ lp_conn_unix() return( s ); } -lp_disconn_inet( fd ) +int lp_disconn_inet( int fd ) { return( close( fd )); } -lp_conn_inet() +int lp_conn_inet(void) { int privfd, port = IPPORT_RESERVED - 1; struct sockaddr_in sin; @@ -493,35 +924,35 @@ lp_conn_inet() struct hostent *hp; if (( sp = getservbyname( "printer", "tcp" )) == NULL ) { - syslog( LOG_ERR, "printer/tcp: unknown service\n" ); + LOG(log_error, logtype_papd, "printer/tcp: unknown service" ); return( -1 ); } if ( gethostname( hostname, sizeof( hostname )) < 0 ) { - syslog( LOG_ERR, "gethostname: %m" ); + LOG(log_error, logtype_papd, "gethostname: %s", strerror(errno) ); exit( 1 ); } if (( hp = gethostbyname( hostname )) == NULL ) { - syslog( LOG_ERR, "%s: unknown host\n", hostname ); + LOG(log_error, logtype_papd, "%s: unknown host", hostname ); return( -1 ); } if (( privfd = rresvport( &port )) < 0 ) { - syslog( LOG_ERR, "lp_connect: socket: %m" ); + LOG(log_error, logtype_papd, "lp_connect: socket: %s", strerror(errno) ); close( privfd ); return( -1 ); } - bzero( &sin, sizeof( struct sockaddr_in )); + memset( &sin, 0, sizeof( struct sockaddr_in )); sin.sin_family = AF_INET; /* sin.sin_addr.s_addr = htonl( INADDR_LOOPBACK ); */ - bcopy( hp->h_addr, &sin.sin_addr, hp->h_length ); + memcpy( &sin.sin_addr, hp->h_addr, hp->h_length ); sin.sin_port = sp->s_port; if ( connect( privfd, (struct sockaddr *)&sin, sizeof( struct sockaddr_in )) < 0 ) { - syslog( LOG_ERR, "lp_connect: %m" ); + LOG(log_error, logtype_papd, "lp_connect: %s", strerror(errno) ); close( privfd ); return( -1 ); } @@ -529,14 +960,13 @@ lp_conn_inet() return( privfd ); } -lp_rmjob( job ) - int job; +int lp_rmjob( int job) { char buf[ 1024 ]; int n, s; if (( s = lp_conn_inet()) < 0 ) { - syslog( LOG_ERR, "lp_rmjob: %m" ); + LOG(log_error, logtype_papd, "lp_rmjob: %s", strerror(errno) ); return( -1 ); } @@ -547,12 +977,12 @@ lp_rmjob( job ) sprintf( buf, "\5%s %s %d\n", printer->p_printer, lp.lp_person, job ); n = strlen( buf ); if ( write( s, buf, n ) != n ) { - syslog( LOG_ERR, "lp_rmjob write: %m" ); + LOG(log_error, logtype_papd, "lp_rmjob write: %s", strerror(errno) ); lp_disconn_inet( s ); return( -1 ); } while (( n = read( s, buf, sizeof( buf ))) > 0 ) { - syslog( LOG_DEBUG, "read %.*s", n, buf ); + LOG(log_debug, logtype_papd, "read %.*s", n, buf ); } lp_disconn_inet( s ); @@ -569,23 +999,24 @@ char *tag_files = "files: "; char *tag_size = "size: "; char *tag_status = "status: "; -lp_queue( out ) - struct papfile *out; +int lp_queue( struct papfile *out) { char buf[ 1024 ], *start, *stop, *p, *q; int linelength, crlflength; static struct papfile pf; - int n, len, s; + int s; + size_t len; + ssize_t n; if (( s = lp_conn_unix()) < 0 ) { - syslog( LOG_ERR, "lp_queue: %m" ); + LOG(log_error, logtype_papd, "lp_queue: %s", strerror(errno) ); return( -1 ); } sprintf( buf, "\3%s\n", printer->p_printer ); n = strlen( buf ); if ( write( s, buf, n ) != n ) { - syslog( LOG_ERR, "lp_queue write: %m" ); + LOG(log_error, logtype_papd, "lp_queue write: %s", strerror(errno) ); lp_disconn_unix( s ); return( -1 ); } @@ -719,3 +1150,4 @@ lp_queue( out ) } } } +#endif /* HAVE_CUPS */