12264Sjacobs /* 22264Sjacobs * CDDL HEADER START 32264Sjacobs * 42264Sjacobs * The contents of this file are subject to the terms of the 52264Sjacobs * Common Development and Distribution License (the "License"). 62264Sjacobs * You may not use this file except in compliance with the License. 72264Sjacobs * 82264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92264Sjacobs * or http://www.opensolaris.org/os/licensing. 102264Sjacobs * See the License for the specific language governing permissions 112264Sjacobs * and limitations under the License. 122264Sjacobs * 132264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 142264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 162264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 172264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 182264Sjacobs * 192264Sjacobs * CDDL HEADER END 202264Sjacobs */ 212264Sjacobs 222264Sjacobs /* 238569SJonathan.Ca@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 242264Sjacobs * Use is subject to license terms. 252264Sjacobs * 262264Sjacobs */ 272264Sjacobs 282264Sjacobs /* $Id: job.c 148 2006-04-25 16:54:17Z njacobs $ */ 292264Sjacobs 302264Sjacobs 312264Sjacobs /*LINTLIBRARY*/ 322264Sjacobs 332264Sjacobs #include <stdlib.h> 342264Sjacobs #include <errno.h> 352264Sjacobs #include <string.h> 362264Sjacobs #include <papi_impl.h> 378569SJonathan.Ca@Sun.COM #include <fcntl.h> 388569SJonathan.Ca@Sun.COM #include <sys/types.h> 398569SJonathan.Ca@Sun.COM #include <sys/stat.h> 402264Sjacobs 412264Sjacobs #ifndef OPID_CUPS_MOVE_JOB 422264Sjacobs #define OPID_CUPS_MOVE_JOB 0x400D 432264Sjacobs #endif 442264Sjacobs 452264Sjacobs void 462264Sjacobs papiJobFree(papi_job_t job) 472264Sjacobs { 482264Sjacobs job_t *tmp = (job_t *)job; 492264Sjacobs 502264Sjacobs if (tmp != NULL) { 512264Sjacobs if (tmp->attributes != NULL) 522264Sjacobs papiAttributeListFree(tmp->attributes); 532264Sjacobs free(tmp); 542264Sjacobs } 552264Sjacobs } 562264Sjacobs 572264Sjacobs void 582264Sjacobs papiJobListFree(papi_job_t *jobs) 592264Sjacobs { 602264Sjacobs if (jobs != NULL) { 612264Sjacobs int i; 622264Sjacobs 632264Sjacobs for (i = 0; jobs[i] != NULL; i++) 642264Sjacobs papiJobFree(jobs[i]); 652264Sjacobs free(jobs); 662264Sjacobs } 672264Sjacobs } 682264Sjacobs 692264Sjacobs papi_attribute_t ** 702264Sjacobs papiJobGetAttributeList(papi_job_t job) 712264Sjacobs { 722264Sjacobs papi_attribute_t **result = NULL; 732264Sjacobs job_t *j = job; 742264Sjacobs 752264Sjacobs if (j != NULL) 762264Sjacobs result = j->attributes; 772264Sjacobs 782264Sjacobs return (result); 792264Sjacobs } 802264Sjacobs 812264Sjacobs char * 822264Sjacobs papiJobGetPrinterName(papi_job_t job) 832264Sjacobs { 842264Sjacobs char *result = NULL; 852264Sjacobs job_t *j = job; 862264Sjacobs 872264Sjacobs if (j != NULL) 882264Sjacobs (void) papiAttributeListGetString(j->attributes, NULL, 898569SJonathan.Ca@Sun.COM "printer-name", &result); 902264Sjacobs 912264Sjacobs return (result); 922264Sjacobs } 932264Sjacobs 942264Sjacobs int32_t 952264Sjacobs papiJobGetId(papi_job_t job) 962264Sjacobs { 972264Sjacobs int32_t result = -1; 982264Sjacobs job_t *j = job; 992264Sjacobs 1002264Sjacobs if (j != NULL) 1012264Sjacobs (void) papiAttributeListGetInteger(j->attributes, NULL, 1028569SJonathan.Ca@Sun.COM "job-id", &result); 1032264Sjacobs 1042264Sjacobs return (result); 1052264Sjacobs } 1062264Sjacobs 1072264Sjacobs papi_job_ticket_t * 1082264Sjacobs papiJobGetJobTicket(papi_job_t job) 1092264Sjacobs { 1102264Sjacobs papi_job_ticket_t *result = NULL; 1112264Sjacobs 1122264Sjacobs return (result); 1132264Sjacobs } 1142264Sjacobs 1152264Sjacobs static void 1162264Sjacobs populate_job_request(service_t *svc, papi_attribute_t ***request, 1172264Sjacobs papi_attribute_t **attributes, char *printer, uint16_t type) 1182264Sjacobs { 1192264Sjacobs papi_attribute_t **operational = NULL, **job = NULL; 1202264Sjacobs static char *operational_names[] = { 1212264Sjacobs "job-name", "ipp-attribute-fidelity", "document-name", 1222264Sjacobs "compression", "document-format", "document-natural-language", 1232264Sjacobs "job-k-octets", "job-impressions", "job-media-sheets", NULL 1242264Sjacobs }; 1252264Sjacobs 1262264Sjacobs /* create the base IPP request */ 1272264Sjacobs ipp_initialize_request(svc, request, type); 1282264Sjacobs 1292264Sjacobs /* create an operational attributes group */ 1303917Sjacobs ipp_initialize_operational_attributes(svc, &operational, printer, -1); 1312264Sjacobs 1322264Sjacobs /* split up the attributes into operational and job attributes */ 1332264Sjacobs split_and_copy_attributes(operational_names, attributes, 1348569SJonathan.Ca@Sun.COM &operational, &job); 1352264Sjacobs 1362264Sjacobs /* add the operational attributes group to the request */ 1372264Sjacobs papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, 1388569SJonathan.Ca@Sun.COM "operational-attributes-group", operational); 1392264Sjacobs papiAttributeListFree(operational); 1402264Sjacobs 1412264Sjacobs /* add the job attributes group to the request */ 1422264Sjacobs if (job != NULL) { 143*9152SSonam.Gupta@Sun.COM /* 144*9152SSonam.Gupta@Sun.COM * Add job-originating-host-name to attributes 145*9152SSonam.Gupta@Sun.COM * if not already set. 146*9152SSonam.Gupta@Sun.COM */ 147*9152SSonam.Gupta@Sun.COM char *hostname = NULL; 148*9152SSonam.Gupta@Sun.COM 149*9152SSonam.Gupta@Sun.COM papiAttributeListGetString(job, NULL, 150*9152SSonam.Gupta@Sun.COM "job-originating-host-name", &hostname); 151*9152SSonam.Gupta@Sun.COM 152*9152SSonam.Gupta@Sun.COM if (hostname == NULL) { 153*9152SSonam.Gupta@Sun.COM char host[BUFSIZ]; 154*9152SSonam.Gupta@Sun.COM 155*9152SSonam.Gupta@Sun.COM if (gethostname(host, sizeof (host)) == 0) 156*9152SSonam.Gupta@Sun.COM papiAttributeListAddString(&job, PAPI_ATTR_EXCL, 157*9152SSonam.Gupta@Sun.COM "job-originating-host-name", host); 158*9152SSonam.Gupta@Sun.COM } 159*9152SSonam.Gupta@Sun.COM 1602264Sjacobs papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, 1618569SJonathan.Ca@Sun.COM "job-attributes-group", job); 1622264Sjacobs papiAttributeListFree(job); 1632264Sjacobs } 1642264Sjacobs } 1652264Sjacobs 1662264Sjacobs static papi_status_t 1672264Sjacobs send_document_uri(service_t *svc, char *file, papi_attribute_t **attributes, 1682264Sjacobs char *printer, int32_t id, char last, uint16_t type) 1692264Sjacobs { 1702264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 1712264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 1722264Sjacobs 1732264Sjacobs /* create the base IPP request */ 1742264Sjacobs ipp_initialize_request(svc, &request, type); 1752264Sjacobs 1762264Sjacobs /* create an operational attributes group */ 1773917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, id); 1782264Sjacobs 1792264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, "document-name", 1808569SJonathan.Ca@Sun.COM file); 1812264Sjacobs papiAttributeListAddBoolean(&op, PAPI_ATTR_REPLACE, "last-document", 1828569SJonathan.Ca@Sun.COM (last ? PAPI_TRUE : PAPI_FALSE)); 1832264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 1848569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 1852264Sjacobs papiAttributeListFree(op); 1862264Sjacobs 1872264Sjacobs /* send the IPP request to the server */ 1882264Sjacobs result = ipp_send_request_with_file(svc, request, &response, file); 1892264Sjacobs papiAttributeListFree(request); 1902264Sjacobs papiAttributeListFree(response); 1912264Sjacobs 1922264Sjacobs return (result); 1932264Sjacobs } 1942264Sjacobs 1952264Sjacobs typedef enum {_WITH_DATA, _BY_REFERENCE, _VALIDATE} call_type_t; 1962264Sjacobs 1972264Sjacobs papi_status_t 1982264Sjacobs internal_job_submit(papi_service_t handle, char *printer, 1992264Sjacobs papi_attribute_t **job_attributes, 2002264Sjacobs papi_job_ticket_t *job_ticket, 2012264Sjacobs char **files, papi_job_t *job, 2022264Sjacobs call_type_t call_type) 2032264Sjacobs { 2042264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 2052264Sjacobs service_t *svc = handle; 2068569SJonathan.Ca@Sun.COM struct stat statbuf; 2072264Sjacobs job_t *j = NULL; 2082264Sjacobs int i; 2092264Sjacobs uint16_t req_type = OPID_PRINT_JOB; 2102264Sjacobs uint16_t data_type = OPID_SEND_DOCUMENT; 2112264Sjacobs papi_attribute_t **request = NULL, **response = NULL; 2122264Sjacobs 2132264Sjacobs if ((svc == NULL) || (printer == NULL) || (job == NULL)) 2142264Sjacobs return (PAPI_BAD_ARGUMENT); 2152264Sjacobs 2162264Sjacobs switch (call_type) { 2172264Sjacobs case _BY_REFERENCE: 2182264Sjacobs #ifdef SOME_DAY_WE_WILL_BE_ABLE_TO_USE_URIS_FOR_JOB_DATA 2192264Sjacobs /* 2202264Sjacobs * For the time being, this is disabled. There are a number 2212264Sjacobs * of issues to be dealt with before we can send a URI 2222264Sjacobs * across the network to the server. For example, the file 2232264Sjacobs * name(s) passed in are most likely relative to the current 2242264Sjacobs * hosts filesystem. They also most likely will require some 2252264Sjacobs * form of authentication information to be passed with the 2262264Sjacobs * URI. 2272264Sjacobs */ 2282264Sjacobs req_type = OPID_PRINT_URI; 2292264Sjacobs req_type = OPID_SEND_URI; 2302264Sjacobs #endif 2312264Sjacobs /* fall-through */ 2322264Sjacobs case _WITH_DATA: 2332264Sjacobs if ((files == NULL) || (files[0] == NULL)) 2342264Sjacobs return (PAPI_BAD_ARGUMENT); 2352264Sjacobs 2362264Sjacobs if (files[1] != NULL) /* more than 1 file */ 2372264Sjacobs req_type = OPID_CREATE_JOB; 2382264Sjacobs 2392264Sjacobs break; 2402264Sjacobs case _VALIDATE: 2412264Sjacobs req_type = OPID_VALIDATE_JOB; 2422264Sjacobs /* if we have files, validate access to them */ 2432264Sjacobs if (files != NULL) { 2448569SJonathan.Ca@Sun.COM for (i = 0; files[i] != NULL; i++) { 2452264Sjacobs if (access(files[i], R_OK) < 0) { 2462264Sjacobs detailed_error(svc, "%s: %s", files[i], 2478569SJonathan.Ca@Sun.COM strerror(errno)); 2482264Sjacobs return (PAPI_DOCUMENT_ACCESS_ERROR); 2492264Sjacobs } 2508569SJonathan.Ca@Sun.COM 2518569SJonathan.Ca@Sun.COM if (strcmp("standard input", files[i]) != 0) { 2528569SJonathan.Ca@Sun.COM stat(files[i], &statbuf); 2538569SJonathan.Ca@Sun.COM if (statbuf.st_size == 0) { 2548569SJonathan.Ca@Sun.COM detailed_error(svc, 2558569SJonathan.Ca@Sun.COM "Zero byte (empty) file: " 2568569SJonathan.Ca@Sun.COM "%s", 2578569SJonathan.Ca@Sun.COM files[i]); 2588569SJonathan.Ca@Sun.COM return (PAPI_BAD_ARGUMENT); 2598569SJonathan.Ca@Sun.COM } 2608569SJonathan.Ca@Sun.COM } 2618569SJonathan.Ca@Sun.COM } 2622264Sjacobs files = NULL; 2632264Sjacobs } 2642264Sjacobs break; 2652264Sjacobs } 2662264Sjacobs 2672264Sjacobs /* if we are already connected, use that connection. */ 2682264Sjacobs if (svc->connection == NULL) 2692264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 2702264Sjacobs return (result); 2712264Sjacobs 2722264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 2732264Sjacobs return (PAPI_TEMPORARY_ERROR); 2742264Sjacobs 2752264Sjacobs /* create IPP request */ 2762264Sjacobs populate_job_request(svc, &request, job_attributes, printer, req_type); 2772264Sjacobs 2782264Sjacobs switch (req_type) { 2792264Sjacobs case OPID_PRINT_JOB: 2802264Sjacobs result = ipp_send_request_with_file(svc, request, &response, 2818569SJonathan.Ca@Sun.COM files[0]); 2822264Sjacobs break; 2832264Sjacobs case OPID_CREATE_JOB: 2842264Sjacobs case OPID_VALIDATE_JOB: 2852264Sjacobs case OPID_PRINT_URI: 2862264Sjacobs result = ipp_send_request(svc, request, &response); 2872264Sjacobs break; 2882264Sjacobs } 2892264Sjacobs papiAttributeListFree(request); 2902264Sjacobs 2912264Sjacobs if (result == PAPI_OK) { 2922264Sjacobs papi_attribute_t **op = NULL; 2932264Sjacobs 2942264Sjacobs /* retrieve the job attributes */ 2952264Sjacobs papiAttributeListGetCollection(response, NULL, 2968569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 2972264Sjacobs copy_attributes(&j->attributes, op); 2982264Sjacobs 2992264Sjacobs if (req_type == OPID_CREATE_JOB) { 3002264Sjacobs int32_t id = 0; 3012264Sjacobs 3022264Sjacobs papiAttributeListGetInteger(j->attributes, NULL, 3038569SJonathan.Ca@Sun.COM "job-id", &id); 3042264Sjacobs /* send each document */ 3052264Sjacobs for (i = 0; ((result == PAPI_OK) && (files[i] != NULL)); 3068569SJonathan.Ca@Sun.COM i++) 3072264Sjacobs result = send_document_uri(svc, files[i], 3088569SJonathan.Ca@Sun.COM job_attributes, 3098569SJonathan.Ca@Sun.COM printer, id, (files[i+1]?0:1), 3108569SJonathan.Ca@Sun.COM data_type); 3112264Sjacobs } 3122264Sjacobs } 3132264Sjacobs papiAttributeListFree(response); 3142264Sjacobs 3152264Sjacobs return (result); 3162264Sjacobs } 3172264Sjacobs 3182264Sjacobs papi_status_t 3192264Sjacobs papiJobSubmit(papi_service_t handle, char *printer, 3202264Sjacobs papi_attribute_t **job_attributes, 3212264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 3222264Sjacobs { 3232264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 3248569SJonathan.Ca@Sun.COM job_ticket, files, job, _WITH_DATA)); 3252264Sjacobs } 3262264Sjacobs 3272264Sjacobs papi_status_t 3282264Sjacobs papiJobSubmitByReference(papi_service_t handle, char *printer, 3292264Sjacobs papi_attribute_t **job_attributes, 3302264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 3312264Sjacobs { 3322264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 3338569SJonathan.Ca@Sun.COM job_ticket, files, job, _BY_REFERENCE)); 3342264Sjacobs } 3352264Sjacobs 3362264Sjacobs papi_status_t 3372264Sjacobs papiJobValidate(papi_service_t handle, char *printer, 3382264Sjacobs papi_attribute_t **job_attributes, 3392264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 3402264Sjacobs { 3412264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 3428569SJonathan.Ca@Sun.COM job_ticket, files, job, _VALIDATE)); 3432264Sjacobs } 3442264Sjacobs 3452264Sjacobs papi_status_t 3462264Sjacobs papiJobStreamOpen(papi_service_t handle, char *printer, 3472264Sjacobs papi_attribute_t **job_attributes, 3482264Sjacobs papi_job_ticket_t *job_ticket, papi_stream_t *stream) 3492264Sjacobs { 3502264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 3512264Sjacobs papi_attribute_t **request = NULL; 3522264Sjacobs service_t *svc = handle; 3532264Sjacobs 3542264Sjacobs if ((svc == NULL) || (printer == NULL) || (stream == NULL)) 3552264Sjacobs return (PAPI_BAD_ARGUMENT); 3562264Sjacobs 3572264Sjacobs /* if we are already connected, use that connection. */ 3582264Sjacobs if (svc->connection == NULL) 3592264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 3602264Sjacobs return (result); 3612264Sjacobs 3622264Sjacobs /* create job request */ 3632264Sjacobs populate_job_request(svc, &request, job_attributes, printer, 3648569SJonathan.Ca@Sun.COM OPID_PRINT_JOB); 3652264Sjacobs 3662264Sjacobs *stream = svc->connection; 3672264Sjacobs 3682264Sjacobs result = ipp_send_initial_request_block(svc, request, 0); 3692264Sjacobs papiAttributeListFree(request); 3702264Sjacobs 3712264Sjacobs return (result); 3722264Sjacobs } 3732264Sjacobs 3742264Sjacobs papi_status_t 3752264Sjacobs papiJobStreamWrite(papi_service_t handle, 3762264Sjacobs papi_stream_t stream, void *buffer, size_t buflen) 3772264Sjacobs { 3782264Sjacobs papi_status_t result = PAPI_OK; 3792264Sjacobs service_t *svc = handle; 3802264Sjacobs size_t rc; 3812264Sjacobs 3822264Sjacobs #ifdef DEBUG 3832264Sjacobs printf("papiJobStreamWrite(0x%8.8x, 0x%8.8x, 0x%8.8x, %d)\n", 3848569SJonathan.Ca@Sun.COM handle, stream, buffer, buflen); 3852264Sjacobs httpDumpData(stdout, "papiJobStreamWrite:", buffer, buflen); 3862264Sjacobs #endif 3872264Sjacobs 3882264Sjacobs if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || 3892264Sjacobs (buflen == 0)) 3902264Sjacobs return (PAPI_BAD_ARGUMENT); 3912264Sjacobs 3922264Sjacobs while ((result == PAPI_OK) && (buflen > 0)) { 3932264Sjacobs rc = ipp_request_write(svc, buffer, buflen); 3942264Sjacobs if (rc < 0) 3952264Sjacobs result = PAPI_TEMPORARY_ERROR; 3962264Sjacobs else { 3972264Sjacobs buffer = (char *)buffer + rc; 3982264Sjacobs buflen -= rc; 3992264Sjacobs } 4002264Sjacobs } 4012264Sjacobs 4022264Sjacobs #ifdef DEBUG 4032264Sjacobs printf("papiJobStreamWrite(): %s\n", papiStatusString(result)); 4042264Sjacobs #endif 4052264Sjacobs 4062264Sjacobs return (result); 4072264Sjacobs } 4082264Sjacobs 4092264Sjacobs papi_status_t 4102264Sjacobs papiJobStreamClose(papi_service_t handle, 4112264Sjacobs papi_stream_t stream, papi_job_t *job) 4122264Sjacobs { 4132264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4142264Sjacobs http_status_t status = HTTP_CONTINUE; 4152264Sjacobs service_t *svc = handle; 4162264Sjacobs papi_attribute_t **response = NULL; 4172264Sjacobs job_t *j = NULL; 4182264Sjacobs 4192264Sjacobs if ((svc == NULL) || (stream == NULL) || (job == NULL)) 4202264Sjacobs return (PAPI_BAD_ARGUMENT); 4212264Sjacobs 4222264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 4232264Sjacobs return (PAPI_TEMPORARY_ERROR); 4242264Sjacobs 4252264Sjacobs (void) ipp_request_write(svc, "", 0); 4262264Sjacobs 4272264Sjacobs /* update our connection info */ 4282264Sjacobs while (status == HTTP_CONTINUE) 4292264Sjacobs status = httpUpdate(svc->connection); 4302264Sjacobs 4312264Sjacobs if (status != HTTP_OK) 4322264Sjacobs return (http_to_papi_status(status)); 4332264Sjacobs httpWait(svc->connection, 1000); 4342264Sjacobs 4352264Sjacobs /* read the IPP response */ 4362264Sjacobs result = ipp_read_message(&ipp_request_read, svc, &response, 4378569SJonathan.Ca@Sun.COM IPP_TYPE_RESPONSE); 4382264Sjacobs if (result == PAPI_OK) 4392264Sjacobs result = ipp_status_info(svc, response); 4402264Sjacobs 4412264Sjacobs if (result == PAPI_OK) { 4422264Sjacobs papi_attribute_t **op = NULL; 4432264Sjacobs 4442264Sjacobs papiAttributeListGetCollection(response, NULL, 4458569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 4462264Sjacobs copy_attributes(&j->attributes, op); 4472264Sjacobs } 4482264Sjacobs papiAttributeListFree(response); 4492264Sjacobs 4502264Sjacobs return (result); 4512264Sjacobs } 4522264Sjacobs 4532264Sjacobs papi_status_t 4542264Sjacobs papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, 4552264Sjacobs char **requested_attrs, 4562264Sjacobs papi_job_t *job) 4572264Sjacobs { 4582264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4592264Sjacobs service_t *svc = handle; 4602264Sjacobs job_t *j = NULL; 4612264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 4622264Sjacobs 4632264Sjacobs if ((svc == NULL) || (printer == NULL)) 4642264Sjacobs return (PAPI_BAD_ARGUMENT); 4652264Sjacobs 4662264Sjacobs /* if we are already connected, use that connection. */ 4672264Sjacobs if (svc->connection == NULL) 4682264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 4692264Sjacobs return (result); 4702264Sjacobs 4712264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 4722264Sjacobs return (PAPI_TEMPORARY_ERROR); 4732264Sjacobs 4742264Sjacobs ipp_initialize_request(svc, &request, OPID_GET_JOB_ATTRIBUTES); 4752264Sjacobs 4763917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 4772264Sjacobs 4782264Sjacobs if (requested_attrs != NULL) { 4792264Sjacobs int i; 4802264Sjacobs 4812264Sjacobs for (i = 0; requested_attrs[i] != NULL; i++) 4822264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 4838569SJonathan.Ca@Sun.COM "requested-attributes", requested_attrs[i]); 4842264Sjacobs } 4852264Sjacobs 4862264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 4878569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 4882264Sjacobs papiAttributeListFree(op); 4892264Sjacobs result = ipp_send_request(svc, request, &response); 4902264Sjacobs papiAttributeListFree(request); 4912264Sjacobs 4922264Sjacobs op = NULL; 4932264Sjacobs papiAttributeListGetCollection(response, NULL, 4948569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 4952264Sjacobs copy_attributes(&j->attributes, op); 4962264Sjacobs papiAttributeListFree(response); 4972264Sjacobs 4982264Sjacobs return (result); 4992264Sjacobs } 5002264Sjacobs 5012264Sjacobs /* papiJob{Cancel|Hold|Release|Restart|Promote} are all the same */ 5022264Sjacobs static papi_status_t 5032264Sjacobs _job_cancel_hold_release_restart_promote(papi_service_t handle, 5042264Sjacobs char *printer, int32_t job_id, uint16_t type) 5052264Sjacobs { 5062264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 5072264Sjacobs service_t *svc = handle; 5082264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 5092264Sjacobs 5102264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0)) 5112264Sjacobs return (PAPI_BAD_ARGUMENT); 5122264Sjacobs 5132264Sjacobs /* if we are already connected, use that connection. */ 5142264Sjacobs if (svc->connection == NULL) 5152264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 5162264Sjacobs return (result); 5172264Sjacobs 5182264Sjacobs ipp_initialize_request(svc, &request, type); 5192264Sjacobs 5203917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 5212264Sjacobs 5222264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 5238569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 5242264Sjacobs papiAttributeListFree(op); 5252264Sjacobs result = ipp_send_request(svc, request, &response); 5262264Sjacobs papiAttributeListFree(request); 5272264Sjacobs papiAttributeListFree(response); 5282264Sjacobs 5292264Sjacobs return (result); 5302264Sjacobs } 5312264Sjacobs 5322264Sjacobs papi_status_t 5332264Sjacobs papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) 5342264Sjacobs { 5352264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5368569SJonathan.Ca@Sun.COM job_id, OPID_CANCEL_JOB)); 5372264Sjacobs } 5382264Sjacobs 5392264Sjacobs 5402264Sjacobs papi_status_t 5412264Sjacobs papiJobHold(papi_service_t handle, char *printer, int32_t job_id) 5422264Sjacobs { 5432264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5448569SJonathan.Ca@Sun.COM job_id, OPID_HOLD_JOB)); 5452264Sjacobs } 5462264Sjacobs 5472264Sjacobs papi_status_t 5482264Sjacobs papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) 5492264Sjacobs { 5502264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5518569SJonathan.Ca@Sun.COM job_id, OPID_RELEASE_JOB)); 5522264Sjacobs } 5532264Sjacobs 5542264Sjacobs papi_status_t 5552264Sjacobs papiJobRestart(papi_service_t handle, char *printer, int32_t job_id) 5562264Sjacobs { 5572264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5588569SJonathan.Ca@Sun.COM job_id, OPID_RESTART_JOB)); 5592264Sjacobs } 5602264Sjacobs 5612264Sjacobs papi_status_t 5622264Sjacobs papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) 5632264Sjacobs { 5642264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5658569SJonathan.Ca@Sun.COM job_id, OPID_PROMOTE_JOB)); 5662264Sjacobs } 5672264Sjacobs 5682264Sjacobs papi_status_t 5692264Sjacobs papiJobMove(papi_service_t handle, char *printer, int32_t job_id, 5702264Sjacobs char *destination) 5712264Sjacobs { 5722264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 5732264Sjacobs service_t *svc = handle; 5742264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 5752264Sjacobs 5762264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 5772264Sjacobs (destination == NULL)) 5782264Sjacobs return (PAPI_BAD_ARGUMENT); 5792264Sjacobs 5802264Sjacobs /* if we are already connected, use that connection. */ 5812264Sjacobs if (svc->connection == NULL) 5822264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 5832264Sjacobs return (result); 5842264Sjacobs 5852264Sjacobs ipp_initialize_request(svc, &request, OPID_CUPS_MOVE_JOB); 5862264Sjacobs 5873917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 5882264Sjacobs 5892264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 5908569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 5912264Sjacobs papiAttributeListFree(op); 5922264Sjacobs 5932264Sjacobs op = NULL; 5942264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_EXCL, 5958569SJonathan.Ca@Sun.COM "job-printer-uri", destination); 5962264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 5978569SJonathan.Ca@Sun.COM "job-attributes-group", op); 5982264Sjacobs papiAttributeListFree(op); 5992264Sjacobs 6002264Sjacobs result = ipp_send_request(svc, request, &response); 6012264Sjacobs papiAttributeListFree(request); 6022264Sjacobs papiAttributeListFree(response); 6032264Sjacobs 6042264Sjacobs return (result); 6052264Sjacobs } 6062264Sjacobs 6072264Sjacobs papi_status_t 6082264Sjacobs papiJobModify(papi_service_t handle, char *printer, int32_t job_id, 6092264Sjacobs papi_attribute_t **attributes, papi_job_t *job) 6102264Sjacobs { 6112264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 6122264Sjacobs service_t *svc = handle; 6132264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 6142264Sjacobs job_t *j = NULL; 6152264Sjacobs 6162264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 6172264Sjacobs (attributes == NULL)) 6182264Sjacobs return (PAPI_BAD_ARGUMENT); 6192264Sjacobs 6202264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 6212264Sjacobs return (PAPI_TEMPORARY_ERROR); 6222264Sjacobs 6232264Sjacobs /* if we are already connected, use that connection. */ 6242264Sjacobs if (svc->connection == NULL) 6252264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 6262264Sjacobs return (result); 6272264Sjacobs 6282264Sjacobs ipp_initialize_request(svc, &request, OPID_SET_JOB_ATTRIBUTES); 6292264Sjacobs 6303917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 6312264Sjacobs 6322264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6338569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 6342264Sjacobs papiAttributeListFree(op); 6352264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6368569SJonathan.Ca@Sun.COM "job-attributes-group", attributes); 6372264Sjacobs result = ipp_send_request(svc, request, &response); 6382264Sjacobs papiAttributeListFree(request); 6392264Sjacobs 6402264Sjacobs op = NULL; 6412264Sjacobs papiAttributeListGetCollection(response, NULL, 6428569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 6432264Sjacobs copy_attributes(&j->attributes, op); 6442264Sjacobs papiAttributeListFree(response); 6452264Sjacobs 6462264Sjacobs return (result); 6472264Sjacobs } 648