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