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]
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 */
37 #include "sys/types.h"
51 ** getprinter() - EXTRACT PRINTER STRUCTURE FROM DISK FILE
55 getprinter(char *name
)
57 static long lastdir
= -1;
73 register char *** ppp
;
79 if (!name
|| !*name
) {
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
);
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
101 if (!(name
= next_dir(Lp_A_Printers
, &lastdir
)))
107 * Get the printer configuration information.
110 path
= getprinterfile(name
, CONFIGFILE
);
117 if ((fd
= open_locked(path
, "r", 0)) < 0) {
119 * go around to loop again for
123 if (!isNameAll
) /* fix for bug 1117241 */
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
);
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
);
154 while (fdgets(buf
, BUFSIZ
, fd
) != NULL
) {
156 buf
[strlen(buf
) - 1] = 0;
158 for (fld
= 0; fld
< PR_MAX
; fld
++)
161 && prtrheadings
[fld
].len
165 prtrheadings
[fld
].len
168 p
= buf
+ prtrheadings
[fld
].len
;
169 while (*p
&& *p
== ' ')
175 * To allow future extensions to not impact applications
176 * using old versions of this routine, ignore strange
185 if ((pp
= getlist(p
, LP_WS
, ":"))) {
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
;
207 prp
->cpi
= getcpi(p
);
211 prp
->lpi
= getsdn(p
);
215 prp
->plen
= getsdn(p
);
219 prp
->pwid
= getsdn(p
);
223 ppp
= &(prp
->char_sets
);
227 ppp
= &(prp
->input_types
);
228 CharStarStar
: if (*ppp
)
230 *ppp
= getlist(p
, LP_WS
, LP_SEP
);
238 pp
= &(prp
->dial_info
);
242 pp
= &(prp
->fault_rec
);
246 pp
= &(prp
->interface
);
250 ppp
= &(prp
->printer_types
);
268 #if defined(CAN_DO_MODULES)
270 ppp
= &(prp
->modules
);
275 ppp
= &(prp
->options
);
288 int save_errno
= errno
;
298 * Get the printer description (if it exists).
300 if (!(path
= getprinterfile(prp
->name
, COMMENTFILE
)))
302 if (!(prp
->description
= loadstring(path
)) && errno
!= ENOENT
) {
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"
314 if (!(pa
= getalert(Lp_A_Printers
, prp
->name
))) {
319 || !getpid() /* we be root */
320 || STREQU(getname(), LPUSER
) /* we be lp */
327 prp
->fault_alert
= *pa
;
330 * Now go through the structure and see if we have
333 if (!okprinter(prp
->name
, prp
, 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''.
351 lenlist(prp
->printer_types
) > 1
354 lenlist(prp
->input_types
) > 1
355 || !STREQU(NAME_SIMPLE
, *prp
->input_types
)
359 badprinter
= BAD_ITYPES
;
365 * If there are more than one printer types, none can
369 lenlist(prp
->printer_types
) > 1
370 && searchlist(NAME_UNKNOWN
, prp
->printer_types
)
373 badprinter
= BAD_PTYPES
;
379 * All the printer types had better agree on whether the
380 * printer takes print wheels!
383 for (pp
= prp
->printer_types
; *pp
; pp
++) {
384 tidbit (*pp
, "daisy", &daisy
);
387 if (prp
->daisy
== -1)
389 else if (prp
->daisy
!= daisy
) {
391 badprinter
= BAD_DAISY
;
398 * Help out those who are still using the obsolete
399 * "printer_type" member.
401 prp
->printer_type
= Strdup(*prp
->printer_types
);