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> 40*9224SJonathan.Ca@Sun.COM #include <libintl.h> 412264Sjacobs 422264Sjacobs #ifndef OPID_CUPS_MOVE_JOB 432264Sjacobs #define OPID_CUPS_MOVE_JOB 0x400D 442264Sjacobs #endif 452264Sjacobs 462264Sjacobs void 472264Sjacobs papiJobFree(papi_job_t job) 482264Sjacobs { 492264Sjacobs job_t *tmp = (job_t *)job; 502264Sjacobs 512264Sjacobs if (tmp != NULL) { 522264Sjacobs if (tmp->attributes != NULL) 532264Sjacobs papiAttributeListFree(tmp->attributes); 542264Sjacobs free(tmp); 552264Sjacobs } 562264Sjacobs } 572264Sjacobs 582264Sjacobs void 592264Sjacobs papiJobListFree(papi_job_t *jobs) 602264Sjacobs { 612264Sjacobs if (jobs != NULL) { 622264Sjacobs int i; 632264Sjacobs 642264Sjacobs for (i = 0; jobs[i] != NULL; i++) 652264Sjacobs papiJobFree(jobs[i]); 662264Sjacobs free(jobs); 672264Sjacobs } 682264Sjacobs } 692264Sjacobs 702264Sjacobs papi_attribute_t ** 712264Sjacobs papiJobGetAttributeList(papi_job_t job) 722264Sjacobs { 732264Sjacobs papi_attribute_t **result = NULL; 742264Sjacobs job_t *j = job; 752264Sjacobs 762264Sjacobs if (j != NULL) 772264Sjacobs result = j->attributes; 782264Sjacobs 792264Sjacobs return (result); 802264Sjacobs } 812264Sjacobs 822264Sjacobs char * 832264Sjacobs papiJobGetPrinterName(papi_job_t job) 842264Sjacobs { 852264Sjacobs char *result = NULL; 862264Sjacobs job_t *j = job; 872264Sjacobs 882264Sjacobs if (j != NULL) 892264Sjacobs (void) papiAttributeListGetString(j->attributes, NULL, 908569SJonathan.Ca@Sun.COM "printer-name", &result); 912264Sjacobs 922264Sjacobs return (result); 932264Sjacobs } 942264Sjacobs 952264Sjacobs int32_t 962264Sjacobs papiJobGetId(papi_job_t job) 972264Sjacobs { 982264Sjacobs int32_t result = -1; 992264Sjacobs job_t *j = job; 1002264Sjacobs 1012264Sjacobs if (j != NULL) 1022264Sjacobs (void) papiAttributeListGetInteger(j->attributes, NULL, 1038569SJonathan.Ca@Sun.COM "job-id", &result); 1042264Sjacobs 1052264Sjacobs return (result); 1062264Sjacobs } 1072264Sjacobs 1082264Sjacobs papi_job_ticket_t * 1092264Sjacobs papiJobGetJobTicket(papi_job_t job) 1102264Sjacobs { 1112264Sjacobs papi_job_ticket_t *result = NULL; 1122264Sjacobs 1132264Sjacobs return (result); 1142264Sjacobs } 1152264Sjacobs 1162264Sjacobs static void 1172264Sjacobs populate_job_request(service_t *svc, papi_attribute_t ***request, 1182264Sjacobs papi_attribute_t **attributes, char *printer, uint16_t type) 1192264Sjacobs { 1202264Sjacobs papi_attribute_t **operational = NULL, **job = NULL; 1212264Sjacobs static char *operational_names[] = { 1222264Sjacobs "job-name", "ipp-attribute-fidelity", "document-name", 1232264Sjacobs "compression", "document-format", "document-natural-language", 1242264Sjacobs "job-k-octets", "job-impressions", "job-media-sheets", NULL 1252264Sjacobs }; 1262264Sjacobs 1272264Sjacobs /* create the base IPP request */ 1282264Sjacobs ipp_initialize_request(svc, request, type); 1292264Sjacobs 1302264Sjacobs /* create an operational attributes group */ 1313917Sjacobs ipp_initialize_operational_attributes(svc, &operational, printer, -1); 1322264Sjacobs 1332264Sjacobs /* split up the attributes into operational and job attributes */ 1342264Sjacobs split_and_copy_attributes(operational_names, attributes, 1358569SJonathan.Ca@Sun.COM &operational, &job); 1362264Sjacobs 1372264Sjacobs /* add the operational attributes group to the request */ 1382264Sjacobs papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, 1398569SJonathan.Ca@Sun.COM "operational-attributes-group", operational); 1402264Sjacobs papiAttributeListFree(operational); 1412264Sjacobs 1422264Sjacobs /* add the job attributes group to the request */ 1432264Sjacobs if (job != NULL) { 1449152SSonam.Gupta@Sun.COM /* 1459152SSonam.Gupta@Sun.COM * Add job-originating-host-name to attributes 1469152SSonam.Gupta@Sun.COM * if not already set. 1479152SSonam.Gupta@Sun.COM */ 1489152SSonam.Gupta@Sun.COM char *hostname = NULL; 1499152SSonam.Gupta@Sun.COM 1509152SSonam.Gupta@Sun.COM papiAttributeListGetString(job, NULL, 1519152SSonam.Gupta@Sun.COM "job-originating-host-name", &hostname); 1529152SSonam.Gupta@Sun.COM 1539152SSonam.Gupta@Sun.COM if (hostname == NULL) { 1549152SSonam.Gupta@Sun.COM char host[BUFSIZ]; 1559152SSonam.Gupta@Sun.COM 1569152SSonam.Gupta@Sun.COM if (gethostname(host, sizeof (host)) == 0) 1579152SSonam.Gupta@Sun.COM papiAttributeListAddString(&job, PAPI_ATTR_EXCL, 1589152SSonam.Gupta@Sun.COM "job-originating-host-name", host); 1599152SSonam.Gupta@Sun.COM } 1609152SSonam.Gupta@Sun.COM 1612264Sjacobs papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, 1628569SJonathan.Ca@Sun.COM "job-attributes-group", job); 1632264Sjacobs papiAttributeListFree(job); 1642264Sjacobs } 1652264Sjacobs } 1662264Sjacobs 1672264Sjacobs static papi_status_t 1682264Sjacobs send_document_uri(service_t *svc, char *file, papi_attribute_t **attributes, 1692264Sjacobs char *printer, int32_t id, char last, uint16_t type) 1702264Sjacobs { 1712264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 1722264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 1732264Sjacobs 1742264Sjacobs /* create the base IPP request */ 1752264Sjacobs ipp_initialize_request(svc, &request, type); 1762264Sjacobs 1772264Sjacobs /* create an operational attributes group */ 1783917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, id); 1792264Sjacobs 1802264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, "document-name", 1818569SJonathan.Ca@Sun.COM file); 1822264Sjacobs papiAttributeListAddBoolean(&op, PAPI_ATTR_REPLACE, "last-document", 1838569SJonathan.Ca@Sun.COM (last ? PAPI_TRUE : PAPI_FALSE)); 1842264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 1858569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 1862264Sjacobs papiAttributeListFree(op); 1872264Sjacobs 1882264Sjacobs /* send the IPP request to the server */ 1892264Sjacobs result = ipp_send_request_with_file(svc, request, &response, file); 1902264Sjacobs papiAttributeListFree(request); 1912264Sjacobs papiAttributeListFree(response); 1922264Sjacobs 1932264Sjacobs return (result); 1942264Sjacobs } 1952264Sjacobs 1962264Sjacobs typedef enum {_WITH_DATA, _BY_REFERENCE, _VALIDATE} call_type_t; 1972264Sjacobs 1982264Sjacobs papi_status_t 1992264Sjacobs internal_job_submit(papi_service_t handle, char *printer, 2002264Sjacobs papi_attribute_t **job_attributes, 2012264Sjacobs papi_job_ticket_t *job_ticket, 2022264Sjacobs char **files, papi_job_t *job, 2032264Sjacobs call_type_t call_type) 2042264Sjacobs { 2052264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 2062264Sjacobs service_t *svc = handle; 2078569SJonathan.Ca@Sun.COM struct stat statbuf; 2082264Sjacobs job_t *j = NULL; 2092264Sjacobs int i; 2102264Sjacobs uint16_t req_type = OPID_PRINT_JOB; 2112264Sjacobs uint16_t data_type = OPID_SEND_DOCUMENT; 2122264Sjacobs papi_attribute_t **request = NULL, **response = NULL; 2132264Sjacobs 2142264Sjacobs if ((svc == NULL) || (printer == NULL) || (job == NULL)) 2152264Sjacobs return (PAPI_BAD_ARGUMENT); 2162264Sjacobs 2172264Sjacobs switch (call_type) { 2182264Sjacobs case _BY_REFERENCE: 2192264Sjacobs #ifdef SOME_DAY_WE_WILL_BE_ABLE_TO_USE_URIS_FOR_JOB_DATA 2202264Sjacobs /* 2212264Sjacobs * For the time being, this is disabled. There are a number 2222264Sjacobs * of issues to be dealt with before we can send a URI 2232264Sjacobs * across the network to the server. For example, the file 2242264Sjacobs * name(s) passed in are most likely relative to the current 2252264Sjacobs * hosts filesystem. They also most likely will require some 2262264Sjacobs * form of authentication information to be passed with the 2272264Sjacobs * URI. 2282264Sjacobs */ 2292264Sjacobs req_type = OPID_PRINT_URI; 2302264Sjacobs req_type = OPID_SEND_URI; 2312264Sjacobs #endif 2322264Sjacobs /* fall-through */ 2332264Sjacobs case _WITH_DATA: 2342264Sjacobs if ((files == NULL) || (files[0] == NULL)) 2352264Sjacobs return (PAPI_BAD_ARGUMENT); 2362264Sjacobs 2372264Sjacobs if (files[1] != NULL) /* more than 1 file */ 2382264Sjacobs req_type = OPID_CREATE_JOB; 2392264Sjacobs 2402264Sjacobs break; 2412264Sjacobs case _VALIDATE: 2422264Sjacobs req_type = OPID_VALIDATE_JOB; 2432264Sjacobs /* if we have files, validate access to them */ 2442264Sjacobs if (files != NULL) { 2458569SJonathan.Ca@Sun.COM for (i = 0; files[i] != NULL; i++) { 2462264Sjacobs if (access(files[i], R_OK) < 0) { 2472264Sjacobs detailed_error(svc, "%s: %s", files[i], 2488569SJonathan.Ca@Sun.COM strerror(errno)); 2492264Sjacobs return (PAPI_DOCUMENT_ACCESS_ERROR); 2502264Sjacobs } 2518569SJonathan.Ca@Sun.COM 2528569SJonathan.Ca@Sun.COM if (strcmp("standard input", files[i]) != 0) { 253*9224SJonathan.Ca@Sun.COM if (stat(files[i], &statbuf) < 0) { 254*9224SJonathan.Ca@Sun.COM detailed_error(svc, gettext( 255*9224SJonathan.Ca@Sun.COM "Cannot access file: %s:" 256*9224SJonathan.Ca@Sun.COM " %s"), files[i], 257*9224SJonathan.Ca@Sun.COM strerror(errno)); 258*9224SJonathan.Ca@Sun.COM return ( 259*9224SJonathan.Ca@Sun.COM PAPI_DOCUMENT_ACCESS_ERROR); 260*9224SJonathan.Ca@Sun.COM } 2618569SJonathan.Ca@Sun.COM if (statbuf.st_size == 0) { 2628569SJonathan.Ca@Sun.COM detailed_error(svc, 2638569SJonathan.Ca@Sun.COM "Zero byte (empty) file: " 2648569SJonathan.Ca@Sun.COM "%s", 2658569SJonathan.Ca@Sun.COM files[i]); 2668569SJonathan.Ca@Sun.COM return (PAPI_BAD_ARGUMENT); 2678569SJonathan.Ca@Sun.COM } 2688569SJonathan.Ca@Sun.COM } 2698569SJonathan.Ca@Sun.COM } 2702264Sjacobs files = NULL; 2712264Sjacobs } 2722264Sjacobs break; 2732264Sjacobs } 2742264Sjacobs 2752264Sjacobs /* if we are already connected, use that connection. */ 2762264Sjacobs if (svc->connection == NULL) 2772264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 2782264Sjacobs return (result); 2792264Sjacobs 2802264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 2812264Sjacobs return (PAPI_TEMPORARY_ERROR); 2822264Sjacobs 2839166SSonam.Gupta@Sun.COM /* 2849166SSonam.Gupta@Sun.COM * before creating IPP request 2859166SSonam.Gupta@Sun.COM * add the job-name 2869166SSonam.Gupta@Sun.COM */ 2879166SSonam.Gupta@Sun.COM if ((files != NULL) && (files[0] != NULL)) 2889166SSonam.Gupta@Sun.COM papiAttributeListAddString(&job_attributes, PAPI_ATTR_EXCL, 2899166SSonam.Gupta@Sun.COM "job-name", files[0]); 2909166SSonam.Gupta@Sun.COM 2912264Sjacobs /* create IPP request */ 2922264Sjacobs populate_job_request(svc, &request, job_attributes, printer, req_type); 2932264Sjacobs 2942264Sjacobs switch (req_type) { 2952264Sjacobs case OPID_PRINT_JOB: 2962264Sjacobs result = ipp_send_request_with_file(svc, request, &response, 2978569SJonathan.Ca@Sun.COM files[0]); 2982264Sjacobs break; 2992264Sjacobs case OPID_CREATE_JOB: 3002264Sjacobs case OPID_VALIDATE_JOB: 3012264Sjacobs case OPID_PRINT_URI: 3022264Sjacobs result = ipp_send_request(svc, request, &response); 3032264Sjacobs break; 3042264Sjacobs } 3052264Sjacobs papiAttributeListFree(request); 3062264Sjacobs 3072264Sjacobs if (result == PAPI_OK) { 3082264Sjacobs papi_attribute_t **op = NULL; 3092264Sjacobs 3102264Sjacobs /* retrieve the job attributes */ 3112264Sjacobs papiAttributeListGetCollection(response, NULL, 3128569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 3132264Sjacobs copy_attributes(&j->attributes, op); 3142264Sjacobs 3152264Sjacobs if (req_type == OPID_CREATE_JOB) { 3162264Sjacobs int32_t id = 0; 3172264Sjacobs 3182264Sjacobs papiAttributeListGetInteger(j->attributes, NULL, 3198569SJonathan.Ca@Sun.COM "job-id", &id); 3202264Sjacobs /* send each document */ 3212264Sjacobs for (i = 0; ((result == PAPI_OK) && (files[i] != NULL)); 3228569SJonathan.Ca@Sun.COM i++) 3232264Sjacobs result = send_document_uri(svc, files[i], 3248569SJonathan.Ca@Sun.COM job_attributes, 3258569SJonathan.Ca@Sun.COM printer, id, (files[i+1]?0:1), 3268569SJonathan.Ca@Sun.COM data_type); 3272264Sjacobs } 3282264Sjacobs } 3292264Sjacobs papiAttributeListFree(response); 3302264Sjacobs 3312264Sjacobs return (result); 3322264Sjacobs } 3332264Sjacobs 3342264Sjacobs papi_status_t 3352264Sjacobs papiJobSubmit(papi_service_t handle, char *printer, 3362264Sjacobs papi_attribute_t **job_attributes, 3372264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 3382264Sjacobs { 3392264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 3408569SJonathan.Ca@Sun.COM job_ticket, files, job, _WITH_DATA)); 3412264Sjacobs } 3422264Sjacobs 3432264Sjacobs papi_status_t 3442264Sjacobs papiJobSubmitByReference(papi_service_t handle, char *printer, 3452264Sjacobs papi_attribute_t **job_attributes, 3462264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 3472264Sjacobs { 3482264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 3498569SJonathan.Ca@Sun.COM job_ticket, files, job, _BY_REFERENCE)); 3502264Sjacobs } 3512264Sjacobs 3522264Sjacobs papi_status_t 3532264Sjacobs papiJobValidate(papi_service_t handle, char *printer, 3542264Sjacobs papi_attribute_t **job_attributes, 3552264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 3562264Sjacobs { 3572264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 3588569SJonathan.Ca@Sun.COM job_ticket, files, job, _VALIDATE)); 3592264Sjacobs } 3602264Sjacobs 3612264Sjacobs papi_status_t 3622264Sjacobs papiJobStreamOpen(papi_service_t handle, char *printer, 3632264Sjacobs papi_attribute_t **job_attributes, 3642264Sjacobs papi_job_ticket_t *job_ticket, papi_stream_t *stream) 3652264Sjacobs { 3662264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 3672264Sjacobs papi_attribute_t **request = NULL; 3682264Sjacobs service_t *svc = handle; 3692264Sjacobs 3702264Sjacobs if ((svc == NULL) || (printer == NULL) || (stream == NULL)) 3712264Sjacobs return (PAPI_BAD_ARGUMENT); 3722264Sjacobs 3732264Sjacobs /* if we are already connected, use that connection. */ 3742264Sjacobs if (svc->connection == NULL) 3752264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 3762264Sjacobs return (result); 3772264Sjacobs 3782264Sjacobs /* create job request */ 3792264Sjacobs populate_job_request(svc, &request, job_attributes, printer, 3808569SJonathan.Ca@Sun.COM OPID_PRINT_JOB); 3812264Sjacobs 3822264Sjacobs *stream = svc->connection; 3832264Sjacobs 3842264Sjacobs result = ipp_send_initial_request_block(svc, request, 0); 3852264Sjacobs papiAttributeListFree(request); 3862264Sjacobs 3872264Sjacobs return (result); 3882264Sjacobs } 3892264Sjacobs 3902264Sjacobs papi_status_t 3912264Sjacobs papiJobStreamWrite(papi_service_t handle, 3922264Sjacobs papi_stream_t stream, void *buffer, size_t buflen) 3932264Sjacobs { 3942264Sjacobs papi_status_t result = PAPI_OK; 3952264Sjacobs service_t *svc = handle; 3962264Sjacobs size_t rc; 3972264Sjacobs 3982264Sjacobs #ifdef DEBUG 3992264Sjacobs printf("papiJobStreamWrite(0x%8.8x, 0x%8.8x, 0x%8.8x, %d)\n", 4008569SJonathan.Ca@Sun.COM handle, stream, buffer, buflen); 4012264Sjacobs httpDumpData(stdout, "papiJobStreamWrite:", buffer, buflen); 4022264Sjacobs #endif 4032264Sjacobs 4042264Sjacobs if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || 4052264Sjacobs (buflen == 0)) 4062264Sjacobs return (PAPI_BAD_ARGUMENT); 4072264Sjacobs 4082264Sjacobs while ((result == PAPI_OK) && (buflen > 0)) { 4092264Sjacobs rc = ipp_request_write(svc, buffer, buflen); 4102264Sjacobs if (rc < 0) 4112264Sjacobs result = PAPI_TEMPORARY_ERROR; 4122264Sjacobs else { 4132264Sjacobs buffer = (char *)buffer + rc; 4142264Sjacobs buflen -= rc; 4152264Sjacobs } 4162264Sjacobs } 4172264Sjacobs 4182264Sjacobs #ifdef DEBUG 4192264Sjacobs printf("papiJobStreamWrite(): %s\n", papiStatusString(result)); 4202264Sjacobs #endif 4212264Sjacobs 4222264Sjacobs return (result); 4232264Sjacobs } 4242264Sjacobs 4252264Sjacobs papi_status_t 4262264Sjacobs papiJobStreamClose(papi_service_t handle, 4272264Sjacobs papi_stream_t stream, papi_job_t *job) 4282264Sjacobs { 4292264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4302264Sjacobs http_status_t status = HTTP_CONTINUE; 4312264Sjacobs service_t *svc = handle; 4322264Sjacobs papi_attribute_t **response = NULL; 4332264Sjacobs job_t *j = NULL; 4342264Sjacobs 4352264Sjacobs if ((svc == NULL) || (stream == NULL) || (job == NULL)) 4362264Sjacobs return (PAPI_BAD_ARGUMENT); 4372264Sjacobs 4382264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 4392264Sjacobs return (PAPI_TEMPORARY_ERROR); 4402264Sjacobs 4412264Sjacobs (void) ipp_request_write(svc, "", 0); 4422264Sjacobs 4432264Sjacobs /* update our connection info */ 4442264Sjacobs while (status == HTTP_CONTINUE) 4452264Sjacobs status = httpUpdate(svc->connection); 4462264Sjacobs 4472264Sjacobs if (status != HTTP_OK) 4482264Sjacobs return (http_to_papi_status(status)); 4492264Sjacobs httpWait(svc->connection, 1000); 4502264Sjacobs 4512264Sjacobs /* read the IPP response */ 4522264Sjacobs result = ipp_read_message(&ipp_request_read, svc, &response, 4538569SJonathan.Ca@Sun.COM IPP_TYPE_RESPONSE); 4542264Sjacobs if (result == PAPI_OK) 4552264Sjacobs result = ipp_status_info(svc, response); 4562264Sjacobs 4572264Sjacobs if (result == PAPI_OK) { 4582264Sjacobs papi_attribute_t **op = NULL; 4592264Sjacobs 4602264Sjacobs papiAttributeListGetCollection(response, NULL, 4618569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 4622264Sjacobs copy_attributes(&j->attributes, op); 4632264Sjacobs } 4642264Sjacobs papiAttributeListFree(response); 4652264Sjacobs 4662264Sjacobs return (result); 4672264Sjacobs } 4682264Sjacobs 4692264Sjacobs papi_status_t 4702264Sjacobs papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, 4712264Sjacobs char **requested_attrs, 4722264Sjacobs papi_job_t *job) 4732264Sjacobs { 4742264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4752264Sjacobs service_t *svc = handle; 4762264Sjacobs job_t *j = NULL; 4772264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 4782264Sjacobs 4792264Sjacobs if ((svc == NULL) || (printer == NULL)) 4802264Sjacobs return (PAPI_BAD_ARGUMENT); 4812264Sjacobs 4822264Sjacobs /* if we are already connected, use that connection. */ 4832264Sjacobs if (svc->connection == NULL) 4842264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 4852264Sjacobs return (result); 4862264Sjacobs 4872264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 4882264Sjacobs return (PAPI_TEMPORARY_ERROR); 4892264Sjacobs 4902264Sjacobs ipp_initialize_request(svc, &request, OPID_GET_JOB_ATTRIBUTES); 4912264Sjacobs 4923917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 4932264Sjacobs 4942264Sjacobs if (requested_attrs != NULL) { 4952264Sjacobs int i; 4962264Sjacobs 4972264Sjacobs for (i = 0; requested_attrs[i] != NULL; i++) 4982264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 4998569SJonathan.Ca@Sun.COM "requested-attributes", requested_attrs[i]); 5002264Sjacobs } 5012264Sjacobs 5022264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 5038569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 5042264Sjacobs papiAttributeListFree(op); 5052264Sjacobs result = ipp_send_request(svc, request, &response); 5062264Sjacobs papiAttributeListFree(request); 5072264Sjacobs 5082264Sjacobs op = NULL; 5092264Sjacobs papiAttributeListGetCollection(response, NULL, 5108569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 5112264Sjacobs copy_attributes(&j->attributes, op); 5122264Sjacobs papiAttributeListFree(response); 5132264Sjacobs 5142264Sjacobs return (result); 5152264Sjacobs } 5162264Sjacobs 5172264Sjacobs /* papiJob{Cancel|Hold|Release|Restart|Promote} are all the same */ 5182264Sjacobs static papi_status_t 5192264Sjacobs _job_cancel_hold_release_restart_promote(papi_service_t handle, 5202264Sjacobs char *printer, int32_t job_id, uint16_t type) 5212264Sjacobs { 5222264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 5232264Sjacobs service_t *svc = handle; 5242264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 5252264Sjacobs 5262264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0)) 5272264Sjacobs return (PAPI_BAD_ARGUMENT); 5282264Sjacobs 5292264Sjacobs /* if we are already connected, use that connection. */ 5302264Sjacobs if (svc->connection == NULL) 5312264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 5322264Sjacobs return (result); 5332264Sjacobs 5342264Sjacobs ipp_initialize_request(svc, &request, type); 5352264Sjacobs 5363917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 5372264Sjacobs 5382264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 5398569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 5402264Sjacobs papiAttributeListFree(op); 5412264Sjacobs result = ipp_send_request(svc, request, &response); 5422264Sjacobs papiAttributeListFree(request); 5432264Sjacobs papiAttributeListFree(response); 5442264Sjacobs 5452264Sjacobs return (result); 5462264Sjacobs } 5472264Sjacobs 5482264Sjacobs papi_status_t 5492264Sjacobs papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) 5502264Sjacobs { 5512264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5528569SJonathan.Ca@Sun.COM job_id, OPID_CANCEL_JOB)); 5532264Sjacobs } 5542264Sjacobs 5552264Sjacobs 5562264Sjacobs papi_status_t 5572264Sjacobs papiJobHold(papi_service_t handle, char *printer, int32_t job_id) 5582264Sjacobs { 5592264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5608569SJonathan.Ca@Sun.COM job_id, OPID_HOLD_JOB)); 5612264Sjacobs } 5622264Sjacobs 5632264Sjacobs papi_status_t 5642264Sjacobs papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) 5652264Sjacobs { 5662264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5678569SJonathan.Ca@Sun.COM job_id, OPID_RELEASE_JOB)); 5682264Sjacobs } 5692264Sjacobs 5702264Sjacobs papi_status_t 5712264Sjacobs papiJobRestart(papi_service_t handle, char *printer, int32_t job_id) 5722264Sjacobs { 5732264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5748569SJonathan.Ca@Sun.COM job_id, OPID_RESTART_JOB)); 5752264Sjacobs } 5762264Sjacobs 5772264Sjacobs papi_status_t 5782264Sjacobs papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) 5792264Sjacobs { 5802264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5818569SJonathan.Ca@Sun.COM job_id, OPID_PROMOTE_JOB)); 5822264Sjacobs } 5832264Sjacobs 5842264Sjacobs papi_status_t 5852264Sjacobs papiJobMove(papi_service_t handle, char *printer, int32_t job_id, 5862264Sjacobs char *destination) 5872264Sjacobs { 5882264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 5892264Sjacobs service_t *svc = handle; 5902264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 5912264Sjacobs 5922264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 5932264Sjacobs (destination == NULL)) 5942264Sjacobs return (PAPI_BAD_ARGUMENT); 5952264Sjacobs 5962264Sjacobs /* if we are already connected, use that connection. */ 5972264Sjacobs if (svc->connection == NULL) 5982264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 5992264Sjacobs return (result); 6002264Sjacobs 6012264Sjacobs ipp_initialize_request(svc, &request, OPID_CUPS_MOVE_JOB); 6022264Sjacobs 6033917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 6042264Sjacobs 6052264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6068569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 6072264Sjacobs papiAttributeListFree(op); 6082264Sjacobs 6092264Sjacobs op = NULL; 6102264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_EXCL, 6118569SJonathan.Ca@Sun.COM "job-printer-uri", destination); 6122264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6138569SJonathan.Ca@Sun.COM "job-attributes-group", op); 6142264Sjacobs papiAttributeListFree(op); 6152264Sjacobs 6162264Sjacobs result = ipp_send_request(svc, request, &response); 6172264Sjacobs papiAttributeListFree(request); 6182264Sjacobs papiAttributeListFree(response); 6192264Sjacobs 6202264Sjacobs return (result); 6212264Sjacobs } 6222264Sjacobs 6232264Sjacobs papi_status_t 6242264Sjacobs papiJobModify(papi_service_t handle, char *printer, int32_t job_id, 6252264Sjacobs papi_attribute_t **attributes, papi_job_t *job) 6262264Sjacobs { 6272264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 6282264Sjacobs service_t *svc = handle; 6292264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 6302264Sjacobs job_t *j = NULL; 6312264Sjacobs 6322264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 6332264Sjacobs (attributes == NULL)) 6342264Sjacobs return (PAPI_BAD_ARGUMENT); 6352264Sjacobs 6362264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 6372264Sjacobs return (PAPI_TEMPORARY_ERROR); 6382264Sjacobs 6392264Sjacobs /* if we are already connected, use that connection. */ 6402264Sjacobs if (svc->connection == NULL) 6412264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 6422264Sjacobs return (result); 6432264Sjacobs 6442264Sjacobs ipp_initialize_request(svc, &request, OPID_SET_JOB_ATTRIBUTES); 6452264Sjacobs 6463917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 6472264Sjacobs 6482264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6498569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 6502264Sjacobs papiAttributeListFree(op); 6512264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6528569SJonathan.Ca@Sun.COM "job-attributes-group", attributes); 6532264Sjacobs result = ipp_send_request(svc, request, &response); 6542264Sjacobs papiAttributeListFree(request); 6552264Sjacobs 6562264Sjacobs op = NULL; 6572264Sjacobs papiAttributeListGetCollection(response, NULL, 6588569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 6592264Sjacobs copy_attributes(&j->attributes, op); 6602264Sjacobs papiAttributeListFree(response); 6612264Sjacobs 6622264Sjacobs return (result); 6632264Sjacobs } 664