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