common code for checking if rm==localhost
[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
b5eb1530 19static char sccsid[] = "@(#)common.c 5.5 (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 */
b5eb1530 75int sendtorem; /* are we sending to a remote? */
cc6a4ffd
RC
76
77/*
78 * Create a connection to the remote printer server.
79 * Most of this code comes from rcmd.c.
80 */
a87bde97
RC
81getport(rhost)
82 char *rhost;
cc6a4ffd
RC
83{
84 struct hostent *hp;
85 struct servent *sp;
86 struct sockaddr_in sin;
87 int s, timo = 1, lport = IPPORT_RESERVED - 1;
38465a03 88 int err;
cc6a4ffd
RC
89
90 /*
91 * Get the host address and port number to connect to.
92 */
a87bde97 93 if (rhost == NULL)
cc6a4ffd 94 fatal("no remote host to connect to");
a87bde97 95 hp = gethostbyname(rhost);
cc6a4ffd 96 if (hp == NULL)
a87bde97 97 fatal("unknown host %s", rhost);
cc6a4ffd
RC
98 sp = getservbyname("printer", "tcp");
99 if (sp == NULL)
100 fatal("printer/tcp: unknown service");
101 bzero((char *)&sin, sizeof(sin));
102 bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
103 sin.sin_family = hp->h_addrtype;
104 sin.sin_port = sp->s_port;
105
106 /*
107 * Try connecting to the server.
108 */
109retry:
110 s = rresvport(&lport);
111 if (s < 0)
112 return(-1);
b5eb1530 113 if (connect(s, (caddr_t)&sin, sizeof(sin)) < 0) {
38465a03
RC
114 err = errno;
115 (void) close(s);
116 errno = err;
cc6a4ffd 117 if (errno == EADDRINUSE) {
cc6a4ffd
RC
118 lport--;
119 goto retry;
120 }
121 if (errno == ECONNREFUSED && timo <= 16) {
cc6a4ffd
RC
122 sleep(timo);
123 timo *= 2;
124 goto retry;
125 }
126 return(-1);
127 }
128 return(s);
129}
130
cc6a4ffd
RC
131/*
132 * Getline reads a line from the control file cfp, removes tabs, converts
133 * new-line to null and leaves it in line.
134 * Returns 0 at EOF or the number of characters read.
135 */
136getline(cfp)
137 FILE *cfp;
138{
139 register int linel = 0;
140 register char *lp = line;
141 register c;
142
143 while ((c = getc(cfp)) != '\n') {
144 if (c == EOF)
145 return(0);
146 if (c == '\t') {
147 do {
148 *lp++ = ' ';
149 linel++;
150 } while ((linel & 07) != 0);
151 continue;
152 }
153 *lp++ = c;
154 linel++;
155 }
156 *lp++ = '\0';
157 return(linel);
158}
159
160/*
161 * Scan the current directory and make a list of daemon files sorted by
162 * creation time.
163 * Return the number of entries and a pointer to the list.
164 */
165getq(namelist)
166 struct queue *(*namelist[]);
167{
168 register struct direct *d;
169 register struct queue *q, **queue;
170 register int nitems;
171 struct stat stbuf;
172 int arraysz, compar();
173 DIR *dirp;
174
c6d1c018 175 if ((dirp = opendir(SD)) == NULL)
cc6a4ffd
RC
176 return(-1);
177 if (fstat(dirp->dd_fd, &stbuf) < 0)
38465a03 178 goto errdone;
cc6a4ffd
RC
179
180 /*
181 * Estimate the array size by taking the size of the directory file
182 * and dividing it by a multiple of the minimum size entry.
183 */
184 arraysz = (stbuf.st_size / 24);
185 queue = (struct queue **)malloc(arraysz * sizeof(struct queue *));
186 if (queue == NULL)
38465a03 187 goto errdone;
cc6a4ffd
RC
188
189 nitems = 0;
190 while ((d = readdir(dirp)) != NULL) {
191 if (d->d_name[0] != 'c' || d->d_name[1] != 'f')
192 continue; /* daemon control files only */
193 if (stat(d->d_name, &stbuf) < 0)
194 continue; /* Doesn't exist */
195 q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1);
196 if (q == NULL)
38465a03 197 goto errdone;
cc6a4ffd
RC
198 q->q_time = stbuf.st_mtime;
199 strcpy(q->q_name, d->d_name);
200 /*
201 * Check to make sure the array has space left and
202 * realloc the maximum size.
203 */
204 if (++nitems > arraysz) {
205 queue = (struct queue **)realloc((char *)queue,
206 (stbuf.st_size/12) * sizeof(struct queue *));
207 if (queue == NULL)
38465a03 208 goto errdone;
cc6a4ffd
RC
209 }
210 queue[nitems-1] = q;
211 }
212 closedir(dirp);
213 if (nitems)
214 qsort(queue, nitems, sizeof(struct queue *), compar);
215 *namelist = queue;
216 return(nitems);
38465a03
RC
217
218errdone:
219 closedir(dirp);
220 return(-1);
cc6a4ffd
RC
221}
222
223/*
224 * Compare modification times.
225 */
226static
227compar(p1, p2)
228 register struct queue **p1, **p2;
229{
230 if ((*p1)->q_time < (*p2)->q_time)
231 return(-1);
232 if ((*p1)->q_time > (*p2)->q_time)
233 return(1);
234 return(0);
235}
236
b5eb1530
TF
237/*
238 * Figure out whether the local machine is the same
239 * as the remote machine (RM) entry (if it exists).
240 */
241char *
242checkremote()
243{
244 char name[MAXHOSTNAMELEN];
245 register struct hostent *hp;
246 static char errbuf[128];
247
248 sendtorem = 0; /* assume printer is local */
249 if (RM != (char *)NULL) {
250 /* get the official name of the local host */
251 gethostname(name, sizeof(name));
252 name[sizeof(name)-1] = '\0';
253 hp = gethostbyname(name);
254 if (hp == (struct hostent *) NULL) {
255 (void) sprintf(errbuf,
256 "unable to get official name for local machine %s",
257 name);
258 return errbuf;
259 } else (void) strcpy(name, hp->h_name);
260
261 /* get the official name of RM */
262 hp = gethostbyname(RM);
263 if (hp == (struct hostent *) NULL) {
264 (void) sprintf(errbuf,
265 "unable to get official name for remote machine %s",
266 RM);
267 return errbuf;
268 }
269
270 /*
271 * if the two hosts are not the same,
272 * then the printer must be remote.
273 */
274 if (strcmp(name, hp->h_name) != 0)
275 sendtorem = 1;
276 }
277 return (char *)0;
278}
279
cc6a4ffd
RC
280/*VARARGS1*/
281fatal(msg, a1, a2, a3)
282 char *msg;
283{
284 if (from != host)
285 printf("%s: ", host);
286 printf("%s: ", name);
287 if (printer)
288 printf("%s: ", printer);
289 printf(msg, a1, a2, a3);
290 putchar('\n');
291 exit(1);
292}