Libinfo-173.tar.gz
[apple/libinfo.git] / gen.subproj / printerdb.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * /etc/printcap reader (in case NetInfo is not running)
27 * Copyright (C) 1989 by NeXT, Inc.
28 */
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <printerdb.h>
32
33 #define strdup(x) strcpy(malloc(strlen(x) + 1), x)
34
35 extern size_t strlen(const char *);
36 extern char *index(const char *, int);
37 extern char *strcpy(char *, const char *);
38 extern int strcmp(const char *, const char*);
39 extern void *bcopy(void *, void *, unsigned);
40
41 static FILE *pf;
42 static char *getline(FILE *);
43 static int emptyfield(char *);
44
45 static void
46 _prdb_free_ent(
47 prdb_ent *ent
48 )
49 {
50 int i;
51
52 for (i = 0; ent->pe_name[i]; i++) {
53 free(ent->pe_name[i]);
54 }
55 free(ent->pe_name);
56 ent->pe_name = NULL;
57 for (i = 0; i < ent->pe_nprops; i++) {
58 free(ent->pe_prop[i].pp_key);
59 free(ent->pe_prop[i].pp_value);
60 }
61 free(ent->pe_prop);
62 ent->pe_prop = NULL;
63 }
64
65 void
66 _old_prdb_end(
67 void
68 )
69 {
70 if (pf != NULL) {
71 fclose(pf);
72 pf = NULL;
73 }
74 }
75
76 void
77 _old_prdb_set(
78 void
79 )
80 {
81 if (pf == NULL) {
82 pf = fopen("/etc/printcap", "r");
83 }
84 }
85
86 static void
87 pename_insert(
88 char ***target,
89 char *name,
90 int which
91 )
92 {
93 if (which == 0) {
94 *target = malloc(sizeof(char *) * 2);
95 } else {
96 *target = realloc(*target, sizeof(char *) * (which + 2));
97 }
98 (*target)[which] = strdup(name);
99 (*target)[which + 1] = NULL;
100 }
101
102 static void
103 peprop_insert(
104 prdb_property **target,
105 prdb_property prop,
106 int which
107 )
108 {
109 if (which == 0) {
110 *target = malloc(sizeof(prop));
111 } else {
112 *target = realloc(*target, (which + 1) * sizeof(prop));
113 }
114 (*target)[which] = prop;
115 }
116
117 prdb_ent *
118 _old_prdb_get(
119 void
120 )
121 {
122 char *line;
123 char *p;
124 char *end;
125 char *hash;
126 char *equal;
127 char *where;
128 static prdb_ent ent;
129 prdb_property prop;
130 int which;
131
132 _old_prdb_set();
133 if (pf == NULL) {
134 return (NULL);
135 }
136 do {
137 line = getline(pf);
138 if (line == NULL) {
139 return (NULL);
140 }
141 } while (*line == 0);
142 where = line;
143 end = index(where, ':');
144 if (end != NULL) {
145 *end++ = 0;
146 }
147 which = 0;
148 if (ent.pe_name != NULL) {
149 _prdb_free_ent(&ent);
150 }
151 for (;;) {
152 p = index(where, '|');
153 if (p != NULL && (end == NULL || p < end)) {
154 *p++ = 0;
155 pename_insert(&ent.pe_name, where, which++);
156 where = p;
157 } else {
158 pename_insert(&ent.pe_name, where, which);
159 break;
160 }
161 }
162 where = end;
163 which = 0;
164 for (;;) {
165 end = index(where, ':');
166 if (end != NULL) {
167 *end++ = 0;
168 }
169 hash = index(where, '#');
170 equal = index(where, '=');
171 if (hash != NULL && (end == NULL || hash < end)) {
172 *hash = 0;
173 prop.pp_key = strdup(where);
174 *hash = '#';
175 prop.pp_value = strdup(hash);
176 peprop_insert(&ent.pe_prop, prop, which++);
177 } else if (equal != NULL && (end == NULL ||
178 equal < end)) {
179 *equal++ = 0;
180 prop.pp_key = strdup(where);
181 prop.pp_value = strdup(equal);
182 peprop_insert(&ent.pe_prop, prop, which++);
183 } else if (!emptyfield(where)) {
184 prop.pp_key = strdup(where);
185 prop.pp_value = strdup("");
186 peprop_insert(&ent.pe_prop, prop, which++);
187 }
188 where = end;
189 if (end == NULL) {
190 break;
191 }
192 }
193 free(line);
194 ent.pe_nprops = which;
195 return (&ent);
196 }
197
198 static int
199 prmatch(
200 prdb_ent *ent,
201 char *name
202 )
203 {
204 int i;
205
206 for (i = 0; ent->pe_name[i] != NULL; i++) {
207 if (strcmp(ent->pe_name[i], name) == 0) {
208 return (1);
209 }
210 }
211 return (0);
212 }
213
214 prdb_ent *
215 _old_prdb_getbyname(
216 char *prname
217 )
218 {
219 prdb_ent *ent;
220
221 _old_prdb_set();
222 if (pf == NULL) {
223 return (NULL);
224 }
225 while ((ent = _old_prdb_get())) {
226 if (prmatch(ent, prname)) {
227 break;
228 }
229 }
230 _old_prdb_end();
231 return (ent);
232 }
233
234
235
236 static char *
237 getline(
238 FILE *f
239 )
240 {
241 char line[BUFSIZ];
242 char *res = NULL;
243 int more = 1;
244 int len;
245 int inclen;
246
247 len = 0;
248 while (more && fgets(line, sizeof(line), f)) {
249 inclen = strlen(line);
250 if (line[inclen - 1] == '\n') {
251 line[inclen - 1] = 0;
252 inclen--;
253 }
254 if (*line == '#') {
255 continue;
256 }
257 if (res == NULL) {
258 res = malloc(inclen + 1);
259 } else {
260 res = realloc(res, len + inclen + 1);
261 }
262 if (line[inclen - 1] == '\\') {
263 line[inclen - 1] = 0;
264 inclen--;
265 } else {
266 more = 0;
267 }
268 bcopy(line, res + len, inclen);
269 len += inclen;
270 res[len] = 0;
271 }
272 return (res);
273 }
274
275 static int
276 emptyfield(
277 char *line
278 )
279 {
280 while (*line) {
281 if (*line != ' ' && *line != '\t') {
282 return (0);
283 }
284 line++;
285 }
286 return (1);
287 }