1355b4669Sjacobs /* 2355b4669Sjacobs * CDDL HEADER START 3355b4669Sjacobs * 4355b4669Sjacobs * The contents of this file are subject to the terms of the 5355b4669Sjacobs * Common Development and Distribution License (the "License"). 6355b4669Sjacobs * You may not use this file except in compliance with the License. 7355b4669Sjacobs * 8355b4669Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9355b4669Sjacobs * or http://www.opensolaris.org/os/licensing. 10355b4669Sjacobs * See the License for the specific language governing permissions 11355b4669Sjacobs * and limitations under the License. 12355b4669Sjacobs * 13355b4669Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 14355b4669Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15355b4669Sjacobs * If applicable, add the following below this CDDL HEADER, with the 16355b4669Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 17355b4669Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 18355b4669Sjacobs * 19355b4669Sjacobs * CDDL HEADER END 20355b4669Sjacobs */ 21355b4669Sjacobs 22355b4669Sjacobs /* 23*edafac1fSKeerthi Kondaka * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24355b4669Sjacobs * Use is subject to license terms. 25355b4669Sjacobs * 26355b4669Sjacobs */ 27355b4669Sjacobs 28355b4669Sjacobs /* $Id: job.c 148 2006-04-25 16:54:17Z njacobs $ */ 29355b4669Sjacobs 30355b4669Sjacobs 31355b4669Sjacobs /*LINTLIBRARY*/ 32355b4669Sjacobs 33355b4669Sjacobs #include <stdlib.h> 34355b4669Sjacobs #include <errno.h> 35355b4669Sjacobs #include <string.h> 36355b4669Sjacobs #include <papi_impl.h> 3795c2d302SJonathan Cowper-Andrewes #include <fcntl.h> 3895c2d302SJonathan Cowper-Andrewes #include <sys/types.h> 3995c2d302SJonathan Cowper-Andrewes #include <sys/stat.h> 40a5669307SJonathan Cowper-Andrewes #include <libintl.h> 41355b4669Sjacobs 42355b4669Sjacobs #ifndef OPID_CUPS_MOVE_JOB 43355b4669Sjacobs #define OPID_CUPS_MOVE_JOB 0x400D 44355b4669Sjacobs #endif 45355b4669Sjacobs 46355b4669Sjacobs void 47355b4669Sjacobs papiJobFree(papi_job_t job) 48355b4669Sjacobs { 49355b4669Sjacobs job_t *tmp = (job_t *)job; 50355b4669Sjacobs 51355b4669Sjacobs if (tmp != NULL) { 52355b4669Sjacobs if (tmp->attributes != NULL) 53355b4669Sjacobs papiAttributeListFree(tmp->attributes); 54355b4669Sjacobs free(tmp); 55355b4669Sjacobs } 56355b4669Sjacobs } 57355b4669Sjacobs 58355b4669Sjacobs void 59355b4669Sjacobs papiJobListFree(papi_job_t *jobs) 60355b4669Sjacobs { 61355b4669Sjacobs if (jobs != NULL) { 62355b4669Sjacobs int i; 63355b4669Sjacobs 64355b4669Sjacobs for (i = 0; jobs[i] != NULL; i++) 65355b4669Sjacobs papiJobFree(jobs[i]); 66355b4669Sjacobs free(jobs); 67355b4669Sjacobs } 68355b4669Sjacobs } 69355b4669Sjacobs 70355b4669Sjacobs papi_attribute_t ** 71355b4669Sjacobs papiJobGetAttributeList(papi_job_t job) 72355b4669Sjacobs { 73355b4669Sjacobs papi_attribute_t **result = NULL; 74355b4669Sjacobs job_t *j = job; 75355b4669Sjacobs 76355b4669Sjacobs if (j != NULL) 77355b4669Sjacobs result = j->attributes; 78355b4669Sjacobs 79355b4669Sjacobs return (result); 80355b4669Sjacobs } 81355b4669Sjacobs 82355b4669Sjacobs char * 83355b4669Sjacobs papiJobGetPrinterName(papi_job_t job) 84355b4669Sjacobs { 85355b4669Sjacobs char *result = NULL; 86355b4669Sjacobs job_t *j = job; 87355b4669Sjacobs 88355b4669Sjacobs if (j != NULL) 89355b4669Sjacobs (void) papiAttributeListGetString(j->attributes, NULL, 90355b4669Sjacobs "printer-name", &result); 91355b4669Sjacobs 92355b4669Sjacobs return (result); 93355b4669Sjacobs } 94355b4669Sjacobs 95355b4669Sjacobs int32_t 96355b4669Sjacobs papiJobGetId(papi_job_t job) 97355b4669Sjacobs { 98355b4669Sjacobs int32_t result = -1; 99355b4669Sjacobs job_t *j = job; 100355b4669Sjacobs 101355b4669Sjacobs if (j != NULL) 102355b4669Sjacobs (void) papiAttributeListGetInteger(j->attributes, NULL, 103355b4669Sjacobs "job-id", &result); 104355b4669Sjacobs 105355b4669Sjacobs return (result); 106355b4669Sjacobs } 107355b4669Sjacobs 108355b4669Sjacobs papi_job_ticket_t * 109355b4669Sjacobs papiJobGetJobTicket(papi_job_t job) 110355b4669Sjacobs { 111355b4669Sjacobs papi_job_ticket_t *result = NULL; 112355b4669Sjacobs 113355b4669Sjacobs return (result); 114355b4669Sjacobs } 115355b4669Sjacobs 116355b4669Sjacobs static void 117355b4669Sjacobs populate_job_request(service_t *svc, papi_attribute_t ***request, 118355b4669Sjacobs papi_attribute_t **attributes, char *printer, uint16_t type) 119355b4669Sjacobs { 120355b4669Sjacobs papi_attribute_t **operational = NULL, **job = NULL; 121355b4669Sjacobs static char *operational_names[] = { 122355b4669Sjacobs "job-name", "ipp-attribute-fidelity", "document-name", 123355b4669Sjacobs "compression", "document-format", "document-natural-language", 124355b4669Sjacobs "job-k-octets", "job-impressions", "job-media-sheets", NULL 125355b4669Sjacobs }; 126355b4669Sjacobs 127355b4669Sjacobs /* create the base IPP request */ 128355b4669Sjacobs ipp_initialize_request(svc, request, type); 129355b4669Sjacobs 130355b4669Sjacobs /* create an operational attributes group */ 131223f6c28Sjacobs ipp_initialize_operational_attributes(svc, &operational, printer, -1); 132355b4669Sjacobs 133355b4669Sjacobs /* split up the attributes into operational and job attributes */ 134355b4669Sjacobs split_and_copy_attributes(operational_names, attributes, 135355b4669Sjacobs &operational, &job); 136355b4669Sjacobs 137355b4669Sjacobs /* add the operational attributes group to the request */ 138355b4669Sjacobs papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, 139355b4669Sjacobs "operational-attributes-group", operational); 140355b4669Sjacobs papiAttributeListFree(operational); 141355b4669Sjacobs 142355b4669Sjacobs /* add the job attributes group to the request */ 143355b4669Sjacobs if (job != NULL) { 1443d09a4feSsonam gupta - Sun Microsystems - Bangalore India /* 1453d09a4feSsonam gupta - Sun Microsystems - Bangalore India * Add job-originating-host-name to attributes 1463d09a4feSsonam gupta - Sun Microsystems - Bangalore India * if not already set. 1473d09a4feSsonam gupta - Sun Microsystems - Bangalore India */ 1483d09a4feSsonam gupta - Sun Microsystems - Bangalore India char *hostname = NULL; 1493d09a4feSsonam gupta - Sun Microsystems - Bangalore India 1503d09a4feSsonam gupta - Sun Microsystems - Bangalore India papiAttributeListGetString(job, NULL, 1513d09a4feSsonam gupta - Sun Microsystems - Bangalore India "job-originating-host-name", &hostname); 1523d09a4feSsonam gupta - Sun Microsystems - Bangalore India 1533d09a4feSsonam gupta - Sun Microsystems - Bangalore India if (hostname == NULL) { 1543d09a4feSsonam gupta - Sun Microsystems - Bangalore India char host[BUFSIZ]; 1553d09a4feSsonam gupta - Sun Microsystems - Bangalore India 1563d09a4feSsonam gupta - Sun Microsystems - Bangalore India if (gethostname(host, sizeof (host)) == 0) 1573d09a4feSsonam gupta - Sun Microsystems - Bangalore India papiAttributeListAddString(&job, PAPI_ATTR_EXCL, 1583d09a4feSsonam gupta - Sun Microsystems - Bangalore India "job-originating-host-name", host); 1593d09a4feSsonam gupta - Sun Microsystems - Bangalore India } 1603d09a4feSsonam gupta - Sun Microsystems - Bangalore India 161355b4669Sjacobs papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, 162355b4669Sjacobs "job-attributes-group", job); 163355b4669Sjacobs papiAttributeListFree(job); 164355b4669Sjacobs } 165355b4669Sjacobs } 166355b4669Sjacobs 167355b4669Sjacobs static papi_status_t 168355b4669Sjacobs send_document_uri(service_t *svc, char *file, papi_attribute_t **attributes, 169355b4669Sjacobs char *printer, int32_t id, char last, uint16_t type) 170355b4669Sjacobs { 171355b4669Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 172355b4669Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 173355b4669Sjacobs 174355b4669Sjacobs /* create the base IPP request */ 175355b4669Sjacobs ipp_initialize_request(svc, &request, type); 176355b4669Sjacobs 177355b4669Sjacobs /* create an operational attributes group */ 178223f6c28Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, id); 179355b4669Sjacobs 180355b4669Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, "document-name", 181355b4669Sjacobs file); 182355b4669Sjacobs papiAttributeListAddBoolean(&op, PAPI_ATTR_REPLACE, "last-document", 183355b4669Sjacobs (last ? PAPI_TRUE : PAPI_FALSE)); 184355b4669Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 185355b4669Sjacobs "operational-attributes-group", op); 186355b4669Sjacobs papiAttributeListFree(op); 187355b4669Sjacobs 188355b4669Sjacobs /* send the IPP request to the server */ 189355b4669Sjacobs result = ipp_send_request_with_file(svc, request, &response, file); 190355b4669Sjacobs papiAttributeListFree(request); 191355b4669Sjacobs papiAttributeListFree(response); 192355b4669Sjacobs 193355b4669Sjacobs return (result); 194355b4669Sjacobs } 195355b4669Sjacobs 196355b4669Sjacobs typedef enum {_WITH_DATA, _BY_REFERENCE, _VALIDATE} call_type_t; 197355b4669Sjacobs 198355b4669Sjacobs papi_status_t 199355b4669Sjacobs internal_job_submit(papi_service_t handle, char *printer, 200355b4669Sjacobs papi_attribute_t **job_attributes, 201355b4669Sjacobs papi_job_ticket_t *job_ticket, 202355b4669Sjacobs char **files, papi_job_t *job, 203355b4669Sjacobs call_type_t call_type) 204355b4669Sjacobs { 205355b4669Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 206355b4669Sjacobs service_t *svc = handle; 20795c2d302SJonathan Cowper-Andrewes struct stat statbuf; 208355b4669Sjacobs job_t *j = NULL; 209355b4669Sjacobs int i; 210355b4669Sjacobs uint16_t req_type = OPID_PRINT_JOB; 211355b4669Sjacobs uint16_t data_type = OPID_SEND_DOCUMENT; 212355b4669Sjacobs papi_attribute_t **request = NULL, **response = NULL; 213355b4669Sjacobs 214355b4669Sjacobs if ((svc == NULL) || (printer == NULL) || (job == NULL)) 215355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 216355b4669Sjacobs 217355b4669Sjacobs switch (call_type) { 218355b4669Sjacobs case _BY_REFERENCE: 219355b4669Sjacobs #ifdef SOME_DAY_WE_WILL_BE_ABLE_TO_USE_URIS_FOR_JOB_DATA 220355b4669Sjacobs /* 221355b4669Sjacobs * For the time being, this is disabled. There are a number 222355b4669Sjacobs * of issues to be dealt with before we can send a URI 223355b4669Sjacobs * across the network to the server. For example, the file 224355b4669Sjacobs * name(s) passed in are most likely relative to the current 225355b4669Sjacobs * hosts filesystem. They also most likely will require some 226355b4669Sjacobs * form of authentication information to be passed with the 227355b4669Sjacobs * URI. 228355b4669Sjacobs */ 229355b4669Sjacobs req_type = OPID_PRINT_URI; 230355b4669Sjacobs req_type = OPID_SEND_URI; 231355b4669Sjacobs #endif 232355b4669Sjacobs /* fall-through */ 233355b4669Sjacobs case _WITH_DATA: 234355b4669Sjacobs if ((files == NULL) || (files[0] == NULL)) 235355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 236355b4669Sjacobs 237355b4669Sjacobs if (files[1] != NULL) /* more than 1 file */ 238355b4669Sjacobs req_type = OPID_CREATE_JOB; 239355b4669Sjacobs 240355b4669Sjacobs break; 241355b4669Sjacobs case _VALIDATE: 242355b4669Sjacobs req_type = OPID_VALIDATE_JOB; 243355b4669Sjacobs /* if we have files, validate access to them */ 244355b4669Sjacobs if (files != NULL) { 24595c2d302SJonathan Cowper-Andrewes for (i = 0; files[i] != NULL; i++) { 246355b4669Sjacobs if (access(files[i], R_OK) < 0) { 247355b4669Sjacobs detailed_error(svc, "%s: %s", files[i], 248355b4669Sjacobs strerror(errno)); 249355b4669Sjacobs return (PAPI_DOCUMENT_ACCESS_ERROR); 250355b4669Sjacobs } 25195c2d302SJonathan Cowper-Andrewes 25295c2d302SJonathan Cowper-Andrewes if (strcmp("standard input", files[i]) != 0) { 253a5669307SJonathan Cowper-Andrewes if (stat(files[i], &statbuf) < 0) { 254a5669307SJonathan Cowper-Andrewes detailed_error(svc, gettext( 255a5669307SJonathan Cowper-Andrewes "Cannot access file: %s:" 256a5669307SJonathan Cowper-Andrewes " %s"), files[i], 257a5669307SJonathan Cowper-Andrewes strerror(errno)); 258a5669307SJonathan Cowper-Andrewes return ( 259a5669307SJonathan Cowper-Andrewes PAPI_DOCUMENT_ACCESS_ERROR); 260a5669307SJonathan Cowper-Andrewes } 26195c2d302SJonathan Cowper-Andrewes if (statbuf.st_size == 0) { 26295c2d302SJonathan Cowper-Andrewes detailed_error(svc, 26395c2d302SJonathan Cowper-Andrewes "Zero byte (empty) file: " 26495c2d302SJonathan Cowper-Andrewes "%s", 26595c2d302SJonathan Cowper-Andrewes files[i]); 26695c2d302SJonathan Cowper-Andrewes return (PAPI_BAD_ARGUMENT); 26795c2d302SJonathan Cowper-Andrewes } 26895c2d302SJonathan Cowper-Andrewes } 26995c2d302SJonathan Cowper-Andrewes } 270355b4669Sjacobs files = NULL; 271355b4669Sjacobs } 272355b4669Sjacobs break; 273355b4669Sjacobs } 274355b4669Sjacobs 275355b4669Sjacobs /* if we are already connected, use that connection. */ 276355b4669Sjacobs if (svc->connection == NULL) 277355b4669Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 278355b4669Sjacobs return (result); 279355b4669Sjacobs 280355b4669Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 281355b4669Sjacobs return (PAPI_TEMPORARY_ERROR); 282355b4669Sjacobs 283e3ccc2c3Ssonam gupta - Sun Microsystems - Bangalore India /* 284e3ccc2c3Ssonam gupta - Sun Microsystems - Bangalore India * before creating IPP request 285e3ccc2c3Ssonam gupta - Sun Microsystems - Bangalore India * add the job-name 286e3ccc2c3Ssonam gupta - Sun Microsystems - Bangalore India */ 287e3ccc2c3Ssonam gupta - Sun Microsystems - Bangalore India if ((files != NULL) && (files[0] != NULL)) 288e3ccc2c3Ssonam gupta - Sun Microsystems - Bangalore India papiAttributeListAddString(&job_attributes, PAPI_ATTR_EXCL, 289e3ccc2c3Ssonam gupta - Sun Microsystems - Bangalore India "job-name", files[0]); 290e3ccc2c3Ssonam gupta - Sun Microsystems - Bangalore India 291355b4669Sjacobs /* create IPP request */ 292355b4669Sjacobs populate_job_request(svc, &request, job_attributes, printer, req_type); 293355b4669Sjacobs 294355b4669Sjacobs switch (req_type) { 295355b4669Sjacobs case OPID_PRINT_JOB: 296355b4669Sjacobs result = ipp_send_request_with_file(svc, request, &response, 297355b4669Sjacobs files[0]); 298355b4669Sjacobs break; 299355b4669Sjacobs case OPID_CREATE_JOB: 300355b4669Sjacobs case OPID_VALIDATE_JOB: 301355b4669Sjacobs case OPID_PRINT_URI: 302355b4669Sjacobs result = ipp_send_request(svc, request, &response); 303355b4669Sjacobs break; 304355b4669Sjacobs } 305355b4669Sjacobs papiAttributeListFree(request); 306355b4669Sjacobs 307355b4669Sjacobs if (result == PAPI_OK) { 308355b4669Sjacobs papi_attribute_t **op = NULL; 309355b4669Sjacobs 310355b4669Sjacobs /* retrieve the job attributes */ 311355b4669Sjacobs papiAttributeListGetCollection(response, NULL, 312355b4669Sjacobs "job-attributes-group", &op); 313355b4669Sjacobs copy_attributes(&j->attributes, op); 314355b4669Sjacobs 315355b4669Sjacobs if (req_type == OPID_CREATE_JOB) { 316355b4669Sjacobs int32_t id = 0; 317355b4669Sjacobs 318355b4669Sjacobs papiAttributeListGetInteger(j->attributes, NULL, 319355b4669Sjacobs "job-id", &id); 320355b4669Sjacobs /* send each document */ 321355b4669Sjacobs for (i = 0; ((result == PAPI_OK) && (files[i] != NULL)); 322355b4669Sjacobs i++) 323355b4669Sjacobs result = send_document_uri(svc, files[i], 324355b4669Sjacobs job_attributes, 325355b4669Sjacobs printer, id, (files[i+1]?0:1), 326355b4669Sjacobs data_type); 327355b4669Sjacobs } 328355b4669Sjacobs } 329355b4669Sjacobs papiAttributeListFree(response); 330355b4669Sjacobs 331355b4669Sjacobs return (result); 332355b4669Sjacobs } 333355b4669Sjacobs 334355b4669Sjacobs papi_status_t 335355b4669Sjacobs papiJobSubmit(papi_service_t handle, char *printer, 336355b4669Sjacobs papi_attribute_t **job_attributes, 337355b4669Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 338355b4669Sjacobs { 339355b4669Sjacobs return (internal_job_submit(handle, printer, job_attributes, 340355b4669Sjacobs job_ticket, files, job, _WITH_DATA)); 341355b4669Sjacobs } 342355b4669Sjacobs 343355b4669Sjacobs papi_status_t 344355b4669Sjacobs papiJobSubmitByReference(papi_service_t handle, char *printer, 345355b4669Sjacobs papi_attribute_t **job_attributes, 346355b4669Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 347355b4669Sjacobs { 348355b4669Sjacobs return (internal_job_submit(handle, printer, job_attributes, 349355b4669Sjacobs job_ticket, files, job, _BY_REFERENCE)); 350355b4669Sjacobs } 351355b4669Sjacobs 352355b4669Sjacobs papi_status_t 353355b4669Sjacobs papiJobValidate(papi_service_t handle, char *printer, 354355b4669Sjacobs papi_attribute_t **job_attributes, 355355b4669Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 356355b4669Sjacobs { 357355b4669Sjacobs return (internal_job_submit(handle, printer, job_attributes, 358355b4669Sjacobs job_ticket, files, job, _VALIDATE)); 359355b4669Sjacobs } 360355b4669Sjacobs 361355b4669Sjacobs papi_status_t 362355b4669Sjacobs papiJobStreamOpen(papi_service_t handle, char *printer, 363355b4669Sjacobs papi_attribute_t **job_attributes, 364355b4669Sjacobs papi_job_ticket_t *job_ticket, papi_stream_t *stream) 365355b4669Sjacobs { 366355b4669Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 367355b4669Sjacobs papi_attribute_t **request = NULL; 368355b4669Sjacobs service_t *svc = handle; 369355b4669Sjacobs 370355b4669Sjacobs if ((svc == NULL) || (printer == NULL) || (stream == NULL)) 371355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 372355b4669Sjacobs 373355b4669Sjacobs /* if we are already connected, use that connection. */ 374355b4669Sjacobs if (svc->connection == NULL) 375355b4669Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 376355b4669Sjacobs return (result); 377355b4669Sjacobs 378*edafac1fSKeerthi Kondaka papiAttributeListAddString(&job_attributes, PAPI_ATTR_EXCL, 379*edafac1fSKeerthi Kondaka "job-name", "standard input"); 380*edafac1fSKeerthi Kondaka 381355b4669Sjacobs /* create job request */ 382355b4669Sjacobs populate_job_request(svc, &request, job_attributes, printer, 383355b4669Sjacobs OPID_PRINT_JOB); 384355b4669Sjacobs 385355b4669Sjacobs *stream = svc->connection; 386355b4669Sjacobs 387355b4669Sjacobs result = ipp_send_initial_request_block(svc, request, 0); 388355b4669Sjacobs papiAttributeListFree(request); 389355b4669Sjacobs 390355b4669Sjacobs return (result); 391355b4669Sjacobs } 392355b4669Sjacobs 393355b4669Sjacobs papi_status_t 394355b4669Sjacobs papiJobStreamWrite(papi_service_t handle, 395355b4669Sjacobs papi_stream_t stream, void *buffer, size_t buflen) 396355b4669Sjacobs { 397355b4669Sjacobs papi_status_t result = PAPI_OK; 398355b4669Sjacobs service_t *svc = handle; 399355b4669Sjacobs size_t rc; 400355b4669Sjacobs 401355b4669Sjacobs #ifdef DEBUG 402355b4669Sjacobs printf("papiJobStreamWrite(0x%8.8x, 0x%8.8x, 0x%8.8x, %d)\n", 403355b4669Sjacobs handle, stream, buffer, buflen); 404355b4669Sjacobs httpDumpData(stdout, "papiJobStreamWrite:", buffer, buflen); 405355b4669Sjacobs #endif 406355b4669Sjacobs 407355b4669Sjacobs if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || 408355b4669Sjacobs (buflen == 0)) 409355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 410355b4669Sjacobs 411355b4669Sjacobs while ((result == PAPI_OK) && (buflen > 0)) { 412355b4669Sjacobs rc = ipp_request_write(svc, buffer, buflen); 413355b4669Sjacobs if (rc < 0) 414355b4669Sjacobs result = PAPI_TEMPORARY_ERROR; 415355b4669Sjacobs else { 416355b4669Sjacobs buffer = (char *)buffer + rc; 417355b4669Sjacobs buflen -= rc; 418355b4669Sjacobs } 419355b4669Sjacobs } 420355b4669Sjacobs 421355b4669Sjacobs #ifdef DEBUG 422355b4669Sjacobs printf("papiJobStreamWrite(): %s\n", papiStatusString(result)); 423355b4669Sjacobs #endif 424355b4669Sjacobs 425355b4669Sjacobs return (result); 426355b4669Sjacobs } 427355b4669Sjacobs 428355b4669Sjacobs papi_status_t 429355b4669Sjacobs papiJobStreamClose(papi_service_t handle, 430355b4669Sjacobs papi_stream_t stream, papi_job_t *job) 431355b4669Sjacobs { 432355b4669Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 433355b4669Sjacobs http_status_t status = HTTP_CONTINUE; 434355b4669Sjacobs service_t *svc = handle; 435355b4669Sjacobs papi_attribute_t **response = NULL; 436355b4669Sjacobs job_t *j = NULL; 437355b4669Sjacobs 438355b4669Sjacobs if ((svc == NULL) || (stream == NULL) || (job == NULL)) 439355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 440355b4669Sjacobs 441355b4669Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 442355b4669Sjacobs return (PAPI_TEMPORARY_ERROR); 443355b4669Sjacobs 444355b4669Sjacobs (void) ipp_request_write(svc, "", 0); 445355b4669Sjacobs 446355b4669Sjacobs /* update our connection info */ 447355b4669Sjacobs while (status == HTTP_CONTINUE) 448355b4669Sjacobs status = httpUpdate(svc->connection); 449355b4669Sjacobs 450355b4669Sjacobs if (status != HTTP_OK) 451355b4669Sjacobs return (http_to_papi_status(status)); 452355b4669Sjacobs httpWait(svc->connection, 1000); 453355b4669Sjacobs 454355b4669Sjacobs /* read the IPP response */ 455355b4669Sjacobs result = ipp_read_message(&ipp_request_read, svc, &response, 456355b4669Sjacobs IPP_TYPE_RESPONSE); 457355b4669Sjacobs if (result == PAPI_OK) 458355b4669Sjacobs result = ipp_status_info(svc, response); 459355b4669Sjacobs 460355b4669Sjacobs if (result == PAPI_OK) { 461355b4669Sjacobs papi_attribute_t **op = NULL; 462355b4669Sjacobs 463355b4669Sjacobs papiAttributeListGetCollection(response, NULL, 464355b4669Sjacobs "job-attributes-group", &op); 465355b4669Sjacobs copy_attributes(&j->attributes, op); 466355b4669Sjacobs } 467355b4669Sjacobs papiAttributeListFree(response); 468355b4669Sjacobs 469355b4669Sjacobs return (result); 470355b4669Sjacobs } 471355b4669Sjacobs 472355b4669Sjacobs papi_status_t 473355b4669Sjacobs papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, 474355b4669Sjacobs char **requested_attrs, 475355b4669Sjacobs papi_job_t *job) 476355b4669Sjacobs { 477355b4669Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 478355b4669Sjacobs service_t *svc = handle; 479355b4669Sjacobs job_t *j = NULL; 480355b4669Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 481355b4669Sjacobs 482355b4669Sjacobs if ((svc == NULL) || (printer == NULL)) 483355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 484355b4669Sjacobs 485355b4669Sjacobs /* if we are already connected, use that connection. */ 486355b4669Sjacobs if (svc->connection == NULL) 487355b4669Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 488355b4669Sjacobs return (result); 489355b4669Sjacobs 490355b4669Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 491355b4669Sjacobs return (PAPI_TEMPORARY_ERROR); 492355b4669Sjacobs 493355b4669Sjacobs ipp_initialize_request(svc, &request, OPID_GET_JOB_ATTRIBUTES); 494355b4669Sjacobs 495223f6c28Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 496355b4669Sjacobs 497355b4669Sjacobs if (requested_attrs != NULL) { 498355b4669Sjacobs int i; 499355b4669Sjacobs 500355b4669Sjacobs for (i = 0; requested_attrs[i] != NULL; i++) 501355b4669Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 502355b4669Sjacobs "requested-attributes", requested_attrs[i]); 503355b4669Sjacobs } 504355b4669Sjacobs 505355b4669Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 506355b4669Sjacobs "operational-attributes-group", op); 507355b4669Sjacobs papiAttributeListFree(op); 508355b4669Sjacobs result = ipp_send_request(svc, request, &response); 509355b4669Sjacobs papiAttributeListFree(request); 510355b4669Sjacobs 511355b4669Sjacobs op = NULL; 512355b4669Sjacobs papiAttributeListGetCollection(response, NULL, 513355b4669Sjacobs "job-attributes-group", &op); 514355b4669Sjacobs copy_attributes(&j->attributes, op); 515355b4669Sjacobs papiAttributeListFree(response); 516355b4669Sjacobs 517355b4669Sjacobs return (result); 518355b4669Sjacobs } 519355b4669Sjacobs 520355b4669Sjacobs /* papiJob{Cancel|Hold|Release|Restart|Promote} are all the same */ 521355b4669Sjacobs static papi_status_t 522355b4669Sjacobs _job_cancel_hold_release_restart_promote(papi_service_t handle, 523355b4669Sjacobs char *printer, int32_t job_id, uint16_t type) 524355b4669Sjacobs { 525355b4669Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 526355b4669Sjacobs service_t *svc = handle; 527355b4669Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 528355b4669Sjacobs 529355b4669Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0)) 530355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 531355b4669Sjacobs 532355b4669Sjacobs /* if we are already connected, use that connection. */ 533355b4669Sjacobs if (svc->connection == NULL) 534355b4669Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 535355b4669Sjacobs return (result); 536355b4669Sjacobs 537355b4669Sjacobs ipp_initialize_request(svc, &request, type); 538355b4669Sjacobs 539223f6c28Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 540355b4669Sjacobs 541355b4669Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 542355b4669Sjacobs "operational-attributes-group", op); 543355b4669Sjacobs papiAttributeListFree(op); 544355b4669Sjacobs result = ipp_send_request(svc, request, &response); 545355b4669Sjacobs papiAttributeListFree(request); 546355b4669Sjacobs papiAttributeListFree(response); 547355b4669Sjacobs 548355b4669Sjacobs return (result); 549355b4669Sjacobs } 550355b4669Sjacobs 551355b4669Sjacobs papi_status_t 552355b4669Sjacobs papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) 553355b4669Sjacobs { 554355b4669Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 555355b4669Sjacobs job_id, OPID_CANCEL_JOB)); 556355b4669Sjacobs } 557355b4669Sjacobs 558355b4669Sjacobs 559355b4669Sjacobs papi_status_t 560355b4669Sjacobs papiJobHold(papi_service_t handle, char *printer, int32_t job_id) 561355b4669Sjacobs { 562355b4669Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 563355b4669Sjacobs job_id, OPID_HOLD_JOB)); 564355b4669Sjacobs } 565355b4669Sjacobs 566355b4669Sjacobs papi_status_t 567355b4669Sjacobs papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) 568355b4669Sjacobs { 569355b4669Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 570355b4669Sjacobs job_id, OPID_RELEASE_JOB)); 571355b4669Sjacobs } 572355b4669Sjacobs 573355b4669Sjacobs papi_status_t 574355b4669Sjacobs papiJobRestart(papi_service_t handle, char *printer, int32_t job_id) 575355b4669Sjacobs { 576355b4669Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 577355b4669Sjacobs job_id, OPID_RESTART_JOB)); 578355b4669Sjacobs } 579355b4669Sjacobs 580355b4669Sjacobs papi_status_t 581355b4669Sjacobs papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) 582355b4669Sjacobs { 583355b4669Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 584355b4669Sjacobs job_id, OPID_PROMOTE_JOB)); 585355b4669Sjacobs } 586355b4669Sjacobs 587355b4669Sjacobs papi_status_t 588355b4669Sjacobs papiJobMove(papi_service_t handle, char *printer, int32_t job_id, 589355b4669Sjacobs char *destination) 590355b4669Sjacobs { 591355b4669Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 592355b4669Sjacobs service_t *svc = handle; 593355b4669Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 594355b4669Sjacobs 595355b4669Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 596355b4669Sjacobs (destination == NULL)) 597355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 598355b4669Sjacobs 599355b4669Sjacobs /* if we are already connected, use that connection. */ 600355b4669Sjacobs if (svc->connection == NULL) 601355b4669Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 602355b4669Sjacobs return (result); 603355b4669Sjacobs 604355b4669Sjacobs ipp_initialize_request(svc, &request, OPID_CUPS_MOVE_JOB); 605355b4669Sjacobs 606223f6c28Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 607355b4669Sjacobs 608355b4669Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 609355b4669Sjacobs "operational-attributes-group", op); 610355b4669Sjacobs papiAttributeListFree(op); 611355b4669Sjacobs 612355b4669Sjacobs op = NULL; 613355b4669Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_EXCL, 614355b4669Sjacobs "job-printer-uri", destination); 615355b4669Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 616355b4669Sjacobs "job-attributes-group", op); 617355b4669Sjacobs papiAttributeListFree(op); 618355b4669Sjacobs 619355b4669Sjacobs result = ipp_send_request(svc, request, &response); 620355b4669Sjacobs papiAttributeListFree(request); 621355b4669Sjacobs papiAttributeListFree(response); 622355b4669Sjacobs 623355b4669Sjacobs return (result); 624355b4669Sjacobs } 625355b4669Sjacobs 626355b4669Sjacobs papi_status_t 627355b4669Sjacobs papiJobModify(papi_service_t handle, char *printer, int32_t job_id, 628355b4669Sjacobs papi_attribute_t **attributes, papi_job_t *job) 629355b4669Sjacobs { 630355b4669Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 631355b4669Sjacobs service_t *svc = handle; 632355b4669Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 633355b4669Sjacobs job_t *j = NULL; 634355b4669Sjacobs 635355b4669Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 636355b4669Sjacobs (attributes == NULL)) 637355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 638355b4669Sjacobs 639355b4669Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 640355b4669Sjacobs return (PAPI_TEMPORARY_ERROR); 641355b4669Sjacobs 642355b4669Sjacobs /* if we are already connected, use that connection. */ 643355b4669Sjacobs if (svc->connection == NULL) 644355b4669Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 645355b4669Sjacobs return (result); 646355b4669Sjacobs 647355b4669Sjacobs ipp_initialize_request(svc, &request, OPID_SET_JOB_ATTRIBUTES); 648355b4669Sjacobs 649223f6c28Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 650355b4669Sjacobs 651355b4669Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 652355b4669Sjacobs "operational-attributes-group", op); 653355b4669Sjacobs papiAttributeListFree(op); 654355b4669Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 655355b4669Sjacobs "job-attributes-group", attributes); 656355b4669Sjacobs result = ipp_send_request(svc, request, &response); 657355b4669Sjacobs papiAttributeListFree(request); 658355b4669Sjacobs 659355b4669Sjacobs op = NULL; 660355b4669Sjacobs papiAttributeListGetCollection(response, NULL, 661355b4669Sjacobs "job-attributes-group", &op); 662355b4669Sjacobs copy_attributes(&j->attributes, op); 663355b4669Sjacobs papiAttributeListFree(response); 664355b4669Sjacobs 665355b4669Sjacobs return (result); 666355b4669Sjacobs } 667