xref: /illumos-gate/usr/src/lib/print/libpapi-dynamic/common/printer.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  */
27 
28 /* $Id: printer.c 151 2006-04-25 16:55:34Z njacobs $ */
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 /*LINTLIBRARY*/
33 
34 #include <stdlib.h>
35 #include <papi_impl.h>
36 
37 void
38 papiPrinterFree(papi_printer_t printer)
39 {
40 	printer_t *tmp = printer;
41 
42 	if (tmp != NULL) {
43 		void (*f)();
44 
45 		f = (void (*)())psm_sym(tmp->svc, "papiPrinterFree");
46 		if (f != NULL)
47 			f(tmp->printer);
48 		if (tmp->attributes != NULL)
49 			papiAttributeListFree(tmp->attributes);
50 		if (tmp->svc_is_internal != 0)
51 			papiServiceDestroy(tmp->svc);
52 		free(tmp);
53 	}
54 }
55 
56 void
57 papiPrinterListFree(papi_printer_t *printers)
58 {
59 	if (printers != NULL) {
60 		int i;
61 
62 		for (i = 0; printers[i] != NULL; i++)
63 			papiPrinterFree(printers[i]);
64 		free(printers);
65 	}
66 }
67 
68 /* Enumerate a list of printers from the loaded print service. */
69 static papi_status_t
70 printers_from_service(service_t *svc, char **requested_attrs,
71 		papi_filter_t *filter, papi_printer_t **printers)
72 {
73 	papi_status_t result = PAPI_INTERNAL_ERROR;
74 	papi_printer_t *svc_printers = NULL;
75 	papi_status_t (*f)();
76 
77 	if ((svc == NULL) || (printers == NULL))
78 		return (PAPI_BAD_ARGUMENT);
79 
80 	/* connect to the service if we are not connected */
81 	if ((result = service_connect(svc, svc->name)) != PAPI_OK)
82 		return (result);
83 
84 	f = (papi_status_t (*)())psm_sym(svc, "papiPrintersList");
85 	if (f != NULL)
86 		result = f(svc->svc_handle, requested_attrs, filter,
87 				&svc_printers);
88 
89 	/*
90 	 * copy the resulting printer object pointers into our own
91 	 * representation of a printer object because we need the
92 	 * service context to operate against the individual printer
93 	 * objects.  We free the list now because we no longer need
94 	 * it and would have no way of freeing it later.
95 	 */
96 	if ((result == PAPI_OK) && (svc_printers != NULL)) {
97 		int i;
98 
99 		*printers = NULL;
100 		for (i = 0; svc_printers[i] != NULL; i++) {
101 			printer_t *p = NULL;
102 
103 			if ((p = calloc(1, sizeof (*p))) == NULL)
104 				return (PAPI_TEMPORARY_ERROR);
105 
106 			p->svc = svc;
107 			p->printer = svc_printers[i];
108 			list_append(printers, p);
109 		}
110 		free(svc_printers);
111 	}
112 
113 	return (result);
114 }
115 
116 /* Get printer attributes from it's print service */
117 static papi_status_t
118 printer_from_service(service_t *svc, printer_t *p, char **requested_attrs)
119 {
120 	papi_status_t result;
121 	papi_service_t p_svc = NULL;
122 	papi_printer_t printer = NULL;
123 	char *psm = NULL;
124 	char *uri = NULL;
125 
126 	/* get the psm and uri from the attributes */
127 	papiAttributeListGetString(p->attributes, NULL,
128 			"print-service-module", &psm);
129 	papiAttributeListGetString(p->attributes, NULL, "printer-name", &uri);
130 	papiAttributeListGetString(p->attributes, NULL, "printer-uri-supported",
131 			&uri);
132 
133 	/* contact the service for the printer */
134 	result = papiServiceCreate((papi_service_t *)&p_svc, psm, svc->user,
135 				svc->password, svc->authCB, svc->encryption,
136 				svc->app_data);
137 	if (result != PAPI_OK)
138 		return (result);
139 
140 	/* get the printer from the service */
141 	result = papiPrinterQuery(p_svc, uri, requested_attrs, NULL, &printer);
142 	if (result == PAPI_OK) {
143 		papi_attribute_t **attributes;
144 
145 		attributes = papiPrinterGetAttributeList(printer);
146 		copy_attributes(&p->attributes, attributes);
147 	}
148 	papiPrinterFree(printer);
149 	papiServiceDestroy(p_svc);
150 
151 	return (result);
152 }
153 
154 /* are the requested attributes contained in the list */
155 static int
156 contained(char **requested, papi_attribute_t **list)
157 {
158 	int i;
159 
160 	if (requested == NULL)	/* we want every possible attribute */
161 		return (0);
162 
163 	for (i = 0; requested[i] != NULL; i++)
164 		if (papiAttributeListFind(list, requested[i]) == NULL)
165 			return (0);
166 
167 	return (1);
168 }
169 
170 /* Enumerate a list of printers from the Name Service */
171 static papi_status_t
172 printers_from_name_service(service_t *svc, char **requested_attrs,
173 		papi_filter_t *filter, papi_printer_t **printers)
174 {
175 	papi_status_t result = PAPI_INTERNAL_ERROR;
176 	papi_attribute_t **attrs;
177 
178 	if ((svc == NULL) || (printers == NULL))
179 		return (PAPI_BAD_ARGUMENT);
180 
181 	/* retrieve printers from the nameservice */
182 	setprinterentry(0, NULL);
183 	while ((attrs = getprinterentry(NULL)) != NULL) {
184 		printer_t *p = NULL;
185 
186 		if ((p = calloc(1, sizeof (*p))) == NULL)
187 			return (PAPI_TEMPORARY_ERROR);
188 
189 		p->attributes = attrs;
190 		list_append(printers, p);
191 	}
192 
193 	/* if we have printers, check if our request has been satisfied */
194 	if ((printers != NULL) && (*printers != NULL)) {
195 		int i;
196 
197 		/* walk through the list */
198 		for (i = 0; (*printers)[i] != NULL; i++) {
199 			printer_t *p = (*printers)[i];
200 
201 			/* see if the name service satisfied the request */
202 			if (contained(requested_attrs, p->attributes) == 0)
203 				printer_from_service(svc, p, requested_attrs);
204 		}
205 	}
206 
207 	return (PAPI_OK);
208 }
209 
210 papi_status_t
211 papiPrintersList(papi_service_t handle, char **requested_attrs,
212 		papi_filter_t *filter, papi_printer_t **printers)
213 {
214 	papi_status_t result = PAPI_INTERNAL_ERROR;
215 	service_t *svc = handle;
216 	papi_printer_t *svc_printers = NULL;
217 	papi_status_t (*f)();
218 
219 	if ((svc == NULL) || (printers == NULL))
220 		return (PAPI_BAD_ARGUMENT);
221 
222 	if (svc->so_handle != NULL)	/* connected, use the print svc */
223 		result = printers_from_service(svc, requested_attrs,
224 					filter, printers);
225 	else				/* not connected, use the name svc */
226 		result = printers_from_name_service(svc, requested_attrs,
227 					filter, printers);
228 
229 	return (result);
230 }
231 
232 papi_status_t
233 papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs,
234 		papi_attribute_t **job_attributes, papi_printer_t *printer)
235 {
236 	papi_status_t result = PAPI_INTERNAL_ERROR;
237 	service_t *svc = handle;
238 	printer_t *p = NULL;
239 	papi_status_t (*f)();
240 
241 	if ((svc == NULL) || (name == NULL) || (printer == NULL))
242 		return (PAPI_BAD_ARGUMENT);
243 
244 	if ((result = service_connect(svc, name)) != PAPI_OK)
245 		return (result);
246 
247 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
248 		return (PAPI_TEMPORARY_ERROR);
249 
250 	if ((svc->name != NULL) && (svc->svc_handle != NULL) &&
251 	    (svc->uri != NULL)) {
252 		p->svc = svc;
253 		f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery");
254 		if (f != NULL)
255 			result = f(svc->svc_handle, svc->name, requested_attrs,
256 					job_attributes, &p->printer);
257 	} else {
258 		setprinterentry(0, NULL);
259 		p->attributes = getprinterbyname(name, NULL);
260 		if (p->attributes == NULL)
261 			result = PAPI_NOT_FOUND;
262 		else
263 			result = PAPI_OK;
264 	}
265 
266 	return (result);
267 }
268 
269 static papi_status_t
270 _papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message,
271 		char *function)
272 {
273 	papi_status_t result = PAPI_INTERNAL_ERROR;
274 	service_t *svc = handle;
275 	papi_status_t (*f)();
276 
277 	if ((svc == NULL) || (name == NULL))
278 		return (PAPI_BAD_ARGUMENT);
279 
280 	if ((result = service_connect(svc, name)) != PAPI_OK)
281 		return (result);
282 
283 	f = (papi_status_t (*)())psm_sym(svc, function);
284 	if (f != NULL)
285 		result = f(svc->svc_handle, svc->name, message);
286 
287 	return (result);
288 }
289 
290 static papi_status_t
291 _papi_printer_enable_or_resume(papi_service_t handle, char *name,
292 		char *function)
293 {
294 	papi_status_t result = PAPI_INTERNAL_ERROR;
295 	service_t *svc = handle;
296 	papi_status_t (*f)();
297 
298 	if ((svc == NULL) || (name == NULL))
299 		return (PAPI_BAD_ARGUMENT);
300 
301 	if ((result = service_connect(svc, name)) != PAPI_OK)
302 		return (result);
303 
304 	f = (papi_status_t (*)())psm_sym(svc, function);
305 	if (f != NULL)
306 		result = f(svc->svc_handle, svc->name);
307 
308 	return (result);
309 }
310 
311 papi_status_t
312 papiPrinterDisable(papi_service_t handle, char *name, char *message)
313 {
314 	return (_papi_printer_disable_or_pause(handle, name, message,
315 						"papiPrinterDisable"));
316 }
317 
318 papi_status_t
319 papiPrinterPause(papi_service_t handle, char *name, char *message)
320 {
321 	return (_papi_printer_disable_or_pause(handle, name, message,
322 						"papiPrinterPause"));
323 }
324 
325 papi_status_t
326 papiPrinterEnable(papi_service_t handle, char *name)
327 {
328 	return (_papi_printer_enable_or_resume(handle, name,
329 						"papiPrinterEnable"));
330 }
331 
332 papi_status_t
333 papiPrinterResume(papi_service_t handle, char *name)
334 {
335 	return (_papi_printer_enable_or_resume(handle, name,
336 						"papiPrinterResume"));
337 }
338 
339 static papi_status_t
340 _papi_printer_add_or_modify(papi_service_t handle, char *name,
341 		papi_attribute_t **attributes, papi_printer_t *printer,
342 		char *function)
343 {
344 	papi_status_t result = PAPI_INTERNAL_ERROR;
345 	service_t *svc = handle;
346 	printer_t *p = NULL;
347 	papi_status_t (*f)();
348 
349 	if ((svc == NULL) || (name == NULL) || (attributes == NULL))
350 		return (PAPI_BAD_ARGUMENT);
351 
352 	if ((result = service_connect(svc, name)) != PAPI_OK)
353 		return (result);
354 
355 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
356 		return (PAPI_TEMPORARY_ERROR);
357 
358 	p->svc = svc;
359 	f = (papi_status_t (*)())psm_sym(p->svc, function);
360 	if (f != NULL)
361 		result = f(svc->svc_handle, svc->name, attributes,
362 				&p->printer);
363 
364 	return (result);
365 }
366 
367 papi_status_t
368 papiPrinterAdd(papi_service_t handle, char *name,
369 		papi_attribute_t **attributes, papi_printer_t *printer)
370 {
371 	return (_papi_printer_add_or_modify(handle, name, attributes, printer,
372 						"papiPrinterAdd"));
373 }
374 
375 papi_status_t
376 papiPrinterModify(papi_service_t handle, char *name,
377 		papi_attribute_t **attributes, papi_printer_t *printer)
378 {
379 	return (_papi_printer_add_or_modify(handle, name, attributes, printer,
380 						"papiPrinterModify"));
381 }
382 
383 
384 papi_status_t
385 papiPrinterRemove(papi_service_t handle, char *name)
386 {
387 	papi_status_t result = PAPI_INTERNAL_ERROR;
388 	service_t *svc = handle;
389 	papi_status_t (*f)();
390 
391 	if ((svc == NULL) || (name == NULL))
392 		return (PAPI_BAD_ARGUMENT);
393 
394 	if ((result = service_connect(svc, name)) != PAPI_OK)
395 		return (result);
396 
397 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove");
398 	if (f != NULL)
399 		result = f(svc->svc_handle, svc->name);
400 
401 	return (result);
402 }
403 
404 papi_status_t
405 papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs)
406 {
407 	papi_status_t result = PAPI_INTERNAL_ERROR;
408 	service_t *svc = handle;
409 	papi_job_t *svc_jobs = NULL;
410 	papi_status_t (*f)();
411 
412 	if ((svc == NULL) || (name == NULL))
413 		return (PAPI_BAD_ARGUMENT);
414 
415 	if ((result = service_connect(svc, name)) != PAPI_OK)
416 		return (result);
417 
418 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs");
419 	if (f != NULL)
420 		result = f(svc->svc_handle, svc->name, &svc_jobs);
421 
422 	/*
423 	 * copy the resulting job object pointers into our own
424 	 * representation of a job object because we need the
425 	 * service context to operate against the individual job
426 	 * objects.  We free the list now because we no longer need
427 	 * it and would have no way of freeing it later.
428 	 */
429 	if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) {
430 		int i;
431 
432 		*jobs = NULL;
433 		for (i = 0; svc_jobs[i] != NULL; i++) {
434 			job_t *j = NULL;
435 
436 			if ((j = calloc(1, sizeof (*j))) == NULL)
437 				return (PAPI_TEMPORARY_ERROR);
438 
439 			j->svc = svc;
440 			j->job = svc_jobs[i];
441 			list_append(jobs, j);
442 		}
443 		free(svc_jobs);
444 	}
445 
446 	return (result);
447 }
448 
449 papi_status_t
450 papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs,
451 		int type_mask, int max_num_jobs, papi_job_t **jobs)
452 {
453 	papi_status_t result = PAPI_INTERNAL_ERROR;
454 	service_t *svc = handle;
455 	papi_job_t *svc_jobs = NULL;
456 	papi_status_t (*f)();
457 
458 	if ((svc == NULL) || (name == NULL) || (jobs == NULL))
459 		return (PAPI_BAD_ARGUMENT);
460 
461 	if ((result = service_connect(svc, name)) != PAPI_OK)
462 		return (result);
463 
464 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs");
465 	if (f != NULL)
466 		result = f(svc->svc_handle, svc->name, requested_attrs,
467 				type_mask, max_num_jobs, &svc_jobs);
468 
469 	/*
470 	 * copy the resulting job object pointers into our own
471 	 * representation of a job object because we need the
472 	 * service context to operate against the individual job
473 	 * objects.  We free the list now because we no longer need
474 	 * it and would have no way of freeing it later.
475 	 */
476 	if ((result == PAPI_OK) && (svc_jobs != NULL)) {
477 		int i;
478 
479 		*jobs = NULL;
480 		for (i = 0; svc_jobs[i] != NULL; i++) {
481 			job_t *j = NULL;
482 
483 			if ((j = calloc(1, sizeof (*j))) == NULL)
484 				return (PAPI_TEMPORARY_ERROR);
485 
486 			j->svc = svc;
487 			j->job = svc_jobs[i];
488 			list_append(jobs, j);
489 		}
490 		free(svc_jobs);
491 	}
492 
493 	return (result);
494 }
495 
496 papi_attribute_t **
497 papiPrinterGetAttributeList(papi_printer_t printer)
498 {
499 	papi_attribute_t **result = NULL;
500 	printer_t *p = printer;
501 
502 	if ((p != NULL) && (p->printer != NULL)) {
503 		papi_attribute_t **(*f)();
504 
505 		f = (papi_attribute_t **(*)())psm_sym(p->svc,
506 					"papiPrinterGetAttributeList");
507 		if (f != NULL)
508 			result = f(p->printer);
509 	} else
510 		result = p->attributes;
511 
512 	return (result);
513 }
514