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