display local queue first, then foreign queue
[unix-history] / usr / src / usr.sbin / lpr / common_source / common.c
CommitLineData
d0aeaf5a
DF
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
5f84f8f0 7#ifndef lint
7b7806ec 8static char sccsid[] = "@(#)common.c 5.2 (Berkeley) %G%";
d0aeaf5a 9#endif not lint
5f84f8f0 10
cc6a4ffd
RC
11/*
12 * Routines and data common to all the line printer functions.
13 */
14
15#include "lp.h"
16
17int DU; /* daeomon user-id */
18int MX; /* maximum number of blocks to copy */
c6d1c018 19int MC; /* maximum number of copies allowed */
cc6a4ffd
RC
20char *LP; /* line printer device name */
21char *RM; /* remote machine name */
22char *RP; /* remote printer name */
23char *LO; /* lock file name */
24char *ST; /* status file name */
25char *SD; /* spool directory */
26char *AF; /* accounting file */
27char *LF; /* log file for error messages */
28char *OF; /* name of output filter (created once) */
29char *IF; /* name of input filter (created per job) */
4d4caa50 30char *RF; /* name of fortran text filter (per job) */
cc6a4ffd 31char *TF; /* name of troff filter (per job) */
a4f59913 32char *NF; /* name of ditroff filter (per job) */
cc6a4ffd
RC
33char *DF; /* name of tex filter (per job) */
34char *GF; /* name of graph(1G) filter (per job) */
35char *VF; /* name of vplot filter (per job) */
36char *CF; /* name of cifplot filter (per job) */
37char *PF; /* name of vrast filter (per job) */
38char *FF; /* form feed string */
39char *TR; /* trailer string to be output when Q empties */
c6d1c018 40short SC; /* suppress multiple copies */
cc6a4ffd
RC
41short SF; /* suppress FF on each print job */
42short SH; /* suppress header page */
43short SB; /* short banner instead of normal header */
1e7998ee 44short HL; /* print header last */
cc6a4ffd
RC
45short RW; /* open LP for reading and writing */
46short PW; /* page width */
47short PL; /* page length */
4d4caa50
RC
48short PX; /* page width in pixels */
49short PY; /* page length in pixels */
cc6a4ffd 50short BR; /* baud rate if lp is a tty */
c6d1c018
RC
51int FC; /* flags to clear if lp is a tty */
52int FS; /* flags to set if lp is a tty */
53int XC; /* flags to clear for local mode */
54int XS; /* flags to set for local mode */
4d4caa50 55short RS; /* restricted to those with local accounts */
cc6a4ffd
RC
56
57char line[BUFSIZ];
58char pbuf[BUFSIZ/2]; /* buffer for printcap strings */
59char *bp = pbuf; /* pointer into pbuf for pgetent() */
60char *name; /* program name */
61char *printer; /* printer name */
62char host[32]; /* host machine name */
63char *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 */
a87bde97
RC
69getport(rhost)
70 char *rhost;
cc6a4ffd
RC
71{
72 struct hostent *hp;
73 struct servent *sp;
74 struct sockaddr_in sin;
75 int s, timo = 1, lport = IPPORT_RESERVED - 1;
38465a03 76 int err;
cc6a4ffd
RC
77
78 /*
79 * Get the host address and port number to connect to.
80 */
a87bde97 81 if (rhost == NULL)
cc6a4ffd 82 fatal("no remote host to connect to");
a87bde97 83 hp = gethostbyname(rhost);
cc6a4ffd 84 if (hp == NULL)
a87bde97 85 fatal("unknown host %s", rhost);
cc6a4ffd
RC
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 */
97retry:
98 s = rresvport(&lport);
99 if (s < 0)
100 return(-1);
101 if (connect(s, (caddr_t)&sin, sizeof(sin), 0) < 0) {
38465a03
RC
102 err = errno;
103 (void) close(s);
104 errno = err;
cc6a4ffd 105 if (errno == EADDRINUSE) {
cc6a4ffd
RC
106 lport--;
107 goto retry;
108 }
109 if (errno == ECONNREFUSED && timo <= 16) {
cc6a4ffd
RC
110 sleep(timo);
111 timo *= 2;
112 goto retry;
113 }
114 return(-1);
115 }
116 return(s);
117}
118
cc6a4ffd
RC
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 */
124getline(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 */
153getq(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
c6d1c018 163 if ((dirp = opendir(SD)) == NULL)
cc6a4ffd
RC
164 return(-1);
165 if (fstat(dirp->dd_fd, &stbuf) < 0)
38465a03 166 goto errdone;
cc6a4ffd
RC
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)
38465a03 175 goto errdone;
cc6a4ffd
RC
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)
38465a03 185 goto errdone;
cc6a4ffd
RC
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)
38465a03 196 goto errdone;
cc6a4ffd
RC
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);
38465a03
RC
205
206errdone:
207 closedir(dirp);
208 return(-1);
cc6a4ffd
RC
209}
210
211/*
212 * Compare modification times.
213 */
214static
215compar(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
cc6a4ffd
RC
225/*VARARGS1*/
226fatal(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}