8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / lp / lib / printers / getprinter.c
blob058d1ae2d7e95e143e9bb487d3fa3fe74e8112fd
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
32 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
34 #include "stdio.h"
35 #include "string.h"
36 #include "errno.h"
37 #include "sys/types.h"
38 #include "stdlib.h"
39 #include <syslog.h>
41 #include "lp.h"
42 #include "printers.h"
44 extern struct {
45 char *v;
46 short len,
47 okremote;
48 } prtrheadings[];
50 /**
51 ** getprinter() - EXTRACT PRINTER STRUCTURE FROM DISK FILE
52 **/
54 PRINTER *
55 getprinter(char *name)
57 static long lastdir = -1;
59 PRINTER *prp;
61 char buf[BUFSIZ];
63 short daisy;
65 int fld;
67 int fd;
69 FALERT *pa;
71 register char * p;
72 register char ** pp;
73 register char *** ppp;
74 register char * path;
75 int isNameAll;
79 if (!name || !*name) {
80 errno = EINVAL;
81 return (0);
84 syslog(LOG_DEBUG, "getprinter(%s)", name ? name : "");
86 * Getting ``all''? If so, jump into the directory
87 * wherever we left off.
89 isNameAll = STREQU(NAME_ALL, name);
90 for (; ; ) {
91 /* fix for bug 1117241
92 * occasionally when a printer is removed, a printer directory
93 * is left behind, but the CONFIGFILE is removed. In this
94 * case this directory terminates the search for additional
95 * printers as we have been returning 0 in this case.
96 * Now, we loop back and try the next directory until
97 * we have no more directories or we find a directory with
98 * a CONFIGFILE
100 if (isNameAll) {
101 if (!(name = next_dir(Lp_A_Printers, &lastdir)))
102 return (0);
103 } else
104 lastdir = -1;
107 * Get the printer configuration information.
110 path = getprinterfile(name, CONFIGFILE);
111 if (!path) {
112 if (isNameAll)
113 Free(name);
114 return (0);
117 if ((fd = open_locked(path, "r", 0)) < 0) {
118 Free(path); /*
119 * go around to loop again for
120 * NAME_ALL case
123 if (!isNameAll) /* fix for bug 1117241 */
124 return(0);
125 else
126 Free(name);
128 else
129 break;
131 Free (path);
134 * Initialize the entire structure, to ensure no random
135 * values get in it. However, make sure some values won't
136 * be null or empty. Do the latter here as opposed to
137 * after reading the file, because sometimes the file
138 * contains an empty header to FORCE a null/empty value.
140 prp = calloc(sizeof (*prp), 1);
141 prp->name = Strdup(name);
142 if (isNameAll)
143 Free(name);
144 prp->printer_types = getlist(NAME_UNKNOWN, LP_WS, LP_SEP);
145 prp->input_types = getlist(NAME_SIMPLE, LP_WS, LP_SEP);
146 #if defined(CAN_DO_MODULES)
147 prp->modules = getlist(NAME_DEFAULT, LP_WS, LP_SEP);
148 #endif
151 * Read the file.
153 errno = 0;
154 while (fdgets(buf, BUFSIZ, fd) != NULL) {
156 buf[strlen(buf) - 1] = 0;
158 for (fld = 0; fld < PR_MAX; fld++)
159 if (
160 prtrheadings[fld].v
161 && prtrheadings[fld].len
162 && STRNEQU(
163 buf,
164 prtrheadings[fld].v,
165 prtrheadings[fld].len
168 p = buf + prtrheadings[fld].len;
169 while (*p && *p == ' ')
170 p++;
171 break;
175 * To allow future extensions to not impact applications
176 * using old versions of this routine, ignore strange
177 * fields.
179 if (fld >= PR_MAX)
180 continue;
182 switch (fld) {
184 case PR_BAN:
185 if ((pp = getlist(p, LP_WS, ":"))) {
186 if (pp[0] != NULL) {
187 if (strcmp(pp[0], NAME_OPTIONAL) == 0)
188 prp->banner = BAN_OPTIONAL;
189 else if (strcmp(pp[0], NAME_OFF) == 0)
190 prp->banner = BAN_NEVER;
191 else if (strcmp(pp[0], NAME_ON) == 0)
192 prp->banner = BAN_ALWAYS;
193 else /* default to the LP default */
194 prp->banner = BAN_ALWAYS;
196 if (pp[1] && CS_STREQU(pp[1], NAME_ALWAYS))
197 prp->banner |= BAN_ALWAYS;
198 freelist (pp);
200 break;
202 case PR_LOGIN:
203 prp->login = LOG_IN;
204 break;
206 case PR_CPI:
207 prp->cpi = getcpi(p);
208 break;
210 case PR_LPI:
211 prp->lpi = getsdn(p);
212 break;
214 case PR_LEN:
215 prp->plen = getsdn(p);
216 break;
218 case PR_WIDTH:
219 prp->pwid = getsdn(p);
220 break;
222 case PR_CS:
223 ppp = &(prp->char_sets);
224 goto CharStarStar;
226 case PR_ITYPES:
227 ppp = &(prp->input_types);
228 CharStarStar: if (*ppp)
229 freelist (*ppp);
230 *ppp = getlist(p, LP_WS, LP_SEP);
231 break;
233 case PR_DEV:
234 pp = &(prp->device);
235 goto CharStar;
237 case PR_DIAL:
238 pp = &(prp->dial_info);
239 goto CharStar;
241 case PR_RECOV:
242 pp = &(prp->fault_rec);
243 goto CharStar;
245 case PR_INTFC:
246 pp = &(prp->interface);
247 goto CharStar;
249 case PR_PTYPE:
250 ppp = &(prp->printer_types);
251 goto CharStarStar;
253 case PR_REMOTE:
254 pp = &(prp->remote);
255 goto CharStar;
257 case PR_SPEED:
258 pp = &(prp->speed);
259 goto CharStar;
261 case PR_STTY:
262 pp = &(prp->stty);
263 CharStar: if (*pp)
264 Free (*pp);
265 *pp = Strdup(p);
266 break;
268 #if defined(CAN_DO_MODULES)
269 case PR_MODULES:
270 ppp = &(prp->modules);
271 goto CharStarStar;
272 #endif
274 case PR_OPTIONS:
275 ppp = &(prp->options);
276 goto CharStarStar;
277 break;
279 case PR_PPD:
281 pp = &(prp->ppd);
282 goto CharStar;
287 if (errno != 0) {
288 int save_errno = errno;
290 freeprinter (prp);
291 close(fd);
292 errno = save_errno;
293 return (0);
295 close(fd);
298 * Get the printer description (if it exists).
300 if (!(path = getprinterfile(prp->name, COMMENTFILE)))
301 return (0);
302 if (!(prp->description = loadstring(path)) && errno != ENOENT) {
303 Free (path);
304 freeprinter (prp);
305 return (0);
307 Free (path);
310 * Get the information for the alert. Don't fail if we can't
311 * read it because of access permission UNLESS we're "root"
312 * or "lp"
314 if (!(pa = getalert(Lp_A_Printers, prp->name))) {
315 if (
316 errno != ENOENT
317 && (
318 errno != EACCES
319 || !getpid() /* we be root */
320 || STREQU(getname(), LPUSER) /* we be lp */
323 freeprinter (prp);
324 return (0);
326 } else
327 prp->fault_alert = *pa;
330 * Now go through the structure and see if we have
331 * anything strange.
333 if (!okprinter(prp->name, prp, 0)) {
334 freeprinter (prp);
335 errno = EBADF;
336 return (0);
340 * Just in case somebody tried to pull a fast one
341 * by giving a printer type header by itself....
343 if (!prp->printer_types)
344 prp->printer_types = getlist(NAME_UNKNOWN, LP_WS, LP_SEP);
347 * If there are more than one printer type, then we can't
348 * have any input types, except perhaps ``simple''.
350 if (
351 lenlist(prp->printer_types) > 1
352 && prp->input_types
353 && (
354 lenlist(prp->input_types) > 1
355 || !STREQU(NAME_SIMPLE, *prp->input_types)
358 freeprinter (prp);
359 badprinter = BAD_ITYPES;
360 errno = EBADF;
361 return (0);
365 * If there are more than one printer types, none can
366 * be ``unknown''.
368 if (
369 lenlist(prp->printer_types) > 1
370 && searchlist(NAME_UNKNOWN, prp->printer_types)
372 freeprinter (prp);
373 badprinter = BAD_PTYPES;
374 errno = EBADF;
375 return (0);
379 * All the printer types had better agree on whether the
380 * printer takes print wheels!
382 prp->daisy = -1;
383 for (pp = prp->printer_types; *pp; pp++) {
384 tidbit (*pp, "daisy", &daisy);
385 if (daisy == -1)
386 daisy = 0;
387 if (prp->daisy == -1)
388 prp->daisy = daisy;
389 else if (prp->daisy != daisy) {
390 freeprinter (prp);
391 badprinter = BAD_DAISY;
392 errno = EBADF;
393 return (0);
398 * Help out those who are still using the obsolete
399 * "printer_type" member.
401 prp->printer_type = Strdup(*prp->printer_types);
403 return (prp);