10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*1676Sjpk * Common Development and Distribution License (the "License"). 6*1676Sjpk * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*1676Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate /*LINTLIBRARY*/ 290Sstevel@tonic-gate 300Sstevel@tonic-gate #include <stdlib.h> 310Sstevel@tonic-gate #include <string.h> 320Sstevel@tonic-gate #include <unistd.h> 330Sstevel@tonic-gate #include <libintl.h> 340Sstevel@tonic-gate #include <pwd.h> 350Sstevel@tonic-gate 360Sstevel@tonic-gate /* lpsched include files */ 370Sstevel@tonic-gate #include "lp.h" 380Sstevel@tonic-gate #include "requests.h" 390Sstevel@tonic-gate #include "printers.h" 400Sstevel@tonic-gate 410Sstevel@tonic-gate #include <papi_impl.h> 420Sstevel@tonic-gate 430Sstevel@tonic-gate papi_status_t 440Sstevel@tonic-gate job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, 450Sstevel@tonic-gate papi_attribute_t **attributes) 460Sstevel@tonic-gate { 470Sstevel@tonic-gate papi_attribute_t *attr; 480Sstevel@tonic-gate int i; 490Sstevel@tonic-gate char *s; 500Sstevel@tonic-gate 510Sstevel@tonic-gate char **options = NULL; 520Sstevel@tonic-gate char **modes = NULL; 530Sstevel@tonic-gate char *class = NULL; 540Sstevel@tonic-gate char *job_name = NULL; 550Sstevel@tonic-gate 560Sstevel@tonic-gate char pr_filter = 0; 570Sstevel@tonic-gate char *pr_title = NULL; 580Sstevel@tonic-gate int pr_width = -1; 590Sstevel@tonic-gate int pr_indent = -1; 600Sstevel@tonic-gate int numberUp = 0; 610Sstevel@tonic-gate int orientation = 0; 620Sstevel@tonic-gate int lowerPage = 0; 630Sstevel@tonic-gate int upperPage = 0; 640Sstevel@tonic-gate papi_status_t getResult = 0; 650Sstevel@tonic-gate char buf[256]; 660Sstevel@tonic-gate void *iterator = NULL; 670Sstevel@tonic-gate 680Sstevel@tonic-gate char banner = 0; 690Sstevel@tonic-gate 700Sstevel@tonic-gate if (attributes == NULL) 710Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 720Sstevel@tonic-gate 730Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, "job-printer", 740Sstevel@tonic-gate &r->destination); 750Sstevel@tonic-gate 760Sstevel@tonic-gate i = r->copies; 770Sstevel@tonic-gate papiAttributeListGetInteger(attributes, NULL, "copies", &i); 780Sstevel@tonic-gate if (i <= 0) 790Sstevel@tonic-gate i = 1; 800Sstevel@tonic-gate r->copies = i; 810Sstevel@tonic-gate 820Sstevel@tonic-gate if (papiAttributeListGetInteger(attributes, NULL, "priority", &i) 830Sstevel@tonic-gate == PAPI_OK) { 840Sstevel@tonic-gate if ((i < 1) || (i > 100)) 850Sstevel@tonic-gate i = 50; 860Sstevel@tonic-gate i = (i + 1) / 2.5; 870Sstevel@tonic-gate r->priority = i; 880Sstevel@tonic-gate } 890Sstevel@tonic-gate 900Sstevel@tonic-gate if ((r->priority < 0) || (r->priority > 39)) 910Sstevel@tonic-gate r->priority = 20; 920Sstevel@tonic-gate 930Sstevel@tonic-gate /* 940Sstevel@tonic-gate * 'media' size should be processed both in the lpsched filter and 950Sstevel@tonic-gate * the foomatic filter (if present) so that we ensure the result of 960Sstevel@tonic-gate * other options like 'page-ranges' are consistent. 970Sstevel@tonic-gate */ 980Sstevel@tonic-gate /* 990Sstevel@tonic-gate * TODO - I thing we should really have this but I can't get it to filter 1000Sstevel@tonic-gate * so its commented out for now (paulcun) 1010Sstevel@tonic-gate * papiAttributeListGetString(attributes, NULL, "media", &r->form); 1020Sstevel@tonic-gate */ 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate #ifndef LP_USE_PAPI_ATTR 1050Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, "page-ranges", &r->pages); 1060Sstevel@tonic-gate #else 1070Sstevel@tonic-gate getResult = 1080Sstevel@tonic-gate papiAttributeListGetRange(attributes, &iterator, 1090Sstevel@tonic-gate "page-ranges", &lowerPage, &upperPage); 1100Sstevel@tonic-gate while (getResult == PAPI_OK) { 1110Sstevel@tonic-gate if (r->pages == NULL) { 1120Sstevel@tonic-gate snprintf(buf, sizeof (buf), 1130Sstevel@tonic-gate "%d-%d", lowerPage, upperPage); 1140Sstevel@tonic-gate r->pages = (char *)strdup(buf); 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate else 1170Sstevel@tonic-gate { 1180Sstevel@tonic-gate snprintf(buf, sizeof (buf), "%s,%d-%d", 1190Sstevel@tonic-gate r->pages, lowerPage, upperPage); 1200Sstevel@tonic-gate free(r->pages); 1210Sstevel@tonic-gate r->pages = (char *)strdup(buf); 1220Sstevel@tonic-gate } 1230Sstevel@tonic-gate /* 1240Sstevel@tonic-gate * get the next value; note the attribute 'name' is set to 1250Sstevel@tonic-gate * NULL to do this. 1260Sstevel@tonic-gate */ 1270Sstevel@tonic-gate getResult = 1280Sstevel@tonic-gate papiAttributeListGetRange(attributes, &iterator, 1290Sstevel@tonic-gate "page-ranges", &lowerPage, &upperPage); 1300Sstevel@tonic-gate } 1310Sstevel@tonic-gate #endif 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate 1340Sstevel@tonic-gate s = NULL; 1350Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, "document-format", &s); 1360Sstevel@tonic-gate if (s != NULL) 1370Sstevel@tonic-gate r->input_type = strdup(mime_type_to_lp_type(s)); 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate /* 1400Sstevel@tonic-gate * If we don't have an owner, set one. 1410Sstevel@tonic-gate */ 1420Sstevel@tonic-gate if (r->user == NULL) { 1430Sstevel@tonic-gate uid_t uid = getuid(); 1440Sstevel@tonic-gate struct passwd *pw; 1450Sstevel@tonic-gate char *user = "intruder"; 1460Sstevel@tonic-gate char *host = NULL; 1470Sstevel@tonic-gate char buf[256]; 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate if ((pw = getpwuid(uid)) != NULL) 1500Sstevel@tonic-gate user = pw->pw_name; /* default to the process owner */ 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate if ((uid == 0) || (uid == 71)) { /* root/lp can forge this */ 1530Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, 1540Sstevel@tonic-gate "job-host", &host); 1550Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, 1560Sstevel@tonic-gate "job-originating-user-name", &user); 1570Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, 1580Sstevel@tonic-gate "requesting-user-name", &user); 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate snprintf(buf, sizeof (buf), "%s%s%s", user, 1610Sstevel@tonic-gate (host ? "@" : ""), (host ? host : "")); 1620Sstevel@tonic-gate user = buf; 1630Sstevel@tonic-gate } 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate r->user = strdup(user); 1660Sstevel@tonic-gate } 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate s = NULL; 1690Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, "job-hold-until", &s); 1700Sstevel@tonic-gate if (s != NULL) { 1710Sstevel@tonic-gate if (strcmp(s, "immediate") == 0) 1720Sstevel@tonic-gate r->actions |= ACT_IMMEDIATE; 1730Sstevel@tonic-gate else if ((strcmp(s, "resume") == 0) || 1740Sstevel@tonic-gate (strcmp(s, "no-hold") == 0)) 1750Sstevel@tonic-gate r->actions |= ACT_RESUME; 1760Sstevel@tonic-gate else if ((strcmp(s, "hold") == 0) || 1770Sstevel@tonic-gate (strcmp(s, "indefinite") == 0)) 1780Sstevel@tonic-gate r->actions |= ACT_HOLD; 1790Sstevel@tonic-gate } 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, "lp-charset", &r->charset); 1820Sstevel@tonic-gate 1830Sstevel@tonic-gate /* legacy pr(1) filter related garbage "lpr -p" */ 1840Sstevel@tonic-gate papiAttributeListGetBoolean(attributes, NULL, "pr-filter", &pr_filter); 1850Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, "pr-title", &pr_title); 1860Sstevel@tonic-gate papiAttributeListGetInteger(attributes, NULL, "pr-width", &pr_width); 1870Sstevel@tonic-gate papiAttributeListGetInteger(attributes, NULL, "pr-indent", &pr_indent); 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate if (pr_filter != 0) { 1900Sstevel@tonic-gate char buf[128]; 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate if (pr_title != NULL) { 1930Sstevel@tonic-gate snprintf(buf, sizeof (buf), "prtitle='%s'", pr_title); 1940Sstevel@tonic-gate appendlist(&modes, buf); 1950Sstevel@tonic-gate } 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate if (pr_width > 0) { 1980Sstevel@tonic-gate snprintf(buf, sizeof (buf), "prwidth=%d", pr_width); 1990Sstevel@tonic-gate appendlist(&modes, buf); 2000Sstevel@tonic-gate } 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate if (pr_indent > 0) { 2030Sstevel@tonic-gate snprintf(buf, sizeof (buf), "indent=%d", pr_indent); 2040Sstevel@tonic-gate appendlist(&modes, buf); 2050Sstevel@tonic-gate } 2060Sstevel@tonic-gate } else if ((pr_title != NULL) || (pr_width >= 0) || (pr_indent >= 0)) 2070Sstevel@tonic-gate detailed_error(svc, gettext( 2080Sstevel@tonic-gate "pr(1) filter options specified without enabling pr(1) filter")); 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate /* add burst page information */ 2110Sstevel@tonic-gate papiAttributeListGetBoolean(attributes, NULL, "job-sheets", &banner); 2120Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, "job-class", &class); 2130Sstevel@tonic-gate papiAttributeListGetString(attributes, NULL, "job-name", &job_name); 2140Sstevel@tonic-gate 2150Sstevel@tonic-gate { 2160Sstevel@tonic-gate char buf[128]; 2170Sstevel@tonic-gate /* burst page is enabled by default, add the title */ 2180Sstevel@tonic-gate snprintf(buf, sizeof (buf), "%s%s%s", 2190Sstevel@tonic-gate (job_name ? job_name : ""), 2200Sstevel@tonic-gate (job_name && class ? "\\n#####\\n#####\\t\\t " : ""), 2210Sstevel@tonic-gate (class ? class : "")); 2220Sstevel@tonic-gate if (buf[0] != '\0') { 2230Sstevel@tonic-gate if (r->title != NULL) 2240Sstevel@tonic-gate free(r->title); 2250Sstevel@tonic-gate r->title = strdup(buf); 2260Sstevel@tonic-gate } 2270Sstevel@tonic-gate } 2280Sstevel@tonic-gate if (banner == 0) /* burst page is disabled via lp "option" */ 2290Sstevel@tonic-gate appendlist(&options, "nobanner"); 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate /* add "lp -o" options */ 2320Sstevel@tonic-gate attr = papiAttributeListFind(attributes, "lp-options"); 2330Sstevel@tonic-gate if ((attr != NULL) && (attr->type == PAPI_STRING) && 2340Sstevel@tonic-gate (attr->values != NULL)) { 2350Sstevel@tonic-gate int i; 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate for (i = 0; attr->values[i] != NULL; i++) 2380Sstevel@tonic-gate appendlist(&options, attr->values[i]->string); 2390Sstevel@tonic-gate } 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate if (options != NULL) { 2420Sstevel@tonic-gate if (r->options != NULL) 2430Sstevel@tonic-gate free(r->options); 2440Sstevel@tonic-gate r->options = sprintlist(options); 2450Sstevel@tonic-gate freelist(options); 2460Sstevel@tonic-gate } 2470Sstevel@tonic-gate 2480Sstevel@tonic-gate /* Convert attribute "number-up" to mode group=n */ 2490Sstevel@tonic-gate papiAttributeListGetInteger(attributes, NULL, "number-up", &numberUp); 2500Sstevel@tonic-gate if ((numberUp >= 2) && ((numberUp % 2) == 0)) { 2510Sstevel@tonic-gate snprintf(buf, sizeof (buf), "group=%d", numberUp); 2520Sstevel@tonic-gate appendlist(&modes, buf); 2530Sstevel@tonic-gate } 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate /* 2560Sstevel@tonic-gate * Convert attribute "orientation-requested" to modes 2570Sstevel@tonic-gate * 'landscape', 'portrait', etc. 2580Sstevel@tonic-gate */ 2590Sstevel@tonic-gate papiAttributeListGetInteger(attributes, NULL, 2600Sstevel@tonic-gate "orientation-requested", &orientation); 2610Sstevel@tonic-gate if ((orientation >= 3) && (orientation <= 6)) { 2620Sstevel@tonic-gate switch (orientation) { 2630Sstevel@tonic-gate case 3: 2640Sstevel@tonic-gate { 2650Sstevel@tonic-gate /* 3 = portrait */ 2660Sstevel@tonic-gate appendlist(&modes, "portrait"); 2670Sstevel@tonic-gate break; 2680Sstevel@tonic-gate } 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate case 4: 2710Sstevel@tonic-gate { 2720Sstevel@tonic-gate /* 4 = landscape */ 2730Sstevel@tonic-gate appendlist(&modes, "landscape"); 2740Sstevel@tonic-gate break; 2750Sstevel@tonic-gate } 2760Sstevel@tonic-gate 2770Sstevel@tonic-gate case 5: 2780Sstevel@tonic-gate { 2790Sstevel@tonic-gate /* 2800Sstevel@tonic-gate * 5 = reverse-landscape - not supported in 2810Sstevel@tonic-gate * lpsched so just use 'landscape' for now 2820Sstevel@tonic-gate */ 2830Sstevel@tonic-gate appendlist(&modes, "landscape"); 2840Sstevel@tonic-gate break; 2850Sstevel@tonic-gate } 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate case 6: 2880Sstevel@tonic-gate { 2890Sstevel@tonic-gate /* 2900Sstevel@tonic-gate * 6 = reverse-portrait not supported in 2910Sstevel@tonic-gate * lpsched so just use 'portrait' for now 2920Sstevel@tonic-gate */ 2930Sstevel@tonic-gate appendlist(&modes, "portrait"); 2940Sstevel@tonic-gate break; 2950Sstevel@tonic-gate } 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate default: 2980Sstevel@tonic-gate { 2990Sstevel@tonic-gate appendlist(&modes, "portrait"); 3000Sstevel@tonic-gate break; 3010Sstevel@tonic-gate } 3020Sstevel@tonic-gate } 3030Sstevel@tonic-gate } 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate /* add "lp -y" modes */ 3060Sstevel@tonic-gate attr = papiAttributeListFind(attributes, "lp-modes"); 3070Sstevel@tonic-gate if ((attr != NULL) && (attr->type == PAPI_STRING) && 3080Sstevel@tonic-gate (attr->values != NULL)) { 3090Sstevel@tonic-gate int i; 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate for (i = 0; attr->values[i] != NULL; i++) 3120Sstevel@tonic-gate appendlist(&modes, attr->values[i]->string); 3130Sstevel@tonic-gate } 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate if (modes != NULL) { 3160Sstevel@tonic-gate if (r->modes == NULL) 3170Sstevel@tonic-gate free(r->modes); 3180Sstevel@tonic-gate r->modes = sprintlist(modes); 3190Sstevel@tonic-gate freelist(modes); 3200Sstevel@tonic-gate } 3210Sstevel@tonic-gate 3220Sstevel@tonic-gate return (PAPI_OK); 3230Sstevel@tonic-gate } 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate /* 3260Sstevel@tonic-gate * Convert REQUEST->outcome (or R_REQUEST_* state) to the equivalent 3270Sstevel@tonic-gate * PAPI attribute representation. 3280Sstevel@tonic-gate */ 3290Sstevel@tonic-gate static void 3300Sstevel@tonic-gate lpsched_request_outcome_to_attributes(papi_attribute_t ***attributes, 3310Sstevel@tonic-gate unsigned short state) 3320Sstevel@tonic-gate { 3330Sstevel@tonic-gate if (attributes == NULL) 3340Sstevel@tonic-gate return; 3350Sstevel@tonic-gate 3360Sstevel@tonic-gate if (state & (RS_HELD|RS_ADMINHELD)) { 3370Sstevel@tonic-gate papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE, 3380Sstevel@tonic-gate "job-state", 0x04); /* held */ 3390Sstevel@tonic-gate papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, 3400Sstevel@tonic-gate "job-state-reasons", "job-hold-until-specified"); 3410Sstevel@tonic-gate } else if (state & RS_ACTIVE) { 3420Sstevel@tonic-gate papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE, 3430Sstevel@tonic-gate "job-state", 0x05); 3440Sstevel@tonic-gate if (state & RS_FILTERING) 3450Sstevel@tonic-gate papiAttributeListAddString(attributes, 3460Sstevel@tonic-gate PAPI_ATTR_REPLACE, 3470Sstevel@tonic-gate "job-state-reasons", "job-transforming"); 3480Sstevel@tonic-gate else if (state & RS_PRINTING) 3490Sstevel@tonic-gate papiAttributeListAddString(attributes, 3500Sstevel@tonic-gate PAPI_ATTR_REPLACE, 3510Sstevel@tonic-gate "job-state-reasons", "job-printing"); 3520Sstevel@tonic-gate else 3530Sstevel@tonic-gate papiAttributeListAddString(attributes, 3540Sstevel@tonic-gate PAPI_ATTR_REPLACE, 3550Sstevel@tonic-gate "job-state-reasons", "job-processing"); 3560Sstevel@tonic-gate } else if (state & RS_CANCELLED) { 3570Sstevel@tonic-gate papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE, 3580Sstevel@tonic-gate "job-state", 0x07); 3590Sstevel@tonic-gate papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, 3600Sstevel@tonic-gate "job-state-reasons", "job-canceled-by-user"); 3610Sstevel@tonic-gate } else if (state & RS_PRINTED) { 3620Sstevel@tonic-gate papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE, 3630Sstevel@tonic-gate "job-state", 0x09); 3640Sstevel@tonic-gate papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, 3650Sstevel@tonic-gate "job-state-reasons", "job-complete"); 3660Sstevel@tonic-gate } else { 3670Sstevel@tonic-gate papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE, 3680Sstevel@tonic-gate "job-state", 0x03); 3690Sstevel@tonic-gate papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, 3700Sstevel@tonic-gate "job-state-reasons", "job-queued"); 3710Sstevel@tonic-gate } 3720Sstevel@tonic-gate papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, 3730Sstevel@tonic-gate "job-hold-until", 3740Sstevel@tonic-gate ((state & RS_HELD) ? "indefinite" : "no-hold")); 3750Sstevel@tonic-gate } 3760Sstevel@tonic-gate 3770Sstevel@tonic-gate /* 3780Sstevel@tonic-gate * Convert REQUEST structure to the equivalent PAPI attribute representation. 3790Sstevel@tonic-gate */ 3800Sstevel@tonic-gate void 3810Sstevel@tonic-gate lpsched_request_to_job_attributes(REQUEST *r, job_t *j) 3820Sstevel@tonic-gate { 3830Sstevel@tonic-gate char *tmp; 3840Sstevel@tonic-gate int i; 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate /* copies */ 3870Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 3880Sstevel@tonic-gate "copies", r->copies); 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate /* destination */ 3910Sstevel@tonic-gate addLPString(&j->attributes, PAPI_ATTR_REPLACE, "printer-name", 3920Sstevel@tonic-gate r->destination); 3930Sstevel@tonic-gate 3940Sstevel@tonic-gate /* file_list */ 3950Sstevel@tonic-gate addLPStrings(&j->attributes, PAPI_ATTR_REPLACE, 3960Sstevel@tonic-gate "lpsched-files", r->file_list); 3970Sstevel@tonic-gate 3980Sstevel@tonic-gate /* form */ 3990Sstevel@tonic-gate addLPString(&j->attributes, PAPI_ATTR_REPLACE, "media", r->form); 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate /* actions */ 4020Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 4030Sstevel@tonic-gate "lpsched-actions", r->actions); 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate /* alert */ 4060Sstevel@tonic-gate addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-alert", r->alert); 4070Sstevel@tonic-gate 4080Sstevel@tonic-gate /* options */ 4090Sstevel@tonic-gate addLPString(&j->attributes, PAPI_ATTR_REPLACE, 4100Sstevel@tonic-gate "lp-options", r->options); 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate tmp = (((r->options != NULL) && (strstr(r->options, "nobanner") 4130Sstevel@tonic-gate != NULL)) ? "none" : "standard"); 4140Sstevel@tonic-gate papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE, 4150Sstevel@tonic-gate "job-sheets", tmp); 4160Sstevel@tonic-gate 4170Sstevel@tonic-gate tmp = (((r->options != NULL) && (strstr(r->options, "duplex") 4180Sstevel@tonic-gate != NULL)) ? "two-sized" : "one-sided"); 4190Sstevel@tonic-gate papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE, 4200Sstevel@tonic-gate "sides", tmp); 4210Sstevel@tonic-gate 4220Sstevel@tonic-gate i = (((r->options != NULL) && (strstr(r->options, "landscape") 4230Sstevel@tonic-gate != NULL)) ? 4 : 3); 4240Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 4250Sstevel@tonic-gate "orientation-requested", i); 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate /* priority (map 0-39 to 1-100) */ 4280Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 4290Sstevel@tonic-gate "job-priority", (int)((r->priority + 1) * 2.5)); 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate /* pages */ 4320Sstevel@tonic-gate addLPString(&j->attributes, PAPI_ATTR_REPLACE, "page-ranges", r->pages); 4330Sstevel@tonic-gate 4340Sstevel@tonic-gate /* charset */ 4350Sstevel@tonic-gate addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-charset", 4360Sstevel@tonic-gate r->charset); 4370Sstevel@tonic-gate 4380Sstevel@tonic-gate /* modes */ 4390Sstevel@tonic-gate addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-modes", r->modes); 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate /* title */ 4420Sstevel@tonic-gate addLPString(&j->attributes, PAPI_ATTR_REPLACE, "job-name", r->title); 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate /* input_type */ 4450Sstevel@tonic-gate 4460Sstevel@tonic-gate /* user */ 4470Sstevel@tonic-gate addLPString(&j->attributes, PAPI_ATTR_REPLACE, 4480Sstevel@tonic-gate "job-originating-user-name", r->user); 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate /* outcome */ 4510Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 4520Sstevel@tonic-gate "lpsched-outcome", r->outcome); 4530Sstevel@tonic-gate lpsched_request_outcome_to_attributes(&j->attributes, r->outcome); 4540Sstevel@tonic-gate 4550Sstevel@tonic-gate /* version */ 4560Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 4570Sstevel@tonic-gate "lpsched-version", r->version); 4580Sstevel@tonic-gate 4590Sstevel@tonic-gate /* constants, (should be derived from options) */ 4600Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 4610Sstevel@tonic-gate "number-up", 1); 4620Sstevel@tonic-gate 4630Sstevel@tonic-gate papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE, 4640Sstevel@tonic-gate "multiple-document-handling", 4650Sstevel@tonic-gate "seperate-documents-collated-copies"); 4660Sstevel@tonic-gate } 4670Sstevel@tonic-gate 4680Sstevel@tonic-gate /* 4690Sstevel@tonic-gate * Convert R_REQUEST_* results to the equivalent PAPI attribute representation. 4700Sstevel@tonic-gate */ 4710Sstevel@tonic-gate void 472*1676Sjpk job_status_to_attributes(job_t *job, char *req_id, char *user, char *slabel, 473*1676Sjpk size_t size, time_t date, short state, char *destination, 474*1676Sjpk char *form, char *charset, short rank, char *file) 4750Sstevel@tonic-gate { 4760Sstevel@tonic-gate char buf[BUFSIZ]; 4770Sstevel@tonic-gate char *p; 4780Sstevel@tonic-gate 4790Sstevel@tonic-gate addLPString(&job->attributes, PAPI_ATTR_REPLACE, 4800Sstevel@tonic-gate "job-originating-user-name", user); 4810Sstevel@tonic-gate papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, 4820Sstevel@tonic-gate "job-k-octets", size/1024); 4830Sstevel@tonic-gate papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, 4840Sstevel@tonic-gate "job-octets", size); 4850Sstevel@tonic-gate if ((p = strrchr(req_id, '-')) != NULL) { 4860Sstevel@tonic-gate papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, 4870Sstevel@tonic-gate "job-id", atoi(++p)); 4880Sstevel@tonic-gate } 4890Sstevel@tonic-gate snprintf(buf, sizeof (buf), "lpsched://%s/%d", destination, atoi(p)); 4900Sstevel@tonic-gate papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE, 4910Sstevel@tonic-gate "job-uri", buf); 4920Sstevel@tonic-gate snprintf(buf, sizeof (buf), "lpsched://%s", destination); 4930Sstevel@tonic-gate papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE, 4940Sstevel@tonic-gate "job-printer-uri", buf); 4950Sstevel@tonic-gate papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, 4960Sstevel@tonic-gate "job-printer-up-time", time(NULL)); 4970Sstevel@tonic-gate papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE, 4980Sstevel@tonic-gate "output-device-assigned", destination); 4990Sstevel@tonic-gate papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE, 5000Sstevel@tonic-gate "printer-name", destination); 5010Sstevel@tonic-gate addLPString(&job->attributes, PAPI_ATTR_REPLACE, "media", form); 5020Sstevel@tonic-gate 5030Sstevel@tonic-gate lpsched_request_outcome_to_attributes(&job->attributes, state); 5040Sstevel@tonic-gate 5050Sstevel@tonic-gate papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, 5060Sstevel@tonic-gate "time-at-creation", date); 5070Sstevel@tonic-gate addLPString(&job->attributes, PAPI_ATTR_REPLACE, 5080Sstevel@tonic-gate "lpsched-request-id", req_id); 5090Sstevel@tonic-gate addLPString(&job->attributes, PAPI_ATTR_REPLACE, 5100Sstevel@tonic-gate "lp-charset", charset); 5110Sstevel@tonic-gate papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, 5120Sstevel@tonic-gate "lpsched-job-state", state); 5130Sstevel@tonic-gate papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, 5140Sstevel@tonic-gate "number-of-intervening-jobs", rank - 1); 5150Sstevel@tonic-gate addLPString(&job->attributes, PAPI_ATTR_REPLACE, 5160Sstevel@tonic-gate "lpsched-file", file); 5170Sstevel@tonic-gate addLPString(&job->attributes, PAPI_ATTR_EXCL, 5180Sstevel@tonic-gate "job-name", file); 519*1676Sjpk addLPString(&job->attributes, PAPI_ATTR_EXCL, 520*1676Sjpk "tsol-sensitivity-label", slabel); 5210Sstevel@tonic-gate } 5220Sstevel@tonic-gate 5230Sstevel@tonic-gate void 5240Sstevel@tonic-gate lpsched_read_job_configuration(service_t *svc, job_t *j, char *file) 5250Sstevel@tonic-gate { 5260Sstevel@tonic-gate REQUEST *r; 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate if ((r = getrequest(file)) == NULL) { 5290Sstevel@tonic-gate detailed_error(svc, gettext("unable to read job data: %s"), 5300Sstevel@tonic-gate file); 5310Sstevel@tonic-gate return; 5320Sstevel@tonic-gate } 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate lpsched_request_to_job_attributes(r, j); 5350Sstevel@tonic-gate } 536