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 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
31 
32 #include "stdio.h"
33 #include "string.h"
34 #include "errno.h"
35 #include "sys/types.h"
36 #include "stdlib.h"
37 
38 #include "lp.h"
39 #include "printers.h"
40 
41 extern struct {
42 	char			*v;
43 	short			len,
44 				okremote;
45 }			prtrheadings[];
46 
47 /*
48  * getpentry() - EXTRACT ONE PRINTER ENTRY FROM DISK FILE
49  */
50 
51 char *
getpentry(char * name,int want_fld)52 getpentry(char *name, int want_fld)
53 {
54 	static long		lastdir		= -1;
55 	char			buf[BUFSIZ];
56 	int			fld;
57 	int fd;
58 	register char *		p;
59 	register char *		path;
60 	int			isNameAll;
61 	char * option_entry = NULL;
62 
63 
64 
65 	if (!name || !*name) {
66 		errno = EINVAL;
67 		return (0);
68 	}
69 
70 	/*
71 	 * Getting ``all''? If so, jump into the directory
72 	 * wherever we left off.
73 	 */
74 	isNameAll = STREQU(NAME_ALL, name);
75 	for (; ; ) {
76 		/*
77 		 * fix for bug 1117241
78 		 * occasionally when a printer is removed, a printer directory
79 		 * is left behind, but the CONFIGFILE is removed.  In this
80 		 * case this directory terminates the search for additional
81 		 * printers as we have been returning 0 in this case.
82 		 * Now, we loop back and try the next directory until
83 		 * we have no more directories or we find a directory with
84 		 * a CONFIGFILE
85 		 */
86 		if (isNameAll) {
87 			if (!(name = next_dir(Lp_A_Printers, &lastdir)))
88 				return (0);
89 		} else
90 			lastdir = -1;
91 
92 		/*
93 		 * Get the printer configuration information.
94 		 */
95 
96 		path = getprinterfile(name, CONFIGFILE);
97 		if (!path) {
98 			if (isNameAll)
99 				Free(name);
100 			return (0);
101 		}
102 
103 		if ((fd = open_locked(path, "r", 0)) < 0) {
104 			Free(path);
105 
106 			/*
107 			 * go around to loop again for
108 			 * NAME_ALL case
109 			 */
110 
111 			if (!isNameAll) /* fix for bug 1117241 */
112 				return (0);
113 			else
114 				Free(name);
115 		}
116 		else
117 			break;
118 	}
119 	Free(path);
120 
121 	/*
122 	 * Read the file.
123 	 */
124 	errno = 0;
125 	while (fdgets(buf, BUFSIZ, fd) != NULL) {
126 
127 		buf[strlen(buf) - 1] = 0;
128 
129 		for (fld = 0; fld < PR_MAX; fld++)
130 			if (prtrheadings[fld].v &&
131 				prtrheadings[fld].len &&
132 				STRNEQU(
133 					buf,
134 					prtrheadings[fld].v,
135 					prtrheadings[fld].len)) {
136 
137 				p = buf + prtrheadings[fld].len;
138 				while (*p && *p == ' ')
139 					p++;
140 				break;
141 			}
142 
143 		/*
144 		 * To allow future extensions to not impact applications
145 		 * using old versions of this routine, ignore strange
146 		 * fields.
147 		 */
148 		if (fld >= PR_MAX)
149 			continue;
150 
151 		if (fld == want_fld) {
152 			if ((option_entry = strdup(p)) == NULL) {
153 				return (0);
154 			}
155 		}
156 
157 
158 	}
159 	if (errno != 0) {
160 		int save_errno = errno;
161 		close(fd);
162 		errno = save_errno;
163 		return (0);
164 	}
165 	close(fd);
166 
167 	return (option_entry);
168 }
169