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 #include #include #include #include #ifndef _TYPES # include /* assume included by param.h */ #endif _TYPES #include #include #include #include #include /* include appletalk definitions */ #include #include #include #include "../../lib/cap/abpap.h" /* urk, puke, etc */ #ifdef USEDIRENT #include #else USEDIRENT #ifdef xenix5 #include #else xenix5 #include #endif xenix5 #endif USEDIRENT #ifdef USESTRINGDOTH # include #else USESTRINGDOTH # include #endif USESTRINGDOTH #ifdef NEEDFCNTLDOTH # include #endif NEEDFCNTLDOTH #ifdef SOLARIS #include #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 #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 -p \n",s); #else /* LWSRV8 */ if (err != NULL) fprintf(stderr,"%s: %s\n",myname,err); fprintf(stderr,"usage: %s []\n",myname); fprintf(stderr,"\t contains options and printer descriptions\n"); fprintf(stderr,"\t of printer templates\n\n"); #ifdef LW_TYPE fprintf(stderr,"usage: %s -n -p ",myname); fprintf(stderr," -Y \n"); #else LW_TYPE fprintf(stderr,"usage: %s -n -p \n",myname); #endif LW_TYPE #endif /* LWSRV8 */ fprintf(stderr,"usage:\t\t-a -f \n"); fprintf(stderr,"usage:\t\t[-l ] [-t ] [-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* is the unix printer to print to\n"); fprintf(stderr,"\t-n* specifies the name %s registers.\n", myname); #ifdef LWSRV8 #ifdef LW_TYPE fprintf(stderr,"\t-Y 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* is the ProcSet directory.\n"); fprintf(stderr,"\t-f* contains an font coordination list.\n"); fprintf(stderr,"\t-t stores session and appledict in\n"); fprintf(stderr,"\t without printing.\n"); fprintf(stderr,"\t-F directory to store temporary files\n"); fprintf(stderr,"\t-l specifies a file to log the %s session\n", myname); #ifdef LWSRV8 fprintf(stderr,"\t-q 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 Specify print spooler rather than lp/lpr\n"); #ifdef LPRARGS fprintf(stderr,"\t-L 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 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 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 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; iprtname); 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 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; inbpbuf,"%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 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 : "", lprcmd); #else TIMESTAMP fprintf(stderr, "%s: Invoking lpr as user %s using execv: %s", myname, (requname) ? requname : "", 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 : "", 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 */