2 * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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
22 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (C) 1989 by NeXT, Inc.
29 #include <mach/mach.h>
32 #include <rpc/types.h>
36 #include "_lu_types.h"
38 #include "printerdb.h"
41 static pthread_mutex_t _printer_lock
= PTHREAD_MUTEX_INITIALIZER
;
46 extern prdb_ent
*_old_prdb_get();
47 extern prdb_ent
*_old_prdb_getbyname();
48 extern void _old_prdb_set();
49 extern void _old_prdb_end();
52 free_printer_data(prdb_ent
*p
)
57 if (p
== NULL
) return;
62 while (*names
) free(*names
++);
66 for (i
= 0; i
< p
->pe_nprops
; i
++)
68 free(p
->pe_prop
[i
].pp_key
);
69 free(p
->pe_prop
[i
].pp_value
);
76 free_printer(prdb_ent
*p
)
78 if (p
== NULL
) return;
84 free_lu_thread_info_printer(void *x
)
86 struct lu_thread_info
*tdata
;
88 if (x
== NULL
) return;
90 tdata
= (struct lu_thread_info
*)x
;
92 if (tdata
->lu_entry
!= NULL
)
94 free_printer((prdb_ent
*)tdata
->lu_entry
);
95 tdata
->lu_entry
= NULL
;
98 _lu_data_free_vm_xdr(tdata
);
104 extract_printer(XDR
*xdr
)
107 int i
, j
, nvals
, nkeys
, status
;
110 if (xdr
== NULL
) return NULL
;
112 if (!xdr_int(xdr
, &nkeys
)) return NULL
;
114 p
= (prdb_ent
*)calloc(1, sizeof(prdb_ent
));
116 for (i
= 0; i
< nkeys
; i
++)
122 status
= _lu_xdr_attribute(xdr
, &key
, &vals
, &nvals
);
131 if ((p
->pe_name
== NULL
) && (!strcmp("name", key
)))
140 if (p
->pe_nprops
== 0)
142 p
->pe_prop
= (prdb_property
*)calloc(1, sizeof(prdb_property
));
146 p
->pe_prop
= (prdb_property
*)realloc(p
->pe_prop
, (p
->pe_nprops
+ 1) * sizeof(prdb_property
));
148 p
->pe_prop
[p
->pe_nprops
].pp_key
= key
;
149 p
->pe_prop
[p
->pe_nprops
].pp_value
= NULL
;
152 p
->pe_prop
[p
->pe_nprops
].pp_value
= vals
[0];
157 p
->pe_prop
[p
->pe_nprops
].pp_value
= strdup("");
164 for (; j
< nvals
; j
++) free(vals
[j
]);
169 if (p
->pe_name
== NULL
) p
->pe_name
= (char **)calloc(1, sizeof(char *));
170 if (p
->pe_prop
== NULL
) p
->pe_prop
= (prdb_property
*)calloc(1, sizeof(prdb_property
));
176 copy_printer(prdb_ent
*in
)
181 if (in
== NULL
) return NULL
;
183 p
= (prdb_ent
*)calloc(1, sizeof(prdb_ent
));
185 if (in
->pe_name
!= NULL
)
187 for (i
= 0; in
->pe_name
[i
] != NULL
; i
++);
188 p
->pe_name
= (char **)calloc(i
, sizeof(char *));
189 for (i
= 0; p
->pe_name
[i
] != NULL
; i
++) p
->pe_name
[i
] = strdup(in
->pe_name
[i
]);
193 p
->pe_name
= (char **)calloc(1, sizeof(char *));
196 if (in
->pe_nprops
> 0)
198 p
->pe_prop
= (struct prdb_property
*)calloc(in
->pe_nprops
, sizeof(struct prdb_property
));
200 for (i
= 0; in
->pe_nprops
; i
++)
202 p
->pe_prop
[i
].pp_key
= strdup(in
->pe_prop
[i
].pp_key
);
203 p
->pe_prop
[i
].pp_value
= NULL
;
204 if (in
->pe_prop
[i
].pp_value
!= NULL
) p
->pe_prop
[i
].pp_value
= strdup(in
->pe_prop
[i
].pp_value
);
209 p
->pe_prop
= (prdb_property
*)calloc(1, sizeof(prdb_property
));
216 recycle_printer(struct lu_thread_info
*tdata
, struct prdb_ent
*in
)
220 if (tdata
== NULL
) return;
221 p
= (struct prdb_ent
*)tdata
->lu_entry
;
226 tdata
->lu_entry
= NULL
;
229 if (tdata
->lu_entry
== NULL
)
231 tdata
->lu_entry
= in
;
235 free_printer_data(p
);
237 p
->pe_name
= in
->pe_name
;
238 p
->pe_nprops
= in
->pe_nprops
;
239 p
->pe_prop
= in
->pe_prop
;
245 lu_prdb_getbyname(const char *name
)
249 char namebuf
[_LU_MAXLUSTRLEN
+ BYTES_PER_XDR_UNIT
];
252 static int proc
= -1;
258 if (_lookup_link(_lu_port
, "prdb_getbyname", &proc
) != KERN_SUCCESS
)
264 xdrmem_create(&outxdr
, namebuf
, sizeof(namebuf
), XDR_ENCODE
);
265 if (!xdr__lu_string(&outxdr
, (_lu_string
*)&name
))
267 xdr_destroy(&outxdr
);
274 if (_lookup_all(_lu_port
, proc
, (unit
*)namebuf
, xdr_getpos(&outxdr
) / BYTES_PER_XDR_UNIT
, &lookup_buf
, &datalen
) != KERN_SUCCESS
)
276 xdr_destroy(&outxdr
);
280 xdr_destroy(&outxdr
);
282 datalen
*= BYTES_PER_XDR_UNIT
;
283 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
285 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
288 if (!xdr_int(&inxdr
, &count
))
291 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
298 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
302 p
= extract_printer(&inxdr
);
304 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
312 struct lu_thread_info
*tdata
;
314 tdata
= _lu_data_create_key(_lu_data_key_printer
, free_lu_thread_info_printer
);
315 _lu_data_free_vm_xdr(tdata
);
328 static int proc
= -1;
329 struct lu_thread_info
*tdata
;
331 tdata
= _lu_data_create_key(_lu_data_key_printer
, free_lu_thread_info_printer
);
334 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
335 _lu_data_set_key(_lu_data_key_printer
, tdata
);
338 if (tdata
->lu_vm
== NULL
)
342 if (_lookup_link(_lu_port
, "prdb_get", &proc
) != KERN_SUCCESS
)
349 if (_lookup_all(_lu_port
, proc
, NULL
, 0, &(tdata
->lu_vm
), &(tdata
->lu_vm_length
)) != KERN_SUCCESS
)
355 /* mig stubs measure size in words (4 bytes) */
356 tdata
->lu_vm_length
*= 4;
358 if (tdata
->lu_xdr
!= NULL
)
360 xdr_destroy(tdata
->lu_xdr
);
363 tdata
->lu_xdr
= (XDR
*)calloc(1, sizeof(XDR
));
365 xdrmem_create(tdata
->lu_xdr
, tdata
->lu_vm
, tdata
->lu_vm_length
, XDR_DECODE
);
366 if (!xdr_int(tdata
->lu_xdr
, &tdata
->lu_vm_cursor
))
373 if (tdata
->lu_vm_cursor
== 0)
379 p
= extract_printer(tdata
->lu_xdr
);
386 tdata
->lu_vm_cursor
--;
392 getprinter(const char *name
, int source
)
394 prdb_ent
*res
= NULL
;
395 struct lu_thread_info
*tdata
;
397 tdata
= _lu_data_create_key(_lu_data_key_printer
, free_lu_thread_info_printer
);
400 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
401 _lu_data_set_key(_lu_data_key_printer
, tdata
);
409 res
= lu_prdb_getbyname(name
);
419 pthread_mutex_lock(&_printer_lock
);
423 res
= copy_printer(_old_prdb_getbyname(name
));
426 res
= copy_printer(_old_prdb_get());
430 pthread_mutex_unlock(&_printer_lock
);
433 recycle_printer(tdata
, res
);
434 return (prdb_ent
*)tdata
->lu_entry
;
438 prdb_getbyname(const char *name
)
440 return (const prdb_ent
*)getprinter(name
, P_GET_NAME
);
446 return (const prdb_ent
*)getprinter(NULL
, P_GET_ENT
);
450 prdb_set(const char *name
)
452 if (_lu_running()) lu_prdb_set();
453 else _old_prdb_set();
459 if (_lu_running()) lu_prdb_end();
460 else _old_prdb_end();