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