install correct aliases file
[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.
9d85c861
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
a399f6c8
KB
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.
d0aeaf5a
DF
16 */
17
5f84f8f0 18#ifndef lint
a399f6c8 19static char sccsid[] = "@(#)common.c 5.4 (Berkeley) %G%";
9d85c861 20#endif /* not lint */
5f84f8f0 21
cc6a4ffd
RC
22/*
23 * Routines and data common to all the line printer functions.
24 */
25
26#include "lp.h"
27
28int DU; /* daeomon user-id */
29int MX; /* maximum number of blocks to copy */
c6d1c018 30int MC; /* maximum number of copies allowed */
cc6a4ffd
RC
31char *LP; /* line printer device name */
32char *RM; /* remote machine name */
33char *RP; /* remote printer name */
34char *LO; /* lock file name */
35char *ST; /* status file name */
36char *SD; /* spool directory */
37char *AF; /* accounting file */
38char *LF; /* log file for error messages */
39char *OF; /* name of output filter (created once) */
40char *IF; /* name of input filter (created per job) */
4d4caa50 41char *RF; /* name of fortran text filter (per job) */
cc6a4ffd 42char *TF; /* name of troff filter (per job) */
a4f59913 43char *NF; /* name of ditroff filter (per job) */
cc6a4ffd
RC
44char *DF; /* name of tex filter (per job) */
45char *GF; /* name of graph(1G) filter (per job) */
46char *VF; /* name of vplot filter (per job) */
47char *CF; /* name of cifplot filter (per job) */
48char *PF; /* name of vrast filter (per job) */
49char *FF; /* form feed string */
50char *TR; /* trailer string to be output when Q empties */
c6d1c018 51short SC; /* suppress multiple copies */
cc6a4ffd
RC
52short SF; /* suppress FF on each print job */
53short SH; /* suppress header page */
54short SB; /* short banner instead of normal header */
1e7998ee 55short HL; /* print header last */
cc6a4ffd
RC
56short RW; /* open LP for reading and writing */
57short PW; /* page width */
58short PL; /* page length */
4d4caa50
RC
59short PX; /* page width in pixels */
60short PY; /* page length in pixels */
cc6a4ffd 61short BR; /* baud rate if lp is a tty */
c6d1c018
RC
62int FC; /* flags to clear if lp is a tty */
63int FS; /* flags to set if lp is a tty */
64int XC; /* flags to clear for local mode */
65int XS; /* flags to set for local mode */
4d4caa50 66short RS; /* restricted to those with local accounts */
cc6a4ffd
RC
67
68char line[BUFSIZ];
69char pbuf[BUFSIZ/2]; /* buffer for printcap strings */
70char *bp = pbuf; /* pointer into pbuf for pgetent() */
71char *name; /* program name */
72char *printer; /* printer name */
73char host[32]; /* host machine name */
74char *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 */
a87bde97
RC
80getport(rhost)
81 char *rhost;
cc6a4ffd
RC
82{
83 struct hostent *hp;
84 struct servent *sp;
85 struct sockaddr_in sin;
86 int s, timo = 1, lport = IPPORT_RESERVED - 1;
38465a03 87 int err;
cc6a4ffd
RC
88
89 /*
90 * Get the host address and port number to connect to.
91 */
a87bde97 92 if (rhost == NULL)
cc6a4ffd 93 fatal("no remote host to connect to");
a87bde97 94 hp = gethostbyname(rhost);
cc6a4ffd 95 if (hp == NULL)
a87bde97 96 fatal("unknown host %s", rhost);
cc6a4ffd
RC
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 */
108retry:
109 s = rresvport(&lport);
110 if (s < 0)
111 return(-1);
112 if (connect(s, (caddr_t)&sin, sizeof(sin), 0) < 0) {
38465a03
RC
113 err = errno;
114 (void) close(s);
115 errno = err;
cc6a4ffd 116 if (errno == EADDRINUSE) {
cc6a4ffd
RC
117 lport--;
118 goto retry;
119 }
120 if (errno == ECONNREFUSED && timo <= 16) {
cc6a4ffd
RC
121 sleep(timo);
122 timo *= 2;
123 goto retry;
124 }
125 return(-1);
126 }
127 return(s);
128}
129
cc6a4ffd
RC
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 */
135getline(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 */
164getq(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
c6d1c018 174 if ((dirp = opendir(SD)) == NULL)
cc6a4ffd
RC
175 return(-1);
176 if (fstat(dirp->dd_fd, &stbuf) < 0)
38465a03 177 goto errdone;
cc6a4ffd
RC
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)
38465a03 186 goto errdone;
cc6a4ffd
RC
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)
38465a03 196 goto errdone;
cc6a4ffd
RC
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)
38465a03 207 goto errdone;
cc6a4ffd
RC
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);
38465a03
RC
216
217errdone:
218 closedir(dirp);
219 return(-1);
cc6a4ffd
RC
220}
221
222/*
223 * Compare modification times.
224 */
225static
226compar(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
cc6a4ffd
RC
236/*VARARGS1*/
237fatal(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}