Libinfo-78.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_printer.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 * Printer lookup
26 * Copyright (C) 1989 by NeXT, Inc.
27 */
28 #include <stdlib.h>
29 #include <mach/mach.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include "lookup.h"
33 #include <rpc/types.h>
34 #include <rpc/xdr.h>
35 #include "_lu_types.h"
36 #include "printerdb.h"
37 #include "lu_utils.h"
38
39 extern struct prdb_ent *_old_prdb_get();
40 extern struct prdb_ent *_old_prdb_getbyname();
41 extern void _old_prdb_set();
42 extern void _old_prdb_end();
43
44 static lookup_state prdb_state = LOOKUP_CACHE;
45 static struct prdb_ent global_prdb;
46 static int global_free = 1;
47 static char *prdb_data = NULL;
48 static unsigned prdb_datalen = 0;
49 static int prdb_nentries;
50 static int prdb_start = 1;
51 static XDR prdb_xdr = { 0 };
52
53 static void
54 freeold(void)
55 {
56 char **names;
57 int i;
58
59 if (global_free == 1) return;
60
61 names = global_prdb.pe_name;
62 if (names != NULL)
63 {
64 while (*names) free(*names++);
65 free(global_prdb.pe_name);
66 }
67
68 for (i = 0; i < global_prdb.pe_nprops; i++)
69 {
70 free(global_prdb.pe_prop[i].pp_key);
71 free(global_prdb.pe_prop[i].pp_value);
72 }
73
74 free(global_prdb.pe_prop);
75
76 global_free = 1;
77 }
78
79
80 static void
81 convert_prdb(_lu_prdb_ent *lu_prdb)
82 {
83 int i, len;
84
85 freeold();
86
87 len = lu_prdb->pe_names.pe_names_len;
88 global_prdb.pe_name = (char **)malloc((len + 1) * sizeof(char *));
89 for (i = 0; i < len; i++)
90 {
91 global_prdb.pe_name[i] = strdup(lu_prdb->pe_names.pe_names_val[i]);
92 }
93
94 global_prdb.pe_name[len] = NULL;
95
96 len = lu_prdb->pe_props.pe_props_len;
97 global_prdb.pe_prop = (prdb_property *)malloc(len * sizeof(prdb_property));
98 for (i = 0; i < len; i++)
99 {
100 global_prdb.pe_prop[i].pp_key =
101 strdup(lu_prdb->pe_props.pe_props_val[i].pp_key);
102
103 global_prdb.pe_prop[i].pp_value =
104 strdup(lu_prdb->pe_props.pe_props_val[i].pp_value);
105 }
106
107 global_prdb.pe_nprops = lu_prdb->pe_props.pe_props_len;
108
109 global_free = 0;
110 }
111
112 static void
113 lu_prdb_end()
114 {
115 prdb_nentries = 0;
116 if (prdb_data != NULL)
117 {
118 freeold();
119 vm_deallocate(mach_task_self(), (vm_address_t)prdb_data, prdb_datalen);
120 prdb_data = NULL;
121 }
122 }
123
124 static void
125 lu_prdb_set()
126 {
127 lu_prdb_end();
128 prdb_start = 1;
129 }
130
131 static struct prdb_ent *
132 lu_prdb_getbyname(const char *name)
133 {
134 unsigned datalen;
135 char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
136 XDR outxdr;
137 XDR inxdr;
138 _lu_prdb_ent_ptr lu_prdb;
139 static int proc = -1;
140 unit lookup_buf[MAX_INLINE_UNITS];
141
142 if (proc < 0)
143 {
144 if (_lookup_link(_lu_port, "prdb_getbyname", &proc) != KERN_SUCCESS)
145 {
146 return (NULL);
147 }
148 }
149
150 xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
151 if (!xdr__lu_string(&outxdr, &name))
152 {
153 xdr_destroy(&outxdr);
154 return (NULL);
155 }
156
157 datalen = MAX_INLINE_UNITS;
158 if (_lookup_one(_lu_port, proc, (unit *)namebuf,
159 xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen)
160 != KERN_SUCCESS)
161 {
162 xdr_destroy(&outxdr);
163 return (NULL);
164 }
165
166 xdr_destroy(&outxdr);
167
168 datalen *= BYTES_PER_XDR_UNIT;
169 xdrmem_create(&inxdr, lookup_buf, datalen,
170 XDR_DECODE);
171 lu_prdb = NULL;
172 if (!xdr__lu_prdb_ent_ptr(&inxdr, &lu_prdb) || (lu_prdb == NULL))
173 {
174 xdr_destroy(&inxdr);
175 return (NULL);
176 }
177
178 xdr_destroy(&inxdr);
179
180 convert_prdb(lu_prdb);
181 xdr_free(xdr__lu_prdb_ent_ptr, &lu_prdb);
182 return (&global_prdb);
183 }
184
185 static prdb_ent *
186 lu_prdb_get()
187 {
188 static int proc = -1;
189 _lu_prdb_ent lu_prdb;
190
191 if (prdb_start == 1)
192 {
193 prdb_start = 0;
194
195 if (proc < 0)
196 {
197 if (_lookup_link(_lu_port, "prdb_get", &proc) != KERN_SUCCESS)
198 {
199 lu_prdb_end();
200 return (NULL);
201 }
202 }
203 if (_lookup_all(_lu_port, proc, NULL, 0, &prdb_data, &prdb_datalen)
204 != KERN_SUCCESS)
205 {
206 lu_prdb_end();
207 return (NULL);
208 }
209
210 #ifdef NOTDEF
211 /* NOTDEF because OOL buffers are counted in bytes with untyped IPC */
212 prdb_datalen *= BYTES_PER_XDR_UNIT;
213 #endif
214
215 xdrmem_create(&prdb_xdr, prdb_data, prdb_datalen,
216 XDR_DECODE);
217 if (!xdr_int(&prdb_xdr, &prdb_nentries))
218 {
219 xdr_destroy(&prdb_xdr);
220 lu_prdb_end();
221 return (NULL);
222 }
223 }
224
225 if (prdb_nentries == 0)
226 {
227 xdr_destroy(&prdb_xdr);
228 lu_prdb_end();
229 return (NULL);
230 }
231
232 bzero(&lu_prdb, sizeof(lu_prdb));
233 if (!xdr__lu_prdb_ent(&prdb_xdr, &lu_prdb))
234 {
235 xdr_destroy(&prdb_xdr);
236 lu_prdb_end();
237 return (NULL);
238 }
239
240 prdb_nentries--;
241 convert_prdb(&lu_prdb);
242 xdr_free(xdr__lu_prdb_ent, &lu_prdb);
243 return (&global_prdb);
244 }
245
246 const prdb_ent *
247 prdb_getbyname(const char *name)
248 {
249 LOOKUP1(lu_prdb_getbyname, _old_prdb_getbyname, name, prdb_ent);
250 }
251
252 const prdb_ent *
253 prdb_get(void)
254 {
255 GETENT(lu_prdb_get, _old_prdb_get, &prdb_state, prdb_ent);
256 }
257
258 void
259 prdb_set(const char *name)
260 {
261 SETSTATE(lu_prdb_set, _old_prdb_set, &prdb_state, name);
262 }
263
264 void
265 prdb_end(void)
266 {
267 UNSETSTATE(lu_prdb_end, _old_prdb_end, &prdb_state);
268 }