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