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