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