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 #include <sys/stat.h> 37*0Sstevel@tonic-gate #include <papi_impl.h> 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 40*0Sstevel@tonic-gate static papi_status_t psm_modifyAttrsFile(const papi_attribute_t **attrs, 41*0Sstevel@tonic-gate char *file); 42*0Sstevel@tonic-gate static papi_status_t psm_modifyAttrsList(char *file, 43*0Sstevel@tonic-gate const papi_attribute_t **attrs, papi_attribute_t ***newAttrs); 44*0Sstevel@tonic-gate #endif 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gate void 48*0Sstevel@tonic-gate papiJobFree(papi_job_t job) 49*0Sstevel@tonic-gate { 50*0Sstevel@tonic-gate job_t *tmp = (job_t *)job; 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate if (tmp != NULL) { 53*0Sstevel@tonic-gate papiAttributeListFree(tmp->attributes); 54*0Sstevel@tonic-gate free(tmp); 55*0Sstevel@tonic-gate } 56*0Sstevel@tonic-gate } 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate void 59*0Sstevel@tonic-gate papiJobListFree(papi_job_t *jobs) 60*0Sstevel@tonic-gate { 61*0Sstevel@tonic-gate if (jobs != NULL) { 62*0Sstevel@tonic-gate int i; 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate for (i = 0; jobs[i] != NULL; i++) { 65*0Sstevel@tonic-gate papiJobFree(jobs[i]); 66*0Sstevel@tonic-gate } 67*0Sstevel@tonic-gate free(jobs); 68*0Sstevel@tonic-gate } 69*0Sstevel@tonic-gate } 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate papi_attribute_t ** 72*0Sstevel@tonic-gate papiJobGetAttributeList(papi_job_t job) 73*0Sstevel@tonic-gate { 74*0Sstevel@tonic-gate job_t *tmp = (job_t *)job; 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate if (tmp != NULL) 77*0Sstevel@tonic-gate return (tmp->attributes); 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate return (NULL); 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate char * 83*0Sstevel@tonic-gate papiJobGetPrinterName(papi_job_t job) 84*0Sstevel@tonic-gate { 85*0Sstevel@tonic-gate job_t *tmp = (job_t *)job; 86*0Sstevel@tonic-gate char *result = NULL; 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate if (tmp != NULL) 89*0Sstevel@tonic-gate papiAttributeListGetString(tmp->attributes, NULL, 90*0Sstevel@tonic-gate "printer-name", &result); 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate return (result); 93*0Sstevel@tonic-gate } 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate int32_t 96*0Sstevel@tonic-gate papiJobGetId(papi_job_t job) 97*0Sstevel@tonic-gate { 98*0Sstevel@tonic-gate job_t *tmp = (job_t *)job; 99*0Sstevel@tonic-gate int result = -1; 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate if (tmp != NULL) 102*0Sstevel@tonic-gate papiAttributeListGetInteger(tmp->attributes, NULL, "job-id", 103*0Sstevel@tonic-gate &result); 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate return (result); 106*0Sstevel@tonic-gate } 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate papi_job_ticket_t * 109*0Sstevel@tonic-gate papiJobGetJobTicket(papi_job_t job) 110*0Sstevel@tonic-gate { 111*0Sstevel@tonic-gate return (NULL); /* NOT SUPPORTED */ 112*0Sstevel@tonic-gate } 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate static REQUEST * 115*0Sstevel@tonic-gate create_request(papi_service_t svc, char *printer, papi_attribute_t **attributes) 116*0Sstevel@tonic-gate { 117*0Sstevel@tonic-gate static REQUEST r; 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate memset(&r, 0, sizeof (r)); 120*0Sstevel@tonic-gate r.priority = -1; 121*0Sstevel@tonic-gate r.destination = printer_name_from_uri_id(printer, -1); 122*0Sstevel@tonic-gate job_attributes_to_lpsched_request(svc, &r, attributes); 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate return (&r); 125*0Sstevel@tonic-gate } 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate static papi_status_t 128*0Sstevel@tonic-gate authorized(service_t *svc, int32_t id) 129*0Sstevel@tonic-gate { 130*0Sstevel@tonic-gate papi_status_t result = PAPI_NOT_AUTHORIZED; /* assume the worst */ 131*0Sstevel@tonic-gate char file[32]; 132*0Sstevel@tonic-gate REQUEST *r; 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate snprintf(file, sizeof (file), "%d-0", id); 135*0Sstevel@tonic-gate if ((r = getrequest(file)) != NULL) { 136*0Sstevel@tonic-gate uid_t uid = getuid(); 137*0Sstevel@tonic-gate struct passwd *pw = NULL; 138*0Sstevel@tonic-gate char *user = "intruder"; /* assume an intruder */ 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate if ((pw = getpwuid(uid)) != NULL) 141*0Sstevel@tonic-gate user = pw->pw_name; /* use the process owner */ 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate if ((uid == 0) || (uid == 71)) { /* root/lp can forge this */ 144*0Sstevel@tonic-gate papi_status_t s; 145*0Sstevel@tonic-gate s = papiAttributeListGetString(svc->attributes, NULL, 146*0Sstevel@tonic-gate "user-name", &user); 147*0Sstevel@tonic-gate if (s != PAPI_OK) /* true root/lp are almighty */ 148*0Sstevel@tonic-gate result = PAPI_OK; 149*0Sstevel@tonic-gate } 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate if ((result != PAPI_OK) && (strcmp(user, r->user) == 0)) 152*0Sstevel@tonic-gate result = PAPI_OK; 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate freerequest(r); 155*0Sstevel@tonic-gate } else 156*0Sstevel@tonic-gate result = PAPI_NOT_FOUND; 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gate return (result); 159*0Sstevel@tonic-gate } 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate static papi_status_t 162*0Sstevel@tonic-gate copy_file(const char *from, char *to) 163*0Sstevel@tonic-gate { 164*0Sstevel@tonic-gate int ifd, ofd; 165*0Sstevel@tonic-gate char buf[BUFSIZ]; 166*0Sstevel@tonic-gate int rc; 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate if ((ifd = open(from, O_RDONLY)) < 0) 169*0Sstevel@tonic-gate return (PAPI_DOCUMENT_ACCESS_ERROR); 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate if ((ofd = open(to, O_WRONLY)) < 0) { 172*0Sstevel@tonic-gate close(ifd); 173*0Sstevel@tonic-gate return (PAPI_NOT_POSSIBLE); 174*0Sstevel@tonic-gate } 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate while ((rc = read(ifd, buf, sizeof (buf))) > 0) 177*0Sstevel@tonic-gate write(ofd, buf, rc); 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate close(ifd); 180*0Sstevel@tonic-gate close(ofd); 181*0Sstevel@tonic-gate 182*0Sstevel@tonic-gate return (PAPI_OK); 183*0Sstevel@tonic-gate } 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 187*0Sstevel@tonic-gate /* 188*0Sstevel@tonic-gate * ***************************************************************************** 189*0Sstevel@tonic-gate * 190*0Sstevel@tonic-gate * Description: Create a file containing all the attributes in the attribute 191*0Sstevel@tonic-gate * list passed to this function. 192*0Sstevel@tonic-gate * This file is then passed through lpsched and given to either 193*0Sstevel@tonic-gate * a slow-filter or to the printer's interface script to process 194*0Sstevel@tonic-gate * the attributes. 195*0Sstevel@tonic-gate * 196*0Sstevel@tonic-gate * Parameters: attrs - list of attributes and their values 197*0Sstevel@tonic-gate * file - file pathname to create and put the attributes into. 198*0Sstevel@tonic-gate * 199*0Sstevel@tonic-gate * ***************************************************************************** 200*0Sstevel@tonic-gate */ 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate static papi_status_t 203*0Sstevel@tonic-gate psm_copy_attrsToFile(const papi_attribute_t **attrs, char *file) 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate { 206*0Sstevel@tonic-gate papi_status_t result = PAPI_OK; 207*0Sstevel@tonic-gate FILE *out = NULL; 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate if ((attrs != NULL) && (*attrs != NULL)) 210*0Sstevel@tonic-gate { 211*0Sstevel@tonic-gate out = fopen(file, "w"); 212*0Sstevel@tonic-gate if (out != NULL) 213*0Sstevel@tonic-gate { 214*0Sstevel@tonic-gate papiAttributeListPrint( 215*0Sstevel@tonic-gate out, "", (papi_attribute_t **)attrs); 216*0Sstevel@tonic-gate fclose(out); 217*0Sstevel@tonic-gate } 218*0Sstevel@tonic-gate else 219*0Sstevel@tonic-gate { 220*0Sstevel@tonic-gate result = PAPI_NOT_POSSIBLE; 221*0Sstevel@tonic-gate } 222*0Sstevel@tonic-gate } 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate return (result); 225*0Sstevel@tonic-gate } /* psm_copy_attrsToFile */ 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate /* 229*0Sstevel@tonic-gate * ***************************************************************************** 230*0Sstevel@tonic-gate * 231*0Sstevel@tonic-gate * Description: Modify the given attribute 'file' with the attributes from the 232*0Sstevel@tonic-gate * 'attrs' list. Attributes already in the file will be replaced 233*0Sstevel@tonic-gate * with the new value. New attributes will be added into the file. 234*0Sstevel@tonic-gate * 235*0Sstevel@tonic-gate * Parameters: attrs - list of attributes and their values 236*0Sstevel@tonic-gate * file - file pathname to create and put the attributes into. 237*0Sstevel@tonic-gate * 238*0Sstevel@tonic-gate * ***************************************************************************** 239*0Sstevel@tonic-gate */ 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate static papi_status_t 242*0Sstevel@tonic-gate psm_modifyAttrsFile(const papi_attribute_t **attrs, char *file) 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate { 245*0Sstevel@tonic-gate papi_status_t result = PAPI_OK; 246*0Sstevel@tonic-gate papi_attribute_t **newAttrs = NULL; 247*0Sstevel@tonic-gate struct stat tmpBuf; 248*0Sstevel@tonic-gate FILE *fd = NULL; 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate if ((attrs != NULL) && (*attrs != NULL) && (file != NULL)) 251*0Sstevel@tonic-gate { 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate /* 254*0Sstevel@tonic-gate * check file exist before try to modify it, if it doesn't 255*0Sstevel@tonic-gate * exist assume there is an error 256*0Sstevel@tonic-gate */ 257*0Sstevel@tonic-gate if (stat(file, &tmpBuf) == 0) 258*0Sstevel@tonic-gate { 259*0Sstevel@tonic-gate /* 260*0Sstevel@tonic-gate * if file is currently empty just write the given 261*0Sstevel@tonic-gate * attributes to the file otherwise exact the attributes 262*0Sstevel@tonic-gate * from the file and modify them accordingly before 263*0Sstevel@tonic-gate * writing them back to the file 264*0Sstevel@tonic-gate */ 265*0Sstevel@tonic-gate if (tmpBuf.st_size == 0) 266*0Sstevel@tonic-gate { 267*0Sstevel@tonic-gate printf("psm_modifyAttrsFile() @1 - empty attribute file\n"); 268*0Sstevel@tonic-gate newAttrs = (papi_attribute_t **)attrs; 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate fd = fopen(file, "w"); 271*0Sstevel@tonic-gate if (fd != NULL) 272*0Sstevel@tonic-gate { 273*0Sstevel@tonic-gate papiAttributeListPrint(fd, 274*0Sstevel@tonic-gate "", newAttrs); 275*0Sstevel@tonic-gate fclose(fd); 276*0Sstevel@tonic-gate } 277*0Sstevel@tonic-gate else 278*0Sstevel@tonic-gate { 279*0Sstevel@tonic-gate result = PAPI_NOT_POSSIBLE; 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate else 283*0Sstevel@tonic-gate { 284*0Sstevel@tonic-gate printf("psm_modifyAttrsFile() @2 - modify file\n"); 285*0Sstevel@tonic-gate result = 286*0Sstevel@tonic-gate psm_modifyAttrsList(file, attrs, &newAttrs); 287*0Sstevel@tonic-gate 288*0Sstevel@tonic-gate fd = fopen(file, "w"); 289*0Sstevel@tonic-gate if (fd != NULL) 290*0Sstevel@tonic-gate { 291*0Sstevel@tonic-gate papiAttributeListPrint(fd, 292*0Sstevel@tonic-gate "", newAttrs); 293*0Sstevel@tonic-gate fclose(fd); 294*0Sstevel@tonic-gate } 295*0Sstevel@tonic-gate else 296*0Sstevel@tonic-gate { 297*0Sstevel@tonic-gate result = PAPI_NOT_POSSIBLE; 298*0Sstevel@tonic-gate } 299*0Sstevel@tonic-gate 300*0Sstevel@tonic-gate papiAttributeListFree(newAttrs); 301*0Sstevel@tonic-gate } 302*0Sstevel@tonic-gate } 303*0Sstevel@tonic-gate else 304*0Sstevel@tonic-gate { 305*0Sstevel@tonic-gate result = PAPI_NOT_POSSIBLE; 306*0Sstevel@tonic-gate } 307*0Sstevel@tonic-gate } 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate return (result); 310*0Sstevel@tonic-gate } /* psm_modifyAttrsFile */ 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate /* 314*0Sstevel@tonic-gate * ***************************************************************************** 315*0Sstevel@tonic-gate * 316*0Sstevel@tonic-gate * Description: Extracts the attributes in the given attribute 'file' and 317*0Sstevel@tonic-gate * creates a new list 'newAttrs' containing the modified list of 318*0Sstevel@tonic-gate * attributes. 319*0Sstevel@tonic-gate * 320*0Sstevel@tonic-gate * Parameters: file - pathname of file containing attributes to be modified 321*0Sstevel@tonic-gate * attrs - list of attributes and their values to modify 322*0Sstevel@tonic-gate * newAttrs - returns the modified list of attributes 323*0Sstevel@tonic-gate * 324*0Sstevel@tonic-gate * ***************************************************************************** 325*0Sstevel@tonic-gate */ 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gate static papi_status_t 328*0Sstevel@tonic-gate psm_modifyAttrsList(char *file, const papi_attribute_t **attrs, 329*0Sstevel@tonic-gate papi_attribute_t ***newAttrs) 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate { 332*0Sstevel@tonic-gate papi_status_t result = PAPI_OK; 333*0Sstevel@tonic-gate papi_attribute_t *nextAttr = NULL; 334*0Sstevel@tonic-gate papi_attribute_value_t **values = NULL; 335*0Sstevel@tonic-gate void *iter = NULL; 336*0Sstevel@tonic-gate FILE *fd = NULL; 337*0Sstevel@tonic-gate register int fD = 0; 338*0Sstevel@tonic-gate char aBuff[200]; 339*0Sstevel@tonic-gate char *a = NULL; 340*0Sstevel@tonic-gate char *p = NULL; 341*0Sstevel@tonic-gate int count = 0; 342*0Sstevel@tonic-gate int n = 0; 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate fd = fopen(file, "r"); 345*0Sstevel@tonic-gate if (fd != NULL) 346*0Sstevel@tonic-gate { 347*0Sstevel@tonic-gate fD = fileno(fd); 348*0Sstevel@tonic-gate a = &aBuff[0]; 349*0Sstevel@tonic-gate p = &aBuff[0]; 350*0Sstevel@tonic-gate count = read(fD, &aBuff[0], sizeof (aBuff) - 1); 351*0Sstevel@tonic-gate while ((result == PAPI_OK) && (count > 0)) 352*0Sstevel@tonic-gate { 353*0Sstevel@tonic-gate aBuff[count+n] = '\0'; 354*0Sstevel@tonic-gate if (count == sizeof (aBuff) - n - 1) 355*0Sstevel@tonic-gate { 356*0Sstevel@tonic-gate p = strrchr(aBuff, '\n'); 357*0Sstevel@tonic-gate if (p != NULL) 358*0Sstevel@tonic-gate { 359*0Sstevel@tonic-gate /* terminate at last complete line */ 360*0Sstevel@tonic-gate *p = '\0'; 361*0Sstevel@tonic-gate } 362*0Sstevel@tonic-gate } 363*0Sstevel@tonic-gate printf("psm_modifyAttrsList() @3 - aBuff=\n"); 364*0Sstevel@tonic-gate printf("%s\n", aBuff); 365*0Sstevel@tonic-gate result = papiAttributeListFromString( 366*0Sstevel@tonic-gate newAttrs, PAPI_ATTR_EXCL, aBuff); 367*0Sstevel@tonic-gate printf("psm_modifyAttrsList() @4 - result=%d\n", result); 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate if (result == PAPI_OK) 370*0Sstevel@tonic-gate { 371*0Sstevel@tonic-gate /* 372*0Sstevel@tonic-gate * handle any part lines and then read the next 373*0Sstevel@tonic-gate * buffer from the file 374*0Sstevel@tonic-gate */ 375*0Sstevel@tonic-gate n = 0; 376*0Sstevel@tonic-gate if (p != a) 377*0Sstevel@tonic-gate { 378*0Sstevel@tonic-gate p++; /* skip NL */ 379*0Sstevel@tonic-gate n = sizeof (aBuff) - 1 - (p - a); 380*0Sstevel@tonic-gate strncpy(aBuff, p, n); 381*0Sstevel@tonic-gate } 382*0Sstevel@tonic-gate count = read(fD, &aBuff[n], 383*0Sstevel@tonic-gate sizeof (aBuff) - n - 1); 384*0Sstevel@tonic-gate p = &aBuff[0]; 385*0Sstevel@tonic-gate } 386*0Sstevel@tonic-gate } 387*0Sstevel@tonic-gate fclose(fd); 388*0Sstevel@tonic-gate } 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate /* now modify the attribute list with the new attributes in 'attrs' */ 391*0Sstevel@tonic-gate 392*0Sstevel@tonic-gate nextAttr = papiAttributeListGetNext((papi_attribute_t **)attrs, &iter); 393*0Sstevel@tonic-gate while ((result == PAPI_OK) && (nextAttr != NULL)) 394*0Sstevel@tonic-gate { 395*0Sstevel@tonic-gate values = nextAttr->values; 396*0Sstevel@tonic-gate 397*0Sstevel@tonic-gate if ((values != NULL) && (*values != NULL)) 398*0Sstevel@tonic-gate { 399*0Sstevel@tonic-gate result = papiAttributeListAdd(newAttrs, 400*0Sstevel@tonic-gate PAPI_ATTR_REPLACE, 401*0Sstevel@tonic-gate nextAttr->name, 402*0Sstevel@tonic-gate nextAttr->type, *values); 403*0Sstevel@tonic-gate values++; 404*0Sstevel@tonic-gate } 405*0Sstevel@tonic-gate 406*0Sstevel@tonic-gate while ((result == PAPI_OK) && 407*0Sstevel@tonic-gate (values != NULL) && (*values != NULL)) 408*0Sstevel@tonic-gate { 409*0Sstevel@tonic-gate result = papiAttributeListAdd(newAttrs, 410*0Sstevel@tonic-gate PAPI_ATTR_APPEND, 411*0Sstevel@tonic-gate nextAttr->name, 412*0Sstevel@tonic-gate nextAttr->type, *values); 413*0Sstevel@tonic-gate values++; 414*0Sstevel@tonic-gate } 415*0Sstevel@tonic-gate nextAttr = 416*0Sstevel@tonic-gate papiAttributeListGetNext((papi_attribute_t **)attrs, &iter); 417*0Sstevel@tonic-gate } 418*0Sstevel@tonic-gate 419*0Sstevel@tonic-gate return (result); 420*0Sstevel@tonic-gate } /* papi_modifyAttrsList() */ 421*0Sstevel@tonic-gate #endif 422*0Sstevel@tonic-gate 423*0Sstevel@tonic-gate 424*0Sstevel@tonic-gate papi_status_t 425*0Sstevel@tonic-gate papiJobSubmit(papi_service_t handle, const char *printer, 426*0Sstevel@tonic-gate const papi_attribute_t **job_attributes, 427*0Sstevel@tonic-gate const papi_job_ticket_t *job_ticket, 428*0Sstevel@tonic-gate const char **files, papi_job_t *job) 429*0Sstevel@tonic-gate { 430*0Sstevel@tonic-gate papi_status_t status; 431*0Sstevel@tonic-gate service_t *svc = handle; 432*0Sstevel@tonic-gate job_t *j; 433*0Sstevel@tonic-gate int file_no; 434*0Sstevel@tonic-gate char *request_id = NULL; 435*0Sstevel@tonic-gate REQUEST *request; 436*0Sstevel@tonic-gate int i; 437*0Sstevel@tonic-gate char *c; 438*0Sstevel@tonic-gate char *tmp = NULL; 439*0Sstevel@tonic-gate char lpfile[BUFSIZ]; 440*0Sstevel@tonic-gate 441*0Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (files == NULL) || 442*0Sstevel@tonic-gate (job == NULL)) 443*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 444*0Sstevel@tonic-gate 445*0Sstevel@tonic-gate if (job_ticket != NULL) 446*0Sstevel@tonic-gate return (PAPI_OPERATION_NOT_SUPPORTED); 447*0Sstevel@tonic-gate 448*0Sstevel@tonic-gate if (files != NULL) 449*0Sstevel@tonic-gate for (file_no = 0; files[file_no] != NULL; file_no++) 450*0Sstevel@tonic-gate if (access(files[file_no], R_OK) < 0) { 451*0Sstevel@tonic-gate detailed_error(svc, 452*0Sstevel@tonic-gate gettext("Cannot access file: %s: %s"), 453*0Sstevel@tonic-gate files[file_no], strerror(errno)); 454*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 455*0Sstevel@tonic-gate } 456*0Sstevel@tonic-gate 457*0Sstevel@tonic-gate if ((*job = j = calloc(1, sizeof (*j))) == NULL) 458*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 459*0Sstevel@tonic-gate 460*0Sstevel@tonic-gate /* file_no + 1 for the control file (-0) */ 461*0Sstevel@tonic-gate status = lpsched_alloc_files(svc, file_no + 1, &request_id); 462*0Sstevel@tonic-gate if (status != PAPI_OK) 463*0Sstevel@tonic-gate return (status); 464*0Sstevel@tonic-gate 465*0Sstevel@tonic-gate request = create_request(svc, (char *)printer, 466*0Sstevel@tonic-gate (papi_attribute_t **)job_attributes); 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate for (i = 0; files[i] != NULL; i++) { 469*0Sstevel@tonic-gate papi_status_t status; 470*0Sstevel@tonic-gate snprintf(lpfile, sizeof (lpfile), "%s%s-%d", 471*0Sstevel@tonic-gate "/var/spool/lp/temp/", request_id, i+1); 472*0Sstevel@tonic-gate status = copy_file(files[i], lpfile); 473*0Sstevel@tonic-gate if (status != PAPI_OK) { 474*0Sstevel@tonic-gate detailed_error(svc, 475*0Sstevel@tonic-gate gettext("unable to copy: %s -> %s: %s"), 476*0Sstevel@tonic-gate files[i], lpfile, strerror(errno)); 477*0Sstevel@tonic-gate freerequest(request); 478*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 479*0Sstevel@tonic-gate } 480*0Sstevel@tonic-gate addlist(&(request->file_list), lpfile); 481*0Sstevel@tonic-gate } 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 484*0Sstevel@tonic-gate /* 485*0Sstevel@tonic-gate * store the job attributes in the PAPI job attribute file that was 486*0Sstevel@tonic-gate * created by lpsched_alloc_files(), the attributes will then pass 487*0Sstevel@tonic-gate * through lpsched and be given to the slow-filters and the printer's 488*0Sstevel@tonic-gate * interface script to process them 489*0Sstevel@tonic-gate */ 490*0Sstevel@tonic-gate snprintf(lpfile, sizeof (lpfile), "%s%s-%s", 491*0Sstevel@tonic-gate "/var/spool/lp/temp/", request_id, LP_PAPIATTRNAME); 492*0Sstevel@tonic-gate status = psm_copy_attrsToFile(job_attributes, lpfile); 493*0Sstevel@tonic-gate if (status != PAPI_OK) { 494*0Sstevel@tonic-gate detailed_error(svc, "unable to copy attributes to file: %s: %s", 495*0Sstevel@tonic-gate lpfile, strerror(errno)); 496*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 497*0Sstevel@tonic-gate } 498*0Sstevel@tonic-gate #endif 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate /* store the meta-data file */ 501*0Sstevel@tonic-gate snprintf(lpfile, sizeof (lpfile), "%s-0", request_id); 502*0Sstevel@tonic-gate if (putrequest(lpfile, request) < 0) { 503*0Sstevel@tonic-gate detailed_error(svc, gettext("unable to save request: %s: %s"), 504*0Sstevel@tonic-gate lpfile, strerror(errno)); 505*0Sstevel@tonic-gate freerequest(request); 506*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 507*0Sstevel@tonic-gate } 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gate status = lpsched_commit_job(svc, lpfile, &tmp); 510*0Sstevel@tonic-gate if (status != PAPI_OK) { 511*0Sstevel@tonic-gate unlink(lpfile); 512*0Sstevel@tonic-gate freerequest(request); 513*0Sstevel@tonic-gate return (status); 514*0Sstevel@tonic-gate } 515*0Sstevel@tonic-gate 516*0Sstevel@tonic-gate lpsched_request_to_job_attributes(request, j); 517*0Sstevel@tonic-gate freerequest(request); 518*0Sstevel@tonic-gate 519*0Sstevel@tonic-gate if ((c = strrchr(tmp, '-')) != NULL) 520*0Sstevel@tonic-gate c++; 521*0Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 522*0Sstevel@tonic-gate "job-id", atoi(c)); 523*0Sstevel@tonic-gate papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE, 524*0Sstevel@tonic-gate "job-uri", tmp); 525*0Sstevel@tonic-gate 526*0Sstevel@tonic-gate return (PAPI_OK); 527*0Sstevel@tonic-gate } 528*0Sstevel@tonic-gate 529*0Sstevel@tonic-gate papi_status_t 530*0Sstevel@tonic-gate papiJobSubmitByReference(papi_service_t handle, const char *printer, 531*0Sstevel@tonic-gate const papi_attribute_t **job_attributes, 532*0Sstevel@tonic-gate const papi_job_ticket_t *job_ticket, 533*0Sstevel@tonic-gate const char **files, papi_job_t *job) 534*0Sstevel@tonic-gate { 535*0Sstevel@tonic-gate service_t *svc = handle; 536*0Sstevel@tonic-gate job_t *j; 537*0Sstevel@tonic-gate int file_no; 538*0Sstevel@tonic-gate short status; 539*0Sstevel@tonic-gate char *request_id = NULL; 540*0Sstevel@tonic-gate REQUEST *request; 541*0Sstevel@tonic-gate char *c; 542*0Sstevel@tonic-gate char *tmp = NULL; 543*0Sstevel@tonic-gate char lpfile[BUFSIZ]; 544*0Sstevel@tonic-gate char **file_list = NULL; 545*0Sstevel@tonic-gate 546*0Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (files == NULL) || 547*0Sstevel@tonic-gate (job == NULL)) 548*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate if (job_ticket != NULL) 551*0Sstevel@tonic-gate return (PAPI_OPERATION_NOT_SUPPORTED); 552*0Sstevel@tonic-gate 553*0Sstevel@tonic-gate if (files != NULL) 554*0Sstevel@tonic-gate for (file_no = 0; files[file_no] != NULL; file_no++) { 555*0Sstevel@tonic-gate if (access(files[file_no], R_OK) < 0) { 556*0Sstevel@tonic-gate detailed_error(svc, 557*0Sstevel@tonic-gate gettext("Cannot access file: %s: %s"), 558*0Sstevel@tonic-gate files[file_no], strerror(errno)); 559*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 560*0Sstevel@tonic-gate } 561*0Sstevel@tonic-gate addlist(&file_list, (char *)files[file_no]); 562*0Sstevel@tonic-gate } 563*0Sstevel@tonic-gate 564*0Sstevel@tonic-gate if ((*job = j = calloc(1, sizeof (*j))) == NULL) 565*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate /* 1 for the control file (-0) */ 568*0Sstevel@tonic-gate status = lpsched_alloc_files(svc, 1, &request_id); 569*0Sstevel@tonic-gate if (status != PAPI_OK) 570*0Sstevel@tonic-gate return (status); 571*0Sstevel@tonic-gate 572*0Sstevel@tonic-gate request = create_request(svc, (char *)printer, 573*0Sstevel@tonic-gate (papi_attribute_t **)job_attributes); 574*0Sstevel@tonic-gate request->file_list = file_list; 575*0Sstevel@tonic-gate 576*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 577*0Sstevel@tonic-gate /* 578*0Sstevel@tonic-gate * store the job attributes in the PAPI job attribute file that was 579*0Sstevel@tonic-gate * created by lpsched_alloc_files(), the attributes will then pass 580*0Sstevel@tonic-gate * through lpsched and be given to the slow-filters and the printer's 581*0Sstevel@tonic-gate * interface script to process them 582*0Sstevel@tonic-gate */ 583*0Sstevel@tonic-gate snprintf(lpfile, sizeof (lpfile), "%s%s-%s", 584*0Sstevel@tonic-gate "/var/spool/lp/temp/", request_id, LP_PAPIATTRNAME); 585*0Sstevel@tonic-gate status = psm_copy_attrsToFile(job_attributes, lpfile); 586*0Sstevel@tonic-gate if (status != PAPI_OK) { 587*0Sstevel@tonic-gate detailed_error(svc, "unable to copy attributes to file: %s: %s", 588*0Sstevel@tonic-gate lpfile, strerror(errno)); 589*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 590*0Sstevel@tonic-gate } 591*0Sstevel@tonic-gate #endif 592*0Sstevel@tonic-gate 593*0Sstevel@tonic-gate /* store the meta-data file */ 594*0Sstevel@tonic-gate snprintf(lpfile, sizeof (lpfile), "%s-0", request_id); 595*0Sstevel@tonic-gate if (putrequest(lpfile, request) < 0) { 596*0Sstevel@tonic-gate detailed_error(svc, gettext("unable to save request: %s: %s"), 597*0Sstevel@tonic-gate lpfile, strerror(errno)); 598*0Sstevel@tonic-gate freerequest(request); 599*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 600*0Sstevel@tonic-gate } 601*0Sstevel@tonic-gate 602*0Sstevel@tonic-gate status = lpsched_commit_job(svc, lpfile, &tmp); 603*0Sstevel@tonic-gate if (status != PAPI_OK) { 604*0Sstevel@tonic-gate unlink(lpfile); 605*0Sstevel@tonic-gate freerequest(request); 606*0Sstevel@tonic-gate return (status); 607*0Sstevel@tonic-gate } 608*0Sstevel@tonic-gate 609*0Sstevel@tonic-gate lpsched_request_to_job_attributes(request, j); 610*0Sstevel@tonic-gate 611*0Sstevel@tonic-gate freerequest(request); 612*0Sstevel@tonic-gate 613*0Sstevel@tonic-gate if ((c = strrchr(tmp, '-')) != NULL) 614*0Sstevel@tonic-gate c++; 615*0Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 616*0Sstevel@tonic-gate "job-id", atoi(c)); 617*0Sstevel@tonic-gate papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE, 618*0Sstevel@tonic-gate "job-uri", tmp); 619*0Sstevel@tonic-gate 620*0Sstevel@tonic-gate return (PAPI_OK); 621*0Sstevel@tonic-gate } 622*0Sstevel@tonic-gate 623*0Sstevel@tonic-gate papi_status_t 624*0Sstevel@tonic-gate papiJobValidate(papi_service_t handle, const char *printer, 625*0Sstevel@tonic-gate const papi_attribute_t **job_attributes, 626*0Sstevel@tonic-gate const papi_job_ticket_t *job_ticket, 627*0Sstevel@tonic-gate const char **files, papi_job_t *job) 628*0Sstevel@tonic-gate { 629*0Sstevel@tonic-gate papi_status_t status; 630*0Sstevel@tonic-gate papi_attribute_t **attributes = NULL; 631*0Sstevel@tonic-gate int i; 632*0Sstevel@tonic-gate 633*0Sstevel@tonic-gate papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 634*0Sstevel@tonic-gate "job-hold-until", "hold"); 635*0Sstevel@tonic-gate for (i = 0; job_attributes[i]; i++) 636*0Sstevel@tonic-gate list_append(&attributes, job_attributes[i]); 637*0Sstevel@tonic-gate 638*0Sstevel@tonic-gate status = papiJobSubmitByReference(handle, printer, 639*0Sstevel@tonic-gate (const papi_attribute_t **)attributes, 640*0Sstevel@tonic-gate job_ticket, files, job); 641*0Sstevel@tonic-gate if (status == PAPI_OK) { 642*0Sstevel@tonic-gate int id = papiJobGetId(*job); 643*0Sstevel@tonic-gate 644*0Sstevel@tonic-gate if (id != -1) 645*0Sstevel@tonic-gate papiJobCancel(handle, printer, id); 646*0Sstevel@tonic-gate } 647*0Sstevel@tonic-gate 648*0Sstevel@tonic-gate attributes[1] = NULL; /* after attr[0], they are in another list */ 649*0Sstevel@tonic-gate papiAttributeListFree(attributes); 650*0Sstevel@tonic-gate 651*0Sstevel@tonic-gate return (status); 652*0Sstevel@tonic-gate } 653*0Sstevel@tonic-gate 654*0Sstevel@tonic-gate papi_status_t 655*0Sstevel@tonic-gate papiJobStreamOpen(papi_service_t handle, const char *printer, 656*0Sstevel@tonic-gate const papi_attribute_t **job_attributes, 657*0Sstevel@tonic-gate const papi_job_ticket_t *job_ticket, papi_stream_t *stream) 658*0Sstevel@tonic-gate { 659*0Sstevel@tonic-gate papi_status_t status; 660*0Sstevel@tonic-gate service_t *svc = handle; 661*0Sstevel@tonic-gate job_stream_t *s = NULL; 662*0Sstevel@tonic-gate char *request_id = NULL; 663*0Sstevel@tonic-gate char lpfile[BUFSIZ]; 664*0Sstevel@tonic-gate 665*0Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (stream == NULL)) 666*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 667*0Sstevel@tonic-gate 668*0Sstevel@tonic-gate if (job_ticket != NULL) 669*0Sstevel@tonic-gate return (PAPI_OPERATION_NOT_SUPPORTED); 670*0Sstevel@tonic-gate 671*0Sstevel@tonic-gate if ((*stream = s = calloc(1, sizeof (*s))) == NULL) 672*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 673*0Sstevel@tonic-gate 674*0Sstevel@tonic-gate /* 1 for data, 1 for the meta-data (-0) */ 675*0Sstevel@tonic-gate status = lpsched_alloc_files(svc, 2, &request_id); 676*0Sstevel@tonic-gate if (status != PAPI_OK) 677*0Sstevel@tonic-gate return (status); 678*0Sstevel@tonic-gate 679*0Sstevel@tonic-gate s->request = create_request(svc, (char *)printer, 680*0Sstevel@tonic-gate (papi_attribute_t **)job_attributes); 681*0Sstevel@tonic-gate snprintf(lpfile, sizeof (lpfile), "/var/spool/lp/temp/%s-1", 682*0Sstevel@tonic-gate request_id); 683*0Sstevel@tonic-gate s->fd = open(lpfile, O_WRONLY); 684*0Sstevel@tonic-gate addlist(&(s->request->file_list), lpfile); 685*0Sstevel@tonic-gate 686*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 687*0Sstevel@tonic-gate /* 688*0Sstevel@tonic-gate * store the job attributes in the PAPI job attribute file that was 689*0Sstevel@tonic-gate * created by lpsched_alloc_files(), the attributes will then pass 690*0Sstevel@tonic-gate * through lpsched and be given to the slow-filters and the printer's 691*0Sstevel@tonic-gate * interface script to process them 692*0Sstevel@tonic-gate */ 693*0Sstevel@tonic-gate snprintf(lpfile, sizeof (lpfile), "%s%s-%s", 694*0Sstevel@tonic-gate "/var/spool/lp/temp/", request_id, LP_PAPIATTRNAME); 695*0Sstevel@tonic-gate status = psm_copy_attrsToFile(job_attributes, lpfile); 696*0Sstevel@tonic-gate if (status != PAPI_OK) { 697*0Sstevel@tonic-gate detailed_error(svc, "unable to copy attributes to file: %s: %s", 698*0Sstevel@tonic-gate lpfile, strerror(errno)); 699*0Sstevel@tonic-gate close(s->fd); 700*0Sstevel@tonic-gate free(s); 701*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 702*0Sstevel@tonic-gate } 703*0Sstevel@tonic-gate #endif 704*0Sstevel@tonic-gate 705*0Sstevel@tonic-gate /* store the meta-data file */ 706*0Sstevel@tonic-gate snprintf(lpfile, sizeof (lpfile), "%s-0", request_id); 707*0Sstevel@tonic-gate s->meta_data_file = strdup(lpfile); 708*0Sstevel@tonic-gate if (putrequest(lpfile, s->request) < 0) { 709*0Sstevel@tonic-gate detailed_error(svc, gettext("unable to save request: %s: %s"), 710*0Sstevel@tonic-gate lpfile, strerror(errno)); 711*0Sstevel@tonic-gate s->request = NULL; 712*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 713*0Sstevel@tonic-gate } 714*0Sstevel@tonic-gate 715*0Sstevel@tonic-gate return (PAPI_OK); 716*0Sstevel@tonic-gate } 717*0Sstevel@tonic-gate 718*0Sstevel@tonic-gate papi_status_t 719*0Sstevel@tonic-gate papiJobStreamWrite(papi_service_t handle, 720*0Sstevel@tonic-gate papi_stream_t stream, const void *buffer, const size_t buflen) 721*0Sstevel@tonic-gate { 722*0Sstevel@tonic-gate service_t *svc = handle; 723*0Sstevel@tonic-gate job_stream_t *s = stream; 724*0Sstevel@tonic-gate 725*0Sstevel@tonic-gate if ((svc == NULL) || (stream == NULL) || (buffer == NULL)) 726*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 727*0Sstevel@tonic-gate 728*0Sstevel@tonic-gate if (write(s->fd, buffer, buflen) != buflen) 729*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 730*0Sstevel@tonic-gate 731*0Sstevel@tonic-gate return (PAPI_OK); 732*0Sstevel@tonic-gate } 733*0Sstevel@tonic-gate papi_status_t 734*0Sstevel@tonic-gate papiJobStreamClose(papi_service_t handle, 735*0Sstevel@tonic-gate papi_stream_t stream, papi_job_t *job) 736*0Sstevel@tonic-gate { 737*0Sstevel@tonic-gate papi_status_t status = PAPI_OK; 738*0Sstevel@tonic-gate service_t *svc = handle; 739*0Sstevel@tonic-gate job_stream_t *s = stream; 740*0Sstevel@tonic-gate job_t *j = NULL; 741*0Sstevel@tonic-gate char *tmp = NULL, *c; 742*0Sstevel@tonic-gate 743*0Sstevel@tonic-gate if ((svc == NULL) || (stream == NULL) || (job == NULL)) 744*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 745*0Sstevel@tonic-gate 746*0Sstevel@tonic-gate if ((*job = j = calloc(1, sizeof (*j))) == NULL) 747*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 748*0Sstevel@tonic-gate 749*0Sstevel@tonic-gate close(s->fd); 750*0Sstevel@tonic-gate 751*0Sstevel@tonic-gate lpsched_request_to_job_attributes(s->request, j); 752*0Sstevel@tonic-gate 753*0Sstevel@tonic-gate if (s->meta_data_file != NULL) { 754*0Sstevel@tonic-gate status = lpsched_commit_job(svc, s->meta_data_file, &tmp); 755*0Sstevel@tonic-gate if (status != PAPI_OK) { 756*0Sstevel@tonic-gate unlink(s->meta_data_file); 757*0Sstevel@tonic-gate return (status); 758*0Sstevel@tonic-gate } 759*0Sstevel@tonic-gate if ((c = strrchr(tmp, '-')) != NULL) 760*0Sstevel@tonic-gate c++; 761*0Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 762*0Sstevel@tonic-gate "job-id", atoi(c)); 763*0Sstevel@tonic-gate papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE, 764*0Sstevel@tonic-gate "job-uri", tmp); 765*0Sstevel@tonic-gate free(s->meta_data_file); 766*0Sstevel@tonic-gate } 767*0Sstevel@tonic-gate free(s); 768*0Sstevel@tonic-gate 769*0Sstevel@tonic-gate return (PAPI_OK); 770*0Sstevel@tonic-gate } 771*0Sstevel@tonic-gate 772*0Sstevel@tonic-gate papi_status_t 773*0Sstevel@tonic-gate papiJobQuery(papi_service_t handle, const char *printer, const int32_t job_id, 774*0Sstevel@tonic-gate const char **requested_attrs, 775*0Sstevel@tonic-gate papi_job_t *job) 776*0Sstevel@tonic-gate { 777*0Sstevel@tonic-gate service_t *svc = handle; 778*0Sstevel@tonic-gate job_t *j; 779*0Sstevel@tonic-gate char *dest; 780*0Sstevel@tonic-gate char req_id[32]; 781*0Sstevel@tonic-gate short rc; 782*0Sstevel@tonic-gate char *form = NULL, 783*0Sstevel@tonic-gate *request_id = NULL, 784*0Sstevel@tonic-gate *charset = NULL, 785*0Sstevel@tonic-gate *user = NULL, 786*0Sstevel@tonic-gate *file = NULL; 787*0Sstevel@tonic-gate time_t date = 0; 788*0Sstevel@tonic-gate size_t size = 0; 789*0Sstevel@tonic-gate short rank = 0, 790*0Sstevel@tonic-gate state = 0; 791*0Sstevel@tonic-gate 792*0Sstevel@tonic-gate if ((handle == NULL) || (printer == NULL) || (job_id < 0)) 793*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 794*0Sstevel@tonic-gate 795*0Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, job_id); 796*0Sstevel@tonic-gate snprintf(req_id, sizeof (req_id), "%s-%d", dest, job_id); 797*0Sstevel@tonic-gate free(dest); 798*0Sstevel@tonic-gate 799*0Sstevel@tonic-gate rc = snd_msg(svc, S_INQUIRE_REQUEST_RANK, 0, "", "", req_id, "", ""); 800*0Sstevel@tonic-gate if (rc < 0) 801*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 802*0Sstevel@tonic-gate 803*0Sstevel@tonic-gate if (rcv_msg(svc, R_INQUIRE_REQUEST_RANK, &rc, &request_id, 804*0Sstevel@tonic-gate &user, &size, &date, &state, &dest, &form, 805*0Sstevel@tonic-gate &charset, &rank, &file) < 0) { 806*0Sstevel@tonic-gate detailed_error(svc, 807*0Sstevel@tonic-gate gettext("failed to read response from scheduler")); 808*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 809*0Sstevel@tonic-gate } 810*0Sstevel@tonic-gate 811*0Sstevel@tonic-gate if ((request_id == NULL) || (request_id[0] == NULL)) 812*0Sstevel@tonic-gate return (PAPI_NOT_FOUND); 813*0Sstevel@tonic-gate 814*0Sstevel@tonic-gate if ((*job = j = calloc(1, sizeof (*j))) == NULL) 815*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 816*0Sstevel@tonic-gate 817*0Sstevel@tonic-gate job_status_to_attributes(j, request_id, user, size, date, state, 818*0Sstevel@tonic-gate dest, form, charset, rank, file); 819*0Sstevel@tonic-gate 820*0Sstevel@tonic-gate snprintf(req_id, sizeof (req_id), "%d-0", job_id); 821*0Sstevel@tonic-gate lpsched_read_job_configuration(svc, j, req_id); 822*0Sstevel@tonic-gate 823*0Sstevel@tonic-gate return (PAPI_OK); 824*0Sstevel@tonic-gate } 825*0Sstevel@tonic-gate 826*0Sstevel@tonic-gate papi_status_t 827*0Sstevel@tonic-gate papiJobCancel(papi_service_t handle, const char *printer, const int32_t job_id) 828*0Sstevel@tonic-gate { 829*0Sstevel@tonic-gate papi_status_t result = PAPI_OK; 830*0Sstevel@tonic-gate service_t *svc = handle; 831*0Sstevel@tonic-gate char req_id[64]; 832*0Sstevel@tonic-gate char *dest; 833*0Sstevel@tonic-gate char *user = NULL; 834*0Sstevel@tonic-gate 835*0Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (job_id < 0)) 836*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 837*0Sstevel@tonic-gate 838*0Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, job_id); 839*0Sstevel@tonic-gate snprintf(req_id, sizeof (req_id), "%s-%d", dest, job_id); 840*0Sstevel@tonic-gate free(dest); 841*0Sstevel@tonic-gate 842*0Sstevel@tonic-gate if (papiAttributeListGetString(svc->attributes, NULL, "user-name", 843*0Sstevel@tonic-gate &user) == PAPI_OK) { 844*0Sstevel@tonic-gate REQUEST *r = getrequest(req_id); 845*0Sstevel@tonic-gate 846*0Sstevel@tonic-gate if ((r != NULL) && (strcmp(r->user, user) != 0)) 847*0Sstevel@tonic-gate result = PAPI_NOT_AUTHORIZED; 848*0Sstevel@tonic-gate freerequest(r); 849*0Sstevel@tonic-gate } 850*0Sstevel@tonic-gate 851*0Sstevel@tonic-gate if (result == PAPI_OK) { 852*0Sstevel@tonic-gate short status = MOK; 853*0Sstevel@tonic-gate 854*0Sstevel@tonic-gate if ((snd_msg(svc, S_CANCEL_REQUEST, req_id) < 0) || 855*0Sstevel@tonic-gate (rcv_msg(svc, R_CANCEL_REQUEST, &status) < 0)) 856*0Sstevel@tonic-gate status = MTRANSMITERR; 857*0Sstevel@tonic-gate 858*0Sstevel@tonic-gate result = lpsched_status_to_papi_status(status); 859*0Sstevel@tonic-gate } 860*0Sstevel@tonic-gate 861*0Sstevel@tonic-gate return (result); 862*0Sstevel@tonic-gate } 863*0Sstevel@tonic-gate 864*0Sstevel@tonic-gate papi_status_t 865*0Sstevel@tonic-gate hold_release_job(papi_service_t handle, const char *printer, 866*0Sstevel@tonic-gate const int32_t job_id, int flag) 867*0Sstevel@tonic-gate { 868*0Sstevel@tonic-gate papi_status_t status; 869*0Sstevel@tonic-gate service_t *svc = handle; 870*0Sstevel@tonic-gate REQUEST *r = NULL; 871*0Sstevel@tonic-gate char *file; 872*0Sstevel@tonic-gate char *dest; 873*0Sstevel@tonic-gate 874*0Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (job_id < 0)) 875*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 876*0Sstevel@tonic-gate 877*0Sstevel@tonic-gate if ((status = authorized(svc, job_id)) != PAPI_OK) 878*0Sstevel@tonic-gate return (status); 879*0Sstevel@tonic-gate 880*0Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, job_id); 881*0Sstevel@tonic-gate status = lpsched_start_change(svc, dest, job_id, &file); 882*0Sstevel@tonic-gate if (status != PAPI_OK) 883*0Sstevel@tonic-gate return (status); 884*0Sstevel@tonic-gate 885*0Sstevel@tonic-gate if ((r = getrequest(file)) != NULL) { 886*0Sstevel@tonic-gate r->actions &= ~ACT_RESUME; 887*0Sstevel@tonic-gate if (flag == 0) 888*0Sstevel@tonic-gate r->actions |= ACT_HOLD; 889*0Sstevel@tonic-gate else 890*0Sstevel@tonic-gate r->actions |= ACT_RESUME; 891*0Sstevel@tonic-gate if (putrequest(file, r) < 0) { 892*0Sstevel@tonic-gate detailed_error(svc, 893*0Sstevel@tonic-gate gettext("failed to write job: %s: %s"), 894*0Sstevel@tonic-gate file, strerror(errno)); 895*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 896*0Sstevel@tonic-gate } 897*0Sstevel@tonic-gate } else { 898*0Sstevel@tonic-gate detailed_error(svc, gettext("failed to read job: %s: %s"), 899*0Sstevel@tonic-gate file, strerror(errno)); 900*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 901*0Sstevel@tonic-gate } 902*0Sstevel@tonic-gate 903*0Sstevel@tonic-gate status = lpsched_end_change(svc, dest, job_id); 904*0Sstevel@tonic-gate freerequest(r); 905*0Sstevel@tonic-gate free(dest); 906*0Sstevel@tonic-gate 907*0Sstevel@tonic-gate return (status); 908*0Sstevel@tonic-gate } 909*0Sstevel@tonic-gate 910*0Sstevel@tonic-gate papi_status_t 911*0Sstevel@tonic-gate papiJobHold(papi_service_t handle, const char *printer, const int32_t job_id, 912*0Sstevel@tonic-gate const char *hold_until, const time_t *hold_until_time) 913*0Sstevel@tonic-gate { 914*0Sstevel@tonic-gate return (hold_release_job(handle, printer, job_id, 0)); 915*0Sstevel@tonic-gate } 916*0Sstevel@tonic-gate 917*0Sstevel@tonic-gate papi_status_t 918*0Sstevel@tonic-gate papiJobRelease(papi_service_t handle, const char *printer, const int32_t job_id) 919*0Sstevel@tonic-gate { 920*0Sstevel@tonic-gate return (hold_release_job(handle, printer, job_id, 1)); 921*0Sstevel@tonic-gate } 922*0Sstevel@tonic-gate 923*0Sstevel@tonic-gate papi_status_t 924*0Sstevel@tonic-gate papiJobRestart(papi_service_t handle, const char *printer, const int32_t job_id) 925*0Sstevel@tonic-gate { 926*0Sstevel@tonic-gate return (PAPI_OPERATION_NOT_SUPPORTED); 927*0Sstevel@tonic-gate } 928*0Sstevel@tonic-gate 929*0Sstevel@tonic-gate papi_status_t 930*0Sstevel@tonic-gate papiJobModify(papi_service_t handle, const char *printer, const int32_t job_id, 931*0Sstevel@tonic-gate const papi_attribute_t **attributes, papi_job_t *job) 932*0Sstevel@tonic-gate { 933*0Sstevel@tonic-gate papi_status_t status; 934*0Sstevel@tonic-gate job_t *j = NULL; 935*0Sstevel@tonic-gate service_t *svc = handle; 936*0Sstevel@tonic-gate char *file = NULL; 937*0Sstevel@tonic-gate char *dest; 938*0Sstevel@tonic-gate REQUEST *r = NULL; 939*0Sstevel@tonic-gate char lpfile[BUFSIZ]; 940*0Sstevel@tonic-gate 941*0Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 942*0Sstevel@tonic-gate (attributes == NULL)) 943*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 944*0Sstevel@tonic-gate 945*0Sstevel@tonic-gate if ((status = authorized(svc, job_id)) != PAPI_OK) 946*0Sstevel@tonic-gate return (status); 947*0Sstevel@tonic-gate 948*0Sstevel@tonic-gate if ((*job = j = calloc(1, sizeof (*j))) == NULL) 949*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 950*0Sstevel@tonic-gate 951*0Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, job_id); 952*0Sstevel@tonic-gate status = lpsched_start_change(svc, dest, job_id, &file); 953*0Sstevel@tonic-gate if (status != PAPI_OK) 954*0Sstevel@tonic-gate return (status); 955*0Sstevel@tonic-gate 956*0Sstevel@tonic-gate if ((r = getrequest(file)) != NULL) { 957*0Sstevel@tonic-gate job_attributes_to_lpsched_request(handle, r, 958*0Sstevel@tonic-gate (papi_attribute_t **)attributes); 959*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 960*0Sstevel@tonic-gate /* 961*0Sstevel@tonic-gate * store the job attributes in the PAPI job attribute file 962*0Sstevel@tonic-gate * that was created by the origonal job request. We need to 963*0Sstevel@tonic-gate * modify the attributes in the file as per the new attributes 964*0Sstevel@tonic-gate */ 965*0Sstevel@tonic-gate snprintf(lpfile, sizeof (lpfile), "%s%d-%s", 966*0Sstevel@tonic-gate "/var/spool/lp/temp/", job_id, LP_PAPIATTRNAME); 967*0Sstevel@tonic-gate status = psm_modifyAttrsFile(attributes, lpfile); 968*0Sstevel@tonic-gate if (status != PAPI_OK) { 969*0Sstevel@tonic-gate detailed_error(svc, 970*0Sstevel@tonic-gate "unable to modify the attributes file: %s: %s", 971*0Sstevel@tonic-gate lpfile, strerror(errno)); 972*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 973*0Sstevel@tonic-gate } 974*0Sstevel@tonic-gate #endif 975*0Sstevel@tonic-gate 976*0Sstevel@tonic-gate if (putrequest(file, r) < 0) { 977*0Sstevel@tonic-gate detailed_error(svc, 978*0Sstevel@tonic-gate gettext("failed to write job: %s: %s"), 979*0Sstevel@tonic-gate file, strerror(errno)); 980*0Sstevel@tonic-gate freerequest(r); 981*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 982*0Sstevel@tonic-gate } 983*0Sstevel@tonic-gate } else { 984*0Sstevel@tonic-gate detailed_error(svc, gettext("failed to read job: %s: %s"), 985*0Sstevel@tonic-gate file, strerror(errno)); 986*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 987*0Sstevel@tonic-gate } 988*0Sstevel@tonic-gate 989*0Sstevel@tonic-gate status = lpsched_end_change(svc, dest, job_id); 990*0Sstevel@tonic-gate lpsched_request_to_job_attributes(r, j); 991*0Sstevel@tonic-gate freerequest(r); 992*0Sstevel@tonic-gate free(dest); 993*0Sstevel@tonic-gate 994*0Sstevel@tonic-gate return (status); 995*0Sstevel@tonic-gate } 996*0Sstevel@tonic-gate 997*0Sstevel@tonic-gate /* 998*0Sstevel@tonic-gate * Extension to PAPI, a variation of this is slated for post-1.0 999*0Sstevel@tonic-gate */ 1000*0Sstevel@tonic-gate #define DUMMY_FILE "/var/spool/lp/fifos/FIFO" 1001*0Sstevel@tonic-gate 1002*0Sstevel@tonic-gate papi_status_t 1003*0Sstevel@tonic-gate papiJobCreate(papi_service_t handle, const char *printer, 1004*0Sstevel@tonic-gate const papi_attribute_t **job_attributes, 1005*0Sstevel@tonic-gate const papi_job_ticket_t *job_ticket, papi_job_t *job) 1006*0Sstevel@tonic-gate { 1007*0Sstevel@tonic-gate papi_status_t status; 1008*0Sstevel@tonic-gate service_t *svc = handle; 1009*0Sstevel@tonic-gate job_t *j = NULL; 1010*0Sstevel@tonic-gate REQUEST *request; 1011*0Sstevel@tonic-gate char *request_id = NULL; 1012*0Sstevel@tonic-gate char *c; 1013*0Sstevel@tonic-gate char *tmp = NULL; 1014*0Sstevel@tonic-gate char metadata_file[MAXPATHLEN]; 1015*0Sstevel@tonic-gate 1016*0Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (job == NULL)) 1017*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 1018*0Sstevel@tonic-gate 1019*0Sstevel@tonic-gate if (job_ticket != NULL) 1020*0Sstevel@tonic-gate return (PAPI_JOB_TICKET_NOT_SUPPORTED); 1021*0Sstevel@tonic-gate 1022*0Sstevel@tonic-gate if ((*job = j = calloc(1, sizeof (*j))) == NULL) 1023*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 1024*0Sstevel@tonic-gate 1025*0Sstevel@tonic-gate /* 1 for the control file (-0) */ 1026*0Sstevel@tonic-gate status = lpsched_alloc_files(svc, 1, &request_id); 1027*0Sstevel@tonic-gate if (status != PAPI_OK) 1028*0Sstevel@tonic-gate return (status); 1029*0Sstevel@tonic-gate 1030*0Sstevel@tonic-gate /* convert the attributes to an lpsched REQUEST structure */ 1031*0Sstevel@tonic-gate request = create_request(svc, (char *)printer, 1032*0Sstevel@tonic-gate (papi_attribute_t **)job_attributes); 1033*0Sstevel@tonic-gate addlist(&request->file_list, DUMMY_FILE); /* add a dummy file */ 1034*0Sstevel@tonic-gate request->actions |= ACT_HOLD; /* hold the job */ 1035*0Sstevel@tonic-gate 1036*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 1037*0Sstevel@tonic-gate /* 1038*0Sstevel@tonic-gate * store the job attributes in the PAPI job attribute file that was 1039*0Sstevel@tonic-gate * created by lpsched_alloc_files(), the attributes will then pass 1040*0Sstevel@tonic-gate * through lpsched and be given to the slow-filters and the printer's 1041*0Sstevel@tonic-gate * interface script to process them 1042*0Sstevel@tonic-gate */ 1043*0Sstevel@tonic-gate snprintf(metadata_file, sizeof (metadata_file), "%s%s-%s", 1044*0Sstevel@tonic-gate "/var/spool/lp/temp/", request_id, LP_PAPIATTRNAME); 1045*0Sstevel@tonic-gate status = psm_copy_attrsToFile(job_attributes, metadata_file); 1046*0Sstevel@tonic-gate if (status != PAPI_OK) { 1047*0Sstevel@tonic-gate detailed_error(svc, "unable to copy attributes to file: %s: %s", 1048*0Sstevel@tonic-gate metadata_file, strerror(errno)); 1049*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 1050*0Sstevel@tonic-gate } 1051*0Sstevel@tonic-gate #endif 1052*0Sstevel@tonic-gate 1053*0Sstevel@tonic-gate /* store the REQUEST on disk */ 1054*0Sstevel@tonic-gate snprintf(metadata_file, sizeof (metadata_file), "%s-0", request_id); 1055*0Sstevel@tonic-gate if (putrequest(metadata_file, request) < 0) { 1056*0Sstevel@tonic-gate detailed_error(svc, gettext("unable to save request: %s: %s"), 1057*0Sstevel@tonic-gate metadata_file, strerror(errno)); 1058*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 1059*0Sstevel@tonic-gate } 1060*0Sstevel@tonic-gate 1061*0Sstevel@tonic-gate status = lpsched_commit_job(svc, metadata_file, &tmp); 1062*0Sstevel@tonic-gate if (status != PAPI_OK) { 1063*0Sstevel@tonic-gate unlink(metadata_file); 1064*0Sstevel@tonic-gate return (status); 1065*0Sstevel@tonic-gate } 1066*0Sstevel@tonic-gate 1067*0Sstevel@tonic-gate lpsched_request_to_job_attributes(request, j); 1068*0Sstevel@tonic-gate 1069*0Sstevel@tonic-gate if ((c = strrchr(tmp, '-')) != NULL) 1070*0Sstevel@tonic-gate c++; 1071*0Sstevel@tonic-gate papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, 1072*0Sstevel@tonic-gate "job-id", atoi(c)); 1073*0Sstevel@tonic-gate papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE, 1074*0Sstevel@tonic-gate "job-uri", tmp); 1075*0Sstevel@tonic-gate 1076*0Sstevel@tonic-gate return (PAPI_OK); 1077*0Sstevel@tonic-gate } 1078*0Sstevel@tonic-gate 1079*0Sstevel@tonic-gate papi_status_t 1080*0Sstevel@tonic-gate papiJobCommit(papi_service_t handle, char *printer, int32_t id) 1081*0Sstevel@tonic-gate { 1082*0Sstevel@tonic-gate papi_status_t status = PAPI_OK; 1083*0Sstevel@tonic-gate service_t *svc = handle; 1084*0Sstevel@tonic-gate REQUEST *r = NULL; 1085*0Sstevel@tonic-gate char *metadata_file; 1086*0Sstevel@tonic-gate char *dest; 1087*0Sstevel@tonic-gate 1088*0Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL)) 1089*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 1090*0Sstevel@tonic-gate 1091*0Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, id); 1092*0Sstevel@tonic-gate /* tell the scheduler that we want to change the job */ 1093*0Sstevel@tonic-gate status = lpsched_start_change(svc, dest, id, &metadata_file); 1094*0Sstevel@tonic-gate if (status != PAPI_OK) 1095*0Sstevel@tonic-gate return (status); 1096*0Sstevel@tonic-gate 1097*0Sstevel@tonic-gate if ((r = getrequest(metadata_file)) != NULL) { 1098*0Sstevel@tonic-gate r->actions &= ~ACT_RESUME; 1099*0Sstevel@tonic-gate r->actions |= ACT_RESUME; 1100*0Sstevel@tonic-gate dellist(&r->file_list, DUMMY_FILE); 1101*0Sstevel@tonic-gate 1102*0Sstevel@tonic-gate if (putrequest(metadata_file, r) < 0) { 1103*0Sstevel@tonic-gate detailed_error(svc, 1104*0Sstevel@tonic-gate gettext("failed to write job: %s: %s"), 1105*0Sstevel@tonic-gate metadata_file, strerror(errno)); 1106*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 1107*0Sstevel@tonic-gate } 1108*0Sstevel@tonic-gate } else { 1109*0Sstevel@tonic-gate detailed_error(svc, gettext("failed to read job: %s: %s"), 1110*0Sstevel@tonic-gate metadata_file, strerror(errno)); 1111*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 1112*0Sstevel@tonic-gate } 1113*0Sstevel@tonic-gate 1114*0Sstevel@tonic-gate status = lpsched_end_change(svc, dest, id); 1115*0Sstevel@tonic-gate freerequest(r); 1116*0Sstevel@tonic-gate free(dest); 1117*0Sstevel@tonic-gate 1118*0Sstevel@tonic-gate return (status); 1119*0Sstevel@tonic-gate } 1120*0Sstevel@tonic-gate 1121*0Sstevel@tonic-gate papi_status_t 1122*0Sstevel@tonic-gate papiJobStreamAdd(papi_service_t handle, char *printer, int32_t id, 1123*0Sstevel@tonic-gate papi_stream_t *stream) 1124*0Sstevel@tonic-gate { 1125*0Sstevel@tonic-gate papi_status_t status; 1126*0Sstevel@tonic-gate service_t *svc = handle; 1127*0Sstevel@tonic-gate job_stream_t *s = NULL; 1128*0Sstevel@tonic-gate char *metadata_file = NULL; 1129*0Sstevel@tonic-gate char *dest; 1130*0Sstevel@tonic-gate char path[MAXPATHLEN]; 1131*0Sstevel@tonic-gate 1132*0Sstevel@tonic-gate /* allocate space for the stream */ 1133*0Sstevel@tonic-gate if ((*stream = s = calloc(1, sizeof (*s))) == NULL) 1134*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 1135*0Sstevel@tonic-gate 1136*0Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, id); 1137*0Sstevel@tonic-gate /* create/open data file (only root or lp can really do this */ 1138*0Sstevel@tonic-gate snprintf(path, sizeof (path), "/var/spool/lp/temp/%d-XXXXXX", id); 1139*0Sstevel@tonic-gate if ((s->fd = mkstemp(path)) < 0) { 1140*0Sstevel@tonic-gate detailed_error(svc, gettext("unable to create sink (%s): %s"), 1141*0Sstevel@tonic-gate path, strerror(errno)); 1142*0Sstevel@tonic-gate free(s); 1143*0Sstevel@tonic-gate return (PAPI_NOT_AUTHORIZED); 1144*0Sstevel@tonic-gate } 1145*0Sstevel@tonic-gate 1146*0Sstevel@tonic-gate /* add data file to job */ 1147*0Sstevel@tonic-gate status = lpsched_start_change(svc, dest, id, &metadata_file); 1148*0Sstevel@tonic-gate if (status != PAPI_OK) { 1149*0Sstevel@tonic-gate close(s->fd); 1150*0Sstevel@tonic-gate free(s); 1151*0Sstevel@tonic-gate unlink(path); 1152*0Sstevel@tonic-gate return (status); 1153*0Sstevel@tonic-gate } 1154*0Sstevel@tonic-gate 1155*0Sstevel@tonic-gate if ((s->request = getrequest(metadata_file)) == NULL) { 1156*0Sstevel@tonic-gate detailed_error(svc, gettext("unable to load request: %s: %s"), 1157*0Sstevel@tonic-gate metadata_file, strerror(errno)); 1158*0Sstevel@tonic-gate close(s->fd); 1159*0Sstevel@tonic-gate free(s); 1160*0Sstevel@tonic-gate unlink(path); 1161*0Sstevel@tonic-gate return (PAPI_NOT_POSSIBLE); 1162*0Sstevel@tonic-gate } 1163*0Sstevel@tonic-gate 1164*0Sstevel@tonic-gate addlist(&(s->request->file_list), path); 1165*0Sstevel@tonic-gate 1166*0Sstevel@tonic-gate if (putrequest(metadata_file, s->request) < 0) { 1167*0Sstevel@tonic-gate detailed_error(svc, gettext("unable to save request: %s: %s"), 1168*0Sstevel@tonic-gate metadata_file, strerror(errno)); 1169*0Sstevel@tonic-gate close(s->fd); 1170*0Sstevel@tonic-gate free(s); 1171*0Sstevel@tonic-gate unlink(path); 1172*0Sstevel@tonic-gate return (PAPI_NOT_POSSIBLE); 1173*0Sstevel@tonic-gate } 1174*0Sstevel@tonic-gate 1175*0Sstevel@tonic-gate status = lpsched_end_change(svc, dest, id); 1176*0Sstevel@tonic-gate free(dest); 1177*0Sstevel@tonic-gate 1178*0Sstevel@tonic-gate if (status != PAPI_OK) 1179*0Sstevel@tonic-gate return (status); 1180*0Sstevel@tonic-gate 1181*0Sstevel@tonic-gate return (PAPI_OK); 1182*0Sstevel@tonic-gate } 1183