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 /* 23*11699SKeerthi.Kondaka@Sun.COM * Copyright 2010 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> 409224SJonathan.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) { 2539224SJonathan.Ca@Sun.COM if (stat(files[i], &statbuf) < 0) { 2549224SJonathan.Ca@Sun.COM detailed_error(svc, gettext( 2559224SJonathan.Ca@Sun.COM "Cannot access file: %s:" 2569224SJonathan.Ca@Sun.COM " %s"), files[i], 2579224SJonathan.Ca@Sun.COM strerror(errno)); 2589224SJonathan.Ca@Sun.COM return ( 2599224SJonathan.Ca@Sun.COM PAPI_DOCUMENT_ACCESS_ERROR); 2609224SJonathan.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 378*11699SKeerthi.Kondaka@Sun.COM papiAttributeListAddString(&job_attributes, PAPI_ATTR_EXCL, 379*11699SKeerthi.Kondaka@Sun.COM "job-name", "standard input"); 380*11699SKeerthi.Kondaka@Sun.COM 3812264Sjacobs /* create job request */ 3822264Sjacobs populate_job_request(svc, &request, job_attributes, printer, 3838569SJonathan.Ca@Sun.COM OPID_PRINT_JOB); 3842264Sjacobs 3852264Sjacobs *stream = svc->connection; 3862264Sjacobs 3872264Sjacobs result = ipp_send_initial_request_block(svc, request, 0); 3882264Sjacobs papiAttributeListFree(request); 3892264Sjacobs 3902264Sjacobs return (result); 3912264Sjacobs } 3922264Sjacobs 3932264Sjacobs papi_status_t 3942264Sjacobs papiJobStreamWrite(papi_service_t handle, 3952264Sjacobs papi_stream_t stream, void *buffer, size_t buflen) 3962264Sjacobs { 3972264Sjacobs papi_status_t result = PAPI_OK; 3982264Sjacobs service_t *svc = handle; 3992264Sjacobs size_t rc; 4002264Sjacobs 4012264Sjacobs #ifdef DEBUG 4022264Sjacobs printf("papiJobStreamWrite(0x%8.8x, 0x%8.8x, 0x%8.8x, %d)\n", 4038569SJonathan.Ca@Sun.COM handle, stream, buffer, buflen); 4042264Sjacobs httpDumpData(stdout, "papiJobStreamWrite:", buffer, buflen); 4052264Sjacobs #endif 4062264Sjacobs 4072264Sjacobs if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || 4082264Sjacobs (buflen == 0)) 4092264Sjacobs return (PAPI_BAD_ARGUMENT); 4102264Sjacobs 4112264Sjacobs while ((result == PAPI_OK) && (buflen > 0)) { 4122264Sjacobs rc = ipp_request_write(svc, buffer, buflen); 4132264Sjacobs if (rc < 0) 4142264Sjacobs result = PAPI_TEMPORARY_ERROR; 4152264Sjacobs else { 4162264Sjacobs buffer = (char *)buffer + rc; 4172264Sjacobs buflen -= rc; 4182264Sjacobs } 4192264Sjacobs } 4202264Sjacobs 4212264Sjacobs #ifdef DEBUG 4222264Sjacobs printf("papiJobStreamWrite(): %s\n", papiStatusString(result)); 4232264Sjacobs #endif 4242264Sjacobs 4252264Sjacobs return (result); 4262264Sjacobs } 4272264Sjacobs 4282264Sjacobs papi_status_t 4292264Sjacobs papiJobStreamClose(papi_service_t handle, 4302264Sjacobs papi_stream_t stream, papi_job_t *job) 4312264Sjacobs { 4322264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4332264Sjacobs http_status_t status = HTTP_CONTINUE; 4342264Sjacobs service_t *svc = handle; 4352264Sjacobs papi_attribute_t **response = NULL; 4362264Sjacobs job_t *j = NULL; 4372264Sjacobs 4382264Sjacobs if ((svc == NULL) || (stream == NULL) || (job == NULL)) 4392264Sjacobs return (PAPI_BAD_ARGUMENT); 4402264Sjacobs 4412264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 4422264Sjacobs return (PAPI_TEMPORARY_ERROR); 4432264Sjacobs 4442264Sjacobs (void) ipp_request_write(svc, "", 0); 4452264Sjacobs 4462264Sjacobs /* update our connection info */ 4472264Sjacobs while (status == HTTP_CONTINUE) 4482264Sjacobs status = httpUpdate(svc->connection); 4492264Sjacobs 4502264Sjacobs if (status != HTTP_OK) 4512264Sjacobs return (http_to_papi_status(status)); 4522264Sjacobs httpWait(svc->connection, 1000); 4532264Sjacobs 4542264Sjacobs /* read the IPP response */ 4552264Sjacobs result = ipp_read_message(&ipp_request_read, svc, &response, 4568569SJonathan.Ca@Sun.COM IPP_TYPE_RESPONSE); 4572264Sjacobs if (result == PAPI_OK) 4582264Sjacobs result = ipp_status_info(svc, response); 4592264Sjacobs 4602264Sjacobs if (result == PAPI_OK) { 4612264Sjacobs papi_attribute_t **op = NULL; 4622264Sjacobs 4632264Sjacobs papiAttributeListGetCollection(response, NULL, 4648569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 4652264Sjacobs copy_attributes(&j->attributes, op); 4662264Sjacobs } 4672264Sjacobs papiAttributeListFree(response); 4682264Sjacobs 4692264Sjacobs return (result); 4702264Sjacobs } 4712264Sjacobs 4722264Sjacobs papi_status_t 4732264Sjacobs papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, 4742264Sjacobs char **requested_attrs, 4752264Sjacobs papi_job_t *job) 4762264Sjacobs { 4772264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4782264Sjacobs service_t *svc = handle; 4792264Sjacobs job_t *j = NULL; 4802264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 4812264Sjacobs 4822264Sjacobs if ((svc == NULL) || (printer == NULL)) 4832264Sjacobs return (PAPI_BAD_ARGUMENT); 4842264Sjacobs 4852264Sjacobs /* if we are already connected, use that connection. */ 4862264Sjacobs if (svc->connection == NULL) 4872264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 4882264Sjacobs return (result); 4892264Sjacobs 4902264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 4912264Sjacobs return (PAPI_TEMPORARY_ERROR); 4922264Sjacobs 4932264Sjacobs ipp_initialize_request(svc, &request, OPID_GET_JOB_ATTRIBUTES); 4942264Sjacobs 4953917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 4962264Sjacobs 4972264Sjacobs if (requested_attrs != NULL) { 4982264Sjacobs int i; 4992264Sjacobs 5002264Sjacobs for (i = 0; requested_attrs[i] != NULL; i++) 5012264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 5028569SJonathan.Ca@Sun.COM "requested-attributes", requested_attrs[i]); 5032264Sjacobs } 5042264Sjacobs 5052264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 5068569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 5072264Sjacobs papiAttributeListFree(op); 5082264Sjacobs result = ipp_send_request(svc, request, &response); 5092264Sjacobs papiAttributeListFree(request); 5102264Sjacobs 5112264Sjacobs op = NULL; 5122264Sjacobs papiAttributeListGetCollection(response, NULL, 5138569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 5142264Sjacobs copy_attributes(&j->attributes, op); 5152264Sjacobs papiAttributeListFree(response); 5162264Sjacobs 5172264Sjacobs return (result); 5182264Sjacobs } 5192264Sjacobs 5202264Sjacobs /* papiJob{Cancel|Hold|Release|Restart|Promote} are all the same */ 5212264Sjacobs static papi_status_t 5222264Sjacobs _job_cancel_hold_release_restart_promote(papi_service_t handle, 5232264Sjacobs char *printer, int32_t job_id, uint16_t type) 5242264Sjacobs { 5252264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 5262264Sjacobs service_t *svc = handle; 5272264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 5282264Sjacobs 5292264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0)) 5302264Sjacobs return (PAPI_BAD_ARGUMENT); 5312264Sjacobs 5322264Sjacobs /* if we are already connected, use that connection. */ 5332264Sjacobs if (svc->connection == NULL) 5342264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 5352264Sjacobs return (result); 5362264Sjacobs 5372264Sjacobs ipp_initialize_request(svc, &request, type); 5382264Sjacobs 5393917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 5402264Sjacobs 5412264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 5428569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 5432264Sjacobs papiAttributeListFree(op); 5442264Sjacobs result = ipp_send_request(svc, request, &response); 5452264Sjacobs papiAttributeListFree(request); 5462264Sjacobs papiAttributeListFree(response); 5472264Sjacobs 5482264Sjacobs return (result); 5492264Sjacobs } 5502264Sjacobs 5512264Sjacobs papi_status_t 5522264Sjacobs papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) 5532264Sjacobs { 5542264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5558569SJonathan.Ca@Sun.COM job_id, OPID_CANCEL_JOB)); 5562264Sjacobs } 5572264Sjacobs 5582264Sjacobs 5592264Sjacobs papi_status_t 5602264Sjacobs papiJobHold(papi_service_t handle, char *printer, int32_t job_id) 5612264Sjacobs { 5622264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5638569SJonathan.Ca@Sun.COM job_id, OPID_HOLD_JOB)); 5642264Sjacobs } 5652264Sjacobs 5662264Sjacobs papi_status_t 5672264Sjacobs papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) 5682264Sjacobs { 5692264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5708569SJonathan.Ca@Sun.COM job_id, OPID_RELEASE_JOB)); 5712264Sjacobs } 5722264Sjacobs 5732264Sjacobs papi_status_t 5742264Sjacobs papiJobRestart(papi_service_t handle, char *printer, int32_t job_id) 5752264Sjacobs { 5762264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5778569SJonathan.Ca@Sun.COM job_id, OPID_RESTART_JOB)); 5782264Sjacobs } 5792264Sjacobs 5802264Sjacobs papi_status_t 5812264Sjacobs papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) 5822264Sjacobs { 5832264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5848569SJonathan.Ca@Sun.COM job_id, OPID_PROMOTE_JOB)); 5852264Sjacobs } 5862264Sjacobs 5872264Sjacobs papi_status_t 5882264Sjacobs papiJobMove(papi_service_t handle, char *printer, int32_t job_id, 5892264Sjacobs char *destination) 5902264Sjacobs { 5912264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 5922264Sjacobs service_t *svc = handle; 5932264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 5942264Sjacobs 5952264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 5962264Sjacobs (destination == NULL)) 5972264Sjacobs return (PAPI_BAD_ARGUMENT); 5982264Sjacobs 5992264Sjacobs /* if we are already connected, use that connection. */ 6002264Sjacobs if (svc->connection == NULL) 6012264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 6022264Sjacobs return (result); 6032264Sjacobs 6042264Sjacobs ipp_initialize_request(svc, &request, OPID_CUPS_MOVE_JOB); 6052264Sjacobs 6063917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 6072264Sjacobs 6082264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6098569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 6102264Sjacobs papiAttributeListFree(op); 6112264Sjacobs 6122264Sjacobs op = NULL; 6132264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_EXCL, 6148569SJonathan.Ca@Sun.COM "job-printer-uri", destination); 6152264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6168569SJonathan.Ca@Sun.COM "job-attributes-group", op); 6172264Sjacobs papiAttributeListFree(op); 6182264Sjacobs 6192264Sjacobs result = ipp_send_request(svc, request, &response); 6202264Sjacobs papiAttributeListFree(request); 6212264Sjacobs papiAttributeListFree(response); 6222264Sjacobs 6232264Sjacobs return (result); 6242264Sjacobs } 6252264Sjacobs 6262264Sjacobs papi_status_t 6272264Sjacobs papiJobModify(papi_service_t handle, char *printer, int32_t job_id, 6282264Sjacobs papi_attribute_t **attributes, papi_job_t *job) 6292264Sjacobs { 6302264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 6312264Sjacobs service_t *svc = handle; 6322264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 6332264Sjacobs job_t *j = NULL; 6342264Sjacobs 6352264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 6362264Sjacobs (attributes == NULL)) 6372264Sjacobs return (PAPI_BAD_ARGUMENT); 6382264Sjacobs 6392264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 6402264Sjacobs return (PAPI_TEMPORARY_ERROR); 6412264Sjacobs 6422264Sjacobs /* if we are already connected, use that connection. */ 6432264Sjacobs if (svc->connection == NULL) 6442264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 6452264Sjacobs return (result); 6462264Sjacobs 6472264Sjacobs ipp_initialize_request(svc, &request, OPID_SET_JOB_ATTRIBUTES); 6482264Sjacobs 6493917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 6502264Sjacobs 6512264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6528569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 6532264Sjacobs papiAttributeListFree(op); 6542264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6558569SJonathan.Ca@Sun.COM "job-attributes-group", attributes); 6562264Sjacobs result = ipp_send_request(svc, request, &response); 6572264Sjacobs papiAttributeListFree(request); 6582264Sjacobs 6592264Sjacobs op = NULL; 6602264Sjacobs papiAttributeListGetCollection(response, NULL, 6618569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 6622264Sjacobs copy_attributes(&j->attributes, op); 6632264Sjacobs papiAttributeListFree(response); 6642264Sjacobs 6652264Sjacobs return (result); 6662264Sjacobs } 667