/*
+ * $Id: lp.c,v 1.11 2002-01-03 17:49:39 sibaz Exp $
+ *
* Copyright (c) 1990,1994 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
*
* Interface to lpr system.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
#include <sys/param.h>
-#include <sys/syslog.h>
+#include <syslog.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <ctype.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
#if defined( sun ) && defined( __svr4__ )
#include </usr/ucbinclude/sys/file.h>
-#else sun __svr4__
+#else /* sun && __svr4__ */
#include <sys/file.h>
-#endif sun __svr4__
+#endif /* sun && __svr4__ */
#include <sys/un.h>
#include <netinet/in.h>
#undef s_net
#ifdef ABS_PRINT
#include <math.h>
-#endif ABS_PRINT
+#endif /* ABS_PRINT */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
#include <pwd.h>
#include "printer.h"
#include "file.h"
+#include "lp.h"
+
+/* 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 );
char hostname[ MAXHOSTNAMELEN ];
extern struct sockaddr_at *sat;
-/* 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();
-
struct lp {
int lp_flags;
FILE *lp_stream;
#define LP_CONNECT (1<<3)
#define LP_QUEUE (1<<4)
-lp_person( person )
+void lp_person( person )
char *person;
{
if ( lp.lp_person != NULL ) {
}
#ifdef ABS_PRINT
-lp_pagecost()
+int lp_pagecost()
{
char cost[ 22 ];
char balance[ 22 ];
printer->p_balance = atof( balance ) + atof( cost );
return( err < 0 ? -1 : 0 );
}
-#endif ABS_PRINT
+#endif /* ABS_PRINT */
-lp_host( host )
+void lp_host( host )
char *host;
{
if ( lp.lp_host != NULL ) {
strcpy( lp.lp_host, host );
}
-lp_job( job )
+void lp_job( job )
char *job;
{
char *p, *q;
*q = '\0';
}
-lp_init( out, sat )
+int lp_init( out, sat )
struct papfile *out;
struct sockaddr_at *sat;
{
#ifdef ABS_PRINT
char cost[ 22 ];
char balance[ 22 ];
-#endif ABS_PRINT
-#ifdef CAPDIR
- char username[32];
- int addr_net, addr_node;
- FILE *cap_file;
- struct stat cap_st;
- char addr_filename[256];
-#endif /* CAPDIR */
+#endif /* ABS_PRINT */
if ( printer->p_flags & P_AUTH ) {
authenticated = 0;
-#ifdef CAPDIR
- if ( printer->p_flags & P_AUTH_CAP ) {
- addr_net = ntohs( sat->sat_addr.s_net );
- addr_node = sat->sat_addr.s_node;
- sprintf(addr_filename, "%s/net%d.%dnode%d", CAPDIR, addr_net/256, addr_net%256, addr_node);
+
+ /* 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 username[32];
+ struct stat cap_st;
+ FILE *cap_file;
+
+ 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 (fscanf(cap_file, "%s", username) != EOF) {
syslog(LOG_INFO, "CAP error: %m");
}
}
-#endif /* CAPDIR */
if ( printer->p_flags & P_AUTH_PSSP ) {
if ( lp.lp_person != NULL ) {
spoolerror( out, "No ABS funds available." );
return( -1 );
}
-#endif ABS_PRINT
+#endif /* ABS_PRINT */
}
if ( gethostname( hostname, sizeof( hostname )) < 0 ) {
return( 0 );
}
-lp_open( out, sat )
+int lp_open( out, sat )
struct papfile *out;
struct sockaddr_at *sat;
{
spoolerror( out, NULL );
return( -1 );
}
+
+ if (lp.lp_person != NULL) {
+ if ((pwent = getpwnam(lp.lp_person)) == NULL) {
+ syslog(LOG_ERR, "getpwnam %s: no such user", lp.lp_person);
+ spoolerror( out, NULL );
+ return( -1 );
+ }
+ } else {
+ if ((pwent = getpwnam(printer->p_operator)) == NULL) {
+ syslog(LOG_ERR, "getpwnam %s: no such user", printer->p_operator);
+ spoolerror( out, NULL );
+ return( -1 );
+ }
+ }
+
+ if (fchown(fd, pwent->pw_uid, -1) < 0) {
+ syslog(LOG_ERR, "chown %s %s: %m", pwent->pw_name, name);
+ spoolerror( out, NULL );
+ return( -1 );
+ }
+
if (( lp.lp_stream = fdopen( fd, "w" )) == NULL ) {
syslog( LOG_ERR, "lp_open fdopen: %m" );
spoolerror( out, NULL );
return( 0 );
}
-lp_close()
+int lp_close()
{
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;
+ return 0;
}
-lp_write( buf, len )
+int lp_write( buf, len )
char *buf;
int len;
{
return( 0 );
}
-lp_cancel()
+int lp_cancel()
{
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 ) {
}
}
- return;
+ return 0;
}
/*
*
* XXX piped?
*/
-lp_print()
+int lp_print()
{
char buf[ MAXPATHLEN ];
char tfname[ MAXPATHLEN ];
FILE *cfile;
if (( lp.lp_flags & LP_INIT ) == 0 || lp.lp_letter == 'A' ) {
- return;
+ return 0;
}
lp_close();
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;
+ return 0;
}
if (( cfile = fdopen( fd, "w" )) == NULL ) {
syslog( LOG_ERR, "lp_print %s: %m", tfname );
- return;
+ return 0;
}
fprintf( cfile, "H%s\n", hostname ); /* XXX lp_host? */
if ( link( tfname, cfname ) < 0 ) {
syslog( LOG_ERR, "lp_print can't link %s to %s: %m", cfname,
tfname );
- return;
+ return 0;
}
unlink( tfname );
if (( s = lp_conn_unix()) < 0 ) {
syslog( LOG_ERR, "lp_print: lp_conn_unix: %m" );
- return;
+ 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;
+ return 0;
}
if ( read( s, buf, 1 ) != 1 ) {
syslog( LOG_ERR, "lp_print read: %m" );
- return;
+ return 0;
}
lp_disconn_unix( s );
if ( buf[ 0 ] != '\0' ) {
syslog( LOG_ERR, "lp_print lpd said %c: %m", buf[ 0 ] );
- return;
+ return 0;
}
}
syslog( LOG_INFO, "lp_print queued" );
- return;
+ return 0;
}
-lp_disconn_unix( fd )
+int lp_disconn_unix( fd )
{
return( close( fd ));
}
-lp_conn_unix()
+int lp_conn_unix()
{
int s;
struct sockaddr_un saun;
syslog( LOG_ERR, "lp_conn_unix socket: %m" );
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,
return( s );
}
-lp_disconn_inet( fd )
+int lp_disconn_inet( int fd )
{
return( close( fd ));
}
-lp_conn_inet()
+int lp_conn_inet()
{
int privfd, port = IPPORT_RESERVED - 1;
struct sockaddr_in sin;
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,
return( privfd );
}
-lp_rmjob( job )
+int lp_rmjob( job )
int job;
{
char buf[ 1024 ];
char *tag_size = "size: ";
char *tag_status = "status: ";
-lp_queue( out )
+int lp_queue( out )
struct papfile *out;
{
char buf[ 1024 ], *start, *stop, *p, *q;