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