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