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 2010 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26/*LINTLIBRARY*/
27
28#include <stdlib.h>
29#include <libintl.h>
30#include <unistd.h>
31#include <string.h>
32#include <sys/utsname.h>
33#include <papi_impl.h>
34
35#include "class.h"
36
37void
38lpsched_printer_status_to_attributes(papi_attribute_t ***attrs,
39	unsigned short status)
40{
41	if (attrs == NULL)
42		return;
43
44	if (!(status & (PS_DISABLED|PS_LATER))) {
45		if (status & PS_FAULTED) {
46			if (status & PS_BUSY)
47				/* faulted printing */
48				papiAttributeListAddInteger(attrs,
49				    PAPI_ATTR_REPLACE,
50				    "printer-state", 0x06);
51			else
52				/* faulted printer */
53				papiAttributeListAddInteger(attrs,
54				    PAPI_ATTR_REPLACE,
55				    "printer-state", 0x07);
56
57			papiAttributeListAddString(attrs, PAPI_ATTR_REPLACE,
58			    "printer-state-reasons", "none");
59		} else if (status & PS_BUSY) {
60			papiAttributeListAddInteger(attrs, PAPI_ATTR_REPLACE,
61			    "printer-state", 0x04); /* processing */
62			papiAttributeListAddString(attrs, PAPI_ATTR_REPLACE,
63			    "printer-state-reasons", "moving-to-paused");
64		} else if (status & PS_FORM_FAULT) {
65			papiAttributeListAddInteger(attrs, PAPI_ATTR_REPLACE,
66			    "printer-state", 0x05); /* stopped */
67			papiAttributeListAddString(attrs, PAPI_ATTR_REPLACE,
68			    "printer-state-reasons",
69			    "interpreter-resource-unavailable");
70		} else
71			papiAttributeListAddInteger(attrs, PAPI_ATTR_REPLACE,
72			    "printer-state", 0x03); /* idle */
73	} else if (status & PS_DISABLED) {
74		papiAttributeListAddInteger(attrs, PAPI_ATTR_REPLACE,
75		    "printer-state", 0x05); /* stopped */
76		papiAttributeListAddString(attrs, PAPI_ATTR_REPLACE,
77		    "printer-state-reasons", "paused");
78	} else if (status & PS_LATER) {
79		papiAttributeListAddInteger(attrs, PAPI_ATTR_REPLACE,
80		    "printer-state", 0x08); /* waiting for auto reply */
81		papiAttributeListAddString(attrs, PAPI_ATTR_REPLACE,
82		    "printer-state-reasons", "moving-to-paused");
83	} else {
84		papiAttributeListAddInteger(attrs, PAPI_ATTR_REPLACE,
85		    "printer-state", 0x03); /* idle */
86	}
87
88	papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
89	    "printer-is-accepting-jobs",
90	    ((status & PS_REJECTED) != PS_REJECTED));
91	papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
92	    "printer-is-processing-jobs",
93	    ((status & PS_DISABLED) != PS_DISABLED));
94}
95
96void
97lpsched_printer_defaults(papi_attribute_t ***attributes)
98{
99	if (attributes == NULL)
100		return;
101
102	papiAttributeListAddBoolean(attributes, PAPI_ATTR_REPLACE,
103	    "multiple-document-jobs-supported", PAPI_TRUE);
104	papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
105	    "multiple-document-handling-supported",
106	    "seperate-documents-colated-copies");
107	papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
108	    "pdl-override-supported", "not-attempted");
109	papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
110	    "job-priority-supported", 40);
111	papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
112	    "job-priority-default", 20);
113	papiAttributeListAddRange(attributes, PAPI_ATTR_REPLACE,
114	    "copies-supported", 1, 65535);
115	papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
116	    "copies-default", 1);
117	papiAttributeListAddBoolean(attributes, PAPI_ATTR_REPLACE,
118	    "page-ranges-supported", PAPI_TRUE);
119	papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
120	    "number-up-supported", 1);
121	papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
122	    "number-up-default", 1);
123	papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
124	    "job-hold-until-supported", "no-hold");
125	papiAttributeListAddString(attributes, PAPI_ATTR_APPEND,
126	    "job-hold-until-supported", "indefinite");
127	papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
128	    "job-hold-until-default", "no-hold");
129	papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
130	    "document-format-default", "application/octet-stream");
131
132}
133
134papi_status_t
135lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p,
136	char *dest)
137{
138	PRINTER *tmp;
139	char buf[BUFSIZ+1];
140	struct utsname sysname;
141	char **allowed = NULL, **denied = NULL;
142	char **f_allowed = NULL, **f_denied = NULL;
143
144	if ((svc == NULL) || (p == NULL) || (dest == NULL))
145		return (PAPI_BAD_ARGUMENT);
146
147	/* get the configuration DB data */
148	if ((tmp = getprinter(dest)) == NULL) {
149		detailed_error(svc,
150		    gettext("unable to read configuration data"));
151		return (PAPI_DEVICE_ERROR);
152	}
153
154	/* name */
155	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
156	"printer-name", tmp->name);
157	if (tmp->name != NULL) {
158		char uri[BUFSIZ];
159
160		snprintf(uri, sizeof (uri), "lpsched://localhost/printers/%s",
161		    tmp->name);
162		papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE,
163		    "printer-uri-supported", uri);
164	}
165
166	/* banner */
167	if ((tmp->banner & BAN_OPTIONAL) == BAN_OPTIONAL)
168		papiAttributeListAddString(&p->attributes, PAPI_ATTR_APPEND,
169		    "job-sheets-supported", "optional");
170	else if (tmp->banner & BAN_NEVER)
171		papiAttributeListAddString(&p->attributes, PAPI_ATTR_APPEND,
172		    "job-sheets-supported", "none");
173	else if (tmp->banner & BAN_ALWAYS)
174		papiAttributeListAddString(&p->attributes, PAPI_ATTR_APPEND,
175		    "job-sheets-supported", "standard");
176
177	/* input_types */
178	if (tmp->input_types != NULL) {
179		int i;
180
181		for (i = 0; tmp->input_types[i] != NULL; i++)
182			papiAttributeListAddLPString(&p->attributes,
183			    PAPI_ATTR_APPEND, "document-format-supported",
184			    lp_type_to_mime_type(tmp->input_types[i]));
185	}
186
187	/* description */
188	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
189	    "printer-info", tmp->description);
190
191	/* add lpsched specific attributes */
192	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
193	    "device-uri", tmp->device);
194	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
195	    "lpsched-dial-info", tmp->dial_info);
196	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
197	    "lpsched-fault-recovery", tmp->fault_rec);
198	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
199	    "lpsched-interface-script", tmp->interface);
200	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
201	    "lpsched-data-rate", tmp->speed);
202	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
203	    "lpsched-stty", tmp->stty);
204	papiAttributeListAddBoolean(&p->attributes, PAPI_ATTR_REPLACE,
205	    "lpsched-login-term", tmp->login);
206	papiAttributeListAddBoolean(&p->attributes, PAPI_ATTR_REPLACE,
207	    "lpsched-daisy", tmp->daisy);
208	papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
209	    "lpsched-charsets", tmp->char_sets);
210#ifdef CAN_DO_MODULES
211	papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
212	    "lpsched-modules", tmp->modules);
213#endif /* CAN_DO_MODULES */
214	papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
215	    "lpsched-options", tmp->options);
216	papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
217	    "lpsched-printer-type", tmp->printer_types);
218	if (tmp->fault_alert.shcmd != NULL) {
219		papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
220		    "lpsched-fault-alert-command",
221		    tmp->fault_alert.shcmd);
222		papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
223		    "lpsched-fault-alert-threshold",
224		    tmp->fault_alert.Q);
225		papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
226		    "lpsched-fault-alert-interval",
227		    tmp->fault_alert.W);
228	}
229	papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
230	    "lpsched-cpi-value", tmp->cpi.val);
231	papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
232	    "lpsched-cpi-unit", tmp->cpi.sc);
233	papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
234	    "lpsched-lpi-value", tmp->lpi.val);
235	papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
236	    "lpsched-lpi-unit", tmp->lpi.sc);
237	papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
238	    "lpsched-plen-value", tmp->plen.val);
239	papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
240	    "lpsched-plen-unit", tmp->plen.sc);
241	papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
242	    "lpsched-pwid-value", tmp->pwid.val);
243	papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
244	    "lpsched-pwid-unit", tmp->pwid.sc);
245
246	/* allow/deny list */
247	load_userprinter_access(dest, &allowed, &denied);
248	papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
249	    "requesting-user-name-allowed", allowed);
250	papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
251	    "requesting-user-name-denied", denied);
252
253	freelist(allowed);
254	freelist(denied);
255
256	/* forms allow/deny list */
257	load_formprinter_access(dest, &f_allowed, &f_denied);
258	papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
259	    "form-supported", f_allowed);
260
261	/*
262	 * All forms allowed case
263	 * When all forms are allowed forms.allow does not get created but
264	 * forms.deny file gets created with no entries
265	 */
266	if ((f_allowed == NULL) && (f_denied != NULL) && (f_denied[0] == NULL))
267		papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
268		    "form-supported", "all");
269
270	freelist(f_allowed);
271	freelist(f_denied);
272
273#ifdef LP_USE_PAPI_ATTR
274	if (tmp->ppd != NULL) {
275		int fd;
276		struct stat sbuf;
277
278		/* construct the two URIs for the printer's PPD file */
279		if (uname(&sysname) < 0) {
280			/* failed to get systen name */
281			sysname.nodename[0] = 0;
282		}
283		snprintf(buf, sizeof (buf), "file://%s%s/ppd/%s.ppd",
284		    sysname.nodename, ETCDIR, tmp->name);
285		papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE,
286		    "ppd-file-uri", buf);
287
288		snprintf(buf, sizeof (buf), "file://%s%s",
289		    sysname.nodename, tmp->ppd);
290		papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE,
291		    "lpsched-printer-configure-ppd-uri", buf);
292		papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE,
293		    "lpsched-ppd-source-path", tmp->ppd);
294
295		snprintf(buf, sizeof (buf), "%s/ppd/%s.ppd", ETCDIR, tmp->name);
296
297		/*
298		 * We don't return error on any of the error conditions, we just
299		 * silently return without adding the attribute.
300		 */
301		PPDFileToAttributesList(&p->attributes, buf);
302	}
303#endif
304
305	freeprinter(tmp);
306
307	return (PAPI_OK);
308}
309
310papi_status_t
311printer_status_to_attributes(printer_t *p, char *printer, char *form,
312		char *character_set, char *disable_reason, char *reject_reason,
313		short status, char *request_id,
314		long disable_date, long reject_date)
315{
316	if (p == NULL)
317		return (PAPI_BAD_ARGUMENT);
318
319	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
320	    "form-ready", form);
321	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
322	    "lpsched-active-job", request_id);
323	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
324	    "lpsched-mounted-char-set", character_set);
325	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
326	    "lpsched-disable-reason", disable_reason);
327	papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE,
328	    "lpsched-disable-date", disable_date);
329	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
330	    "lpsched-reject-reason", reject_reason);
331	papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE,
332	    "lpsched-reject-date", reject_date);
333
334	/* add the current system time */
335	papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE,
336	    "printer-current-time", time(NULL));
337
338	/* add the time since last enabled */
339	papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
340	    "printer-up-time", time(NULL));
341
342	/* add the status information */
343	lpsched_printer_status_to_attributes(&p->attributes, status);
344
345	papiAttributeListAddString(&p->attributes, PAPI_ATTR_EXCL,
346	    "printer-state-reasons", "none");
347
348	lpsched_printer_defaults(&p->attributes);
349
350	return (PAPI_OK);
351}
352
353
354/*
355 * This puts the class information in only.  It could create a hybrid
356 * printer object to return, but that is problematic at best.
357 */
358papi_status_t
359lpsched_class_configuration_to_attributes(service_t *svc, printer_t *p,
360	char *dest)
361{
362	CLASS *tmp;
363
364	if ((svc == NULL) || (p == NULL))
365		return (PAPI_BAD_ARGUMENT);
366
367	/* get the configuration DB data */
368	if ((tmp = getclass(dest)) == NULL) {
369		detailed_error(svc,
370		    gettext("unable to read configuration data"));
371		return (PAPI_DEVICE_ERROR);
372	}
373
374	/* name */
375	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
376	    "printer-name", tmp->name);
377	if (tmp->name != NULL) {
378		char uri[BUFSIZ];
379
380		snprintf(uri, sizeof (uri), "lpsched://localhost/printers/%s",
381		    tmp->name);
382		papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE,
383		    "printer-uri-supported", uri);
384	}
385
386	if (tmp->members != NULL) {
387		char **members = tmp->members;
388		int i;
389
390		for (i = 0; members[i] != NULL; i++)
391			papiAttributeListAddString(&p->attributes,
392			    PAPI_ATTR_APPEND,
393			    "member-names", members[i]);
394	}
395
396	freeclass(tmp);
397
398	return (PAPI_OK);
399}
400
401papi_status_t
402class_status_to_attributes(printer_t *p, char *printer, short status,
403		char *reject_reason, long reject_date)
404{
405	if (p == NULL)
406		return (PAPI_BAD_ARGUMENT);
407
408	papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
409	    "lpsched-reject-reason", reject_reason);
410	papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE,
411	    "lpsched-reject-date", reject_date);
412
413	/* add the current system time */
414	papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE,
415	    "printer-current-time", time(NULL));
416
417	papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
418	    "printer-up-time", time(NULL));
419
420	/* add the status information */
421	lpsched_printer_status_to_attributes(&p->attributes, status);
422
423	papiAttributeListAddString(&p->attributes, PAPI_ATTR_EXCL,
424	    "printer-state-reasons", "none");
425
426	lpsched_printer_defaults(&p->attributes);
427
428	return (PAPI_OK);
429}
430
431papi_status_t
432attributes_to_printer(papi_attribute_t **attributes, PRINTER *tmp)
433{
434	papi_status_t status;
435	void *iter = NULL;
436	char *string = NULL;
437	int flags;
438	char **list = NULL;
439
440	/* banner needs some conversion to the bitfield */
441	iter = NULL, string = NULL; flags = 0;
442	for (status = papiAttributeListGetString(attributes, &iter,
443	    "job-sheets-supported", &string);
444	    status == PAPI_OK;
445	    status = papiAttributeListGetString(attributes, &iter,
446	    NULL, &string))
447		if (strcasecmp(string, "none") == 0)
448			flags |= BAN_NEVER;
449		else if (strcasecmp(string, "standard") == 0)
450			flags |= BAN_ALWAYS;
451	if (flags != 0)
452		tmp->banner = flags;
453
454	/* input_types needs mime-type conversion */
455	iter = NULL, string = NULL; list = NULL;
456	for (status = papiAttributeListGetString(attributes, &iter,
457	    "document-format-supported", &string);
458	    status == PAPI_OK;
459	    status = papiAttributeListGetString(attributes, &iter,
460	    NULL, &string))
461		addlist(&list, mime_type_to_lp_type(string));
462	if (list != NULL) {
463		if (tmp->input_types != NULL)
464			freelist(tmp->input_types);
465		tmp->input_types = list;
466	}
467
468	papiAttributeListGetLPString(attributes,
469	    "device-uri", &tmp->device);
470	papiAttributeListGetLPString(attributes,
471	    "printer-info", &tmp->description);
472	papiAttributeListGetLPString(attributes,
473	    "lpsched-dial-info", &tmp->dial_info);
474	papiAttributeListGetLPString(attributes,
475	    "lpsched-fault-recovery", &tmp->fault_rec);
476	papiAttributeListGetLPString(attributes,
477	    "lpsched-interface-script", &tmp->interface);
478	papiAttributeListGetLPString(attributes,
479	    "lpsched-data-rate", &tmp->speed);
480	papiAttributeListGetLPString(attributes,
481	    "lpsched-stty", &tmp->stty);
482	papiAttributeListGetLPStrings(attributes,
483	    "lpsched-charsets", &tmp->char_sets);
484	papiAttributeListGetLPStrings(attributes,
485	    "lpsched-printer-types", &tmp->printer_types);
486	papiAttributeListGetLPStrings(attributes,
487	    "lpsched-options", &tmp->options);
488	papiAttributeListGetLPStrings(attributes,
489	    "lpsched-modules", &tmp->modules);
490#ifdef LP_USE_PAPI_ATTR
491	papiAttributeListGetLPString(attributes,
492	    "lpsched-printer-ppd-uri", &tmp->ppd);
493#endif
494
495	return (PAPI_OK);
496}
497