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