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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
34 /* lpsched include files */
39 #include <papi_impl.h>
42 job_attributes_to_lpsched_request(papi_service_t svc
, REQUEST
*r
,
43 papi_attribute_t
**attributes
)
45 papi_status_t status
= PAPI_OK
;
46 papi_attribute_t
*attr
;
47 papi_attribute_t
**unmapped
= NULL
;
48 papi_attribute_t
*tmp
[2];
52 char **options
= NULL
;
56 char *pr_title
= NULL
;
64 void *iterator
= NULL
;
65 char *mapped_keys
[] = { "copies", "document-format", "form",
66 "job-class", "job-hold-until", "job-host", "job-name",
67 "job-originating-user-name", "job-printer",
68 "job-sheets", "lp-charset", "lp-modes", "number-up",
69 "orienttation-requested", "page-ranges", "pr-filter",
70 "pr-indent", "pr-title", "pr-width", "job-priority",
71 "requesting-user-name", "job-originating-host-name",
74 if (attributes
== NULL
)
75 return (PAPI_BAD_ARGUMENT
);
77 /* replace the current destination */
78 papiAttributeListGetLPString(attributes
,
79 "job-printer", &r
->destination
);
81 /* set the copies. We need at least 1 */
83 papiAttributeListGetInteger(attributes
, NULL
, "copies", &i
);
89 * set the priority. PAPI/IPP uses 1-100, lpsched use 0-39, so we
92 if (papiAttributeListGetInteger(attributes
, NULL
, "job-priority", &i
)
94 if ((i
< 1) || (i
> 100))
99 if ((r
->priority
< 0) || (r
->priority
> 39))
102 /* set the requested form to print on */
103 papiAttributeListGetLPString(attributes
, "form", &r
->form
);
105 /* set the page range */
106 memset(tmp
, NULL
, sizeof (tmp
));
107 tmp
[0] = papiAttributeListFind(attributes
, "page-ranges");
108 if (tmp
[0] != NULL
) {
111 papiAttributeListToString(tmp
, " ", buf
, sizeof (buf
));
112 if ((s
= strchr(buf
, '=')) != NULL
)
113 r
->pages
= (char *)strdup(++s
);
117 * set the document format, converting to old format names as
121 papiAttributeListGetString(attributes
, NULL
, "document-format", &s
);
123 r
->input_type
= strdup(mime_type_to_lp_type(s
));
127 * If we don't have an owner, set one.
129 if (r
->user
== NULL
) {
130 uid_t uid
= getuid();
132 char *user
= "intruder";
136 if ((pw
= getpwuid(uid
)) != NULL
)
137 user
= pw
->pw_name
; /* default to the process owner */
139 papiAttributeListGetString(attributes
, NULL
,
140 "job-originating-host-name", &host
);
141 papiAttributeListGetString(attributes
, NULL
,
143 papiAttributeListGetString(attributes
, NULL
,
144 "job-originating-user-name", &user
);
145 papiAttributeListGetString(attributes
, NULL
,
146 "requesting-user-name", &user
);
148 snprintf(buf
, sizeof (buf
), "%s%s%s", user
,
149 (host
? "@" : ""), (host
? host
: ""));
152 r
->user
= strdup(user
);
155 /* set any held state */
157 papiAttributeListGetString(attributes
, NULL
, "job-hold-until", &s
);
159 r
->actions
&= ~(ACT_SPECIAL
); /* strip immediate/hold/resume */
160 if (strcmp(s
, "resume") == 0)
161 r
->actions
|= ACT_RESUME
;
162 else if ((strcmp(s
, "immediate") == 0) ||
163 (strcmp(s
, "no-hold") == 0))
164 r
->actions
|= ACT_IMMEDIATE
;
165 else if ((strcmp(s
, "indefinite") == 0) ||
166 (strcmp(s
, "hold") == 0))
167 r
->actions
|= ACT_HOLD
;
170 /* set lp charset/printwheel */
171 papiAttributeListGetLPString(attributes
, "lp-charset", &r
->charset
);
173 /* legacy pr(1) filter related garbage "lpr -p" */
174 papiAttributeListGetBoolean(attributes
, NULL
, "pr-filter", &pr_filter
);
175 papiAttributeListGetString(attributes
, NULL
, "pr-title", &pr_title
);
176 papiAttributeListGetInteger(attributes
, NULL
, "pr-width", &pr_width
);
177 papiAttributeListGetInteger(attributes
, NULL
, "pr-indent", &pr_indent
);
179 if (pr_filter
!= 0) {
182 if (pr_title
!= NULL
) {
183 snprintf(buf
, sizeof (buf
), "prtitle='%s'", pr_title
);
184 appendlist(&modes
, buf
);
188 snprintf(buf
, sizeof (buf
), "prwidth=%d", pr_width
);
189 appendlist(&modes
, buf
);
193 snprintf(buf
, sizeof (buf
), "indent=%d", pr_indent
);
194 appendlist(&modes
, buf
);
196 } else if ((pr_title
!= NULL
) || (pr_width
>= 0) || (pr_indent
>= 0))
197 detailed_error(svc
, gettext(
198 "pr(1) filter options specified without enabling pr(1) filter"));
200 /* add burst page information */
202 papiAttributeListGetString(attributes
, NULL
, "job-sheets", &s
);
203 if ((s
!= NULL
) && (strcasecmp(s
, "none") != 0)) {
206 char *job_name
= NULL
;
208 papiAttributeListGetLPString(attributes
, "job-class", &class);
209 papiAttributeListGetLPString(attributes
, "job-name", &job_name
);
211 /* burst page is enabled by default, add the title */
212 snprintf(buf
, sizeof (buf
), "%s%s%s",
213 (job_name
? job_name
: ""),
214 (job_name
&& class ? "\\n#####\\n#####\\t\\t " : ""),
215 (class ? class : ""));
216 if (buf
[0] != '\0') {
217 if (r
->title
!= NULL
)
219 r
->title
= strdup(buf
);
221 } else if ((s
!= NULL
) && (strcasecmp(s
, "none") == 0)) {
222 /* burst page is disabled via lp "option" */
223 appendlist(&options
, "nobanner");
226 /* Convert attribute "number-up" to mode group=n */
227 papiAttributeListGetInteger(attributes
, NULL
, "number-up", &numberUp
);
228 if ((numberUp
>= 2) && ((numberUp
% 2) == 0)) {
229 snprintf(buf
, sizeof (buf
), "group=%d", numberUp
);
230 appendlist(&modes
, buf
);
234 * Convert attribute "orientation-requested" to modes
235 * 'landscape', 'portrait', etc.
237 papiAttributeListGetInteger(attributes
, NULL
,
238 "orientation-requested", &orientation
);
239 if ((orientation
>= 3) && (orientation
<= 6)) {
240 switch (orientation
) {
241 case 4: /* landscape */
242 case 5: /* reverse-landscape, use landscape instead */
243 appendlist(&modes
, "landscape");
245 case 3: /* portrait */
246 case 6: /* reverse-portrait, use portrait instead */
248 appendlist(&modes
, "portrait");
253 /* add "lp -y" modes */
254 attr
= papiAttributeListFind(attributes
, "lp-modes");
255 if ((attr
!= NULL
) && (attr
->type
== PAPI_STRING
) &&
256 (attr
->values
!= NULL
)) {
259 for (i
= 0; attr
->values
[i
] != NULL
; i
++)
260 appendlist(&modes
, attr
->values
[i
]->string
);
264 if (r
->modes
== NULL
)
266 r
->modes
= sprintlist(modes
);
270 /* add any unconsumed attributes to the "options" list */
271 split_and_copy_attributes(mapped_keys
, attributes
, NULL
, &unmapped
);
272 if (unmapped
!= NULL
) { /* convert them to lp options */
273 char *buf
= malloc(1024);
276 while (papiAttributeListToString(unmapped
, " ", buf
, size
)
279 buf
= realloc(buf
, size
);
281 appendlist(&options
, buf
);
283 papiAttributeListFree(unmapped
);
286 if (options
!= NULL
) {
287 if (r
->options
!= NULL
)
289 r
->options
= sprintlist(options
);
297 * Convert REQUEST->outcome (or R_REQUEST_* state) to the equivalent
298 * PAPI attribute representation.
301 lpsched_request_outcome_to_attributes(papi_attribute_t
***attributes
,
302 unsigned short state
)
304 if (attributes
== NULL
)
307 if (state
& RS_NOTIFYING
) {
308 papiAttributeListAddInteger(attributes
, PAPI_ATTR_REPLACE
,
309 "job-state", 0x0800); /* notifying user */
310 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
311 "job-state-reasons", "job-notifying");
312 } else if (state
& RS_HELD
) {
313 papiAttributeListAddInteger(attributes
, PAPI_ATTR_REPLACE
,
314 "job-state", 0x0001); /* held */
315 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
316 "job-state-reasons", "job-hold-until-specified");
317 } else if (state
& RS_CANCELLED
) {
318 papiAttributeListAddInteger(attributes
, PAPI_ATTR_REPLACE
,
319 "job-state", 0x0040); /* job cancelled */
320 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
321 "job-state-reasons", "job-canceled-by-user");
322 } else if (state
& RS_PRINTED
) {
323 papiAttributeListAddInteger(attributes
, PAPI_ATTR_REPLACE
,
324 "job-state", 0x0010); /* finished printing job */
325 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
326 "job-state-reasons", "job-complete");
327 } else if (state
& RS_PRINTING
) {
328 papiAttributeListAddInteger(attributes
, PAPI_ATTR_REPLACE
,
329 "job-state", 0x0008); /* printing job */
330 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
331 "job-state-reasons", "job-printing");
332 } else if (state
& RS_ADMINHELD
) {
333 papiAttributeListAddInteger(attributes
, PAPI_ATTR_REPLACE
,
334 "job-state", 0x2000); /* held by admin */
335 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
336 "job-state-reasons", "job-hold-until-specified");
337 } else if (state
& RS_FILTERED
) {
338 papiAttributeListAddInteger(attributes
, PAPI_ATTR_REPLACE
,
339 "job-state", 0x0004); /* filtered */
340 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
341 "job-state-reasons", "job-filtered");
342 } else if (state
& RS_CHANGING
) {
343 papiAttributeListAddInteger(attributes
, PAPI_ATTR_REPLACE
,
344 "job-state", 0x0020); /* job held for changing */
345 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
346 "job-state-reasons", "job-held-for-change");
347 } else if (state
& RS_FILTERING
) {
348 papiAttributeListAddInteger(attributes
, PAPI_ATTR_REPLACE
,
349 "job-state", 0x0002); /* being filtered */
350 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
351 "job-state-reasons", "job-being-filtered");
353 papiAttributeListAddInteger(attributes
, PAPI_ATTR_REPLACE
,
354 "job-state", 0x4000); /* else */
355 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
356 "job-state-reasons", "job-queued");
361 papiAttributeListAddString(attributes
, PAPI_ATTR_REPLACE
,
363 ((state
& RS_HELD
) ? "indefinite" : "no-hold"));
367 * convert user[@host] to papi attributes
370 lpsched_user_to_job_attributes(papi_attribute_t
***list
, char *user
)
372 if ((list
!= NULL
) && (user
!= NULL
) && (user
[0] != NULL
)) {
373 char *host
= strrchr(user
, '@');
377 papiAttributeListAddString(list
, PAPI_ATTR_REPLACE
,
378 "job-originating-user-name", user
);
379 papiAttributeListAddString(list
, PAPI_ATTR_REPLACE
,
380 "job-originating-host-name", host
+ 1);
383 papiAttributeListAddString(list
, PAPI_ATTR_REPLACE
,
384 "job-originating-user-name", user
);
389 * Convert REQUEST structure to the equivalent PAPI attribute representation.
392 lpsched_request_to_job_attributes(REQUEST
*r
, job_t
*j
)
398 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
399 "copies", r
->copies
);
402 papiAttributeListAddLPString(&j
->attributes
, PAPI_ATTR_REPLACE
,
403 "printer-name", r
->destination
);
406 papiAttributeListAddLPString(&j
->attributes
, PAPI_ATTR_REPLACE
,
410 papiAttributeListFromString(&j
->attributes
, PAPI_ATTR_APPEND
,
413 tmp
= (((r
->options
!= NULL
) && (strstr(r
->options
, "nobanner")
414 != NULL
)) ? "none" : "standard");
415 papiAttributeListAddString(&j
->attributes
, PAPI_ATTR_REPLACE
,
418 tmp
= (((r
->options
!= NULL
) && (strstr(r
->options
, "duplex")
419 != NULL
)) ? "two-sized" : "one-sided");
420 papiAttributeListAddString(&j
->attributes
, PAPI_ATTR_REPLACE
,
423 i
= (((r
->options
!= NULL
) && (strstr(r
->options
, "landscape")
425 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
426 "orientation-requested", i
);
428 /* priority (map 0-39 to 1-100) */
429 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
431 (int)(100 - (r
->priority
* 2.5)));
434 papiAttributeListAddLPString(&j
->attributes
, PAPI_ATTR_REPLACE
,
435 "page-ranges", r
->pages
);
438 papiAttributeListAddLPString(&j
->attributes
, PAPI_ATTR_REPLACE
,
439 "lp-charset", r
->charset
);
442 papiAttributeListAddLPString(&j
->attributes
, PAPI_ATTR_REPLACE
,
443 "lp-modes", r
->modes
);
446 papiAttributeListAddLPString(&j
->attributes
, PAPI_ATTR_REPLACE
,
447 "job-name", r
->title
);
452 lpsched_user_to_job_attributes(&j
->attributes
, r
->user
);
455 lpsched_request_outcome_to_attributes(&j
->attributes
, r
->outcome
);
457 /* constants, (should be derived from options) */
458 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
461 papiAttributeListAddString(&j
->attributes
, PAPI_ATTR_REPLACE
,
462 "multiple-document-handling",
463 "seperate-documents-collated-copies");
467 * Convert R_REQUEST_* results to the equivalent PAPI attribute representation.
470 job_status_to_attributes(job_t
*job
, char *req_id
, char *user
, char *slabel
,
471 size_t size
, time_t date
, short state
, char *destination
,
472 char *form
, char *charset
, short rank
, char *file
)
477 lpsched_user_to_job_attributes(&job
->attributes
, user
);
478 papiAttributeListAddInteger(&job
->attributes
, PAPI_ATTR_REPLACE
,
479 "job-k-octets", size
/1024);
480 papiAttributeListAddInteger(&job
->attributes
, PAPI_ATTR_REPLACE
,
482 if ((p
= strrchr(req_id
, '-')) != NULL
) {
483 papiAttributeListAddInteger(&job
->attributes
, PAPI_ATTR_REPLACE
,
484 "job-id", atoi(++p
));
486 snprintf(buf
, sizeof (buf
), "lpsched://localhost/printers/%s/%d",
487 destination
, atoi(p
));
488 papiAttributeListAddString(&job
->attributes
, PAPI_ATTR_REPLACE
,
490 snprintf(buf
, sizeof (buf
), "lpsched://localhost/printers/%s",
492 papiAttributeListAddString(&job
->attributes
, PAPI_ATTR_REPLACE
,
493 "job-printer-uri", buf
);
494 papiAttributeListAddInteger(&job
->attributes
, PAPI_ATTR_REPLACE
,
495 "job-printer-up-time", time(NULL
));
496 papiAttributeListAddString(&job
->attributes
, PAPI_ATTR_REPLACE
,
497 "output-device-assigned", destination
);
498 papiAttributeListAddString(&job
->attributes
, PAPI_ATTR_REPLACE
,
499 "printer-name", destination
);
500 papiAttributeListAddLPString(&job
->attributes
, PAPI_ATTR_REPLACE
,
503 lpsched_request_outcome_to_attributes(&job
->attributes
, state
);
505 papiAttributeListAddInteger(&job
->attributes
, PAPI_ATTR_REPLACE
,
506 "time-at-creation", date
);
507 papiAttributeListAddLPString(&job
->attributes
, PAPI_ATTR_REPLACE
,
508 "lpsched-request-id", req_id
);
509 papiAttributeListAddLPString(&job
->attributes
, PAPI_ATTR_REPLACE
,
510 "lp-charset", charset
);
511 papiAttributeListAddInteger(&job
->attributes
, PAPI_ATTR_REPLACE
,
512 "lpsched-job-state", state
);
513 papiAttributeListAddInteger(&job
->attributes
, PAPI_ATTR_REPLACE
,
514 "number-of-intervening-jobs", rank
- 1);
515 papiAttributeListAddLPString(&job
->attributes
, PAPI_ATTR_REPLACE
,
516 "lpsched-file", file
);
517 papiAttributeListAddLPString(&job
->attributes
, PAPI_ATTR_EXCL
,
519 papiAttributeListAddLPString(&job
->attributes
, PAPI_ATTR_EXCL
,
520 "tsol-sensitivity-label", slabel
);
524 lpsched_read_job_configuration(service_t
*svc
, job_t
*j
, char *file
)
528 if ((r
= getrequest(file
)) == NULL
) {
529 detailed_error(svc
, gettext("unable to read job data: %s"),
534 lpsched_request_to_job_attributes(r
, j
);