xref: /illumos-gate/usr/src/cmd/lp/lib/papi/printer.c (revision 4de2612967d06c4fdbf524a62556a1e8118a006f)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*LINTLIBRARY*/
30 
31 #include <stdlib.h>
32 #include <string.h>
33 #include <libintl.h>
34 #include <papi_impl.h>
35 #include <lp.h>
36 
37 extern int isclass(char *);
38 
39 void
40 papiPrinterFree(papi_printer_t printer)
41 {
42 	printer_t *tmp = printer;
43 
44 	if (tmp != NULL) {
45 		papiAttributeListFree(tmp->attributes);
46 		free(tmp);
47 	}
48 }
49 
50 void
51 papiPrinterListFree(papi_printer_t *printers)
52 {
53 	if (printers != NULL) {
54 		int i;
55 
56 		for (i = 0; printers[i] != NULL; i++)
57 			papiPrinterFree(printers[i]);
58 		free(printers);
59 	}
60 }
61 
62 papi_status_t
63 papiPrintersList(papi_service_t handle, const char **requested_attrs,
64 		const papi_filter_t *filter, papi_printer_t **printers)
65 {
66 	service_t *svc = handle;
67 	printer_t *p = NULL;
68 	short status = MOK;
69 	char *printer = NULL,
70 		*form = NULL,
71 		*request_id = NULL,
72 		*character_set = NULL,
73 		*reject_reason = NULL,
74 		*disable_reason = NULL;
75 	short printer_status = 0;
76 	long enable_date = 0, reject_date = 0;
77 
78 	if ((handle == NULL) || (printers == NULL))
79 		return (PAPI_BAD_ARGUMENT);
80 
81 	if ((filter == NULL) ||
82 	    ((filter->filter.bitmask.mask & PAPI_PRINTER_LOCAL) ==
83 	    (filter->filter.bitmask.value & PAPI_PRINTER_LOCAL))) {
84 		/* ask the spooler for the printer(s) and state */
85 		if (snd_msg(svc, S_INQUIRE_PRINTER_STATUS, NAME_ALL) < 0)
86 			return (PAPI_SERVICE_UNAVAILABLE);
87 
88 		do {
89 			if (rcv_msg(svc, R_INQUIRE_PRINTER_STATUS, &status,
90 					&printer, &form, &character_set,
91 					&disable_reason, &reject_reason,
92 					&printer_status, &request_id,
93 					&enable_date, &reject_date) < 0)
94 				return (PAPI_SERVICE_UNAVAILABLE);
95 
96 			if ((p = calloc(1, sizeof (*p))) == NULL)
97 				return (PAPI_TEMPORARY_ERROR);
98 
99 			lpsched_printer_configuration_to_attributes(svc, p,
100 					printer);
101 
102 			printer_status_to_attributes(p, printer, form,
103 					character_set, disable_reason,
104 					reject_reason, printer_status,
105 					request_id, enable_date, reject_date);
106 
107 			list_append(printers, p);
108 
109 		} while (status == MOKMORE);
110 	}
111 
112 	if ((filter == NULL) ||
113 	    ((filter->filter.bitmask.mask & PAPI_PRINTER_CLASS) ==
114 	    (filter->filter.bitmask.value & PAPI_PRINTER_CLASS))) {
115 		/* ask the spooler for the class(es) and state */
116 		if (snd_msg(svc, S_INQUIRE_CLASS, NAME_ALL) < 0)
117 			return (PAPI_SERVICE_UNAVAILABLE);
118 
119 		do {
120 			if (rcv_msg(svc, R_INQUIRE_CLASS, &status, &printer,
121 					&printer_status, &reject_reason,
122 					&reject_date) < 0)
123 				return (PAPI_SERVICE_UNAVAILABLE);
124 
125 			if ((p = calloc(1, sizeof (*p))) == NULL)
126 				return (PAPI_TEMPORARY_ERROR);
127 
128 			lpsched_class_configuration_to_attributes(svc, p,
129 					printer);
130 
131 			class_status_to_attributes(p, printer, printer_status,
132 					reject_reason, reject_date);
133 
134 			list_append(printers, p);
135 
136 		} while (status == MOKMORE);
137 	}
138 
139 	return (PAPI_OK);
140 }
141 
142 papi_status_t
143 papiPrinterQuery(papi_service_t handle, const char *name,
144 		const char **requested_attrs,
145 		const papi_attribute_t **job_attrs,
146 		papi_printer_t *printer)
147 {
148 	papi_status_t pst;
149 	service_t *svc = handle;
150 	printer_t *p = NULL;
151 	char *dest;
152 	short status = MOK;
153 	char *pname = NULL,
154 		*form = NULL,
155 		*request_id = NULL,
156 		*character_set = NULL,
157 		*reject_reason = NULL,
158 		*disable_reason = NULL;
159 	short printer_status = 0;
160 	long enable_date = 0, reject_date = 0;
161 
162 	if ((handle == NULL) || (name == NULL) || (printer == NULL))
163 		return (PAPI_BAD_ARGUMENT);
164 
165 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
166 		return (PAPI_TEMPORARY_ERROR);
167 
168 	dest = printer_name_from_uri_id(name, -1);
169 
170 	if (isprinter(dest) != 0) {
171 		pst = lpsched_printer_configuration_to_attributes(svc, p, dest);
172 		if (pst != PAPI_OK)
173 			return (pst);
174 
175 		/* get the spooler status data now */
176 		if (snd_msg(svc, S_INQUIRE_PRINTER_STATUS, dest) < 0)
177 			return (PAPI_SERVICE_UNAVAILABLE);
178 
179 		if (rcv_msg(svc, R_INQUIRE_PRINTER_STATUS, &status, &pname,
180 				&form, &character_set, &disable_reason,
181 				&reject_reason, &printer_status, &request_id,
182 				&enable_date, &reject_date) < 0)
183 			return (PAPI_SERVICE_UNAVAILABLE);
184 
185 		printer_status_to_attributes(p, pname, form, character_set,
186 				disable_reason, reject_reason, printer_status,
187 				request_id, enable_date, reject_date);
188 	} else if (isclass(dest) != 0) {
189 		pst = lpsched_class_configuration_to_attributes(svc, p, dest);
190 		if (pst != PAPI_OK)
191 			return (pst);
192 
193 		/* get the spooler status data now */
194 		if (snd_msg(svc, S_INQUIRE_CLASS, dest) < 0)
195 			return (PAPI_SERVICE_UNAVAILABLE);
196 
197 		if (rcv_msg(svc, R_INQUIRE_CLASS, &status, &pname,
198 				&printer_status, &reject_reason,
199 				&reject_date) < 0)
200 			return (PAPI_SERVICE_UNAVAILABLE);
201 
202 		class_status_to_attributes(p, pname, printer_status,
203 				reject_reason, reject_date);
204 	} else if (strcmp(dest, "PrintService") == 0) {
205 		/* fill the printer object with service information */
206 		lpsched_service_information(p);
207 	} else
208 		return (PAPI_NOT_FOUND);
209 
210 	free(dest);
211 
212 	return (PAPI_OK);
213 }
214 
215 papi_status_t
216 papiPrinterModify(papi_service_t handle, const char *name,
217 		const papi_attribute_t **attributes, papi_printer_t *result)
218 {
219 	service_t *svc = handle;
220 
221 	if ((svc == NULL) || (name == NULL) || (attributes == NULL))
222 		return (PAPI_BAD_ARGUMENT);
223 
224 	return (PAPI_OPERATION_NOT_SUPPORTED);
225 }
226 
227 papi_status_t
228 papiPrinterPause(papi_service_t handle, const char *name, const char *message)
229 {
230 	papi_status_t result;
231 
232 	if ((handle == NULL) || (name == NULL))
233 		return (PAPI_BAD_ARGUMENT);
234 
235 	result = lpsched_disable_printer(handle, name, message);
236 
237 	return (result);
238 }
239 
240 papi_status_t
241 papiPrinterResume(papi_service_t handle, const char *name)
242 {
243 	papi_status_t result;
244 
245 	if ((handle == NULL) || (name == NULL))
246 		return (PAPI_BAD_ARGUMENT);
247 
248 	result = lpsched_enable_printer(handle, name);
249 
250 	return (result);
251 }
252 
253 papi_status_t
254 papiPrinterPurgeJobs(papi_service_t handle, const char *name, papi_job_t **jobs)
255 {
256 	service_t *svc = handle;
257 	papi_status_t result = PAPI_OK_SUBST;
258 	short more;
259 	long status;
260 	char *dest;
261 	char *req_id;
262 
263 	if ((handle == NULL) || (name == NULL))
264 		return (PAPI_BAD_ARGUMENT);
265 
266 	dest = printer_name_from_uri_id(name, -1);
267 	if (snd_msg(svc, S_CANCEL, dest, "", "") < 0)
268 		return (PAPI_SERVICE_UNAVAILABLE);
269 
270 	free(dest);
271 
272 	do {
273 		if (rcv_msg(svc, R_CANCEL, &more, &status, &req_id) < 0)
274 			return (PAPI_SERVICE_UNAVAILABLE);
275 
276 	switch (status) {
277 	case MOK:
278 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
279 				"canceled-jobs", req_id);
280 		break;
281 	case M2LATE:
282 	case MUNKNOWN:
283 	case MNOINFO:
284 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
285 				"cancel-failed", req_id);
286 		result = PAPI_DEVICE_ERROR;
287 		break;
288 	case MNOPERM:
289 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
290 				"cancel-failed", req_id);
291 		result = PAPI_NOT_AUTHORIZED;
292 		break;
293 	default:
294 		detailed_error(svc, gettext("cancel failed, bad status (%d)\n"),
295 			status);
296 		return (PAPI_DEVICE_ERROR);
297 	}
298 	} while (more == MOKMORE);
299 
300 	return (result);
301 }
302 
303 papi_status_t
304 papiPrinterListJobs(papi_service_t handle, const char *name,
305 		const char **requested_attrs, const int type_mask,
306 		const int max_num_jobs, papi_job_t **jobs)
307 {
308 	service_t *svc = handle;
309 	char *dest;
310 	short rc;
311 	int count = 1;
312 
313 	if ((handle == NULL) || (name == NULL) || (jobs == NULL))
314 		return (PAPI_BAD_ARGUMENT);
315 
316 	dest = printer_name_from_uri_id(name, -1);
317 
318 	rc = snd_msg(svc, S_INQUIRE_REQUEST_RANK, 0, "", dest, "", "", "");
319 	free(dest);
320 	if (rc < 0)
321 		return (PAPI_SERVICE_UNAVAILABLE);
322 
323 	do {
324 		job_t *job = NULL;
325 		char *dest = NULL,
326 			*ptr,
327 			*form = NULL,
328 			*req_id = NULL,
329 			*charset = NULL,
330 			*owner = 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, &size, &date, &state, &dest, &form,
338 				&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, size, date, state,
356 				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