mirror of https://github.com/mabam/CAP.git
2766 lines
70 KiB
C
2766 lines
70 KiB
C
static char rcsid[] = "$Author: djh $ $Date: 1996/09/10 13:56:31 $";
|
|
static char rcsident[] = "$Header: /mac/src/cap60/applications/lwsrv/RCS/lwsrv.c,v 2.47 1996/09/10 13:56:31 djh Rel djh $";
|
|
static char revision[] = "$Revision: 2.47 $";
|
|
|
|
/*
|
|
* lwsrv - UNIX AppleTalk spooling program: act as a laserwriter
|
|
* driver: handles setup and farms out incoming jobs
|
|
*
|
|
* AppleTalk package for UNIX (4.2 BSD).
|
|
*
|
|
* Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia University in the
|
|
* City of New York.
|
|
*
|
|
* Edit History:
|
|
*
|
|
* Feb 15, 1987 Schilit Created, based on lsrv
|
|
* Mar 17, 1987 Schilit Fixed nonprintables, added -r
|
|
* May 15, 1987 CCKim Add support for LaserPrep 4.0
|
|
* Make multifork by default (turn
|
|
* off by defining SINGLEFORK)
|
|
* Feb 15, 1991 djh Various cleanups & patches
|
|
* Feb 20, 1991 rapatel improve wait code, add lpr logging
|
|
* Jan 21, 1992 gkl300 add simple pass thru (for PC's)
|
|
*
|
|
*/
|
|
|
|
char copyright[] = "Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia University in the City of New York";
|
|
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <assert.h>
|
|
#include <signal.h>
|
|
#include <sys/param.h>
|
|
#ifndef _TYPES
|
|
# include <sys/types.h> /* assume included by param.h */
|
|
#endif _TYPES
|
|
#include <sys/file.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
|
|
#include <netat/appletalk.h> /* include appletalk definitions */
|
|
#include <netat/sysvcompat.h>
|
|
#include <netat/compat.h>
|
|
#include <netinet/in.h>
|
|
#include "../../lib/cap/abpap.h" /* urk, puke, etc */
|
|
|
|
#ifdef USEDIRENT
|
|
#include <dirent.h>
|
|
#else USEDIRENT
|
|
#ifdef xenix5
|
|
#include <sys/ndir.h>
|
|
#else xenix5
|
|
#include <sys/dir.h>
|
|
#endif xenix5
|
|
#endif USEDIRENT
|
|
|
|
#ifdef USESTRINGDOTH
|
|
# include <string.h>
|
|
#else USESTRINGDOTH
|
|
# include <strings.h>
|
|
#endif USESTRINGDOTH
|
|
|
|
#ifdef NEEDFCNTLDOTH
|
|
# include <fcntl.h>
|
|
#endif NEEDFCNTLDOTH
|
|
|
|
#ifdef SOLARIS
|
|
#include <sys/systeminfo.h>
|
|
#define gethostname(n,l) (sysinfo(SI_HOSTNAME,(n),(l)) == (1) ? 0 : -1)
|
|
#endif SOLARIS
|
|
|
|
#ifdef LWSRV8
|
|
#include "list.h"
|
|
#include "query.h"
|
|
#include "parse.h"
|
|
#include "procset.h"
|
|
#include "fontlist.h"
|
|
#endif /* LWSRV8 */
|
|
#include "papstream.h"
|
|
|
|
#if defined (LWSRV_AUFS_SECURITY) | defined (RUN_AS_USER)
|
|
#include <pwd.h>
|
|
#endif LWSRV_AUFS_SECURITY | RUN_AS_USER
|
|
#ifdef RUN_AS_USER
|
|
#ifndef USER_FILE
|
|
#define USER_FILE "/usr/local/lib/cap/macusers"
|
|
#endif USER_FILE
|
|
#ifndef REFUSE_MESSAGE
|
|
#define REFUSE_MESSAGE "/usr/local/lib/cap/refused"
|
|
#endif REFUSE_MESSAGE
|
|
#else RUN_AS_USER
|
|
#undef USER_REQUIRED
|
|
#endif RUN_AS_USER
|
|
|
|
#ifdef LWSRV8
|
|
#define STATUSFILE ".lwsrvstatus"
|
|
#define STATUSSIZE 256
|
|
typedef struct Slot {
|
|
AddrBlock addr;
|
|
int slot;
|
|
int pid;
|
|
int prtno;
|
|
byte status[STATUSSIZE];
|
|
} Slot;
|
|
#endif /* LWSRV8 */
|
|
|
|
private char *logfile = NULL;
|
|
|
|
#ifdef LWSRV8
|
|
#ifdef LW_TYPE
|
|
#define LW_AT_TYPE "LaserWriter"
|
|
#else LW_TYPE
|
|
private char *prttype = "LaserWriter";
|
|
#endif LW_TYPE
|
|
#else /* LWSRV8 */
|
|
private u_char *prtname = NULL;
|
|
private char *tracefile = NULL;
|
|
private char *fontfile = NULL;
|
|
private char *unixpname = NULL;
|
|
private char *prttype = "LaserWriter";
|
|
private char *dictdir = "."; /* assume local dir */
|
|
#endif /* LWSRV8 */
|
|
|
|
private int rflag = FALSE; /* remove print file */
|
|
private int hflag = TRUE; /* default to print banner */
|
|
private int singlefork = FALSE;
|
|
private PAPStatusRec *statbuffp; /* status buffer */
|
|
export int capture = TRUE;
|
|
export char *myname;
|
|
export int verbose = 0;
|
|
|
|
#ifdef LWSRV8
|
|
#ifdef PAGECOUNT
|
|
export int pcopies;
|
|
#endif PAGECOUNT
|
|
export int pagecount;
|
|
export boolean tracing = FALSE; /* set if tracing */
|
|
export char *queryfile = NULL;
|
|
#else /* LWSRV8 */
|
|
#ifdef PAGECOUNT
|
|
export int pagecount;
|
|
export int pcopies;
|
|
#endif PAGECOUNT
|
|
#endif /* LWSRV8 */
|
|
|
|
#ifdef __hpux
|
|
#define MAXJOBNAME 64
|
|
private char username[32],jobname[MAXJOBNAME],jobtitle[MAXJOBNAME];
|
|
#else __hpux
|
|
private char username[128],jobname[1024];
|
|
#endif __hpux
|
|
|
|
#ifndef LWSRV8
|
|
private char buf[1024];
|
|
private int srefnum;
|
|
#endif /* not LWSRV8 */
|
|
|
|
#ifndef TEMPFILE
|
|
# define TEMPFILE "/tmp/lwsrvXXXXXX" /* temporary file holds job */
|
|
#endif TEMPFILE
|
|
|
|
private char *tmpfiledir = NULL;
|
|
|
|
#define RFLOWQ atpMaxNum
|
|
#define BUFMAX (PAPSegSize*RFLOWQ)+10
|
|
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
private int requid, reqgid;
|
|
private char *aufsdb = NULL; /* budd */
|
|
#ifndef LWSRV8
|
|
char *bin, *tempbin;
|
|
int tempbinlen;
|
|
#else /* LWSRV8 */
|
|
private char *bin, *tempbin;
|
|
private boolean aufssecurity[NUMSPAP];
|
|
private char openReplyMessage[STATUSSIZE];
|
|
#endif /* LWSRV8 */
|
|
#endif LWSRV_AUFS_SECURITY
|
|
|
|
#ifdef LWSRV_LPR_LOG
|
|
private char *requname = NULL;
|
|
#endif LWSRV_LPR_LOG
|
|
|
|
#ifdef NeXT
|
|
char *nextdpi = NULL; /* NeXT printer resolution */
|
|
#endif NeXT
|
|
|
|
#ifndef LWSRV8
|
|
#ifdef DONT_PARSE
|
|
export int dont_parse = FALSE;
|
|
#endif DONT_PARSE
|
|
#endif /* not LWSRV8 */
|
|
|
|
#ifdef USESYSVLP
|
|
# ifndef LPRCMD
|
|
# define LPRCMD "/usr/bin/lp"
|
|
# endif LPRCMD
|
|
#endif USESYSVLP
|
|
|
|
#ifndef LPRCMD
|
|
# if defined(xenix5) || defined(__FreeBSD__)
|
|
# define LPRCMD "/usr/bin/lpr"
|
|
# else /* xenix5 || __FreeBSD__ */
|
|
# define LPRCMD "/usr/ucb/lpr"
|
|
# endif /* xenix5 || __FreeBSD__ */
|
|
#endif LPRCMD
|
|
|
|
private char *lprcmd = LPRCMD;
|
|
|
|
#ifdef LPRARGS
|
|
#ifndef LWSRV8
|
|
private char *lprargsbuf[16];
|
|
private char **lprargs = lprargsbuf;
|
|
#else /* LWSRV8 */
|
|
private int lprstarted;
|
|
private List *lprargs;
|
|
#endif /* LWSRV8 */
|
|
#endif LPRARGS
|
|
|
|
#ifndef LWSRV8
|
|
private struct printer_instance {
|
|
u_char *prtname; /* NBP registered printername */
|
|
char *unixpname; /* UNIX printer name */
|
|
char *tracefile; /* .. individual tracefile option */
|
|
PAPStatusRec statbuf;
|
|
int srefnum; /* returned by SLInit */
|
|
char nbpbuf[128]; /* registered name:type@zone */
|
|
int rcomp; /* flag: waiting for job? */
|
|
int cno; /* connection number of next job */
|
|
} prtlist[NUMSPAP], *prtp;
|
|
#else /* LWSRV8 */
|
|
private struct printer_instance prtlist[NUMSPAP];
|
|
struct printer_instance *prtp;
|
|
#endif /* LWSRV8 */
|
|
|
|
private int nprt = 0;
|
|
|
|
#ifdef LWSRV8
|
|
private struct printer_instance _default = {
|
|
NULL, /* default is local dir (-a) */
|
|
0, /* always scan dictdir */
|
|
NULL, /* dictionary list */
|
|
TRUE, /* doing checksum (-k) */
|
|
TRUE, /* print banner (-h) */
|
|
FALSE, /* don't remove file (-r) */
|
|
NULL, /* tracefile (-t) */
|
|
FALSE, /* maybe "eexec" in code(-e) */
|
|
0, /* Transcript options (-T) */
|
|
#ifdef ADOBE_DSC2_CONFORMANT
|
|
TRUE, /* DSC2 compatibility (-A) */
|
|
#else ADOBE_DSC2_CONFORMANT
|
|
FALSE, /* DSC2 compatibility (-A) */
|
|
#endif ADOBE_DSC2_CONFORMANT
|
|
#ifdef LPRARGS
|
|
NULL, /* lpr arguments (-L) */
|
|
#endif LPRARGS
|
|
#ifdef PASS_THRU
|
|
FALSE, /* pass through (-P) */
|
|
#endif PASS_THRU
|
|
#ifdef NeXT
|
|
NULL, /* NeXT resolution (-R) */
|
|
#endif NeXT
|
|
#ifdef LW_TYPE
|
|
LW_AT_TYPE, /* default AppleTalk type (-Y) */
|
|
#endif LW_TYPE
|
|
TRUE, /* capture procset (-N) */
|
|
};
|
|
private int prtno;
|
|
private int prtcopy;
|
|
|
|
private int statusfd = -1;
|
|
private char statusfile[256];
|
|
private char statusidle[] = "status: idle";
|
|
private char statusprocessing[] = "status: processing job(s)";
|
|
private List *slots;
|
|
private int freeslot;
|
|
private int myslot;
|
|
|
|
private void readstatus();
|
|
private void resetstatus();
|
|
private void writestatus();
|
|
private Slot *GetSlot();
|
|
private void FreeSlot();
|
|
private byte *statusreply();
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
private byte *openreply();
|
|
private char *deniedmessage();
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef TIMESTAMP
|
|
private char *timestamp();
|
|
#endif TIMESTAMP
|
|
#endif /* LWSRV8 */
|
|
|
|
private void
|
|
#ifndef LWSRV8
|
|
usage(s, err)
|
|
char *s, *err;
|
|
#else /* LWSRV8 */
|
|
usage(err)
|
|
char *err;
|
|
#endif /* LWSRV8 */
|
|
{
|
|
#ifndef LWSRV8
|
|
if (err != NULL)
|
|
fprintf(stderr,"%s: %s\n",s,err);
|
|
fprintf(stderr,"usage: %s -n <PrinterName> -p <unix printer name>\n",s);
|
|
#else /* LWSRV8 */
|
|
if (err != NULL)
|
|
fprintf(stderr,"%s: %s\n",myname,err);
|
|
fprintf(stderr,"usage: %s <ConfigFile> [<Database>]\n",myname);
|
|
fprintf(stderr,"\t<ConfigFile> contains options and printer descriptions\n");
|
|
fprintf(stderr,"\t<Database> of printer templates\n\n");
|
|
#ifdef LW_TYPE
|
|
fprintf(stderr,"usage: %s -n <PrinterName> -p <unix printer name>",myname);
|
|
fprintf(stderr," -Y <AppleTalkType>\n");
|
|
#else LW_TYPE
|
|
fprintf(stderr,"usage: %s -n <PrinterName> -p <unix printer name>\n",myname);
|
|
#endif LW_TYPE
|
|
#endif /* LWSRV8 */
|
|
fprintf(stderr,"usage:\t\t-a <DictionaryDirectory> -f <FontFile>\n");
|
|
fprintf(stderr,"usage:\t\t[-l <LogFile>] [-t <TraceFile>] [-r] [-h]\n");
|
|
#ifndef LWSRV_AUFS_SECURITY
|
|
fprintf(stderr,"usage:\t\t[-T crtolf] [-T quote8bit]\n\n");
|
|
#else LWSRV_AUFS_SECURITY
|
|
fprintf(stderr,"usage:\t\t[-T crtolf] [-T quote8bit] [-X userlogindb]\n\n");
|
|
#endif LWSRV_AUFS_SECURITY
|
|
fprintf(stderr,"\t-p*<unix printer name> is the unix printer to print to\n");
|
|
fprintf(stderr,"\t-n*<PrinterName> specifies the name %s registers.\n",
|
|
myname);
|
|
#ifdef LWSRV8
|
|
#ifdef LW_TYPE
|
|
fprintf(stderr,"\t-Y <AppleTalkType> specifies an alternate AppleTalk\n");
|
|
fprintf(stderr,"\t type for this printer, default is: ");
|
|
fprintf(stderr,"%s\n", LW_AT_TYPE);
|
|
#endif LW_TYPE
|
|
#endif /* LWSRV8 */
|
|
fprintf(stderr,"\t-a*<DictionaryDirectory> is the ProcSet directory.\n");
|
|
fprintf(stderr,"\t-f*<FontFile> contains an font coordination list.\n");
|
|
fprintf(stderr,"\t-t <Tracefile> stores session and appledict in\n");
|
|
fprintf(stderr,"\t <Tracefile> without printing.\n");
|
|
fprintf(stderr,"\t-F <TmpFileDir> directory to store temporary files\n");
|
|
fprintf(stderr,"\t-l <LogFile> specifies a file to log the %s session\n",
|
|
myname);
|
|
#ifdef LWSRV8
|
|
fprintf(stderr,"\t-q <QueryFile> log unknown queries\n");
|
|
#endif /* LWSRV8 */
|
|
fprintf(stderr,"\t-e Allow an eexec to occur in a procset\n");
|
|
fprintf(stderr," warning: this may cause problems, use carefully\n");
|
|
fprintf(stderr, "\t-N Turns off capturing of new procsets\n");
|
|
fprintf(stderr,"\t-r Will retain temp print file for inspection\n");
|
|
fprintf(stderr,"\t-h means to print without a banner page\n");
|
|
if (is_simple_dsc())
|
|
fprintf(stderr,"\t-A [on*|off] means to turn on or off Adobe document\n");
|
|
else
|
|
fprintf(stderr,"\t-A [on|off*] means to turn on or off Adobe document\n");
|
|
fprintf(stderr,"\tstructuring revision 2 compatibility\n");
|
|
fprintf(stderr,"\t(this can cause problems, *'ed item is default)\n");
|
|
fprintf(stderr,"\t-C <cmd> Specify print spooler rather than lp/lpr\n");
|
|
#ifdef LPRARGS
|
|
fprintf(stderr,"\t-L <arg> Argument to pass to lpr (multiple use)\n");
|
|
#endif LPRARGS
|
|
#ifdef PASS_THRU
|
|
fprintf(stderr,"\t-P %s pass through (no adobe preprocessing)\n", myname);
|
|
#endif PASS_THRU
|
|
#ifdef NeXT
|
|
fprintf(stderr,"\t-R <dpi> Specify resolution for NeXT printer\n");
|
|
#endif NeXT
|
|
fprintf(stderr,"\t-S single %s fork (default is multiforking)\n", myname);
|
|
#ifndef LWSRV8
|
|
#ifdef DONT_PARSE
|
|
fprintf(stderr,"\t-D don't parse any of the file, but allow crtolf if set\n");
|
|
#endif DONT_PARSE
|
|
#endif /* LWSRV8 */
|
|
fprintf(stderr,"\t-T Transcript compatibilty options\n");
|
|
fprintf(stderr,"\t-T crtolf: translate cr to lf for Transcript filters\n");
|
|
fprintf(stderr,"\t-T quote8bit: quote 8 bit chars for Transcript\n");
|
|
fprintf(stderr,"\t-T makenondscconformant: make non DSC conformant: use\n");
|
|
fprintf(stderr,"\t if psrv only works with DSC 1.0 conventions\n");
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
fprintf(stderr,"\t-X <database directory> use aufs for validation\n");/*budd*/
|
|
#endif LWSRV_AUFS_SECURITY
|
|
fprintf(stderr,"\nexample: %s -n Laser -p ps -a/usr/lib/ADicts\n",myname);
|
|
fprintf(stderr,"\t\t-f /usr/lib/LW+Fonts\n");
|
|
fprintf(stderr,"\t(note the starred items above are required)\n");
|
|
exit(0);
|
|
}
|
|
|
|
private void
|
|
#ifndef LWSRV8
|
|
inc_nprt(progname)
|
|
char *progname;
|
|
#else /* LWSRV8 */
|
|
inc_nprt()
|
|
#endif /* LWSRV8 */
|
|
{
|
|
#ifndef LWSRV8
|
|
if (prtp->unixpname == NULL)
|
|
usage(progname,"Missing Unix Printer Name");
|
|
#endif /* LWSRV8 */
|
|
|
|
#ifdef LWSRV8
|
|
if (prtp == &_default) { /* doing default */
|
|
prtp = prtlist;
|
|
if (_default.dictdir == NULL) {
|
|
_default.dictdir = ".";
|
|
_default.dictlist = scandicts(_default.dictdir, &_default.lastried);
|
|
AddToKVTree(_default.querylist, "procset", _default.dictlist, strcmp);
|
|
}
|
|
} else {
|
|
if (prtp->unixpname == NULL)
|
|
usage("Missing Unix Printer Name");
|
|
#endif /* LWSRV8 */
|
|
#ifndef LWSRV8
|
|
if (prtp->prtname == NULL)
|
|
usage(progname,"Missing AppleTalk Printer Name");
|
|
#else /* LWSRV8 */
|
|
if (prtp->prtname == NULL)
|
|
usage("Missing AppleTalk Printer Name");
|
|
if (SearchKVTree(prtp->querylist, "font", strcmp) == NULL)
|
|
usage("No fonts specified");
|
|
#ifdef LW_TYPE
|
|
if (prtp->prttype == NULL)
|
|
usage("Missing AppleTalk type");
|
|
#endif LW_TYPE
|
|
#endif /* LWSRV8 */
|
|
#ifndef LWSRV8
|
|
if (++nprt >= NUMSPAP)
|
|
usage("lwsrv","too many printers");
|
|
#else /* LWSRV8 */
|
|
if (++nprt >= NUMSPAP)
|
|
usage("too many printers");
|
|
#endif /* LWSRV8 */
|
|
prtp++;
|
|
#ifndef LWSRV8
|
|
unixpname = tracefile = NULL;
|
|
prtname = NULL;
|
|
#else /* LWSRV8 */
|
|
}
|
|
bcopy((char *)&_default, (char *)prtp, prtcopy);
|
|
thequery = prtp->querylist = DupKVTree(_default.querylist);
|
|
#ifdef LPRARGS
|
|
lprstarted = FALSE;
|
|
#endif LPRARGS
|
|
#endif /* LWSRV8 */
|
|
}
|
|
|
|
#ifdef LWSRV8
|
|
static char optlist[64] = "a:f:l:p:t:d:n:krehNT:A:C:F:Svq:";
|
|
|
|
private void
|
|
lwsrv_init(name)
|
|
char *name;
|
|
{
|
|
if (myname = rindex(name, '/'))
|
|
myname++;
|
|
else
|
|
myname = name;
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
strcat(optlist, "X:");
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef LPRARGS
|
|
strcat(optlist, "L:");
|
|
#endif LPRARGS
|
|
#ifdef PASS_THRU
|
|
strcat(optlist, "P");
|
|
#endif PASS_THRU
|
|
#ifdef NeXT
|
|
strcat(optlist, "R:");
|
|
#endif NeXT
|
|
#ifdef LW_TYPE
|
|
strcat(optlist, "Y:");
|
|
#endif LW_TYPE
|
|
|
|
thequery = _default.querylist = CreateKVTree();
|
|
prtcopy = (char *)&_default.prtname - (char *)&_default;
|
|
nprt = 0;
|
|
prtp = &_default;
|
|
#ifdef LPRARGS
|
|
lprstarted = FALSE;
|
|
#endif LPRARGS
|
|
}
|
|
|
|
export void
|
|
doargs(argc,argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
register int c;
|
|
register KVTree **kp;
|
|
register List *lp;
|
|
time_t ltime;
|
|
extern char *optarg;
|
|
extern int optind;
|
|
#ifdef ISO_TRANSLATE
|
|
void cISO2Mac();
|
|
#endif ISO_TRANSLATE
|
|
|
|
while ((c = getopt(argc,argv,optlist)) != EOF) {
|
|
switch (c) {
|
|
case 'a':
|
|
if (index(optarg, '/') == NULL) {
|
|
prtp->dictdir = (char *)malloc(strlen(optarg)+4);
|
|
strcpy(prtp->dictdir, "./");
|
|
strcat(prtp->dictdir, optarg);
|
|
} else
|
|
prtp->dictdir = optarg; /* remember dictionary directory */
|
|
ltime = 0;
|
|
if (kp = scandicts(prtp->dictdir, <ime)) {
|
|
prtp->lastried = ltime;
|
|
AddToKVTree(prtp->querylist, "procset", (prtp->dictlist = kp), strcmp);
|
|
}
|
|
break;
|
|
case 'd':
|
|
dbugarg(optarg);
|
|
break;
|
|
case 'f':
|
|
if ((lp = LoadFontList(optarg)) == NULL) { /* -f fontfile */
|
|
fprintf(stderr,"%s: Bad FontList from %s\n", myname, optarg);
|
|
break;
|
|
}
|
|
AddToKVTree(prtp->querylist, "font", lp, strcmp);
|
|
fprintf(stderr,"%s: Font list from file %s\n", myname, optarg);
|
|
break;
|
|
case 'l': /* -l logfile */
|
|
logfile = optarg;
|
|
break;
|
|
case 'q': /* -q queryfile */
|
|
queryfile = optarg;
|
|
break;
|
|
case 'n': /* lwsrv printer name */
|
|
if (prtp->prtname || prtp == &_default)
|
|
inc_nprt();
|
|
#ifdef ISO_TRANSLATE
|
|
cISO2Mac(optarg);
|
|
#endif ISO_TRANSLATE
|
|
prtp->prtname = optarg;
|
|
break;
|
|
case 'p': /* -p unix printer name */
|
|
if (prtp->unixpname || prtp == &_default)
|
|
inc_nprt();
|
|
prtp->unixpname = optarg;
|
|
break;
|
|
case 'k': /* no DDP checksum */
|
|
prtp->dochecksum = FALSE;
|
|
break;
|
|
case 'h':
|
|
prtp->hflag = FALSE; /* do not print banner */
|
|
break;
|
|
case 'r': /* do not remove file */
|
|
prtp->rflag = TRUE;
|
|
break;
|
|
case 't': /* -t tracefile */
|
|
prtp->tracefile = optarg;
|
|
break;
|
|
case 'e':
|
|
prtp->eflag = TRUE; /* maybe "eexec" in code */
|
|
break;
|
|
case 'T':
|
|
if ((c = simple_TranscriptOption(optarg)) < 0)
|
|
usage(NULL);
|
|
prtp->toptions |= c;
|
|
break;
|
|
case 'A':
|
|
if ((c = simple_dsc_option(optarg)) < 0)
|
|
usage(NULL);
|
|
prtp->dsc2 = c;
|
|
break;
|
|
case 'C':
|
|
lprcmd = optarg;
|
|
break;
|
|
#ifdef LPRARGS
|
|
case 'L':
|
|
if (!lprstarted) {
|
|
if (prtp->lprargs)
|
|
prtp->lprargs = DupList(prtp->lprargs);
|
|
else
|
|
prtp->lprargs = CreateList();
|
|
lprstarted = TRUE;
|
|
}
|
|
AddToList(prtp->lprargs, (void *)optarg);
|
|
break;
|
|
#endif LPRARGS
|
|
#ifdef PASS_THRU
|
|
case 'P':
|
|
prtp->passthru = TRUE; /* -P pass through PC jobs */
|
|
break;
|
|
#endif PASS_THRU
|
|
case 'S':
|
|
singlefork = TRUE;
|
|
fprintf(stderr, "%s: single fork\n", myname);
|
|
break;
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
case 'X': /* budd... */
|
|
aufsdb = optarg;
|
|
fprintf(stderr, "%s: aufs db directory in %s\n", myname, aufsdb);
|
|
break; /* ...budd */
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef NeXT
|
|
case 'R':
|
|
prtp->nextdpi = optarg;
|
|
break;
|
|
#endif NeXT
|
|
#ifdef LW_TYPE
|
|
case 'Y':
|
|
prtp->prttype = optarg;
|
|
break;
|
|
#endif LW_TYPE
|
|
case 'F':
|
|
tmpfiledir = optarg;
|
|
break;
|
|
case 'N':
|
|
prtp->capture = FALSE;
|
|
break;
|
|
case 'v':
|
|
verbose++;
|
|
break;
|
|
case '?': /* illegal character */
|
|
usage(NULL); /* usage and exit */
|
|
break;
|
|
}
|
|
}
|
|
if (optind < argc) {
|
|
fprintf(stderr, "%s: surplus arguments starting from \"%s\"\n",
|
|
myname,argv[optind]);
|
|
usage(NULL);
|
|
}
|
|
}
|
|
|
|
void
|
|
set_printer(p)
|
|
register struct printer_instance *p;
|
|
{
|
|
extern boolean dochecksum;
|
|
|
|
set_dict_list(p->dictlist);
|
|
dochecksum = p->dochecksum;
|
|
hflag = p->hflag;
|
|
rflag = p->rflag;
|
|
setflag_encrypted_instream(p->eflag);
|
|
set_toptions(p->toptions);
|
|
set_simple_dsc(p->dsc2);
|
|
#ifdef LPRARGS
|
|
lprargs = p->lprargs;
|
|
#endif LPRARGS
|
|
#ifdef PASS_THRU
|
|
set_simple_pass_thru(p->passthru);
|
|
#endif PASS_THRU
|
|
#ifdef NeXT
|
|
nextdpi = p->nextdpi;
|
|
#endif NeXT
|
|
capture = p->capture;
|
|
tracing = (p->tracefile != NULL);
|
|
statbuffp = &(p->statbuf);
|
|
thequery = p->querylist;
|
|
spool_setup(p->prtname, prtp->dictdir);
|
|
}
|
|
|
|
private void
|
|
childdone(s)
|
|
int s;
|
|
{
|
|
WSTATUS status;
|
|
|
|
resetstatus(wait(&status));
|
|
signal(SIGCHLD, childdone);
|
|
}
|
|
|
|
#else /* LWSRV8 */
|
|
|
|
private void
|
|
doargs(argc,argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
int c;
|
|
extern char *optarg;
|
|
extern int optind;
|
|
extern boolean dochecksum;
|
|
static char optlist[64] = "a:f:l:p:t:d:n:krehNT:A:C:F:Sv";
|
|
#ifdef ISO_TRANSLATE
|
|
void cISO2Mac();
|
|
#endif ISO_TRANSLATE
|
|
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
strcat(optlist, "X:");
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef LPRARGS
|
|
strcat(optlist, "L:");
|
|
#endif LPRARGS
|
|
#ifdef PASS_THRU
|
|
strcat(optlist, "P");
|
|
#endif PASS_THRU
|
|
#ifdef NeXT
|
|
strcat(optlist, "R:");
|
|
#endif NeXT
|
|
#ifdef DONT_PARSE
|
|
strcat(optlist, "D");
|
|
#endif DONT_PARSE
|
|
|
|
nprt = 0; prtp = prtlist;
|
|
|
|
while ((c = getopt(argc,argv,optlist)) != EOF) {
|
|
switch (c) {
|
|
case 'a':
|
|
if (index(optarg, '/') == NULL) {
|
|
dictdir = (char *)malloc(strlen(optarg)+4);
|
|
strcpy(dictdir, "./");
|
|
strcat(dictdir, optarg);
|
|
} else
|
|
dictdir = optarg; /* remember dictionary directory */
|
|
break;
|
|
case 'd':
|
|
dbugarg(optarg);
|
|
break;
|
|
case 'f':
|
|
fontfile = optarg; /* -f fontfile */
|
|
break;
|
|
case 'l': /* -l logfile */
|
|
logfile = optarg;
|
|
break;
|
|
case 'n': /* lwsrv printer name */
|
|
if (prtname != NULL)
|
|
inc_nprt(argv[0]);
|
|
#ifdef ISO_TRANSLATE
|
|
cISO2Mac(optarg);
|
|
#endif ISO_TRANSLATE
|
|
prtp->prtname = prtname = (u_char *)optarg;
|
|
break;
|
|
case 'p': /* -p unix printer name */
|
|
if (unixpname != NULL)
|
|
inc_nprt(argv[0]);
|
|
prtp->unixpname = unixpname = optarg;
|
|
break;
|
|
case 'k': /* no DDP checksum */
|
|
dochecksum = 0;
|
|
break;
|
|
case 'h':
|
|
hflag = FALSE; /* do not print banner */
|
|
break;
|
|
case 'r': /* do not remove file */
|
|
rflag = TRUE;
|
|
break;
|
|
case 't': /* -t tracefile */
|
|
prtp->tracefile = tracefile = optarg;
|
|
break;
|
|
case 'e':
|
|
setflag_encrypted_instream(TRUE); /* maybe "eexec" in code */
|
|
break;
|
|
case 'T':
|
|
if (simple_TranscriptOption(optarg) < 0)
|
|
usage(argv[0], NULL);
|
|
break;
|
|
case 'A':
|
|
if (simple_dsc_option(optarg) < 0)
|
|
usage(argv[0], NULL);
|
|
break;
|
|
case 'C':
|
|
lprcmd = optarg;
|
|
break;
|
|
#ifdef LPRARGS
|
|
case 'L':
|
|
*lprargs++ = optarg;
|
|
break;
|
|
#endif LPRARGS
|
|
#ifdef PASS_THRU
|
|
case 'P':
|
|
set_simple_pass_thru(); /* -P pass through PC jobs */
|
|
break;
|
|
#endif PASS_THRU
|
|
case 'S':
|
|
singlefork = TRUE;
|
|
fprintf(stderr, "lwsrv: single fork\n");
|
|
break;
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
case 'X': /* budd... */
|
|
aufsdb = optarg;
|
|
fprintf(stderr, "lwsrv: aufs db directory in %s\n", aufsdb );
|
|
break; /* ...budd */
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef NeXT
|
|
case 'R':
|
|
nextdpi = optarg;
|
|
break;
|
|
#endif NeXT
|
|
#ifdef DONT_PARSE
|
|
case 'D':
|
|
dont_parse = TRUE;
|
|
break;
|
|
#endif DONT_PARSE
|
|
case 'F':
|
|
tmpfiledir = optarg;
|
|
break;
|
|
case 'N':
|
|
capture = FALSE;
|
|
break;
|
|
case 'v':
|
|
verbose++;
|
|
break;
|
|
case '?': /* illegal character */
|
|
usage(argv[0],NULL); /* usage and exit */
|
|
break;
|
|
}
|
|
}
|
|
if (optind < argc) {
|
|
fprintf(stderr, "%s: surplus arguments starting from \"%s\"\n",
|
|
argv[0],argv[optind]);
|
|
usage(argv[0], NULL);
|
|
}
|
|
|
|
inc_nprt(argv[0]);
|
|
|
|
if (fontfile == NULL)
|
|
usage(argv[0],"No FontFile specified");
|
|
#ifdef LPRARGS
|
|
*lprargs = NULL;
|
|
lprargs = lprargsbuf;
|
|
#endif LPRARGS
|
|
|
|
}
|
|
|
|
void
|
|
set_printer(p)
|
|
struct printer_instance *p;
|
|
{
|
|
prtname = p->prtname;
|
|
unixpname = p->unixpname;
|
|
tracefile = p->tracefile;
|
|
statbuffp = &(p->statbuf);
|
|
srefnum = p->srefnum;
|
|
}
|
|
|
|
private void
|
|
childdone()
|
|
{
|
|
WSTATUS status;
|
|
|
|
(void)wait(&status);
|
|
signal(SIGCHLD, childdone);
|
|
}
|
|
#endif /* LWSRV8 */
|
|
|
|
#ifdef LWSRV8
|
|
private Slot *
|
|
GetSlot(prtno)
|
|
int prtno;
|
|
{
|
|
register Slot *slotp, **sp;
|
|
register int i, n;
|
|
|
|
if ((slotp = (Slot *)malloc(sizeof(Slot))) == NULL)
|
|
errorexit(1, "GetSlot: Out of memory\n");
|
|
i = freeslot;
|
|
sp = (Slot **)AddrList(slots) + i;
|
|
*sp = slotp;
|
|
slotp->slot = i;
|
|
slotp->prtno = prtno;
|
|
|
|
n = NList(slots);
|
|
for ( ; ; ) {
|
|
if (++i >= n) { /* all slots in use, make a new one */
|
|
AddToList(slots, NULL);
|
|
freeslot = n;
|
|
break;
|
|
}
|
|
if (*++sp == NULL) {
|
|
freeslot = i;
|
|
break;
|
|
}
|
|
}
|
|
return(slotp);
|
|
}
|
|
|
|
private void
|
|
FreeSlot(n)
|
|
int n;
|
|
{
|
|
register Slot **sp;
|
|
|
|
sp = (Slot **)AddrList(slots) + n;
|
|
free((char *)*sp);
|
|
*sp = NULL;
|
|
if (freeslot > n)
|
|
freeslot = n;
|
|
}
|
|
|
|
private void
|
|
resetstatus(pid)
|
|
register int pid;
|
|
{
|
|
register Slot **sp;
|
|
register int i, n;
|
|
register int *children;
|
|
|
|
n = NList(slots);
|
|
for (sp = (Slot **)AddrList(slots), i = 0; i < n; sp++, i++) {
|
|
if (*sp == NULL)
|
|
continue;
|
|
if ((*sp)->pid == pid) {
|
|
children = &prtlist[(*sp)->prtno].children;
|
|
if (*children > 0 && --(*children) == 0)
|
|
cpyc2pstr(prtlist[(*sp)->prtno].statbuf.StatusStr, statusidle);
|
|
FreeSlot(i);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void
|
|
readstatus(n)
|
|
int n;
|
|
{
|
|
register Slot **sp;
|
|
|
|
sp = (Slot **)AddrList(slots);
|
|
lseek(statusfd, n * STATUSSIZE, L_SET);
|
|
read(statusfd, sp[n]->status, STATUSSIZE);
|
|
}
|
|
|
|
private void
|
|
writestatus(n, str)
|
|
int n;
|
|
char *str;
|
|
{
|
|
byte message[STATUSSIZE];
|
|
|
|
lseek(statusfd, n * STATUSSIZE, L_SET);
|
|
cpyc2pstr(message, str);
|
|
write(statusfd, message, *message + 1);
|
|
}
|
|
|
|
private byte *
|
|
statusreply(cno, from)
|
|
int cno;
|
|
register AddrBlock *from;
|
|
{
|
|
register Slot **sp;
|
|
register int i, n;
|
|
|
|
n = NList(slots);
|
|
sp = (Slot **)AddrList(slots);
|
|
for (i = 0; i < n; sp++, i++) {
|
|
if (*sp == NULL)
|
|
continue;
|
|
if (from->net == (*sp)->addr.net && from->node == (*sp)->addr.node) {
|
|
readstatus(i);
|
|
return((*sp)->status);
|
|
}
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
private char *
|
|
deniedmessage(cno)
|
|
{
|
|
register List *lp;
|
|
register char *sp, *cp;
|
|
/*
|
|
* We rely on the fact that the cno passed by the callback corresponds to
|
|
* the index into the prtlist array.
|
|
*/
|
|
if ((lp = SearchKVTree(prtlist[cno].querylist, "DeniedMessage", strcmp)) &&
|
|
NList(lp) >= 1) {
|
|
/* remove the trailing newline, if any */
|
|
if (cp = index((sp = *(char **)AddrList(lp)), '\n'))
|
|
*cp = 0;
|
|
return(sp);
|
|
}
|
|
return("Denied: Please login to host %s via AppleShare");
|
|
}
|
|
|
|
private byte *
|
|
openreply(cno, from, result)
|
|
int cno;
|
|
AddrBlock *from;
|
|
int result;
|
|
{
|
|
if (result == papPrinterBusy)
|
|
return(NULL);
|
|
/*** budd.... */
|
|
fprintf(stderr,
|
|
#ifdef TIMESTAMP
|
|
"%s: %s: \"%s\" open request from [Network %d.%d, node %d, socket %d]\n",
|
|
myname, timestamp(), prtlist[cno].prtname, nkipnetnumber(from->net),
|
|
#else TIMESTAMP
|
|
"%s: \"%s\" open request from [Network %d.%d, node %d, socket %d]\n",
|
|
myname, prtlist[cno].prtname, nkipnetnumber(from->net),
|
|
#endif TIMESTAMP
|
|
nkipsubnetnumber(from->net),
|
|
from->node, from->skt);
|
|
|
|
if (aufsdb != NULL) {
|
|
char fname[ 256 ];
|
|
char filename[ 256 ];
|
|
int f, cc, ok = 0;
|
|
struct passwd *pw;
|
|
struct stat statbuf;
|
|
#ifdef HIDE_LWSEC_FILE
|
|
char protecteddir[MAXPATHLEN];
|
|
(void) strcpy(protecteddir, aufsdb);
|
|
make_userlogin(filename, protecteddir, from);
|
|
(void) strcpy(protecteddir, filename);
|
|
filename[0] = '\0';
|
|
make_userlogin(filename, protecteddir, from);
|
|
#else HIDE_LWSEC_FILE
|
|
make_userlogin( filename, aufsdb, from);
|
|
#endif HIDE_LWSEC_FILE
|
|
|
|
if ((f = open( filename, 0)) >= 0) {
|
|
if ((cc = read( f, fname, sizeof(fname)-1)) > 0) {
|
|
if (fname[cc-1] == '\n')
|
|
fname[cc-1] = '\0';
|
|
fprintf( stderr, "%s: Found username in aufsdb (%s): %s\n",
|
|
myname, aufsdb, fname);
|
|
|
|
if ((tempbin = rindex(fname,':')) != NULL) {
|
|
*tempbin='\0';
|
|
tempbin++;
|
|
bin = (char *)malloc(strlen(tempbin)+1);
|
|
strcpy(bin,tempbin);
|
|
}
|
|
|
|
(void) stat(filename, &statbuf);
|
|
if ((pw = getpwuid((int) statbuf.st_uid)) != NULL) {
|
|
if (strcmp(pw->pw_name, fname) == 0) {
|
|
requid = pw->pw_uid;
|
|
reqgid = pw->pw_gid;
|
|
#ifdef LWSRV_LPR_LOG
|
|
requname = pw->pw_name;
|
|
#endif LWSRV_LPR_LOG
|
|
ok = 1;
|
|
}
|
|
} else if ((pw = getpwnam(fname)) != NULL) {
|
|
requid = pw->pw_uid;
|
|
reqgid = pw->pw_gid;
|
|
#ifdef LWSRV_LPR_LOG
|
|
requname = pw->pw_name;
|
|
#endif LWSRV_LPR_LOG
|
|
ok = 1; /* true */
|
|
} /* pwnam ok */
|
|
} /* read OK */
|
|
close(f); /* close the file */
|
|
} /* open OK */
|
|
if (!ok) { /* dump connection with error message */
|
|
static byte message[STATUSSIZE];
|
|
fprintf( stderr, "%s: No username (or invalid) confirmation.\n",
|
|
myname);
|
|
gethostname( fname, sizeof(fname)-1); /* ick */
|
|
|
|
sprintf(openReplyMessage, deniedmessage(cno), fname);
|
|
cpyc2pstr(message, openReplyMessage);
|
|
return(message);
|
|
} /* not ok */
|
|
} /* have aufsdb */
|
|
/* ....budd ***/
|
|
aufssecurity[cno] = TRUE;
|
|
return(NULL);
|
|
}
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#endif /* LWSRV8 */
|
|
|
|
/*
|
|
* delete the NBP name
|
|
*
|
|
*/
|
|
|
|
private int is_child = 0;
|
|
|
|
private void
|
|
#ifndef LWSRV8
|
|
cleanup()
|
|
#else /* LWSRV8 */
|
|
cleanup(s)
|
|
int s;
|
|
#endif /* LWSRV8 */
|
|
{
|
|
#ifndef LWSRV8
|
|
int i;
|
|
#else /* LWSRV8 */
|
|
int i, srefnum;
|
|
#endif /* LWSRV8 */
|
|
|
|
if (is_child)
|
|
exit(0);
|
|
|
|
for (i=0; i<nprt; i++) {
|
|
srefnum = prtlist[i].srefnum;
|
|
SLClose(srefnum); /* close server for child */
|
|
PAPRemName(srefnum, prtlist[i].nbpbuf);
|
|
}
|
|
#ifdef LWSRV8
|
|
close(statusfd);
|
|
unlink(statusfile);
|
|
#endif /* LWSRV8 */
|
|
exit(0);
|
|
}
|
|
|
|
openlogfile()
|
|
{
|
|
int i;
|
|
|
|
if (logfile != NULL) {
|
|
if ((i = open(logfile,O_WRONLY|O_APPEND)) < 0) {
|
|
if ((i = creat(logfile,0666)) < 0) {
|
|
fprintf(stderr, "%s: Cannot open/create logfile (%s)\n",
|
|
myname, logfile);
|
|
exit(1);
|
|
}
|
|
}
|
|
if (i != 2) {
|
|
#ifndef NODUP2
|
|
(void) dup2(i,2);
|
|
#else NODUP2
|
|
close(2); /* try again */
|
|
(void) dup(0); /* for slot 2 */
|
|
#endif NODUP2
|
|
(void) close(i);
|
|
}
|
|
#ifdef LWSRV_LPR_LOG /* Set up logfile to be also stdout/stderr for lpr */
|
|
#ifdef NODUP2
|
|
close(1);
|
|
dup(2);
|
|
#else NODUP2
|
|
dup2 (2, 1);
|
|
#endif NODUP2
|
|
#endif LWSRV_LPR_LOG
|
|
}
|
|
}
|
|
|
|
#ifdef LWSRV8
|
|
main(argc,argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
register KVTree **kp;
|
|
time_t ltime;
|
|
int err,i,srefnum,cno,errcount;
|
|
Slot *slotp;
|
|
void cleanup();
|
|
void childdone();
|
|
#ifdef ISO_TRANSLATE
|
|
void cMac2ISO(), cISO2Mac();
|
|
#endif ISO_TRANSLATE
|
|
int free();
|
|
|
|
lwsrv_init(argv[0]);
|
|
if ((argc == 2 || argc == 3) && *(argv[1]) != '-') { /* configuration file */
|
|
extern FILE *yyin;
|
|
FILE *fp;
|
|
|
|
if ((fp = fopen(argv[1], "r")) == NULL) {
|
|
fprintf(stderr, "%s: Can't open %s\n", myname, argv[1]);
|
|
exit(1);
|
|
}
|
|
yyin = fp; /* set for flex(1) */
|
|
initkeyword(fp);
|
|
if (yyparse()) {
|
|
fprintf(stderr, "%s: Giving up...\n", myname);
|
|
exit(1);
|
|
}
|
|
fclose(fp);
|
|
configargs(argc == 3 ? argv[2] : libraryfile);
|
|
} else
|
|
doargs(argc,argv); /* handle args */
|
|
inc_nprt(); /* check last printer */
|
|
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
requid = getuid(); /* budd */
|
|
reqgid = getgid(); /* budd */
|
|
#endif LWSRV_AUFS_SECURITY
|
|
|
|
#ifdef AUTHENTICATE
|
|
if (nprt == 1)
|
|
initauthenticate(*argv, (char *)prtlist[0].prtname);
|
|
#endif AUTHENTICATE
|
|
|
|
signal(SIGHUP, cleanup);
|
|
signal(SIGINT, cleanup);
|
|
signal(SIGQUIT, cleanup);
|
|
signal(SIGTERM, cleanup);
|
|
|
|
if (!dbug.db_flgs) { /* disassociate */
|
|
if (fork())
|
|
exit(0); /* kill off parent */
|
|
for (i=0; i < 20; i++)
|
|
close(i); /* close all files */
|
|
(void) open("/dev/null",0);
|
|
#ifndef NODUP2
|
|
(void) dup2(0,1);
|
|
#else NODUP2
|
|
(void)dup(0); /* for slot 1 */
|
|
#endif NODUP2
|
|
if (logfile == NULL) {
|
|
#ifndef NODUP2
|
|
(void) dup2(0,2);
|
|
#else NODUP2
|
|
(void) dup(0); /* for slot 2 */
|
|
#endif NODUP2
|
|
} else
|
|
openlogfile();
|
|
#ifndef POSIX
|
|
#ifdef TIOCNOTTY
|
|
if ((i = open("/dev/tty",2)) > 0) {
|
|
ioctl(i, TIOCNOTTY,(char *) 0);
|
|
close(i);
|
|
}
|
|
#endif TIOCNOTTY
|
|
#ifdef xenix5
|
|
/*
|
|
* USG process groups:
|
|
* The fork guarantees that the child is not a process group leader.
|
|
* Then setpgrp() can work, whick loses the controllong tty.
|
|
* Note that we must be careful not to be the first to open any tty,
|
|
* or it will become our controlling tty. C'est la vie.
|
|
*/
|
|
setpgrp();
|
|
#endif xenix5
|
|
#else POSIX
|
|
(void) setsid();
|
|
#endif POSIX
|
|
}
|
|
|
|
/* dbug.db_pap = TRUE; */
|
|
|
|
if (!singlefork) {
|
|
sprintf(statusfile, "%s%05d", STATUSFILE, getpid());
|
|
if ((statusfd = open(statusfile, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0) {
|
|
fprintf(stderr, "%s: Can't open %s\n", myname, statusfile);
|
|
exit(1);
|
|
}
|
|
signal(SIGCHLD, childdone);
|
|
slots = CreateList();
|
|
AddToList(slots, NULL); /* make sure there is one slot set up */
|
|
freeslot = 0;
|
|
papstatuscallback = statusreply;
|
|
}
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
papopencallback = openreply;
|
|
#endif LWSRV_AUFS_SECURITY
|
|
|
|
abInit(FALSE); /* initialize appletalk driver */
|
|
nbpInit(); /* initialize NBP routines */
|
|
PAPInit(); /* init PAP printer routines */
|
|
|
|
errcount = 0;
|
|
for (prtp=prtlist,i=0; i<nprt; prtp++,i++) {
|
|
#ifdef LW_TYPE
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->prtname);
|
|
cMac2ISO(prtp->prttype);
|
|
fprintf(stderr,"%s: Spooler starting for %s:%s@*\n",
|
|
myname,prtp->prtname,prtp->prttype);
|
|
sprintf(prtp->nbpbuf,"%s:%s@*",prtp->prtname,prtp->prttype);
|
|
cISO2Mac(prtp->prttype);
|
|
cISO2Mac(prtp->prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"%s: Spooler starting for %s:%s@*\n",
|
|
myname,prtp->prtname,prtp->prttype);
|
|
sprintf(prtp->nbpbuf,"%s:%s@*",prtp->prtname,prtp->prttype);
|
|
#endif ISO_TRANSLATE
|
|
#else LW_TYPE
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->prtname);
|
|
fprintf(stderr,"%s: Spooler starting for %s:%s@*\n",
|
|
myname,prtp->prtname,prttype);
|
|
sprintf(prtp->nbpbuf,"%s:%s@*",prtp->prtname,prttype);
|
|
cISO2Mac(prtp->prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"%s: Spooler starting for %s:%s@*\n",
|
|
myname,prtp->prtname,prttype);
|
|
sprintf(prtp->nbpbuf,"%s:%s@*",prtp->prtname,prttype);
|
|
#endif ISO_TRANSLATE
|
|
#endif LW_TYPE
|
|
cpyc2pstr(prtp->statbuf.StatusStr, statusidle);
|
|
err = SLInit(&(prtp->srefnum), prtp->nbpbuf, 8, &(prtp->statbuf));
|
|
if (err != noErr) {
|
|
fprintf(stderr,"%s: SLInit %s failed: %d\n",myname,prtp->nbpbuf,err);
|
|
errcount++;
|
|
}
|
|
/* GetNextJob is asynchronous, so call it for each printer */
|
|
err = GetNextJob(prtp->srefnum, &(prtp->cno), &(prtp->rcomp));
|
|
if (err != noErr) {
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->prtname);
|
|
fprintf(stderr,"%s: GetNextJob %s failed: %d\n",myname,prtp->prtname,
|
|
err);
|
|
cISO2Mac(prtp->prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"%s: GetNextJob %s failed: %d\n",myname,prtp->prtname,
|
|
err);
|
|
#endif ISO_TRANSLATE
|
|
errcount++;
|
|
}
|
|
fprintf(stderr, "%s: %s ready and waiting\n", myname, prtp->nbpbuf);
|
|
}
|
|
|
|
if (errcount == nprt) {
|
|
fprintf(stderr, "%s: no printers successful registered!\n", myname);
|
|
exit(1);
|
|
}
|
|
|
|
prtno = 0;
|
|
while (TRUE) {
|
|
openlogfile();
|
|
NewStatus("idle");
|
|
|
|
/* scan each printer in turn, processing each one as "normal" if there
|
|
* is work available. If no work was available then abSleep for a while
|
|
*/
|
|
while (prtno<nprt && prtlist[prtno].rcomp > 0) prtno++;
|
|
if (prtno == nprt) {
|
|
abSleep(20,TRUE); /* wait for some work */
|
|
prtno = 0; /* start scan again */
|
|
continue;
|
|
}
|
|
|
|
prtp = &prtlist[prtno];
|
|
ltime = prtp->lastried;
|
|
if (kp = scandicts(prtp->dictdir, <ime)) {
|
|
if (prtp->dictlist)
|
|
FreeKVTree(prtp->dictlist, free, free);
|
|
prtp->dictlist = kp;
|
|
prtp->lastried = ltime;
|
|
}
|
|
set_printer(prtp); /* set the global variables etc */
|
|
srefnum = prtp->srefnum;
|
|
cno = prtp->cno;
|
|
|
|
/* GetNextJob is asynchronous, so announce readiness for more work */
|
|
/* WTR: is this right - should it depend on singlefork? */
|
|
err = GetNextJob(prtp->srefnum, &(prtp->cno), &(prtp->rcomp));
|
|
if (err != noErr) {
|
|
#ifdef TIMESTAMP
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->prtname);
|
|
fprintf(stderr,"%s: %s: GetNextJob %s failed: %d\n",
|
|
myname, timestamp(), prtp->prtname, err);
|
|
cISO2Mac(prtp->prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"%s: %s: GetNextJob %s failed: %d\n",
|
|
myname, timestamp(), prtp->prtname, err);
|
|
#endif ISO_TRANSLATE
|
|
#else TIMESTAMP
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->prtname);
|
|
fprintf(stderr,"%s: GetNextJob %s failed: %d\n",
|
|
myname, prtp->prtname, err);
|
|
cISO2Mac(prtp->prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"%s: GetNextJob %s failed: %d\n",
|
|
myname, prtp->prtname, err);
|
|
#endif ISO_TRANSLATE
|
|
#endif TIMESTAMP
|
|
}
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
/*
|
|
* abpaps.c and lwsrv.c uses "cno" to refer to different things. The
|
|
* "cno" used by the callbacks is really "srefnum" here. Confusing!
|
|
*/
|
|
if (aufssecurity[srefnum]) {
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef TIMESTAMP
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->prtname);
|
|
fprintf(stderr,"%s: %s: Starting print job for \"%s\", Connection %d\n",
|
|
myname, timestamp(), prtp->prtname, cno);
|
|
cISO2Mac(prtp->prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"%s: %s: Starting print job for \"%s\", Connection %d\n",
|
|
myname, timestamp(), prtp->prtname, cno);
|
|
#endif ISO_TRANSLATE
|
|
#else TIMESTAMP
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->prtname);
|
|
fprintf(stderr,"%s: Starting print job for \"%s\", Connection %d\n",
|
|
myname, prtp->prtname, cno);
|
|
cISO2Mac(prtp->prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"%s: Starting print job for \"%s\", Connection %d\n",
|
|
myname, prtp->prtname, cno);
|
|
#endif ISO_TRANSLATE
|
|
#endif TIMESTAMP
|
|
cpyc2pstr(prtp->statbuf.StatusStr, statusprocessing);
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
}
|
|
#endif LWSRV_AUFS_SECURITY
|
|
if (!singlefork) {
|
|
slotp = GetSlot(prtno);
|
|
myslot = slotp->slot;
|
|
if ((err = PAPGetNetworkInfo(cno, &slotp->addr)) != noErr) {
|
|
fprintf(stderr, "%s: Get Network info failed with error %d", myname,
|
|
err);
|
|
PAPClose(cno, TRUE);
|
|
FreeSlot(slotp->slot);
|
|
continue;
|
|
}
|
|
if (logfile != NULL)
|
|
close(2); /* close log file */
|
|
if ((i = fork()) != 0) {
|
|
PAPShutdown(cno); /* kill off connection */
|
|
slotp->pid = i; /* for resetting status */
|
|
prtp->children++;
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
aufssecurity[srefnum] = FALSE;
|
|
#endif LWSRV_AUFS_SECURITY
|
|
continue;
|
|
}
|
|
for (i = 0; i < nprt; i++) {
|
|
SLClose(prtlist[i].srefnum); /* close all servers for child */
|
|
PAPShutdown(prtlist[i].cno); /* kill off connection */
|
|
}
|
|
nbpShutdown(); /* shutdown nbp for child */
|
|
}
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
if (!aufssecurity[srefnum]) {
|
|
NewStatus(openReplyMessage);
|
|
abSleep(sectotick(20),FALSE);
|
|
PAPClose( cno, TRUE); /* arg2 is ignored!! */
|
|
/* what does it mean? */
|
|
if (singlefork)
|
|
continue;
|
|
else
|
|
exit(1);
|
|
}
|
|
aufssecurity[srefnum] = FALSE;
|
|
#endif LWSRV_AUFS_SECURITY
|
|
/* need for multi-forking, nice for single forking */
|
|
/* handle the connection in cno */
|
|
openlogfile();
|
|
#ifdef SOLARIS
|
|
signal(SIGCHLD,SIG_DFL);
|
|
#else SOLARIS
|
|
signal(SIGCHLD,SIG_IGN);
|
|
#endif SOLARIS
|
|
#ifdef AUTHENTICATE
|
|
if (nprt != 1)
|
|
initauthenticate(*argv, prtp->prtname);
|
|
#endif AUTHENTICATE
|
|
childjob(p_opn(cno, BUFMAX));
|
|
if (!singlefork)
|
|
exit(0);
|
|
else {
|
|
cpyc2pstr(prtp->statbuf.StatusStr, statusidle);
|
|
*username = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
#else /* LWSRV8 */
|
|
|
|
main(argc,argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
int err,i,cno,errcount;
|
|
int prtno,prtcount;
|
|
void cleanup();
|
|
void childdone();
|
|
#ifdef ISO_TRANSLATE
|
|
void cMac2ISO(), cISO2Mac();
|
|
#endif ISO_TRANSLATE
|
|
|
|
if (myname = rindex(argv[0], '/'))
|
|
myname++;
|
|
else
|
|
myname = argv[0];
|
|
|
|
doargs(argc,argv); /* handle args */
|
|
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
requid = getuid(); /* budd */
|
|
reqgid = getgid(); /* budd */
|
|
#endif LWSRV_AUFS_SECURITY
|
|
|
|
#ifdef AUTHENTICATE
|
|
if (nprt == 1)
|
|
initauthenticate(*argv, (char *)prtlist[0].prtname);
|
|
#endif AUTHENTICATE
|
|
|
|
signal(SIGHUP, cleanup);
|
|
signal(SIGINT, cleanup);
|
|
signal(SIGQUIT, cleanup);
|
|
signal(SIGTERM, cleanup);
|
|
|
|
if (!dbug.db_flgs) { /* disassociate */
|
|
if (fork())
|
|
exit(0); /* kill off parent */
|
|
for (i=0; i < 20; i++)
|
|
close(i); /* close all files */
|
|
(void) open("/dev/null",0);
|
|
#ifndef NODUP2
|
|
(void) dup2(0,1);
|
|
#else NODUP2
|
|
(void)dup(0); /* for slot 1 */
|
|
#endif NODUP2
|
|
if (logfile == NULL) {
|
|
#ifndef NODUP2
|
|
(void) dup2(0,2);
|
|
#else NODUP2
|
|
(void) dup(0); /* for slot 2 */
|
|
#endif NODUP2
|
|
} else
|
|
openlogfile();
|
|
#ifndef POSIX
|
|
#ifdef TIOCNOTTY
|
|
if ((i = open("/dev/tty",2)) > 0) {
|
|
ioctl(i, TIOCNOTTY,(char *) 0);
|
|
close(i);
|
|
}
|
|
#endif TIOCNOTTY
|
|
#ifdef xenix5
|
|
/*
|
|
* USG process groups:
|
|
* The fork guarantees that the child is not a process group leader.
|
|
* Then setpgrp() can work, whick loses the controllong tty.
|
|
* Note that we must be careful not to be the first to open any tty,
|
|
* or it will become our controlling tty. C'est la vie.
|
|
*/
|
|
setpgrp();
|
|
#endif xenix5
|
|
#else POSIX
|
|
(void) setsid();
|
|
#endif POSIX
|
|
}
|
|
|
|
/* dbug.db_pap = TRUE; */
|
|
|
|
abInit(FALSE); /* initialize appletalk driver */
|
|
nbpInit(); /* initialize NBP routines */
|
|
PAPInit(); /* init PAP printer routines */
|
|
|
|
set_printer(&prtlist[0]); /* for definiteness */
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtname);
|
|
fprintf(stderr,"lwsrv: Spooler starting for %s.%s.*\n",
|
|
(char *)prtname, prttype);
|
|
cISO2Mac(prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"lwsrv: Spooler starting for %s.%s.*\n",
|
|
(char *)prtname, prttype);
|
|
#endif ISO_TRANSLATE
|
|
if (!spool_setup(tracefile, fontfile, (char *)prtname, dictdir)) {
|
|
usage(argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
if (!singlefork)
|
|
signal(SIGCHLD, childdone);
|
|
|
|
errcount = 0;
|
|
for (prtp=prtlist,i=0; i<nprt; prtp++,i++) {
|
|
sprintf(prtp->nbpbuf,"%s:%s@*",(char *)prtp->prtname,prttype);
|
|
cpyc2pstr(prtp->statbuf.StatusStr,"status: idle");
|
|
err = SLInit(&(prtp->srefnum), prtp->nbpbuf, 8, &(prtp->statbuf));
|
|
if (err != noErr) {
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->nbpbuf);
|
|
fprintf(stderr,"lwsrv: SLInit %s failed: %d\n", prtp->nbpbuf, err);
|
|
cISO2Mac(prtp->nbpbuf);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"lwsrv: SLInit %s failed: %d\n", prtp->nbpbuf, err);
|
|
#endif ISO_TRANSLATE
|
|
errcount++;
|
|
}
|
|
/* GetNextJob is asynchronous, so call it for each printer */
|
|
err = GetNextJob(prtp->srefnum, &(prtp->cno), &(prtp->rcomp));
|
|
if (err != noErr) {
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->prtname);
|
|
fprintf(stderr,"lwsrv: GetNextJob %s failed: %d\n",
|
|
(char *)prtp->prtname, err);
|
|
cISO2Mac(prtp->prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"lwsrv: GetNextJob %s failed: %d\n",
|
|
(char *)prtp->prtname, err);
|
|
#endif ISO_TRANSLATE
|
|
errcount++;
|
|
}
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->nbpbuf);
|
|
fprintf(stderr, "lwsrv: %s ready and waiting\n", prtp->nbpbuf);
|
|
cISO2Mac(prtp->nbpbuf);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr, "lwsrv: %s ready and waiting\n", prtp->nbpbuf);
|
|
#endif ISO_TRANSLATE
|
|
}
|
|
|
|
if (errcount == nprt) {
|
|
fprintf(stderr, "lwsrv: no printers successfully registered!\n");
|
|
exit(1);
|
|
}
|
|
|
|
prtno = 0; prtcount = 0;
|
|
while (TRUE) {
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
AddrBlock addr; /* budd */
|
|
#endif LWSRV_AUFS_SECURITY
|
|
openlogfile();
|
|
NewStatus("idle");
|
|
|
|
/* scan each printer in turn, processing each one as "normal" if there
|
|
* is work available. If no work was available then abSleep for a while
|
|
*/
|
|
while (prtno<nprt && prtlist[prtno].rcomp > 0) prtno++;
|
|
if (prtno == nprt) {
|
|
if (prtcount == 0) {
|
|
abSleep(20,TRUE); /* wait for some work */
|
|
}
|
|
prtno = 0; /* start scan again */
|
|
continue;
|
|
}
|
|
|
|
prtp = &prtlist[prtno];
|
|
set_printer(prtp); /* set the global variables etc */
|
|
cno = prtp->cno;
|
|
|
|
/* GetNextJob is asynchronous, so announce readiness for more work */
|
|
/* WTR: is this right - should it depend on singlefork? */
|
|
err = GetNextJob(prtp->srefnum, &(prtp->cno), &(prtp->rcomp));
|
|
if (err != noErr) {
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->prtname);
|
|
fprintf(stderr,"lwsrv: GetNextJob %s failed: %d\n",
|
|
(char *)prtp->prtname, err);
|
|
cISO2Mac(prtp->prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"lwsrv: GetNextJob %s failed: %d\n",
|
|
(char *)prtp->prtname, err);
|
|
#endif ISO_TRANSLATE
|
|
}
|
|
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtname);
|
|
fprintf(stderr,"lwsrv: Starting print job for %s\n", (char *)prtname);
|
|
cISO2Mac(prtname);
|
|
#else ISO_TRANSLATE
|
|
fprintf(stderr,"lwsrv: Starting print job for %s\n", (char *)prtname);
|
|
#endif ISO_TRANSLATE
|
|
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
/*** budd.... */
|
|
if ((err = PAPGetNetworkInfo(cno, &addr)) != noErr)
|
|
fprintf(stderr, "Get Network info failed with error %d", err);
|
|
else
|
|
fprintf(stderr,"Connection %d from [Network %d.%d, node %d, socket %d]\n",
|
|
cno, nkipnetnumber(addr.net),
|
|
nkipsubnetnumber(addr.net),
|
|
addr.node, addr.skt);
|
|
|
|
if( aufsdb != NULL ) {
|
|
char fname[ 256 ];
|
|
char filename[ 256 ];
|
|
int f, cc, ok = 0;
|
|
struct passwd *pw;
|
|
struct stat statbuf;
|
|
#ifdef HIDE_LWSEC_FILE
|
|
char protecteddir[MAXPATHLEN];
|
|
(void) strcpy(protecteddir, aufsdb);
|
|
make_userlogin(filename, protecteddir, addr);
|
|
(void) strcpy(protecteddir, filename);
|
|
filename[0] = '\0';
|
|
make_userlogin(filename, protecteddir, addr);
|
|
#else HIDE_LWSEC_FILE
|
|
make_userlogin( filename, aufsdb, addr );
|
|
#endif HIDE_LWSEC_FILE
|
|
|
|
if( (f = open( filename, 0)) >= 0) {
|
|
if( (cc = read( f, fname, sizeof( fname )-1 )) > 0 ) {
|
|
if( fname[cc-1] == '\n' )
|
|
fname[cc-1] = '\0';
|
|
fprintf( stderr, "Found username in aufsdb (%s): %s\n",
|
|
aufsdb, fname );
|
|
|
|
if ((tempbin = rindex(fname,':')) != NULL) {
|
|
*tempbin='\0';
|
|
tempbin++;
|
|
bin=(char *) malloc(strlen(tempbin)+1);
|
|
strcpy(bin,tempbin);
|
|
}
|
|
|
|
(void) stat(filename, &statbuf);
|
|
if ( (pw = getpwuid((int) statbuf.st_uid)) != NULL ) {
|
|
if ( strcmp(pw->pw_name, fname) == 0) {
|
|
requid = pw->pw_uid;
|
|
reqgid = pw->pw_gid;
|
|
#ifdef LWSRV_LPR_LOG
|
|
requname = pw->pw_name;
|
|
#endif LWSRV_LPR_LOG
|
|
ok = 1;
|
|
}
|
|
}
|
|
else
|
|
if( (pw = getpwnam( fname )) != NULL ) {
|
|
requid = pw->pw_uid;
|
|
reqgid = pw->pw_gid;
|
|
#ifdef LWSRV_LPR_LOG
|
|
requname = pw->pw_name;
|
|
#endif LWSRV_LPR_LOG
|
|
ok = 1; /* true */
|
|
} /* pwnam ok */
|
|
} /* read OK */
|
|
close(f); /* close the file */
|
|
} /* open OK */
|
|
if( !ok ) { /* dump connection with error message */
|
|
char message[ 512 ];
|
|
fprintf( stderr, "No username (or invalid) confirmation.\n");
|
|
gethostname( fname, sizeof( fname )-1 ); /* ick */
|
|
|
|
/* THIS DOES NOT WORK! */
|
|
sprintf(message, "error: please login to host %s via appleshare",
|
|
fname );
|
|
NewStatus( message );
|
|
sleep( 3 ); /* bleh!! */
|
|
/* PAPShutdown( cno ); /* */
|
|
PAPClose( cno, TRUE ); /* arg2 is ignored!! */
|
|
/* what does it mean? */
|
|
|
|
continue;
|
|
} /* not ok */
|
|
} /* have aufsdb */
|
|
/* ....budd ***/
|
|
#endif LWSRV_AUFS_SECURITY
|
|
|
|
if (!singlefork) {
|
|
if (logfile != NULL)
|
|
close(2); /* close log file */
|
|
if (fork() != 0) {
|
|
PAPShutdown(cno); /* kill off connection */
|
|
continue;
|
|
}
|
|
SLClose(srefnum); /* close server for child */
|
|
nbpShutdown(); /* shutdown nbp for child */
|
|
} else NewStatus("busy, processing job");
|
|
/* need for multi-forking, nice for single forking */
|
|
/* handle the connection in cno */
|
|
openlogfile();
|
|
#ifdef SOLARIS
|
|
signal(SIGCHLD,SIG_DFL);
|
|
#else SOLARIS
|
|
signal(SIGCHLD,SIG_IGN);
|
|
#endif SOLARIS
|
|
#ifdef AUTHENTICATE
|
|
if (nprt != 1)
|
|
initauthenticate(*argv, (char *)prtlist[prtno].prtname);
|
|
#endif AUTHENTICATE
|
|
childjob(p_opn(cno, BUFMAX));
|
|
if (!singlefork)
|
|
exit(0);
|
|
}
|
|
}
|
|
#endif /* LWSRV8 */
|
|
|
|
#ifdef RUN_AS_USER
|
|
/*
|
|
* Conversion table, macintosh ascii with diacriticals to plain ascii.
|
|
* In addition, an ':' also maps to an underscore for obvious reasons.
|
|
* All other junk maps to an underscore.
|
|
*
|
|
*/
|
|
|
|
static unsigned char convert [256] = {
|
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
|
/* 0 */ '_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_',
|
|
/* 1 */ '_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_',
|
|
/* 2 */ ' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/',
|
|
/* 3 */ '0','1','2','3','4','5','6','7','8','9','_',';','<','=','>','?',
|
|
/* 4 */ '@','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
|
|
/* 5 */ 'p','q','r','s','t','u','v','w','x','y','z','[','\\',']','^','_',
|
|
/* 6 */ '`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
|
|
/* 7 */ 'p','q','r','s','t','u','v','w','x','y','z','{','|','}','~','_',
|
|
/* 8 */ 'a','a','c','e','n','o','u','a','a','a','a','a','a','c','e','e',
|
|
/* 9 */ 'e','e','i','i','i','i','n','o','o','o','o','o','u','u','u','u',
|
|
/* a */ '_','_','c','$','_','*','_','_','r','c','_','_','_','_','_','o',
|
|
/* b */ '_','_','_','_','_','m','d','s','p','p','_','a','o','_','_','o',
|
|
/* c */ '?','!','_','_','_','_','_','_','_','_','_','a','a','o','_','_',
|
|
/* d */ '_','_','_','_','_','_','_','_','y','_','_','_','_','_','_','_',
|
|
/* e */ '_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_',
|
|
/* f */ '_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_'
|
|
};
|
|
|
|
static void
|
|
unixize(name)
|
|
char *name;
|
|
{
|
|
register unsigned char *p = (unsigned char *)name;
|
|
|
|
while (*p) {
|
|
*p = convert[*p];
|
|
p += 1;
|
|
}
|
|
}
|
|
|
|
static char *
|
|
getmacname(name, line, file)
|
|
char *name; /* mac name */
|
|
char *line; /* line buffer to use */
|
|
char *file; /* name of file containing table */
|
|
{
|
|
FILE *f;
|
|
char *m, *nl;
|
|
|
|
if ((f = fopen(file, "r")) == NULL)
|
|
return(NULL);
|
|
|
|
while (fgets(line, 255, f) != NULL) {
|
|
if (*line == '#' || *line == '\n')
|
|
continue; /* skip comment line */
|
|
if ((m = index(line, ':')) == NULL)
|
|
continue; /* line in error */
|
|
*m++ = '\0';
|
|
if ((nl = index(m, '\n')) != NULL)
|
|
*nl = '\0'; /* take trailing newline */
|
|
unixize(m);
|
|
if (strcmp(m, name) == 0) {
|
|
fclose(f);
|
|
return(line);
|
|
}
|
|
}
|
|
fclose(f);
|
|
return(NULL);
|
|
}
|
|
|
|
/*
|
|
* We try to find a unix username to match the name from the mac.
|
|
* The approach is simple. We use a simple file to convert mac names
|
|
* to unix login names. The file needs only contain mac names that can't
|
|
* be resolved into unix names by simple means. The other ones are found
|
|
* automaticly. This means that 'Maarten' is resolved into 'maarten' without
|
|
* intervention, whereas 'El Gringo' needs to be in the file to be resolved
|
|
* to 'dolf'.
|
|
*
|
|
* Example file:
|
|
* #comment line
|
|
* dolf:El Gringo
|
|
*
|
|
*/
|
|
|
|
static int
|
|
unixuid(macname)
|
|
char *macname;
|
|
{
|
|
struct passwd *pw;
|
|
char line[256];
|
|
char name[256];
|
|
char *n;
|
|
|
|
strcpy(name, macname);
|
|
unixize(name);
|
|
|
|
if ((n = getmacname(name, line, USER_FILE)) == NULL)
|
|
n = name;
|
|
|
|
if ((pw = getpwnam(n)) == NULL)
|
|
return(0);
|
|
else
|
|
return(pw->pw_uid);
|
|
}
|
|
#endif RUN_AS_USER
|
|
|
|
#ifdef LWSRV8
|
|
export
|
|
childjob(pf)
|
|
PFILE *pf;
|
|
{
|
|
long t;
|
|
int argc, i;
|
|
FILE *outfile;
|
|
char tname[256],status[256];
|
|
char pbuf[256],rhbuf[16],jbuf[1024];
|
|
char *childargv[64];
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
char bbuf[256];
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef NeXT
|
|
char dpistring[6];
|
|
#endif NeXT
|
|
#ifdef RUN_AS_USER
|
|
int uid;
|
|
#endif RUN_AS_USER
|
|
|
|
int waitret;
|
|
WSTATUS waitstatus;
|
|
|
|
int actualprintout;
|
|
int doeof;
|
|
|
|
#ifdef AUTHENTICATE
|
|
register PAPSOCKET *ps;
|
|
register unsigned net;
|
|
#ifdef ISO_TRANSLATE
|
|
void cMac2ISO(), cISO2Mac();
|
|
#endif ISO_TRANSLATE
|
|
|
|
if ((ps = cnotopapskt(pf->p_cno)) == NULL || !authenticate(net =
|
|
ntohs(ps->addr.net), ps->addr.node)) {
|
|
p_cls(pf); /* close out the pap connection */
|
|
(void)time(&t);
|
|
#ifdef TIMESTAMP
|
|
fprintf(stderr,"%s: %s: Authentication failed: net %u.%u node %u\n",
|
|
myname, timestamp(), ((unsigned)net >> 8), (unsigned)(net & 0xff),
|
|
(unsigned)ps->addr.node);
|
|
#else TIMESTAMP
|
|
fprintf(stderr,"%s: Authentication failed: net %u.%u node %u\n",
|
|
myname, ((unsigned)net >> 8), (unsigned)(net & 0xff),
|
|
(unsigned)ps->addr.node);
|
|
#endif TIMESTAMP
|
|
return;
|
|
}
|
|
#endif AUTHENTICATE
|
|
|
|
jobname[0] = username[0] = '\0';
|
|
|
|
if (tracing) { /* is this a trace? */
|
|
strcpy(tname,prtp->tracefile); /* yes... then output is tracefile */
|
|
if ((outfile = fopen(tname, "w+")) == NULL)
|
|
perror(tname);
|
|
#ifndef aux
|
|
#if defined(__hpux) || defined(SOLARIS)
|
|
if (setvbuf(outfile, NULL, _IOLBF, 0) != 0)
|
|
perror(tname);
|
|
#else /* __hpux || SOLARIS */
|
|
setlinebuf(outfile);
|
|
#endif /* __hpux || SOLARIS */
|
|
#endif aux
|
|
chmod(tname, 0644);
|
|
} else { /* otherwise use a temp file */
|
|
if (tmpfiledir != NULL) {
|
|
strcpy(tname,tmpfiledir);
|
|
strcat(tname,"/lwsrvXXXXXX");
|
|
} else
|
|
strcpy(tname,TEMPFILE);
|
|
mktemp(tname);
|
|
if ((outfile = fopen(tname, "w+")) == NULL)
|
|
perror(tname);
|
|
chmod(tname, 0600);
|
|
}
|
|
|
|
NewStatus(prtp->children <= 0 ? "initializing" : statusprocessing);
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtp->prtname);
|
|
sprintf(status,"receiving job for %s", prtp->prtname);
|
|
cISO2Mac(prtp->prtname);
|
|
#else ISO_TRANSLATE
|
|
sprintf(status,"receiving job for %s", prtp->prtname);
|
|
#endif ISO_TRANSLATE
|
|
|
|
pagecount = -1;
|
|
#ifdef PAGECOUNT
|
|
pcopies = 0;
|
|
#endif PAGECOUNT
|
|
|
|
/*
|
|
* Set actualprintout to -1 by default (for non-dcs conforming documents);
|
|
* If we get %!PS-Adobe, set it to zero if it is still negative.
|
|
* On a %%Page, set it to 1.
|
|
*
|
|
*/
|
|
actualprintout = -1;
|
|
while (getjob(pf,outfile,&actualprintout,&doeof)) { /* while still open... */
|
|
NewStatus(status);
|
|
/* don't send out real eof - causes real problems */
|
|
/* given that we are prepending procsets */
|
|
if (doeof)
|
|
fprintf(outfile,"%% *EOF*\n");
|
|
}
|
|
|
|
fclose(outfile);
|
|
|
|
(void) time(&t);
|
|
|
|
#ifdef RUN_AS_USER
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
if (((uid = requid) != 0)
|
|
|| (uid = unixuid(username))) {
|
|
#else LWSRV_AUFS_SECURITY
|
|
if ((uid = unixuid(username))) {
|
|
#ifdef LWSRV_LPR_LOG
|
|
requname = username;
|
|
#endif LWSRV_LPR_LOG
|
|
#endif LWSRV_AUFS_SECURITY
|
|
chown(tname, uid, -1);
|
|
}
|
|
#ifdef USER_REQUIRED
|
|
else if (actualprintout) {
|
|
int n;
|
|
FILE *infile;
|
|
char buffer[BUFSIZ];
|
|
|
|
#ifdef TIMESTAMP
|
|
fprintf(stderr, "%s: %s: Job refused for macuser %s\n",
|
|
myname, timestamp(), username);
|
|
#else TIMESTAMP
|
|
fprintf(stderr, "%s: Job refused for macuser %s\n", myname, username);
|
|
#endif TIMESTAMP
|
|
NewStatus ("Unknown user, job refused");
|
|
unlink(tname);
|
|
if ((outfile = fopen(tname, "w+")) != NULL) {
|
|
fprintf(outfile, "\n\nMacintosh user name: %s\nJob: %s\n",
|
|
username, jobname);
|
|
fprintf(outfile, "\nJob refused. ");
|
|
fprintf(outfile,
|
|
"Can't map Macintosh user name to a Unix user name\n\n");
|
|
if ((infile = fopen(REFUSE_MESSAGE, "r")) != NULL) {
|
|
while ((n = fread(buffer, 1, BUFSIZ, infile)) > 0)
|
|
fwrite(buffer, 1, n, outfile);
|
|
fclose(infile);
|
|
} else
|
|
fprintf(outfile, "No detailed message available\n");
|
|
fclose(outfile);
|
|
}
|
|
}
|
|
#endif USER_REQUIRED
|
|
#endif RUN_AS_USER
|
|
|
|
if (tracing)
|
|
#ifdef TIMESTAMP
|
|
fprintf(stderr,"%s: %s: Tracing to file: %s; job %s; user %s\n",
|
|
myname,timestamp(),prtp->tracefile,jobname,username);
|
|
#else TIMESTAMP
|
|
fprintf(stderr,"%s: Tracing to file: %s; job %s; user %s\n",
|
|
myname,prtp->tracefile,jobname,username);
|
|
#endif TIMESTAMP
|
|
else if (!actualprintout) {
|
|
#ifdef TIMESTAMP
|
|
fprintf(stderr,"%s: %s: No actual output for job %s; user %s\n",
|
|
myname,timestamp(),jobname,username);
|
|
#else TIMESTAMP
|
|
fprintf(stderr,"%s: No actual output for job %s; user %s\n",
|
|
myname,jobname,username);
|
|
#endif TIMESTAMP
|
|
unlink(tname);
|
|
} else {
|
|
if (rflag)
|
|
fprintf(stderr,"%s: Preserving file in %s\n",myname,tname);
|
|
|
|
/*
|
|
* this way lies madness ...
|
|
*/
|
|
|
|
#ifdef RUN_AS_USER
|
|
if (uid)
|
|
#endif RUN_AS_USER
|
|
#ifdef TIMESTAMP
|
|
fprintf(stderr,"%s: %s: Printing job: %s; user %s\n",
|
|
myname,timestamp(),jobname,username);
|
|
#else TIMESTAMP
|
|
fprintf(stderr,"%s: Printing job: %s; user %s\n",
|
|
myname,jobname,username);
|
|
#endif TIMESTAMP
|
|
#ifdef RUN_AS_USER
|
|
else
|
|
#ifdef TIMESTAMP
|
|
fprintf(stderr,"%s: %s: Printing notification: %s; user %s\n",
|
|
myname,timestamp(),jobname,username);
|
|
#else TIMESTAMP
|
|
fprintf(stderr,"%s: Printing notification: %s; user %s\n",
|
|
myname,jobname,username);
|
|
#endif TIMESTAMP
|
|
#endif RUN_AS_USER
|
|
|
|
argc = 0;
|
|
#ifdef USESYSVLP
|
|
childargv[argc++]="lp";
|
|
#else USESYSVLP
|
|
childargv[argc++]="lpr";
|
|
#endif USESYSVLP
|
|
#ifdef MELBOURNE
|
|
childargv[argc++]="-v";
|
|
#endif MELBOURNE
|
|
#ifdef VUW
|
|
childargv[argc++]="-l";
|
|
#endif VUW
|
|
#ifdef xenix5
|
|
childargv[argc++]="-og";
|
|
sprintf(pbuf,"-d%s",prtp->unixpname); /* name of the printer */
|
|
childargv[argc++]=pbuf;
|
|
#else xenix5
|
|
#ifdef USESYSVLP
|
|
sprintf(pbuf,"-d%s",prtp->unixpname); /* name of the printer */
|
|
#else USESYSVLP
|
|
sprintf(pbuf,"-P%s",prtp->unixpname); /* name of the printer */
|
|
#endif USESYSVLP
|
|
childargv[argc++]=pbuf;
|
|
if (hflag) { /* want a burst page */
|
|
#ifdef USESYSVLP
|
|
#ifdef DOCNAME
|
|
#ifdef __hpux
|
|
for (i = 0; i < MAXJOBNAME-1; i++)
|
|
if (isspace(jobname[i]))
|
|
jobtitle[i] = '_';
|
|
else
|
|
jobtitle[i] = jobname[i];
|
|
jobtitle[MAXJOBNAME-1] = '\0';
|
|
sprintf(jbuf,"-tMacJobName:%s",jobtitle);
|
|
#else __hpux
|
|
sprintf(jbuf,"-tMacUser: %s Job: %s",username,jobname); /* job name */
|
|
#endif __hpux
|
|
#else DOCNAME
|
|
sprintf(jbuf,"-tMacUser: %s",username); /* job name */
|
|
#endif DOCNAME
|
|
#else USESYSVLP
|
|
childargv[argc++]="-J";
|
|
#ifdef DOCNAME
|
|
sprintf(jbuf,"MacUser: %s Job: %s",username,jobname); /* job name */
|
|
#else DOCNAME
|
|
sprintf(jbuf,"MacUser: %s",username); /* job name */
|
|
#endif DOCNAME
|
|
#endif USESYSVLP
|
|
#ifdef PAGECOUNT
|
|
if (pagecount >= 0) {
|
|
if (pcopies <= 0)
|
|
pcopies = 1;
|
|
#ifdef __hpux
|
|
sprintf(&jbuf[strlen(jbuf)], "_Pages:_%04d", pcopies*pagecount);
|
|
#else __hpux
|
|
sprintf(&jbuf[strlen(jbuf)], " Pages: %d", pcopies*pagecount);
|
|
#endif __hpux
|
|
}
|
|
#endif PAGECOUNT
|
|
childargv[argc++]=jbuf;
|
|
}
|
|
#ifndef hpux
|
|
else
|
|
#ifdef USESYSVLP
|
|
# ifdef SOLARIS
|
|
childargv[argc++]="-onobanner"; /* suppress burst page */
|
|
# else SOLARIS
|
|
childargv[argc++]="-o-h"; /* suppress burst page */
|
|
# endif SOLARIS
|
|
#else USESYSVLP
|
|
childargv[argc++]="-h"; /* suppress burst page */
|
|
#endif USESYSVLP
|
|
#endif hpux
|
|
#endif xenix5
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
if (aufsdb && bin != NULL) {
|
|
#ifdef RUTGERS
|
|
sprintf(bbuf, "-B%s", bin);
|
|
#else RUTGERS
|
|
sprintf(bbuf, "-C%s", bin);
|
|
#endif RUTGERS
|
|
childargv[argc++]=bbuf;
|
|
}
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef NeXT
|
|
if (nextdpi) {
|
|
sprintf(dpistring, "-R%s", nextdpi);
|
|
childargv[argc++]=dpistring;
|
|
}
|
|
#endif NeXT
|
|
rhbuf[0] = rhbuf[1] = '\0';
|
|
#ifdef xenix5
|
|
/* will this work ... ? */
|
|
sprintf(rhbuf,"-%s%s",rflag ? "" : "r",hflag ? "" : "ob");
|
|
#else xenix5
|
|
#if defined(__hpux) || defined(SOLARIS)
|
|
sprintf(rhbuf,"-c");
|
|
#else /* __hpux || SOLARIS */
|
|
sprintf(rhbuf,"-%s",rflag ? "" : "r");
|
|
#endif /* __hpux || SOLARIS */
|
|
#endif xenix5
|
|
if (rhbuf[1] != '\0')
|
|
childargv[argc++]=rhbuf; /* include h and/or r flags */
|
|
#ifdef USELPRSYM
|
|
#ifndef USESYSVLP
|
|
childargv[argc++]="-s"; /* better for > 1M files */
|
|
#endif USESYSVLP
|
|
#endif USELPRSYM
|
|
#ifdef LPRARGS
|
|
if (lprargs) {
|
|
register int n = NList(lprargs);
|
|
register char **ip = (char **)AddrList(lprargs);
|
|
|
|
while (n-- > 0)
|
|
childargv[argc++] = *ip++;
|
|
}
|
|
#endif LPRARGS
|
|
childargv[argc++]=tname; /* our temporary file name */
|
|
childargv[argc]=(char *) 0; /* end of argument list */
|
|
|
|
switch (fork()) {
|
|
case 0:
|
|
#ifdef RUN_AS_USER
|
|
#ifndef LWSRV_AUFS_SECURITY
|
|
setuid(uid);
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#endif RUN_AS_USER
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
if (aufsdb) {
|
|
/*
|
|
* dissassociate from any tty to make sure
|
|
* lpr uses our requid instead of getlogin()
|
|
*
|
|
*/
|
|
#ifndef LWSRV_LPR_LOG
|
|
for (i = 0 ; i < 10 ; i++)
|
|
(void) close(i);
|
|
(void) open("/", 0);
|
|
(void) dup2(0, 1);
|
|
(void) dup2(0, 2);
|
|
#else LWSRV_LPR_LOG
|
|
for (i = 3 ; i < 10 ; i++)
|
|
(void) close(i);
|
|
/*
|
|
* stderr is the logfile; stdin and stdout are already
|
|
* using /dev/null, therefore disassociated from any tty;
|
|
* The Rutgers hack requires stdout to be the logfile if
|
|
* one exists.
|
|
*
|
|
*/
|
|
/* (void) open("/", 0); */
|
|
/* (void) dup2(0, 1); */
|
|
/* (void) dup2(0, 2); */
|
|
#endif LWSRV_LPR_LOG
|
|
chown(tname, requid, reqgid);
|
|
setuid(requid);
|
|
setgid(reqgid);
|
|
}
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef LWSRV_LPR_LOG
|
|
/*
|
|
* log all lpr invocations for troubleshooting
|
|
* printing problems
|
|
*
|
|
*/
|
|
#ifdef TIMESTAMP
|
|
fprintf(stderr, "%s: %s: Invoking lpr as user %s using execv: %s",
|
|
myname, timestamp(), (requname) ? requname : "<unknown>",
|
|
lprcmd);
|
|
#else TIMESTAMP
|
|
fprintf(stderr, "%s: Invoking lpr as user %s using execv: %s",
|
|
myname, (requname) ? requname : "<unknown>", lprcmd);
|
|
#endif TIMESTAMP
|
|
for ( i = 1 ; i < argc ; i++)
|
|
fprintf(stderr," %s",childargv[i]);
|
|
fprintf(stderr, "\n");
|
|
#endif LWSRV_LPR_LOG
|
|
if (execv(lprcmd,childargv)) {
|
|
#ifdef TIMESTAMP
|
|
fprintf(stderr,"%s: %s: exec of %s failed\n",
|
|
myname, timestamp(), lprcmd);
|
|
#else TIMESTAMP
|
|
fprintf(stderr,"%s: exec of %s failed\n", myname, lprcmd);
|
|
#endif TIMESTAMP
|
|
perror("exec");
|
|
exit(-1);
|
|
}
|
|
break;
|
|
case -1:
|
|
#ifdef TIMESTAMP
|
|
fprintf(stderr,"%s: %s: fork failed trying to run %s\n",
|
|
myname,timestamp(),lprcmd);
|
|
#else TIMESTAMP
|
|
fprintf(stderr,"%s: fork failed trying to run %s\n",myname,lprcmd);
|
|
#endif TIMESTAMP
|
|
perror("fork");
|
|
break;
|
|
default:
|
|
|
|
/*
|
|
* This code is important, since lwsrv relies upon lpr to remove
|
|
* the temporary files, we must remove them if lpr fails for any
|
|
* reason (unless rflag TRUE).
|
|
*
|
|
*/
|
|
|
|
/* wait for the lpr to do its thing */
|
|
|
|
if ((waitret = wait(&waitstatus)) == -1) {
|
|
#ifdef UTS
|
|
waitstatus = 0; /* wait can return early */
|
|
#else UTS
|
|
perror("wait");
|
|
exit(-1);
|
|
#endif UTS
|
|
}
|
|
|
|
#if defined(hpux) || defined(SOLARIS)
|
|
if (!rflag)
|
|
unlink(tname);
|
|
#else /* hpux || SOLARIS */
|
|
if (WIFEXITED(waitstatus)) {
|
|
if (W_RETCODE(waitstatus) != 0) {
|
|
#ifdef TIMESTAMP
|
|
fprintf(stderr,
|
|
"%s: %s: lpr exited with status %d, %sremoving %s\n",
|
|
myname, timestamp(), W_RETCODE(waitstatus),
|
|
(rflag) ? "not " : "", tname);
|
|
#else TIMESTAMP
|
|
fprintf(stderr,
|
|
"%s: lpr exited with status %d, %sremoving %s\n", myname,
|
|
W_RETCODE(waitstatus), (rflag) ? "not " : "", tname);
|
|
#endif TIMESTAMP
|
|
if (!rflag)
|
|
unlink(tname);
|
|
}
|
|
}
|
|
#endif /* hpux || SOLARIS */
|
|
break;
|
|
}
|
|
}
|
|
p_cls(pf); /* close out the pap connection */
|
|
}
|
|
|
|
#else /* LWSRV8 */
|
|
|
|
export
|
|
childjob(pf)
|
|
PFILE *pf;
|
|
{
|
|
long t;
|
|
int argc, i;
|
|
FILE *outfile;
|
|
char tname[256],status[256];
|
|
char pbuf[256],rhbuf[16],jbuf[1024];
|
|
char *childargv[64];
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
char bbuf[256];
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef NeXT
|
|
char dpistring[6];
|
|
#endif NeXT
|
|
#ifdef RUN_AS_USER
|
|
int uid;
|
|
#endif RUN_AS_USER
|
|
|
|
int waitret;
|
|
WSTATUS waitstatus;
|
|
|
|
#ifdef AUTHENTICATE
|
|
register PAPSOCKET *ps;
|
|
register unsigned net;
|
|
#ifdef ISO_TRANSLATION
|
|
void cMac2ISO(), cISO2Mac();
|
|
#endif ISO_TRANSLATION
|
|
|
|
if((ps = cnotopapskt(pf->p_cno)) == NULL || !authenticate(net =
|
|
ntohs(ps->addr.net), ps->addr.node)) {
|
|
p_cls(pf); /* close out the pap connection */
|
|
(void)time(&t);
|
|
fprintf(stderr,"lwsrv: Authentication failed: net %u.%u node %u; on %s",
|
|
((unsigned)net >> 8), (unsigned)(net & 0xff), (unsigned)ps->addr.node,
|
|
ctime(&t));
|
|
return;
|
|
}
|
|
#endif AUTHENTICATE
|
|
|
|
jobname[0] = username[0] = '\0';
|
|
|
|
if (tracefile != NULL) /* is this a trace? */
|
|
strcpy(tname,tracefile); /* yes... then output is tracefile */
|
|
else { /* otherwise use a temp file */
|
|
if (tmpfiledir != NULL) {
|
|
strcpy(tname,tmpfiledir);
|
|
strcat(tname,"/lwsrvXXXXXX");
|
|
} else
|
|
strcat(tname,TEMPFILE);
|
|
mktemp(tname);
|
|
}
|
|
|
|
if ((outfile = fopen(tname, "w+")) == NULL)
|
|
perror(tname);
|
|
|
|
chmod(tname, 0600);
|
|
|
|
if (singlefork)
|
|
NewStatus("initializing");
|
|
|
|
#ifdef ISO_TRANSLATE
|
|
cMac2ISO(prtname);
|
|
sprintf(status,"receiving job for %s", (char *)prtname);
|
|
cISO2Mac(prtname);
|
|
#else ISO_TRANSLATE
|
|
sprintf(status,"receiving job for %s", (char *)prtname);
|
|
#endif ISO_TRANSLATE
|
|
|
|
scandicts(dictdir);
|
|
|
|
#ifdef PAGECOUNT
|
|
pagecount = -1;
|
|
pcopies = 0;
|
|
#endif PAGECOUNT
|
|
|
|
while (getjob(pf,outfile)) { /* while still open... */
|
|
if (singlefork)
|
|
NewStatus(status);
|
|
/* don't send out real eof - causes real problems */
|
|
/* given that we are prepending procsets */
|
|
fprintf(outfile,"%% *EOF*\n");
|
|
}
|
|
|
|
fclose(outfile);
|
|
|
|
(void) time(&t);
|
|
|
|
#ifdef RUN_AS_USER
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
if (((uid = requid) != 0)
|
|
|| (uid = unixuid(username)))
|
|
#else LWSRV_AUFS_SECURITY
|
|
if ((uid = unixuid(username)))
|
|
#endif LWSRV_AUFS_SECURITY
|
|
chown(tname, uid, -1);
|
|
#ifdef USER_REQUIRED
|
|
else {
|
|
int n;
|
|
FILE *infile;
|
|
char buffer[BUFSIZ];
|
|
|
|
fprintf(stderr, "lwsrv: Job refused for macuser %s\n", username);
|
|
/* NewStatus ("Unknown user, job refused"); */
|
|
unlink(tname);
|
|
if ((outfile = fopen(tname, "w+")) != NULL) {
|
|
fprintf(outfile, "\n\nMacintosh user name: %s\nJob: %s\n",
|
|
username, jobname);
|
|
fprintf(outfile, "\nJob refused. ");
|
|
fprintf(outfile,
|
|
"Can't map Macintosh user name to a Unix user name\n\n");
|
|
if ((infile = fopen(REFUSE_MESSAGE, "r")) != NULL) {
|
|
while ((n = fread(buffer, 1, BUFSIZ, infile)) > 0)
|
|
fwrite(buffer, 1, n, outfile);
|
|
fclose(infile);
|
|
} else
|
|
fprintf(outfile, "No detailed message available\n");
|
|
fclose(outfile);
|
|
}
|
|
}
|
|
#endif USER_REQUIRED
|
|
#endif RUN_AS_USER
|
|
|
|
if (tracefile != NULL)
|
|
fprintf(stderr,"lwsrv: Tracing to file: %s; job %s; user %s; on %s\n",
|
|
tracefile,jobname,username,ctime(&t));
|
|
else {
|
|
if (rflag)
|
|
fprintf(stderr,"lwsrv: Preserving file in %s\n",tname);
|
|
|
|
/*
|
|
* this way lies madness ...
|
|
*/
|
|
|
|
#ifdef RUN_AS_USER
|
|
if (uid)
|
|
#endif RUN_AS_USER
|
|
fprintf(stderr,"lwsrv: Printing job: %s; user %s; on %s\n",
|
|
jobname,username,ctime(&t));
|
|
#ifdef RUN_AS_USER
|
|
else
|
|
fprintf(stderr,"lwsrv: Printing notification: %s; user %s; on %s\n",
|
|
jobname,username,ctime(&t));
|
|
#endif RUN_AS_USER
|
|
|
|
argc = 0;
|
|
#ifdef USESYSVLP
|
|
childargv[argc++]="lp";
|
|
#else USESYSVLP
|
|
childargv[argc++]="lpr";
|
|
#endif USESYSVLP
|
|
#ifdef MELBOURNE
|
|
childargv[argc++]="-v";
|
|
#endif MELBOURNE
|
|
#ifdef VUW
|
|
childargv[argc++]="-l";
|
|
#endif VUW
|
|
#ifdef xenix5
|
|
childargv[argc++]="-og";
|
|
sprintf(pbuf,"-d%s",unixpname); /* name of the printer */
|
|
childargv[argc++]=pbuf;
|
|
#else xenix5
|
|
#ifdef USESYSVLP
|
|
sprintf(pbuf,"-d%s",unixpname); /* name of the printer */
|
|
#else USESYSVLP
|
|
sprintf(pbuf,"-P%s",unixpname); /* name of the printer */
|
|
#endif USESYSVLP
|
|
childargv[argc++]=pbuf;
|
|
if (hflag) { /* want a burst page */
|
|
#ifdef USESYSVLP
|
|
#ifdef DOCNAME
|
|
#ifdef __hpux
|
|
for (i = 0; i < MAXJOBNAME-1; i++)
|
|
if (isspace(jobname[i]))
|
|
jobtitle[i] = '_';
|
|
else
|
|
jobtitle[i] = jobname[i];
|
|
jobtitle[MAXJOBNAME-1] = '\0';
|
|
sprintf(jbuf,"-tMacJobName:%s",jobtitle);
|
|
#else __hpux
|
|
sprintf(jbuf,"-tMacUser: %s Job: %s",username,jobname); /* job name */
|
|
#endif __hpux
|
|
#else DOCNAME
|
|
sprintf(jbuf,"-tMacUser: %s",username); /* job name */
|
|
#endif DOCNAME
|
|
#else USESYSVLP
|
|
childargv[argc++]="-J";
|
|
#ifdef DOCNAME
|
|
sprintf(jbuf,"MacUser: %s Job: %s",username,jobname); /* job name */
|
|
#else DOCNAME
|
|
sprintf(jbuf,"MacUser: %s",username); /* job name */
|
|
#endif DOCNAME
|
|
#endif USESYSVLP
|
|
#ifdef PAGECOUNT
|
|
if (pagecount >= 0) {
|
|
if (pcopies <= 0)
|
|
pcopies = 1;
|
|
#ifdef __hpux
|
|
sprintf(&jbuf[strlen(jbuf)], "_Pages:_%04d", pcopies*pagecount);
|
|
#else __hpux
|
|
sprintf(&jbuf[strlen(jbuf)], " Pages: %d", pcopies*pagecount);
|
|
#endif __hpux
|
|
}
|
|
#endif PAGECOUNT
|
|
childargv[argc++]=jbuf;
|
|
}
|
|
#ifndef hpux
|
|
else
|
|
#ifdef USESYSVLP
|
|
# ifdef SOLARIS
|
|
childargv[argc++]="-onobanner"; /* suppress burst page */
|
|
# else SOLARIS
|
|
childargv[argc++]="-o-h"; /* suppress burst page */
|
|
# endif SOLARIS
|
|
#else USESYSVLP
|
|
childargv[argc++]="-h"; /* suppress burst page */
|
|
#endif USESYSVLP
|
|
#endif hpux
|
|
#endif xenix5
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
if (aufsdb && bin != NULL) {
|
|
#ifdef RUTGERS
|
|
sprintf(bbuf, "-B%s", bin);
|
|
#else RUTGERS
|
|
sprintf(bbuf, "-C%s", bin);
|
|
#endif RUTGERS
|
|
childargv[argc++]=bbuf;
|
|
}
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef NeXT
|
|
if (nextdpi) {
|
|
sprintf(dpistring, "-R%s", nextdpi);
|
|
childargv[argc++]=dpistring;
|
|
}
|
|
#endif NeXT
|
|
rhbuf[0] = rhbuf[1] = '\0';
|
|
#ifdef xenix5
|
|
/* will this work ... ? */
|
|
sprintf(rhbuf,"-%s%s",rflag ? "" : "r",hflag ? "" : "ob");
|
|
#else xenix5
|
|
#if defined(__hpux) || defined(SOLARIS)
|
|
sprintf(rhbuf,"-c");
|
|
#else /* __hpux || SOLARIS */
|
|
sprintf(rhbuf,"-%s",rflag ? "" : "r");
|
|
#endif /* __hpux || SOLARIS */
|
|
#endif xenix5
|
|
if (rhbuf[1] != '\0')
|
|
childargv[argc++]=rhbuf; /* include h and/or r flags */
|
|
#ifdef USELPRSYM
|
|
#ifndef USESYSVLP
|
|
childargv[argc++]="-s"; /* better for > 1M files */
|
|
#endif USESYSVLP
|
|
#endif USELPRSYM
|
|
#ifdef LPRARGS
|
|
while(*lprargs)
|
|
childargv[argc++] = *lprargs++;
|
|
lprargs=lprargsbuf;
|
|
#endif LPRARGS
|
|
childargv[argc++]=tname; /* our temporary file name */
|
|
childargv[argc]=(char *) 0; /* end of argument list */
|
|
|
|
switch (fork()) {
|
|
case 0:
|
|
#ifdef RUN_AS_USER
|
|
#ifndef LWSRV_AUFS_SECURITY
|
|
setuid(uid);
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#endif RUN_AS_USER
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
if (aufsdb) {
|
|
/*
|
|
* dissassociate from any tty to make sure
|
|
* lpr uses our requid instead of getlogin()
|
|
*
|
|
*/
|
|
#ifndef LWSRV_LPR_LOG
|
|
for(i = 0 ; i < 10 ; i++)
|
|
(void) close(i);
|
|
(void) open("/", 0);
|
|
(void) dup2(0, 1);
|
|
(void) dup2(0, 2);
|
|
#else LWSRV_LPR_LOG
|
|
for(i = 3 ; i < 10 ; i++)
|
|
(void) close(i);
|
|
/*
|
|
* stderr is the logfile; stdin and stdout are already
|
|
* using /dev/null, therefore disassociated from any tty;
|
|
* The Rutgers hack requires stdout to be the logfile if
|
|
* one exists.
|
|
*
|
|
*/
|
|
/* (void) open("/", 0); */
|
|
/* (void) dup2(0, 1); */
|
|
/* (void) dup2(0, 2); */
|
|
#endif LWSRV_LPR_LOG
|
|
chown(tname, requid, reqgid);
|
|
setuid(requid);
|
|
setgid(reqgid);
|
|
}
|
|
#endif LWSRV_AUFS_SECURITY
|
|
#ifdef LWSRV_LPR_LOG
|
|
/*
|
|
* log all lpr invocations for troubleshooting
|
|
* printing problems
|
|
*
|
|
*/
|
|
fprintf(stderr, "Invoking lpr as user %s using execv: %s",
|
|
(requname) ? requname : "<unknown>", lprcmd);
|
|
for ( i = 1 ; i < argc ; i++)
|
|
fprintf(stderr," %s",childargv[i]);
|
|
fprintf(stderr, "\n");
|
|
#endif LWSRV_LPR_LOG
|
|
if (execv(lprcmd,childargv)) {
|
|
fprintf(stderr,"exec of %s failed\n", lprcmd);
|
|
perror("exec");
|
|
exit(-1);
|
|
}
|
|
break;
|
|
case -1:
|
|
fprintf(stderr,"fork failed trying to run %s\n", lprcmd);
|
|
perror("fork");
|
|
break;
|
|
default:
|
|
|
|
/*
|
|
* This code is important, since lwsrv relies upon lpr to remove
|
|
* the temporary files, we must remove them if lpr fails for any
|
|
* reason (unless rflag TRUE).
|
|
*
|
|
*/
|
|
|
|
/* wait for the lpr to do its thing */
|
|
|
|
if ((waitret = wait(&waitstatus)) == -1 ) {
|
|
#ifdef UTS
|
|
waitstatus = 0; /* wait can return early */
|
|
#else UTS
|
|
perror("wait");
|
|
exit(-1);
|
|
#endif UTS
|
|
}
|
|
|
|
#if defined(hpux) || defined(SOLARIS)
|
|
if (!rflag)
|
|
unlink(tname);
|
|
#else /* hpux || SOLARIS */
|
|
if (WIFEXITED(waitstatus)) {
|
|
if (W_RETCODE(waitstatus) != 0 ) {
|
|
fprintf(stderr,"lpr exited with status %d, %sremoving %s\n",
|
|
W_RETCODE(waitstatus), (rflag) ? "not " : "", tname);
|
|
if (!rflag)
|
|
unlink(tname);
|
|
}
|
|
}
|
|
#endif /* hpux || SOLARIS */
|
|
break;
|
|
}
|
|
}
|
|
p_cls(pf); /* close out the pap connection */
|
|
}
|
|
#endif /* LWSRV8 */
|
|
|
|
export void
|
|
setjobname(ts)
|
|
register char *ts;
|
|
{
|
|
#ifndef LWSRV8
|
|
strncpy(jobname, ts, sizeof(jobname));
|
|
#else /* LWSRV8 */
|
|
strncpy(jobname, ts, sizeof(jobname) - 1);
|
|
jobname[sizeof(jobname) - 1] = 0;
|
|
#ifdef JOBNOPAREN
|
|
/*
|
|
* replace parenthesis so that jobname doesn't screw up banner pages
|
|
* for some print spoolers
|
|
*/
|
|
while (ts = index(jobname, '('))
|
|
*ts = '[';
|
|
while (ts = index(jobname, ')'))
|
|
*ts = ']';
|
|
#endif JOBNOPAREN
|
|
#endif /* LWSRV8 */
|
|
}
|
|
|
|
setusername(ts)
|
|
register char *ts;
|
|
{
|
|
#ifdef RUN_AS_USER
|
|
if (*username != '\0')
|
|
return;
|
|
#endif RUN_AS_USER
|
|
strcpy(username, ts);
|
|
}
|
|
|
|
export
|
|
NewStatus(status)
|
|
char *status;
|
|
{
|
|
char tmp[1024];
|
|
|
|
if (*username != '\0')
|
|
#ifndef LWSRV8
|
|
sprintf(tmp,"job: %s for %s; status: %s", jobname,username,status);
|
|
#else /* LWSRV8 */
|
|
sprintf(tmp,"%s; document: %s: status: %s", username, jobname, status);
|
|
#endif /* LWSRV8 */
|
|
else
|
|
sprintf(tmp,"status: %s",status);
|
|
#ifndef LWSRV8
|
|
cpyc2pstr(statbuffp->StatusStr, tmp);
|
|
#else /* LWSRV8 */
|
|
if (singlefork)
|
|
cpyc2pstr(prtlist[prtno].statbuf.StatusStr, tmp);
|
|
else
|
|
writestatus(myslot, tmp);
|
|
#endif /* LWSRV8 */
|
|
abSleep(0,TRUE); /* make sure protocol runs */
|
|
}
|
|
|
|
#ifdef LWSRV_AUFS_SECURITY
|
|
/**************** budd... ****************/
|
|
/* duplicated in aufs.c and lwsrv.c sigh */
|
|
make_userlogin(buf, dir, addrb)
|
|
char *buf, *dir;
|
|
#ifndef LWSRV8
|
|
AddrBlock addrb;
|
|
#else /* LWSRV8 */
|
|
AddrBlock *addrb;
|
|
#endif /* LWSRV8 */
|
|
{
|
|
sprintf( buf, "%s/net%d.%dnode%d",
|
|
dir,
|
|
#ifndef LWSRV8
|
|
nkipnetnumber(addrb.net), nkipsubnetnumber(addrb.net),
|
|
addrb.node);
|
|
#else /* LWSRV8 */
|
|
nkipnetnumber(addrb->net), nkipsubnetnumber(addrb->net),
|
|
addrb->node);
|
|
#endif /* LWSRV8 */
|
|
}
|
|
#endif LWSRV_AUFS_SECURITY
|
|
|
|
#ifdef LWSRV8
|
|
#ifdef TIMESTAMP
|
|
private char *
|
|
timestamp()
|
|
{
|
|
char *cp;
|
|
time_t t;
|
|
|
|
time(&t);
|
|
cp = ctime(&t);
|
|
cp[24] = 0; /* kill newline */
|
|
return(cp);
|
|
}
|
|
#endif TIMESTAMP
|
|
#endif /* LWSRV8 */
|