2 * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
27 * Copyright (C) 1989 by NeXT, Inc.
30 #include <mach/mach.h>
33 #include <rpc/types.h>
37 #include "_lu_types.h"
39 #include "printerdb.h"
42 static pthread_mutex_t _printer_lock
= PTHREAD_MUTEX_INITIALIZER
;
47 extern prdb_ent
*_old_prdb_get();
48 extern prdb_ent
*_old_prdb_getbyname();
49 extern void _old_prdb_set();
50 extern void _old_prdb_end();
53 free_printer_data(prdb_ent
*p
)
58 if (p
== NULL
) return;
63 while (*names
) free(*names
++);
67 for (i
= 0; i
< p
->pe_nprops
; i
++)
69 free(p
->pe_prop
[i
].pp_key
);
70 free(p
->pe_prop
[i
].pp_value
);
77 free_printer(prdb_ent
*p
)
79 if (p
== NULL
) return;
85 free_lu_thread_info_printer(void *x
)
87 struct lu_thread_info
*tdata
;
89 if (x
== NULL
) return;
91 tdata
= (struct lu_thread_info
*)x
;
93 if (tdata
->lu_entry
!= NULL
)
95 free_printer((prdb_ent
*)tdata
->lu_entry
);
96 tdata
->lu_entry
= NULL
;
99 _lu_data_free_vm_xdr(tdata
);
105 extract_printer(XDR
*xdr
)
108 int i
, j
, nvals
, nkeys
, status
;
111 if (xdr
== NULL
) return NULL
;
113 if (!xdr_int(xdr
, &nkeys
)) return NULL
;
115 p
= (prdb_ent
*)calloc(1, sizeof(prdb_ent
));
117 for (i
= 0; i
< nkeys
; i
++)
123 status
= _lu_xdr_attribute(xdr
, &key
, &vals
, &nvals
);
132 if ((p
->pe_name
== NULL
) && (!strcmp("name", key
)))
141 if (p
->pe_nprops
== 0)
143 p
->pe_prop
= (prdb_property
*)calloc(1, sizeof(prdb_property
));
147 p
->pe_prop
= (prdb_property
*)realloc(p
->pe_prop
, (p
->pe_nprops
+ 1) * sizeof(prdb_property
));
149 p
->pe_prop
[p
->pe_nprops
].pp_key
= key
;
150 p
->pe_prop
[p
->pe_nprops
].pp_value
= NULL
;
153 p
->pe_prop
[p
->pe_nprops
].pp_value
= vals
[0];
158 p
->pe_prop
[p
->pe_nprops
].pp_value
= strdup("");
165 for (; j
< nvals
; j
++) free(vals
[j
]);
170 if (p
->pe_name
== NULL
) p
->pe_name
= (char **)calloc(1, sizeof(char *));
171 if (p
->pe_prop
== NULL
) p
->pe_prop
= (prdb_property
*)calloc(1, sizeof(prdb_property
));
177 copy_printer(prdb_ent
*in
)
182 if (in
== NULL
) return NULL
;
184 p
= (prdb_ent
*)calloc(1, sizeof(prdb_ent
));
186 if (in
->pe_name
!= NULL
)
188 for (i
= 0; in
->pe_name
[i
] != NULL
; i
++);
189 p
->pe_name
= (char **)calloc(i
, sizeof(char *));
190 for (i
= 0; p
->pe_name
[i
] != NULL
; i
++) p
->pe_name
[i
] = strdup(in
->pe_name
[i
]);
194 p
->pe_name
= (char **)calloc(1, sizeof(char *));
197 if (in
->pe_nprops
> 0)
199 p
->pe_prop
= (struct prdb_property
*)calloc(in
->pe_nprops
, sizeof(struct prdb_property
));
201 for (i
= 0; in
->pe_nprops
; i
++)
203 p
->pe_prop
[i
].pp_key
= strdup(in
->pe_prop
[i
].pp_key
);
204 p
->pe_prop
[i
].pp_value
= NULL
;
205 if (in
->pe_prop
[i
].pp_value
!= NULL
) p
->pe_prop
[i
].pp_value
= strdup(in
->pe_prop
[i
].pp_value
);
210 p
->pe_prop
= (prdb_property
*)calloc(1, sizeof(prdb_property
));
217 recycle_printer(struct lu_thread_info
*tdata
, struct prdb_ent
*in
)
221 if (tdata
== NULL
) return;
222 p
= (struct prdb_ent
*)tdata
->lu_entry
;
227 tdata
->lu_entry
= NULL
;
230 if (tdata
->lu_entry
== NULL
)
232 tdata
->lu_entry
= in
;
236 free_printer_data(p
);
238 p
->pe_name
= in
->pe_name
;
239 p
->pe_nprops
= in
->pe_nprops
;
240 p
->pe_prop
= in
->pe_prop
;
246 lu_prdb_getbyname(const char *name
)
250 char namebuf
[_LU_MAXLUSTRLEN
+ BYTES_PER_XDR_UNIT
];
253 static int proc
= -1;
259 if (_lookup_link(_lu_port
, "prdb_getbyname", &proc
) != KERN_SUCCESS
)
265 xdrmem_create(&outxdr
, namebuf
, sizeof(namebuf
), XDR_ENCODE
);
266 if (!xdr__lu_string(&outxdr
, (_lu_string
*)&name
))
268 xdr_destroy(&outxdr
);
275 if (_lookup_all(_lu_port
, proc
, (unit
*)namebuf
, xdr_getpos(&outxdr
) / BYTES_PER_XDR_UNIT
, &lookup_buf
, &datalen
) != KERN_SUCCESS
)
277 xdr_destroy(&outxdr
);
281 xdr_destroy(&outxdr
);
283 datalen
*= BYTES_PER_XDR_UNIT
;
284 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
286 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
289 if (!xdr_int(&inxdr
, &count
))
292 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
299 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
303 p
= extract_printer(&inxdr
);
305 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
313 struct lu_thread_info
*tdata
;
315 tdata
= _lu_data_create_key(_lu_data_key_printer
, free_lu_thread_info_printer
);
316 _lu_data_free_vm_xdr(tdata
);
329 static int proc
= -1;
330 struct lu_thread_info
*tdata
;
332 tdata
= _lu_data_create_key(_lu_data_key_printer
, free_lu_thread_info_printer
);
335 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
336 _lu_data_set_key(_lu_data_key_printer
, tdata
);
339 if (tdata
->lu_vm
== NULL
)
343 if (_lookup_link(_lu_port
, "prdb_get", &proc
) != KERN_SUCCESS
)
350 if (_lookup_all(_lu_port
, proc
, NULL
, 0, &(tdata
->lu_vm
), &(tdata
->lu_vm_length
)) != KERN_SUCCESS
)
356 /* mig stubs measure size in words (4 bytes) */
357 tdata
->lu_vm_length
*= 4;
359 if (tdata
->lu_xdr
!= NULL
)
361 xdr_destroy(tdata
->lu_xdr
);
364 tdata
->lu_xdr
= (XDR
*)calloc(1, sizeof(XDR
));
366 xdrmem_create(tdata
->lu_xdr
, tdata
->lu_vm
, tdata
->lu_vm_length
, XDR_DECODE
);
367 if (!xdr_int(tdata
->lu_xdr
, &tdata
->lu_vm_cursor
))
374 if (tdata
->lu_vm_cursor
== 0)
380 p
= extract_printer(tdata
->lu_xdr
);
387 tdata
->lu_vm_cursor
--;
393 getprinter(const char *name
, int source
)
395 prdb_ent
*res
= NULL
;
396 struct lu_thread_info
*tdata
;
398 tdata
= _lu_data_create_key(_lu_data_key_printer
, free_lu_thread_info_printer
);
401 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
402 _lu_data_set_key(_lu_data_key_printer
, tdata
);
410 res
= lu_prdb_getbyname(name
);
420 pthread_mutex_lock(&_printer_lock
);
424 res
= copy_printer(_old_prdb_getbyname(name
));
427 res
= copy_printer(_old_prdb_get());
431 pthread_mutex_unlock(&_printer_lock
);
434 recycle_printer(tdata
, res
);
435 return (prdb_ent
*)tdata
->lu_entry
;
439 prdb_getbyname(const char *name
)
441 return (const prdb_ent
*)getprinter(name
, P_GET_NAME
);
447 return (const prdb_ent
*)getprinter(NULL
, P_GET_ENT
);
451 prdb_set(const char *name
)
453 if (_lu_running()) lu_prdb_set();
454 else _old_prdb_set();
460 if (_lu_running()) lu_prdb_end();
461 else _old_prdb_end();