|
|
1.1 ! root 1: /* ! 2: * lpr.c ! 3: * 12/13/90 ! 4: * Submit a listing to the line printer spooler. ! 5: * This source produces both lpr and (compiled -DLASER) hpr. ! 6: */ ! 7: ! 8: #include <stdio.h> ! 9: #include <pwd.h> ! 10: #include <signal.h> ! 11: #include <sys/types.h> ! 12: ! 13: #ifdef LASER ! 14: #define USAGE "Usage: %s [-Bcemnr] [-b banner] [-f fontnum] [file ...]\n" ! 15: #else ! 16: #define USAGE "Usage: %s [-Bcmnr] [-b banner] [file ...]\n" ! 17: #endif ! 18: ! 19: /* Schizo is missing so -r doesn't check access privileges */ ! 20: #define NBAN 6 /* Maximum number of banners */ ! 21: #define NFNAME 400 /* Longest filename allowed */ ! 22: ! 23: char *banners[NBAN]; ! 24: char tfspace[20]; ! 25: char cfname[20]; ! 26: char dfname[20]; ! 27: char *tfname; /* Control file during lpr */ ! 28: char *wd; ! 29: char *myuname; ! 30: char *argv0; ! 31: FILE *cfp; /* Control file stream */ ! 32: #ifdef LASER ! 33: char spooldir[] = "/usr/spool/hpd"; ! 34: char lpd[] = "/usr/lib/hpd"; ! 35: #else ! 36: char spooldir[] = "/usr/spool/lpd"; ! 37: char lpd[] = "/usr/lib/lpd"; ! 38: #endif ! 39: char tmb[] = "too many banners, '%s' ignored"; ! 40: ! 41: int Bflag; /* Suppress banners */ ! 42: int cflag; /* Generate a copy */ ! 43: int mflag; /* Send notification */ ! 44: int rflag; /* Remove when done */ ! 45: int banno = 4; /* Current banner number */ ! 46: int myuid; ! 47: #ifdef LASER ! 48: int eflag; /* Erase existing fonts */ ! 49: int fflag; /* Load new fonts */ ! 50: int fontindex; /* Current font index */ ! 51: #endif ! 52: ! 53: extern char *ctime(); ! 54: extern char *getenv(); ! 55: extern char *getlogin(); ! 56: extern char *getwd(); ! 57: extern time_t time(); ! 58: ! 59: char *absname(); ! 60: void lpr(); ! 61: void lprinit(); ! 62: int rmexit(); ! 63: long unique(); ! 64: ! 65: main(argc, argv) int argc; char *argv[]; ! 66: { ! 67: register char *ap; ! 68: register int i, j; ! 69: ! 70: argv0 = argv[0]; ! 71: signal(SIGINT, rmexit); ! 72: signal(SIGHUP, rmexit); ! 73: for (i=1; i<argc; i++) { ! 74: if (*argv[i] != '-') ! 75: break; ! 76: for (ap = &argv[i][1]; *ap != '\0'; ap++) ! 77: switch (*ap) { ! 78: case 'B': ! 79: ++Bflag; ! 80: break; ! 81: ! 82: case 'b': ! 83: if (++i >= argc) ! 84: lperr("missing banner"); ! 85: if (banno >= NBAN) ! 86: fprintf(stderr, tmb, argv[i]); ! 87: else ! 88: banners[banno++] = argv[i]; ! 89: break; ! 90: ! 91: case 'c': ! 92: cflag = 1; ! 93: break; ! 94: ! 95: #ifdef LASER ! 96: case 'e': ! 97: eflag = 1; ! 98: break; ! 99: ! 100: case 'f': ! 101: Bflag = fflag = 1; /* -f forces -B */ ! 102: if (++i >= argc) ! 103: lperr("missing font index"); ! 104: else ! 105: fontindex = atoi(argv[i]); ! 106: break; ! 107: #endif ! 108: case 'm': ! 109: mflag = 1; ! 110: break; ! 111: ! 112: case 'n': ! 113: mflag = 0; ! 114: break; ! 115: ! 116: case 'r': ! 117: cflag = rflag = 1; ! 118: break; ! 119: ! 120: default: ! 121: usage(); ! 122: } ! 123: } ! 124: lprinit(argc, argv); ! 125: #ifdef LASER ! 126: if (eflag) ! 127: fprintf(cfp, "E\n"); ! 128: #endif ! 129: if (Bflag) ! 130: fprintf(cfp, "B\n"); ! 131: for (j = i; j < argc; j++) ! 132: if (banno < NBAN) ! 133: banners[banno++] = argv[j]; ! 134: else ! 135: break; ! 136: for (j = 0; j < banno; j++) ! 137: fprintf(cfp, "L%s\n", banners[j]); ! 138: if (i == argc) ! 139: lpr(NULL); ! 140: else ! 141: for (; i<argc; i++) ! 142: lpr(argv[i]); ! 143: lprterm(); ! 144: for (i=3; i<_NFILE; i++) ! 145: close(i); ! 146: close(0); ! 147: execl(lpd, lpd, NULL); ! 148: lperr("cannot find daemon '%s'", lpd); ! 149: } ! 150: ! 151: /* ! 152: * Initialise the control file. ! 153: * Set up the banners. ! 154: */ ! 155: void ! 156: lprinit(ac, av) int ac; char **av; ! 157: { ! 158: time_t xtime; ! 159: register int i; ! 160: register struct passwd *pwp; ! 161: register char *s; ! 162: ! 163: myuid = getuid(); ! 164: wd = getwd(); ! 165: if (chdir(spooldir) < 0) ! 166: lperr("bad directory '%s'", spooldir); ! 167: tfname = tfspace; ! 168: sprintf(tfname, "tf%ld", unique()); ! 169: strcpy(cfname, tfname); ! 170: cfname[0] = 'c'; ! 171: if ((cfp = fopen(tfname, "w")) == NULL) ! 172: lperr("cannot create control file"); ! 173: putc('D', cfp); ! 174: for (i=0; i<ac; i++) ! 175: fprintf(cfp, "%s%c", av[i], i==ac-1 ? '\n' : ' '); ! 176: banners[0] = "\35\36\37"; ! 177: banners[1] = "Coherent"; /* Mark Williams logo */ ! 178: xtime = time(NULL); ! 179: s = ctime(&xtime); ! 180: s[16] = '\0'; ! 181: banners[2] = s; ! 182: if ((myuname = getlogin()) == NULL) ! 183: if ((pwp = getpwuid(myuid))==NULL) ! 184: myuname = "Guess who?"; ! 185: if (myuname == NULL) ! 186: banners[3] = "Guess who?"; else ! 187: banners[3] = myuname; ! 188: } ! 189: ! 190: /* ! 191: * Called for each file to put ! 192: * an entry for it in the control ! 193: * file and do any copies to the ! 194: * spool area. ! 195: * The NULL 'file' is stdin. ! 196: */ ! 197: void ! 198: lpr(file) char *file; ! 199: { ! 200: FILE *ifp; ! 201: char *abfile; ! 202: ! 203: if (file == NULL) ! 204: ifp = stdin; ! 205: else { ! 206: abfile = absname(file); ! 207: if ((ifp = fopen(abfile, "r")) == NULL) ! 208: lperr("cannot open %s", file); ! 209: } ! 210: if (cflag || file==NULL) { ! 211: copy(ifp); ! 212: #ifdef LASER ! 213: if (fflag) ! 214: fprintf(cfp, "F%s %d\n", dfname, fontindex++); ! 215: else ! 216: #endif ! 217: fprintf(cfp, "A%s\n", dfname); ! 218: fprintf(cfp, "U%s\n", dfname); ! 219: dfname[0] = '\0'; ! 220: } else { ! 221: #ifdef LASER ! 222: if (fflag) ! 223: fprintf(cfp, "F%s %d\n", abfile, fontindex++); ! 224: else ! 225: #endif ! 226: fprintf(cfp, "A%s\n", abfile); ! 227: } ! 228: if (rflag && file!=NULL) { ! 229: if (unperm(abfile)<0 || unlink(abfile)<0) ! 230: lperr("cannot unlink %s", file); ! 231: } ! 232: if (file != NULL) ! 233: fclose(ifp); ! 234: } ! 235: ! 236: /* ! 237: * Given a file, see if we have permissions to unlink it. ! 238: */ ! 239: unperm(np) ! 240: register char *np; ! 241: { ! 242: register char *cp; ! 243: char name[NFNAME]; ! 244: ! 245: cp = name; ! 246: while ((*cp++=*np++) != '\0') ! 247: ; ! 248: while (*--cp != '/') { ! 249: if (cp == name) { ! 250: *cp = '.'; ! 251: break; ! 252: } ! 253: } ! 254: cp[1] = '\0'; ! 255: return (access(name, 2)); ! 256: } ! 257: ! 258: /* ! 259: * Clean up and close out ! 260: * control file. ! 261: */ ! 262: lprterm() ! 263: { ! 264: if (mflag) ! 265: if (myuname == NULL) ! 266: fprintf(cfp, "M%d\n", myuid); else ! 267: fprintf(cfp, "M%s\n", myuname); ! 268: fflush(cfp); ! 269: if (ferror(cfp)) ! 270: lperr("control file I/O error"); ! 271: fclose(cfp); ! 272: link(tfname, cfname); ! 273: unlink(tfname); ! 274: tfname = NULL; ! 275: } ! 276: ! 277: /* ! 278: * Copy the data to a data file ! 279: * in the spool directory. ! 280: */ ! 281: copy(inf) ! 282: register FILE *inf; ! 283: { ! 284: register int c; ! 285: register FILE *outf; ! 286: ! 287: sprintf(dfname, "df%ld", unique()); ! 288: if ((outf = fopen(dfname, "w")) == NULL) ! 289: lperr("cannot create data file"); ! 290: while ((c = getc(inf)) != EOF) ! 291: putc(c, outf); ! 292: fflush(outf); ! 293: if (ferror(outf)) ! 294: lperr("data file I/O error"); ! 295: fclose(outf); ! 296: } ! 297: ! 298: /* ! 299: * Return an absolute pathname ! 300: * for the given filename. ! 301: * (Uses the variable 'wd' which ! 302: * contains the process's working ! 303: * directory.) ! 304: */ ! 305: char * ! 306: absname(fn) ! 307: char *fn; ! 308: { ! 309: static char name[NFNAME]; ! 310: ! 311: if (*fn == '/') ! 312: return (fn); ! 313: sprintf(name, "%s/%s", wd, fn); ! 314: return (name); ! 315: } ! 316: ! 317: usage() ! 318: { ! 319: fprintf(stderr, USAGE, argv0); ! 320: rmexit(1); ! 321: } ! 322: ! 323: /* VARARGS */ ! 324: lperr(x) ! 325: { ! 326: fprintf(stderr, "%s: %r\n", argv0, &x); ! 327: rmexit(1); ! 328: } ! 329: ! 330: /* ! 331: * Exit, removing any files that ! 332: * are left lying around. ! 333: */ ! 334: rmexit(s) ! 335: { ! 336: if (tfname != NULL) ! 337: unlink(tfname); ! 338: if (dfname[0] != '\0') ! 339: unlink(dfname); ! 340: exit(s); ! 341: } ! 342: ! 343: /* end of lpr.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.