|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)common.c 4.8 (Berkeley) 7/17/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * Routines and data common to all the line printer functions. ! 7: */ ! 8: ! 9: #include "lp.h" ! 10: ! 11: int DU; /* daeomon user-id */ ! 12: int MX; /* maximum number of blocks to copy */ ! 13: int MC; /* maximum number of copies allowed */ ! 14: char *LP; /* line printer device name */ ! 15: char *RM; /* remote machine name */ ! 16: char *RP; /* remote printer name */ ! 17: char *LO; /* lock file name */ ! 18: char *ST; /* status file name */ ! 19: char *SD; /* spool directory */ ! 20: char *AF; /* accounting file */ ! 21: char *LF; /* log file for error messages */ ! 22: char *OF; /* name of output filter (created once) */ ! 23: char *IF; /* name of input filter (created per job) */ ! 24: char *RF; /* name of fortran text filter (per job) */ ! 25: char *TF; /* name of troff filter (per job) */ ! 26: char *NF; /* name of ditroff filter (per job) */ ! 27: char *DF; /* name of tex filter (per job) */ ! 28: char *GF; /* name of graph(1G) filter (per job) */ ! 29: char *VF; /* name of vplot filter (per job) */ ! 30: char *CF; /* name of cifplot filter (per job) */ ! 31: char *PF; /* name of vrast filter (per job) */ ! 32: char *FF; /* form feed string */ ! 33: char *TR; /* trailer string to be output when Q empties */ ! 34: short SC; /* suppress multiple copies */ ! 35: short SF; /* suppress FF on each print job */ ! 36: short SH; /* suppress header page */ ! 37: short SB; /* short banner instead of normal header */ ! 38: short RW; /* open LP for reading and writing */ ! 39: short PW; /* page width */ ! 40: short PL; /* page length */ ! 41: short PX; /* page width in pixels */ ! 42: short PY; /* page length in pixels */ ! 43: short BR; /* baud rate if lp is a tty */ ! 44: int FC; /* flags to clear if lp is a tty */ ! 45: int FS; /* flags to set if lp is a tty */ ! 46: int XC; /* flags to clear for local mode */ ! 47: int XS; /* flags to set for local mode */ ! 48: short RS; /* restricted to those with local accounts */ ! 49: ! 50: char line[BUFSIZ]; ! 51: char pbuf[BUFSIZ/2]; /* buffer for printcap strings */ ! 52: char *bp = pbuf; /* pointer into pbuf for pgetent() */ ! 53: char *name; /* program name */ ! 54: char *printer; /* printer name */ ! 55: char host[32]; /* host machine name */ ! 56: char *from = host; /* client's machine name */ ! 57: ! 58: /* ! 59: * Create a connection to the remote printer server. ! 60: * Most of this code comes from rcmd.c. ! 61: */ ! 62: getport(rhost) ! 63: char *rhost; ! 64: { ! 65: struct hostent *hp; ! 66: struct servent *sp; ! 67: struct sockaddr_in sin; ! 68: int s, timo = 1, lport = IPPORT_RESERVED - 1; ! 69: int err; ! 70: ! 71: /* ! 72: * Get the host address and port number to connect to. ! 73: */ ! 74: if (rhost == NULL) ! 75: fatal("no remote host to connect to"); ! 76: hp = gethostbyname(rhost); ! 77: if (hp == NULL) ! 78: fatal("unknown host %s", rhost); ! 79: sp = getservbyname("printer", "tcp"); ! 80: if (sp == NULL) ! 81: fatal("printer/tcp: unknown service"); ! 82: bzero((char *)&sin, sizeof(sin)); ! 83: bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); ! 84: sin.sin_family = hp->h_addrtype; ! 85: sin.sin_port = sp->s_port; ! 86: ! 87: /* ! 88: * Try connecting to the server. ! 89: */ ! 90: retry: ! 91: s = rresvport(&lport); ! 92: if (s < 0) ! 93: return(-1); ! 94: if (connect(s, (caddr_t)&sin, sizeof(sin), 0) < 0) { ! 95: err = errno; ! 96: (void) close(s); ! 97: errno = err; ! 98: if (errno == EADDRINUSE) { ! 99: lport--; ! 100: goto retry; ! 101: } ! 102: if (errno == ECONNREFUSED && timo <= 16) { ! 103: sleep(timo); ! 104: timo *= 2; ! 105: goto retry; ! 106: } ! 107: return(-1); ! 108: } ! 109: return(s); ! 110: } ! 111: ! 112: rresvport(alport) ! 113: int *alport; ! 114: { ! 115: struct sockaddr_in sin; ! 116: int s; ! 117: ! 118: sin.sin_family = AF_INET; ! 119: sin.sin_addr.s_addr = 0; ! 120: s = socket(AF_INET, SOCK_STREAM, 0); ! 121: if (s < 0) ! 122: return(-1); ! 123: for (; *alport > IPPORT_RESERVED/2; (*alport)--) { ! 124: sin.sin_port = htons((u_short) *alport); ! 125: if (bind(s, (caddr_t)&sin, sizeof(sin), 0) >= 0) ! 126: return(s); ! 127: if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) ! 128: break; ! 129: } ! 130: (void) close(s); ! 131: return(-1); ! 132: } ! 133: ! 134: /* ! 135: * Getline reads a line from the control file cfp, removes tabs, converts ! 136: * new-line to null and leaves it in line. ! 137: * Returns 0 at EOF or the number of characters read. ! 138: */ ! 139: getline(cfp) ! 140: FILE *cfp; ! 141: { ! 142: register int linel = 0; ! 143: register char *lp = line; ! 144: register c; ! 145: ! 146: while ((c = getc(cfp)) != '\n') { ! 147: if (c == EOF) ! 148: return(0); ! 149: if (c == '\t') { ! 150: do { ! 151: *lp++ = ' '; ! 152: linel++; ! 153: } while ((linel & 07) != 0); ! 154: continue; ! 155: } ! 156: *lp++ = c; ! 157: linel++; ! 158: } ! 159: *lp++ = '\0'; ! 160: return(linel); ! 161: } ! 162: ! 163: /* ! 164: * Scan the current directory and make a list of daemon files sorted by ! 165: * creation time. ! 166: * Return the number of entries and a pointer to the list. ! 167: */ ! 168: getq(namelist) ! 169: struct queue *(*namelist[]); ! 170: { ! 171: register struct direct *d; ! 172: register struct queue *q, **queue; ! 173: register int nitems; ! 174: struct stat stbuf; ! 175: int arraysz, compar(); ! 176: DIR *dirp; ! 177: ! 178: if ((dirp = opendir(SD)) == NULL) ! 179: return(-1); ! 180: if (fstat(dirp->dd_fd, &stbuf) < 0) ! 181: goto errdone; ! 182: ! 183: /* ! 184: * Estimate the array size by taking the size of the directory file ! 185: * and dividing it by a multiple of the minimum size entry. ! 186: */ ! 187: arraysz = (stbuf.st_size / 24); ! 188: queue = (struct queue **)malloc(arraysz * sizeof(struct queue *)); ! 189: if (queue == NULL) ! 190: goto errdone; ! 191: ! 192: nitems = 0; ! 193: while ((d = readdir(dirp)) != NULL) { ! 194: if (d->d_name[0] != 'c' || d->d_name[1] != 'f') ! 195: continue; /* daemon control files only */ ! 196: if (stat(d->d_name, &stbuf) < 0) ! 197: continue; /* Doesn't exist */ ! 198: q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1); ! 199: if (q == NULL) ! 200: goto errdone; ! 201: q->q_time = stbuf.st_mtime; ! 202: strcpy(q->q_name, d->d_name); ! 203: /* ! 204: * Check to make sure the array has space left and ! 205: * realloc the maximum size. ! 206: */ ! 207: if (++nitems > arraysz) { ! 208: queue = (struct queue **)realloc((char *)queue, ! 209: (stbuf.st_size/12) * sizeof(struct queue *)); ! 210: if (queue == NULL) ! 211: goto errdone; ! 212: } ! 213: queue[nitems-1] = q; ! 214: } ! 215: closedir(dirp); ! 216: if (nitems) ! 217: qsort(queue, nitems, sizeof(struct queue *), compar); ! 218: *namelist = queue; ! 219: return(nitems); ! 220: ! 221: errdone: ! 222: closedir(dirp); ! 223: return(-1); ! 224: } ! 225: ! 226: /* ! 227: * Compare modification times. ! 228: */ ! 229: static ! 230: compar(p1, p2) ! 231: register struct queue **p1, **p2; ! 232: { ! 233: if ((*p1)->q_time < (*p2)->q_time) ! 234: return(-1); ! 235: if ((*p1)->q_time > (*p2)->q_time) ! 236: return(1); ! 237: return(0); ! 238: } ! 239: ! 240: /*VARARGS1*/ ! 241: fatal(msg, a1, a2, a3) ! 242: char *msg; ! 243: { ! 244: if (from != host) ! 245: printf("%s: ", host); ! 246: printf("%s: ", name); ! 247: if (printer) ! 248: printf("%s: ", printer); ! 249: printf(msg, a1, a2, a3); ! 250: putchar('\n'); ! 251: exit(1); ! 252: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.