xref: /onnv-gate/usr/src/cmd/lp/lib/papi/lpsched-jobs.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*LINTLIBRARY*/
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #include <stdlib.h>
32*0Sstevel@tonic-gate #include <string.h>
33*0Sstevel@tonic-gate #include <unistd.h>
34*0Sstevel@tonic-gate #include <libintl.h>
35*0Sstevel@tonic-gate #include <pwd.h>
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate /* lpsched include files */
38*0Sstevel@tonic-gate #include "lp.h"
39*0Sstevel@tonic-gate #include "requests.h"
40*0Sstevel@tonic-gate #include "printers.h"
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate #include <papi_impl.h>
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate papi_status_t
45*0Sstevel@tonic-gate job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
46*0Sstevel@tonic-gate 		papi_attribute_t **attributes)
47*0Sstevel@tonic-gate {
48*0Sstevel@tonic-gate 	papi_attribute_t *attr;
49*0Sstevel@tonic-gate 	int i;
50*0Sstevel@tonic-gate 	char *s;
51*0Sstevel@tonic-gate 
52*0Sstevel@tonic-gate 	char **options = NULL;
53*0Sstevel@tonic-gate 	char **modes = NULL;
54*0Sstevel@tonic-gate 	char *class = NULL;
55*0Sstevel@tonic-gate 	char *job_name = NULL;
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate 	char pr_filter = 0;
58*0Sstevel@tonic-gate 	char *pr_title = NULL;
59*0Sstevel@tonic-gate 	int pr_width = -1;
60*0Sstevel@tonic-gate 	int pr_indent = -1;
61*0Sstevel@tonic-gate 	int numberUp = 0;
62*0Sstevel@tonic-gate 	int orientation = 0;
63*0Sstevel@tonic-gate 	int lowerPage = 0;
64*0Sstevel@tonic-gate 	int upperPage = 0;
65*0Sstevel@tonic-gate 	papi_status_t getResult = 0;
66*0Sstevel@tonic-gate 	char buf[256];
67*0Sstevel@tonic-gate 	void *iterator = NULL;
68*0Sstevel@tonic-gate 
69*0Sstevel@tonic-gate 	char banner = 0;
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate 	if (attributes == NULL)
72*0Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
73*0Sstevel@tonic-gate 
74*0Sstevel@tonic-gate 	papiAttributeListGetString(attributes, NULL, "job-printer",
75*0Sstevel@tonic-gate 				&r->destination);
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate 	i = r->copies;
78*0Sstevel@tonic-gate 	papiAttributeListGetInteger(attributes, NULL, "copies", &i);
79*0Sstevel@tonic-gate 	if (i <= 0)
80*0Sstevel@tonic-gate 		i = 1;
81*0Sstevel@tonic-gate 	r->copies = i;
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate 	if (papiAttributeListGetInteger(attributes, NULL, "priority", &i)
84*0Sstevel@tonic-gate 			== PAPI_OK) {
85*0Sstevel@tonic-gate 		if ((i < 1) || (i > 100))
86*0Sstevel@tonic-gate 			i = 50;
87*0Sstevel@tonic-gate 		i = (i + 1) / 2.5;
88*0Sstevel@tonic-gate 		r->priority = i;
89*0Sstevel@tonic-gate 	}
90*0Sstevel@tonic-gate 
91*0Sstevel@tonic-gate 	if ((r->priority < 0) || (r->priority > 39))
92*0Sstevel@tonic-gate 		r->priority = 20;
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate 	/*
95*0Sstevel@tonic-gate 	 * 'media' size should be processed both in the lpsched filter and
96*0Sstevel@tonic-gate 	 * the foomatic filter (if present) so that we ensure the result of
97*0Sstevel@tonic-gate 	 * other options like 'page-ranges' are consistent.
98*0Sstevel@tonic-gate 	 */
99*0Sstevel@tonic-gate /*
100*0Sstevel@tonic-gate  * TODO - I thing we should really have this but I can't get it to filter
101*0Sstevel@tonic-gate  *        so its commented out for now (paulcun)
102*0Sstevel@tonic-gate  *	papiAttributeListGetString(attributes, NULL, "media", &r->form);
103*0Sstevel@tonic-gate  */
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate #ifndef LP_USE_PAPI_ATTR
106*0Sstevel@tonic-gate 	papiAttributeListGetString(attributes, NULL, "page-ranges", &r->pages);
107*0Sstevel@tonic-gate #else
108*0Sstevel@tonic-gate 	getResult =
109*0Sstevel@tonic-gate 	    papiAttributeListGetRange(attributes, &iterator,
110*0Sstevel@tonic-gate 		"page-ranges", &lowerPage, &upperPage);
111*0Sstevel@tonic-gate 	while (getResult == PAPI_OK) {
112*0Sstevel@tonic-gate 		if (r->pages == NULL) {
113*0Sstevel@tonic-gate 			snprintf(buf, sizeof (buf),
114*0Sstevel@tonic-gate 				"%d-%d", lowerPage, upperPage);
115*0Sstevel@tonic-gate 			r->pages = (char *)strdup(buf);
116*0Sstevel@tonic-gate 		}
117*0Sstevel@tonic-gate 		else
118*0Sstevel@tonic-gate 		{
119*0Sstevel@tonic-gate 			snprintf(buf, sizeof (buf), "%s,%d-%d",
120*0Sstevel@tonic-gate 				r->pages, lowerPage, upperPage);
121*0Sstevel@tonic-gate 			free(r->pages);
122*0Sstevel@tonic-gate 			r->pages = (char *)strdup(buf);
123*0Sstevel@tonic-gate 		}
124*0Sstevel@tonic-gate 		/*
125*0Sstevel@tonic-gate 		 * get the next value; note the attribute 'name' is set to
126*0Sstevel@tonic-gate 		 * NULL to do this.
127*0Sstevel@tonic-gate 		 */
128*0Sstevel@tonic-gate 		getResult =
129*0Sstevel@tonic-gate 		    papiAttributeListGetRange(attributes, &iterator,
130*0Sstevel@tonic-gate 			"page-ranges", &lowerPage, &upperPage);
131*0Sstevel@tonic-gate 	}
132*0Sstevel@tonic-gate #endif
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 	s = NULL;
136*0Sstevel@tonic-gate 	papiAttributeListGetString(attributes, NULL, "document-format", &s);
137*0Sstevel@tonic-gate 	if (s != NULL)
138*0Sstevel@tonic-gate 		r->input_type = strdup(mime_type_to_lp_type(s));
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	/*
141*0Sstevel@tonic-gate 	 * If we don't have an owner, set one.
142*0Sstevel@tonic-gate 	 */
143*0Sstevel@tonic-gate 	if (r->user == NULL) {
144*0Sstevel@tonic-gate 		uid_t uid = getuid();
145*0Sstevel@tonic-gate 		struct passwd *pw;
146*0Sstevel@tonic-gate 		char *user = "intruder";
147*0Sstevel@tonic-gate 		char *host = NULL;
148*0Sstevel@tonic-gate 		char buf[256];
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate 		if ((pw = getpwuid(uid)) != NULL)
151*0Sstevel@tonic-gate 			user = pw->pw_name; /* default to the process owner */
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate 		if ((uid == 0) || (uid == 71)) { /* root/lp can forge this */
154*0Sstevel@tonic-gate 			papiAttributeListGetString(attributes, NULL,
155*0Sstevel@tonic-gate 					"job-host", &host);
156*0Sstevel@tonic-gate 			papiAttributeListGetString(attributes, NULL,
157*0Sstevel@tonic-gate 					"job-originating-user-name", &user);
158*0Sstevel@tonic-gate 			papiAttributeListGetString(attributes, NULL,
159*0Sstevel@tonic-gate 					"requesting-user-name", &user);
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate 			snprintf(buf, sizeof (buf), "%s%s%s", user,
162*0Sstevel@tonic-gate 					(host ? "@" : ""), (host ? host : ""));
163*0Sstevel@tonic-gate 			user = buf;
164*0Sstevel@tonic-gate 		}
165*0Sstevel@tonic-gate 
166*0Sstevel@tonic-gate 		r->user = strdup(user);
167*0Sstevel@tonic-gate 	}
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate 	s = NULL;
170*0Sstevel@tonic-gate 	papiAttributeListGetString(attributes, NULL, "job-hold-until", &s);
171*0Sstevel@tonic-gate 	if (s != NULL) {
172*0Sstevel@tonic-gate 		if (strcmp(s, "immediate") == 0)
173*0Sstevel@tonic-gate 			r->actions |= ACT_IMMEDIATE;
174*0Sstevel@tonic-gate 		else if ((strcmp(s, "resume") == 0) ||
175*0Sstevel@tonic-gate 			    (strcmp(s, "no-hold") == 0))
176*0Sstevel@tonic-gate 			r->actions |= ACT_RESUME;
177*0Sstevel@tonic-gate 		else if ((strcmp(s, "hold") == 0) ||
178*0Sstevel@tonic-gate 			    (strcmp(s, "indefinite") == 0))
179*0Sstevel@tonic-gate 			r->actions |= ACT_HOLD;
180*0Sstevel@tonic-gate 	}
181*0Sstevel@tonic-gate 
182*0Sstevel@tonic-gate 	papiAttributeListGetString(attributes, NULL, "lp-charset", &r->charset);
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate 	/* legacy pr(1) filter related garbage "lpr -p" */
185*0Sstevel@tonic-gate 	papiAttributeListGetBoolean(attributes, NULL, "pr-filter", &pr_filter);
186*0Sstevel@tonic-gate 	papiAttributeListGetString(attributes, NULL, "pr-title", &pr_title);
187*0Sstevel@tonic-gate 	papiAttributeListGetInteger(attributes, NULL, "pr-width", &pr_width);
188*0Sstevel@tonic-gate 	papiAttributeListGetInteger(attributes, NULL, "pr-indent", &pr_indent);
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 	if (pr_filter != 0) {
191*0Sstevel@tonic-gate 		char buf[128];
192*0Sstevel@tonic-gate 
193*0Sstevel@tonic-gate 		if (pr_title != NULL) {
194*0Sstevel@tonic-gate 			snprintf(buf, sizeof (buf), "prtitle='%s'", pr_title);
195*0Sstevel@tonic-gate 			appendlist(&modes, buf);
196*0Sstevel@tonic-gate 		}
197*0Sstevel@tonic-gate 
198*0Sstevel@tonic-gate 		if (pr_width > 0) {
199*0Sstevel@tonic-gate 			snprintf(buf, sizeof (buf), "prwidth=%d", pr_width);
200*0Sstevel@tonic-gate 			appendlist(&modes, buf);
201*0Sstevel@tonic-gate 		}
202*0Sstevel@tonic-gate 
203*0Sstevel@tonic-gate 		if (pr_indent > 0) {
204*0Sstevel@tonic-gate 			snprintf(buf, sizeof (buf), "indent=%d", pr_indent);
205*0Sstevel@tonic-gate 			appendlist(&modes, buf);
206*0Sstevel@tonic-gate 		}
207*0Sstevel@tonic-gate 	} else if ((pr_title != NULL) || (pr_width >= 0) || (pr_indent >= 0))
208*0Sstevel@tonic-gate 		detailed_error(svc, gettext(
209*0Sstevel@tonic-gate 	"pr(1) filter options specified without enabling pr(1) filter"));
210*0Sstevel@tonic-gate 
211*0Sstevel@tonic-gate 	/* add burst page information */
212*0Sstevel@tonic-gate 	papiAttributeListGetBoolean(attributes, NULL, "job-sheets", &banner);
213*0Sstevel@tonic-gate 	papiAttributeListGetString(attributes, NULL, "job-class", &class);
214*0Sstevel@tonic-gate 	papiAttributeListGetString(attributes, NULL, "job-name", &job_name);
215*0Sstevel@tonic-gate 
216*0Sstevel@tonic-gate 	{
217*0Sstevel@tonic-gate 		char buf[128];
218*0Sstevel@tonic-gate 		/* burst page is enabled by default, add the title */
219*0Sstevel@tonic-gate 		snprintf(buf, sizeof (buf), "%s%s%s",
220*0Sstevel@tonic-gate 			(job_name ? job_name : ""),
221*0Sstevel@tonic-gate 			(job_name && class ? "\\n#####\\n#####\\t\\t " : ""),
222*0Sstevel@tonic-gate 			(class ? class : ""));
223*0Sstevel@tonic-gate 		if (buf[0] != '\0') {
224*0Sstevel@tonic-gate 			if (r->title != NULL)
225*0Sstevel@tonic-gate 				free(r->title);
226*0Sstevel@tonic-gate 			r->title = strdup(buf);
227*0Sstevel@tonic-gate 		}
228*0Sstevel@tonic-gate 	}
229*0Sstevel@tonic-gate 	if (banner == 0) /* burst page is disabled via lp "option" */
230*0Sstevel@tonic-gate 		appendlist(&options, "nobanner");
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate 	/* add "lp -o" options */
233*0Sstevel@tonic-gate 	attr = papiAttributeListFind(attributes, "lp-options");
234*0Sstevel@tonic-gate 	if ((attr != NULL) && (attr->type == PAPI_STRING) &&
235*0Sstevel@tonic-gate 	    (attr->values != NULL)) {
236*0Sstevel@tonic-gate 		int i;
237*0Sstevel@tonic-gate 
238*0Sstevel@tonic-gate 		for (i = 0; attr->values[i] != NULL; i++)
239*0Sstevel@tonic-gate 			appendlist(&options, attr->values[i]->string);
240*0Sstevel@tonic-gate 	}
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate 	if (options != NULL) {
243*0Sstevel@tonic-gate 		if (r->options != NULL)
244*0Sstevel@tonic-gate 			free(r->options);
245*0Sstevel@tonic-gate 		r->options = sprintlist(options);
246*0Sstevel@tonic-gate 		freelist(options);
247*0Sstevel@tonic-gate 	}
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate 	/* Convert attribute "number-up" to mode group=n */
250*0Sstevel@tonic-gate 	papiAttributeListGetInteger(attributes, NULL, "number-up", &numberUp);
251*0Sstevel@tonic-gate 	if ((numberUp >= 2) && ((numberUp % 2) == 0)) {
252*0Sstevel@tonic-gate 		snprintf(buf, sizeof (buf), "group=%d", numberUp);
253*0Sstevel@tonic-gate 		appendlist(&modes, buf);
254*0Sstevel@tonic-gate 	}
255*0Sstevel@tonic-gate 
256*0Sstevel@tonic-gate 	/*
257*0Sstevel@tonic-gate 	 * Convert attribute "orientation-requested" to modes
258*0Sstevel@tonic-gate 	 * 'landscape', 'portrait', etc.
259*0Sstevel@tonic-gate 	 */
260*0Sstevel@tonic-gate 	papiAttributeListGetInteger(attributes, NULL,
261*0Sstevel@tonic-gate 				    "orientation-requested", &orientation);
262*0Sstevel@tonic-gate 	if ((orientation >= 3) && (orientation <= 6)) {
263*0Sstevel@tonic-gate 		switch (orientation) {
264*0Sstevel@tonic-gate 			case 3:
265*0Sstevel@tonic-gate 			{
266*0Sstevel@tonic-gate 				/* 3 = portrait */
267*0Sstevel@tonic-gate 				appendlist(&modes, "portrait");
268*0Sstevel@tonic-gate 				break;
269*0Sstevel@tonic-gate 			}
270*0Sstevel@tonic-gate 
271*0Sstevel@tonic-gate 			case 4:
272*0Sstevel@tonic-gate 			{
273*0Sstevel@tonic-gate 				/* 4 = landscape */
274*0Sstevel@tonic-gate 				appendlist(&modes, "landscape");
275*0Sstevel@tonic-gate 				break;
276*0Sstevel@tonic-gate 			}
277*0Sstevel@tonic-gate 
278*0Sstevel@tonic-gate 			case 5:
279*0Sstevel@tonic-gate 			{
280*0Sstevel@tonic-gate 				/*
281*0Sstevel@tonic-gate 				 * 5 = reverse-landscape - not supported in
282*0Sstevel@tonic-gate 				 *    lpsched so just use 'landscape' for now
283*0Sstevel@tonic-gate 				 */
284*0Sstevel@tonic-gate 				appendlist(&modes, "landscape");
285*0Sstevel@tonic-gate 				break;
286*0Sstevel@tonic-gate 			}
287*0Sstevel@tonic-gate 
288*0Sstevel@tonic-gate 			case 6:
289*0Sstevel@tonic-gate 			{
290*0Sstevel@tonic-gate 				/*
291*0Sstevel@tonic-gate 				 * 6 = reverse-portrait not supported in
292*0Sstevel@tonic-gate 				 *    lpsched so just use 'portrait' for now
293*0Sstevel@tonic-gate 				 */
294*0Sstevel@tonic-gate 				appendlist(&modes, "portrait");
295*0Sstevel@tonic-gate 				break;
296*0Sstevel@tonic-gate 			}
297*0Sstevel@tonic-gate 
298*0Sstevel@tonic-gate 			default:
299*0Sstevel@tonic-gate 			{
300*0Sstevel@tonic-gate 				appendlist(&modes, "portrait");
301*0Sstevel@tonic-gate 				break;
302*0Sstevel@tonic-gate 			}
303*0Sstevel@tonic-gate 		}
304*0Sstevel@tonic-gate 	}
305*0Sstevel@tonic-gate 
306*0Sstevel@tonic-gate 	/* add "lp -y" modes */
307*0Sstevel@tonic-gate 	attr = papiAttributeListFind(attributes, "lp-modes");
308*0Sstevel@tonic-gate 	if ((attr != NULL) && (attr->type == PAPI_STRING) &&
309*0Sstevel@tonic-gate 	    (attr->values != NULL)) {
310*0Sstevel@tonic-gate 		int i;
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate 		for (i = 0; attr->values[i] != NULL; i++)
313*0Sstevel@tonic-gate 			appendlist(&modes, attr->values[i]->string);
314*0Sstevel@tonic-gate 	}
315*0Sstevel@tonic-gate 
316*0Sstevel@tonic-gate 	if (modes != NULL) {
317*0Sstevel@tonic-gate 		if (r->modes == NULL)
318*0Sstevel@tonic-gate 			free(r->modes);
319*0Sstevel@tonic-gate 		r->modes = sprintlist(modes);
320*0Sstevel@tonic-gate 		freelist(modes);
321*0Sstevel@tonic-gate 	}
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate 	return (PAPI_OK);
324*0Sstevel@tonic-gate }
325*0Sstevel@tonic-gate 
326*0Sstevel@tonic-gate /*
327*0Sstevel@tonic-gate  * Convert REQUEST->outcome (or R_REQUEST_* state) to the equivalent
328*0Sstevel@tonic-gate  * PAPI attribute representation.
329*0Sstevel@tonic-gate  */
330*0Sstevel@tonic-gate static void
331*0Sstevel@tonic-gate lpsched_request_outcome_to_attributes(papi_attribute_t ***attributes,
332*0Sstevel@tonic-gate 		unsigned short state)
333*0Sstevel@tonic-gate {
334*0Sstevel@tonic-gate 	if (attributes == NULL)
335*0Sstevel@tonic-gate 		return;
336*0Sstevel@tonic-gate 
337*0Sstevel@tonic-gate 	if (state & (RS_HELD|RS_ADMINHELD)) {
338*0Sstevel@tonic-gate 		papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
339*0Sstevel@tonic-gate 			"job-state", 0x04);	/* held */
340*0Sstevel@tonic-gate 		papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
341*0Sstevel@tonic-gate 			"job-state-reasons", "job-hold-until-specified");
342*0Sstevel@tonic-gate 	} else if (state & RS_ACTIVE) {
343*0Sstevel@tonic-gate 		papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
344*0Sstevel@tonic-gate 			"job-state", 0x05);
345*0Sstevel@tonic-gate 		if (state & RS_FILTERING)
346*0Sstevel@tonic-gate 			papiAttributeListAddString(attributes,
347*0Sstevel@tonic-gate 				PAPI_ATTR_REPLACE,
348*0Sstevel@tonic-gate 				"job-state-reasons", "job-transforming");
349*0Sstevel@tonic-gate 		else if (state & RS_PRINTING)
350*0Sstevel@tonic-gate 			papiAttributeListAddString(attributes,
351*0Sstevel@tonic-gate 				PAPI_ATTR_REPLACE,
352*0Sstevel@tonic-gate 				"job-state-reasons", "job-printing");
353*0Sstevel@tonic-gate 		else
354*0Sstevel@tonic-gate 			papiAttributeListAddString(attributes,
355*0Sstevel@tonic-gate 				PAPI_ATTR_REPLACE,
356*0Sstevel@tonic-gate 				"job-state-reasons", "job-processing");
357*0Sstevel@tonic-gate 	} else if (state & RS_CANCELLED) {
358*0Sstevel@tonic-gate 		papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
359*0Sstevel@tonic-gate 			"job-state", 0x07);
360*0Sstevel@tonic-gate 		papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
361*0Sstevel@tonic-gate 			"job-state-reasons", "job-canceled-by-user");
362*0Sstevel@tonic-gate 	} else if (state & RS_PRINTED) {
363*0Sstevel@tonic-gate 		papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
364*0Sstevel@tonic-gate 			"job-state", 0x09);
365*0Sstevel@tonic-gate 		papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
366*0Sstevel@tonic-gate 			"job-state-reasons", "job-complete");
367*0Sstevel@tonic-gate 	} else {
368*0Sstevel@tonic-gate 		papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
369*0Sstevel@tonic-gate 			"job-state", 0x03);
370*0Sstevel@tonic-gate 		papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
371*0Sstevel@tonic-gate 			"job-state-reasons", "job-queued");
372*0Sstevel@tonic-gate 	}
373*0Sstevel@tonic-gate 	papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
374*0Sstevel@tonic-gate 				"job-hold-until",
375*0Sstevel@tonic-gate 		((state & RS_HELD) ? "indefinite" : "no-hold"));
376*0Sstevel@tonic-gate }
377*0Sstevel@tonic-gate 
378*0Sstevel@tonic-gate /*
379*0Sstevel@tonic-gate  * Convert REQUEST structure to the equivalent PAPI attribute representation.
380*0Sstevel@tonic-gate  */
381*0Sstevel@tonic-gate void
382*0Sstevel@tonic-gate lpsched_request_to_job_attributes(REQUEST *r, job_t *j)
383*0Sstevel@tonic-gate {
384*0Sstevel@tonic-gate 	char *tmp;
385*0Sstevel@tonic-gate 	int i;
386*0Sstevel@tonic-gate 
387*0Sstevel@tonic-gate 	/* copies */
388*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
389*0Sstevel@tonic-gate 				"copies", r->copies);
390*0Sstevel@tonic-gate 
391*0Sstevel@tonic-gate 	/* destination */
392*0Sstevel@tonic-gate 	addLPString(&j->attributes, PAPI_ATTR_REPLACE, "printer-name",
393*0Sstevel@tonic-gate 				r->destination);
394*0Sstevel@tonic-gate 
395*0Sstevel@tonic-gate 	/* file_list */
396*0Sstevel@tonic-gate 	addLPStrings(&j->attributes, PAPI_ATTR_REPLACE,
397*0Sstevel@tonic-gate 				"lpsched-files", r->file_list);
398*0Sstevel@tonic-gate 
399*0Sstevel@tonic-gate 	/* form */
400*0Sstevel@tonic-gate 	addLPString(&j->attributes, PAPI_ATTR_REPLACE, "media", r->form);
401*0Sstevel@tonic-gate 
402*0Sstevel@tonic-gate 	/* actions */
403*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
404*0Sstevel@tonic-gate 					"lpsched-actions", r->actions);
405*0Sstevel@tonic-gate 
406*0Sstevel@tonic-gate 	/* alert */
407*0Sstevel@tonic-gate 	addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-alert", r->alert);
408*0Sstevel@tonic-gate 
409*0Sstevel@tonic-gate 	/* options */
410*0Sstevel@tonic-gate 	addLPString(&j->attributes, PAPI_ATTR_REPLACE,
411*0Sstevel@tonic-gate 					"lp-options", r->options);
412*0Sstevel@tonic-gate 
413*0Sstevel@tonic-gate 	tmp = (((r->options != NULL) && (strstr(r->options, "nobanner")
414*0Sstevel@tonic-gate 		!= NULL)) ? "none" : "standard");
415*0Sstevel@tonic-gate 	papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE,
416*0Sstevel@tonic-gate 				"job-sheets", tmp);
417*0Sstevel@tonic-gate 
418*0Sstevel@tonic-gate 	tmp = (((r->options != NULL) && (strstr(r->options, "duplex")
419*0Sstevel@tonic-gate 		!= NULL)) ? "two-sized" : "one-sided");
420*0Sstevel@tonic-gate 	papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE,
421*0Sstevel@tonic-gate 				"sides", tmp);
422*0Sstevel@tonic-gate 
423*0Sstevel@tonic-gate 	i = (((r->options != NULL) && (strstr(r->options, "landscape")
424*0Sstevel@tonic-gate 		!= NULL)) ? 4 : 3);
425*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
426*0Sstevel@tonic-gate 				"orientation-requested", i);
427*0Sstevel@tonic-gate 
428*0Sstevel@tonic-gate 	/* priority (map 0-39 to 1-100) */
429*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
430*0Sstevel@tonic-gate 				"job-priority", (int)((r->priority + 1) * 2.5));
431*0Sstevel@tonic-gate 
432*0Sstevel@tonic-gate 	/* pages */
433*0Sstevel@tonic-gate 	addLPString(&j->attributes, PAPI_ATTR_REPLACE, "page-ranges", r->pages);
434*0Sstevel@tonic-gate 
435*0Sstevel@tonic-gate 	/* charset */
436*0Sstevel@tonic-gate 	addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-charset",
437*0Sstevel@tonic-gate 				r->charset);
438*0Sstevel@tonic-gate 
439*0Sstevel@tonic-gate 	/* modes */
440*0Sstevel@tonic-gate 	addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-modes", r->modes);
441*0Sstevel@tonic-gate 
442*0Sstevel@tonic-gate 	/* title */
443*0Sstevel@tonic-gate 	addLPString(&j->attributes, PAPI_ATTR_REPLACE, "job-name", r->title);
444*0Sstevel@tonic-gate 
445*0Sstevel@tonic-gate 	/* input_type */
446*0Sstevel@tonic-gate 
447*0Sstevel@tonic-gate 	/* user */
448*0Sstevel@tonic-gate 	addLPString(&j->attributes, PAPI_ATTR_REPLACE,
449*0Sstevel@tonic-gate 				"job-originating-user-name", r->user);
450*0Sstevel@tonic-gate 
451*0Sstevel@tonic-gate 	/* outcome */
452*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
453*0Sstevel@tonic-gate 				"lpsched-outcome", r->outcome);
454*0Sstevel@tonic-gate 	lpsched_request_outcome_to_attributes(&j->attributes, r->outcome);
455*0Sstevel@tonic-gate 
456*0Sstevel@tonic-gate 	/* version */
457*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
458*0Sstevel@tonic-gate 				"lpsched-version", r->version);
459*0Sstevel@tonic-gate 
460*0Sstevel@tonic-gate 	/* constants, (should be derived from options) */
461*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
462*0Sstevel@tonic-gate 				"number-up", 1);
463*0Sstevel@tonic-gate 
464*0Sstevel@tonic-gate 	papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE,
465*0Sstevel@tonic-gate 				"multiple-document-handling",
466*0Sstevel@tonic-gate 				"seperate-documents-collated-copies");
467*0Sstevel@tonic-gate }
468*0Sstevel@tonic-gate 
469*0Sstevel@tonic-gate /*
470*0Sstevel@tonic-gate  * Convert R_REQUEST_* results to the equivalent PAPI attribute representation.
471*0Sstevel@tonic-gate  */
472*0Sstevel@tonic-gate void
473*0Sstevel@tonic-gate job_status_to_attributes(job_t *job, char *req_id, char *user, size_t size,
474*0Sstevel@tonic-gate 		time_t date, short state, char *destination, char *form,
475*0Sstevel@tonic-gate 		char *charset, short rank, char *file)
476*0Sstevel@tonic-gate {
477*0Sstevel@tonic-gate 	char buf[BUFSIZ];
478*0Sstevel@tonic-gate 	char *p;
479*0Sstevel@tonic-gate 
480*0Sstevel@tonic-gate 	addLPString(&job->attributes, PAPI_ATTR_REPLACE,
481*0Sstevel@tonic-gate 				"job-originating-user-name", user);
482*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
483*0Sstevel@tonic-gate 				"job-k-octets", size/1024);
484*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
485*0Sstevel@tonic-gate 				"job-octets", size);
486*0Sstevel@tonic-gate 	if ((p = strrchr(req_id, '-')) != NULL) {
487*0Sstevel@tonic-gate 		papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
488*0Sstevel@tonic-gate 				"job-id", atoi(++p));
489*0Sstevel@tonic-gate 	}
490*0Sstevel@tonic-gate 	snprintf(buf, sizeof (buf), "lpsched://%s/%d", destination, atoi(p));
491*0Sstevel@tonic-gate 	papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
492*0Sstevel@tonic-gate 				"job-uri", buf);
493*0Sstevel@tonic-gate 	snprintf(buf, sizeof (buf), "lpsched://%s", destination);
494*0Sstevel@tonic-gate 	papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
495*0Sstevel@tonic-gate 				"job-printer-uri", buf);
496*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
497*0Sstevel@tonic-gate 				"job-printer-up-time", time(NULL));
498*0Sstevel@tonic-gate 	papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
499*0Sstevel@tonic-gate 				"output-device-assigned", destination);
500*0Sstevel@tonic-gate 	papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
501*0Sstevel@tonic-gate 				"printer-name", destination);
502*0Sstevel@tonic-gate 	addLPString(&job->attributes, PAPI_ATTR_REPLACE, "media", form);
503*0Sstevel@tonic-gate 
504*0Sstevel@tonic-gate 	lpsched_request_outcome_to_attributes(&job->attributes, state);
505*0Sstevel@tonic-gate 
506*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
507*0Sstevel@tonic-gate 				"time-at-creation", date);
508*0Sstevel@tonic-gate 	addLPString(&job->attributes, PAPI_ATTR_REPLACE,
509*0Sstevel@tonic-gate 				"lpsched-request-id", req_id);
510*0Sstevel@tonic-gate 	addLPString(&job->attributes, PAPI_ATTR_REPLACE,
511*0Sstevel@tonic-gate 				"lp-charset", charset);
512*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
513*0Sstevel@tonic-gate 				"lpsched-job-state", state);
514*0Sstevel@tonic-gate 	papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
515*0Sstevel@tonic-gate 				"number-of-intervening-jobs", rank - 1);
516*0Sstevel@tonic-gate 	addLPString(&job->attributes, PAPI_ATTR_REPLACE,
517*0Sstevel@tonic-gate 				"lpsched-file", file);
518*0Sstevel@tonic-gate 	addLPString(&job->attributes, PAPI_ATTR_EXCL,
519*0Sstevel@tonic-gate 				"job-name", file);
520*0Sstevel@tonic-gate }
521*0Sstevel@tonic-gate 
522*0Sstevel@tonic-gate void
523*0Sstevel@tonic-gate lpsched_read_job_configuration(service_t *svc, job_t *j, char *file)
524*0Sstevel@tonic-gate {
525*0Sstevel@tonic-gate 	REQUEST *r;
526*0Sstevel@tonic-gate 
527*0Sstevel@tonic-gate 	if ((r = getrequest(file)) == NULL) {
528*0Sstevel@tonic-gate 		detailed_error(svc, gettext("unable to read job data: %s"),
529*0Sstevel@tonic-gate 			file);
530*0Sstevel@tonic-gate 		return;
531*0Sstevel@tonic-gate 	}
532*0Sstevel@tonic-gate 
533*0Sstevel@tonic-gate 	lpsched_request_to_job_attributes(r, j);
534*0Sstevel@tonic-gate }
535