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