1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 1997 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28/*	  All Rights Reserved  	*/
29
30
31#pragma ident	"%Z%%M%	%I%	%E% SMI"
32/* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
33
34#include "stdio.h"
35#include "string.h"
36#include "errno.h"
37#include "sys/types.h"
38#include "stdlib.h"
39
40#include "lp.h"
41#include "printers.h"
42
43extern struct {
44	char			*v;
45	short			len,
46				okremote;
47}			prtrheadings[];
48
49/*
50 * getpentry() - EXTRACT ONE PRINTER ENTRY FROM DISK FILE
51 */
52
53char *
54getpentry(char *name, int want_fld)
55{
56	static long		lastdir		= -1;
57	char			buf[BUFSIZ];
58	int			fld;
59	int fd;
60	register char *		p;
61	register char *		path;
62	int			isNameAll;
63	char * option_entry = NULL;
64
65
66
67	if (!name || !*name) {
68		errno = EINVAL;
69		return (0);
70	}
71
72	/*
73	 * Getting ``all''? If so, jump into the directory
74	 * wherever we left off.
75	 */
76	isNameAll = STREQU(NAME_ALL, name);
77	for (; ; ) {
78		/*
79		 * fix for bug 1117241
80		 * occasionally when a printer is removed, a printer directory
81		 * is left behind, but the CONFIGFILE is removed.  In this
82		 * case this directory terminates the search for additional
83		 * printers as we have been returning 0 in this case.
84		 * Now, we loop back and try the next directory until
85		 * we have no more directories or we find a directory with
86		 * a CONFIGFILE
87		 */
88		if (isNameAll) {
89			if (!(name = next_dir(Lp_A_Printers, &lastdir)))
90				return (0);
91		} else
92			lastdir = -1;
93
94		/*
95		 * Get the printer configuration information.
96		 */
97
98		path = getprinterfile(name, CONFIGFILE);
99		if (!path) {
100			if (isNameAll)
101				Free(name);
102			return (0);
103		}
104
105		if ((fd = open_locked(path, "r", 0)) < 0) {
106			Free(path);
107
108			/*
109			 * go around to loop again for
110			 * NAME_ALL case
111			 */
112
113			if (!isNameAll) /* fix for bug 1117241 */
114				return (0);
115			else
116				Free(name);
117		}
118		else
119			break;
120	}
121	Free(path);
122
123	/*
124	 * Read the file.
125	 */
126	errno = 0;
127	while (fdgets(buf, BUFSIZ, fd) != NULL) {
128
129		buf[strlen(buf) - 1] = 0;
130
131		for (fld = 0; fld < PR_MAX; fld++)
132			if (prtrheadings[fld].v &&
133				prtrheadings[fld].len &&
134				STRNEQU(
135					buf,
136					prtrheadings[fld].v,
137					prtrheadings[fld].len)) {
138
139				p = buf + prtrheadings[fld].len;
140				while (*p && *p == ' ')
141					p++;
142				break;
143			}
144
145		/*
146		 * To allow future extensions to not impact applications
147		 * using old versions of this routine, ignore strange
148		 * fields.
149		 */
150		if (fld >= PR_MAX)
151			continue;
152
153		if (fld == want_fld) {
154			if ((option_entry = strdup(p)) == NULL) {
155				return (0);
156			}
157		}
158
159
160	}
161	if (errno != 0) {
162		int save_errno = errno;
163		close(fd);
164		errno = save_errno;
165		return (0);
166	}
167	close(fd);
168
169	return (option_entry);
170}
171