xref: /illumos-gate/usr/src/cmd/lp/lib/papi/printer.c (revision 03831d35)
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  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*LINTLIBRARY*/
29 
30 #include <stdlib.h>
31 #include <string.h>
32 #include <libintl.h>
33 #include <papi_impl.h>
34 #include <lp.h>
35 
36 extern int isclass(char *);
37 
38 void
39 papiPrinterFree(papi_printer_t printer)
40 {
41 	printer_t *tmp = printer;
42 
43 	if (tmp != NULL) {
44 		papiAttributeListFree(tmp->attributes);
45 		free(tmp);
46 	}
47 }
48 
49 void
50 papiPrinterListFree(papi_printer_t *printers)
51 {
52 	if (printers != NULL) {
53 		int i;
54 
55 		for (i = 0; printers[i] != NULL; i++)
56 			papiPrinterFree(printers[i]);
57 		free(printers);
58 	}
59 }
60 
61 papi_status_t
62 papiPrintersList(papi_service_t handle, const char **requested_attrs,
63 		const papi_filter_t *filter, papi_printer_t **printers)
64 {
65 	service_t *svc = handle;
66 	printer_t *p = NULL;
67 	short status = MOK;
68 	char *printer = NULL,
69 		*form = NULL,
70 		*request_id = NULL,
71 		*character_set = NULL,
72 		*reject_reason = NULL,
73 		*disable_reason = NULL;
74 	short printer_status = 0;
75 	long enable_date = 0, reject_date = 0;
76 
77 	if ((handle == NULL) || (printers == NULL))
78 		return (PAPI_BAD_ARGUMENT);
79 
80 	if ((filter == NULL) ||
81 	    ((filter->filter.bitmask.mask & PAPI_PRINTER_LOCAL) ==
82 	    (filter->filter.bitmask.value & PAPI_PRINTER_LOCAL))) {
83 		/* ask the spooler for the printer(s) and state */
84 		if (snd_msg(svc, S_INQUIRE_PRINTER_STATUS, NAME_ALL) < 0)
85 			return (PAPI_SERVICE_UNAVAILABLE);
86 
87 		do {
88 			if (rcv_msg(svc, R_INQUIRE_PRINTER_STATUS, &status,
89 					&printer, &form, &character_set,
90 					&disable_reason, &reject_reason,
91 					&printer_status, &request_id,
92 					&enable_date, &reject_date) < 0)
93 				return (PAPI_SERVICE_UNAVAILABLE);
94 
95 			if ((p = calloc(1, sizeof (*p))) == NULL)
96 				return (PAPI_TEMPORARY_ERROR);
97 
98 			lpsched_printer_configuration_to_attributes(svc, p,
99 					printer);
100 
101 			printer_status_to_attributes(p, printer, form,
102 					character_set, disable_reason,
103 					reject_reason, printer_status,
104 					request_id, enable_date, reject_date);
105 
106 			list_append(printers, p);
107 
108 		} while (status == MOKMORE);
109 	}
110 
111 	if ((filter == NULL) ||
112 	    ((filter->filter.bitmask.mask & PAPI_PRINTER_CLASS) ==
113 	    (filter->filter.bitmask.value & PAPI_PRINTER_CLASS))) {
114 		/* ask the spooler for the class(es) and state */
115 		if (snd_msg(svc, S_INQUIRE_CLASS, NAME_ALL) < 0)
116 			return (PAPI_SERVICE_UNAVAILABLE);
117 
118 		do {
119 			if (rcv_msg(svc, R_INQUIRE_CLASS, &status, &printer,
120 					&printer_status, &reject_reason,
121 					&reject_date) < 0)
122 				return (PAPI_SERVICE_UNAVAILABLE);
123 
124 			if ((p = calloc(1, sizeof (*p))) == NULL)
125 				return (PAPI_TEMPORARY_ERROR);
126 
127 			lpsched_class_configuration_to_attributes(svc, p,
128 					printer);
129 
130 			class_status_to_attributes(p, printer, printer_status,
131 					reject_reason, reject_date);
132 
133 			list_append(printers, p);
134 
135 		} while (status == MOKMORE);
136 	}
137 
138 	return (PAPI_OK);
139 }
140 
141 papi_status_t
142 papiPrinterQuery(papi_service_t handle, const char *name,
143 		const char **requested_attrs,
144 		const papi_attribute_t **job_attrs,
145 		papi_printer_t *printer)
146 {
147 	papi_status_t pst;
148 	service_t *svc = handle;
149 	printer_t *p = NULL;
150 	char *dest;
151 	short status = MOK;
152 	char *pname = NULL,
153 		*form = NULL,
154 		*request_id = NULL,
155 		*character_set = NULL,
156 		*reject_reason = NULL,
157 		*disable_reason = NULL;
158 	short printer_status = 0;
159 	long enable_date = 0, reject_date = 0;
160 
161 	if ((handle == NULL) || (name == NULL) || (printer == NULL))
162 		return (PAPI_BAD_ARGUMENT);
163 
164 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
165 		return (PAPI_TEMPORARY_ERROR);
166 
167 	dest = printer_name_from_uri_id(name, -1);
168 
169 	if (isprinter(dest) != 0) {
170 		pst = lpsched_printer_configuration_to_attributes(svc, p, dest);
171 		if (pst != PAPI_OK)
172 			return (pst);
173 
174 		/* get the spooler status data now */
175 		if (snd_msg(svc, S_INQUIRE_PRINTER_STATUS, dest) < 0)
176 			return (PAPI_SERVICE_UNAVAILABLE);
177 
178 		if (rcv_msg(svc, R_INQUIRE_PRINTER_STATUS, &status, &pname,
179 				&form, &character_set, &disable_reason,
180 				&reject_reason, &printer_status, &request_id,
181 				&enable_date, &reject_date) < 0)
182 			return (PAPI_SERVICE_UNAVAILABLE);
183 
184 		printer_status_to_attributes(p, pname, form, character_set,
185 				disable_reason, reject_reason, printer_status,
186 				request_id, enable_date, reject_date);
187 	} else if (isclass(dest) != 0) {
188 		pst = lpsched_class_configuration_to_attributes(svc, p, dest);
189 		if (pst != PAPI_OK)
190 			return (pst);
191 
192 		/* get the spooler status data now */
193 		if (snd_msg(svc, S_INQUIRE_CLASS, dest) < 0)
194 			return (PAPI_SERVICE_UNAVAILABLE);
195 
196 		if (rcv_msg(svc, R_INQUIRE_CLASS, &status, &pname,
197 				&printer_status, &reject_reason,
198 				&reject_date) < 0)
199 			return (PAPI_SERVICE_UNAVAILABLE);
200 
201 		class_status_to_attributes(p, pname, printer_status,
202 				reject_reason, reject_date);
203 	} else if (strcmp(dest, "PrintService") == 0) {
204 		/* fill the printer object with service information */
205 		lpsched_service_information(p);
206 	} else
207 		return (PAPI_NOT_FOUND);
208 
209 	free(dest);
210 
211 	return (PAPI_OK);
212 }
213 
214 papi_status_t
215 papiPrinterModify(papi_service_t handle, const char *name,
216 		const papi_attribute_t **attributes, papi_printer_t *result)
217 {
218 	service_t *svc = handle;
219 
220 	if ((svc == NULL) || (name == NULL) || (attributes == NULL))
221 		return (PAPI_BAD_ARGUMENT);
222 
223 	return (PAPI_OPERATION_NOT_SUPPORTED);
224 }
225 
226 papi_status_t
227 papiPrinterPause(papi_service_t handle, const char *name, const char *message)
228 {
229 	papi_status_t result;
230 
231 	if ((handle == NULL) || (name == NULL))
232 		return (PAPI_BAD_ARGUMENT);
233 
234 	result = lpsched_disable_printer(handle, name, message);
235 
236 	return (result);
237 }
238 
239 papi_status_t
240 papiPrinterResume(papi_service_t handle, const char *name)
241 {
242 	papi_status_t result;
243 
244 	if ((handle == NULL) || (name == NULL))
245 		return (PAPI_BAD_ARGUMENT);
246 
247 	result = lpsched_enable_printer(handle, name);
248 
249 	return (result);
250 }
251 
252 papi_status_t
253 papiPrinterPurgeJobs(papi_service_t handle, const char *name, papi_job_t **jobs)
254 {
255 	service_t *svc = handle;
256 	papi_status_t result = PAPI_OK_SUBST;
257 	short more;
258 	long status;
259 	char *dest;
260 	char *req_id;
261 
262 	if ((handle == NULL) || (name == NULL))
263 		return (PAPI_BAD_ARGUMENT);
264 
265 	dest = printer_name_from_uri_id(name, -1);
266 	if (snd_msg(svc, S_CANCEL, dest, "", "") < 0)
267 		return (PAPI_SERVICE_UNAVAILABLE);
268 
269 	free(dest);
270 
271 	do {
272 		if (rcv_msg(svc, R_CANCEL, &more, &status, &req_id) < 0)
273 			return (PAPI_SERVICE_UNAVAILABLE);
274 
275 	switch (status) {
276 	case MOK:
277 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
278 				"canceled-jobs", req_id);
279 		break;
280 	case M2LATE:
281 	case MUNKNOWN:
282 	case MNOINFO:
283 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
284 				"cancel-failed", req_id);
285 		result = PAPI_DEVICE_ERROR;
286 		break;
287 	case MNOPERM:
288 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
289 				"cancel-failed", req_id);
290 		result = PAPI_NOT_AUTHORIZED;
291 		break;
292 	default:
293 		detailed_error(svc, gettext("cancel failed, bad status (%d)\n"),
294 			status);
295 		return (PAPI_DEVICE_ERROR);
296 	}
297 	} while (more == MOKMORE);
298 
299 	return (result);
300 }
301 
302 papi_status_t
303 papiPrinterListJobs(papi_service_t handle, const char *name,
304 		const char **requested_attrs, const int type_mask,
305 		const int max_num_jobs, papi_job_t **jobs)
306 {
307 	service_t *svc = handle;
308 	char *dest;
309 	short rc;
310 	int count = 1;
311 
312 	if ((handle == NULL) || (name == NULL) || (jobs == NULL))
313 		return (PAPI_BAD_ARGUMENT);
314 
315 	dest = printer_name_from_uri_id(name, -1);
316 
317 	rc = snd_msg(svc, S_INQUIRE_REQUEST_RANK, 0, "", dest, "", "", "");
318 	free(dest);
319 	if (rc < 0)
320 		return (PAPI_SERVICE_UNAVAILABLE);
321 
322 	do {
323 		job_t *job = NULL;
324 		char *dest = NULL,
325 			*ptr,
326 			*form = NULL,
327 			*req_id = NULL,
328 			*charset = NULL,
329 			*owner = NULL,
330 			*slabel = NULL,
331 			*file = NULL;
332 		time_t date = 0;
333 		size_t size = 0;
334 		short  rank = 0, state = 0;
335 
336 		if (rcv_msg(svc, R_INQUIRE_REQUEST_RANK, &rc, &req_id,
337 				&owner, &slabel, &size, &date, &state, &dest,
338 				&form, &charset, &rank, &file) < 0)
339 			return (PAPI_SERVICE_UNAVAILABLE);
340 
341 		if ((rc != MOK) && (rc != MOKMORE))
342 			continue;
343 		/*
344 		 * at this point, we should check to see if the job matches the
345 		 * selection criterion defined in "type_mask".
346 		 */
347 
348 		/* too many yet? */
349 		if ((max_num_jobs != 0) && (count++ > max_num_jobs))
350 			continue;
351 
352 		if ((job = calloc(1, sizeof (*job))) == NULL)
353 			continue;
354 
355 		job_status_to_attributes(job, req_id, owner, slabel, size,
356 				date, state, dest, form, charset, rank, file);
357 
358 		if ((ptr = strrchr(file, '-')) != NULL) {
359 			*++ptr = '0';
360 			*++ptr = NULL;
361 		}
362 
363 		lpsched_read_job_configuration(svc, job, file);
364 
365 		list_append(jobs, job);
366 
367 	} while (rc == MOKMORE);
368 
369 	if (rc == MNOINFO)	/* If no jobs are found, it's still ok */
370 		rc = MOK;
371 
372 	return (lpsched_status_to_papi_status(rc));
373 }
374 
375 papi_attribute_t **
376 papiPrinterGetAttributeList(papi_printer_t printer)
377 {
378 	printer_t *tmp = printer;
379 
380 	if (tmp == NULL)
381 		return (NULL);
382 
383 	return (tmp->attributes);
384 }
385