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*3917Sjacobs * Copyright 2007 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 #pragma ident "%Z%%M% %I% %E% SMI" 312264Sjacobs 322264Sjacobs /*LINTLIBRARY*/ 332264Sjacobs 342264Sjacobs #include <stdlib.h> 352264Sjacobs #include <errno.h> 362264Sjacobs #include <string.h> 372264Sjacobs #include <papi_impl.h> 382264Sjacobs 392264Sjacobs #ifndef OPID_CUPS_MOVE_JOB 402264Sjacobs #define OPID_CUPS_MOVE_JOB 0x400D 412264Sjacobs #endif 422264Sjacobs 432264Sjacobs void 442264Sjacobs papiJobFree(papi_job_t job) 452264Sjacobs { 462264Sjacobs job_t *tmp = (job_t *)job; 472264Sjacobs 482264Sjacobs if (tmp != NULL) { 492264Sjacobs if (tmp->attributes != NULL) 502264Sjacobs papiAttributeListFree(tmp->attributes); 512264Sjacobs free(tmp); 522264Sjacobs } 532264Sjacobs } 542264Sjacobs 552264Sjacobs void 562264Sjacobs papiJobListFree(papi_job_t *jobs) 572264Sjacobs { 582264Sjacobs if (jobs != NULL) { 592264Sjacobs int i; 602264Sjacobs 612264Sjacobs for (i = 0; jobs[i] != NULL; i++) 622264Sjacobs papiJobFree(jobs[i]); 632264Sjacobs free(jobs); 642264Sjacobs } 652264Sjacobs } 662264Sjacobs 672264Sjacobs papi_attribute_t ** 682264Sjacobs papiJobGetAttributeList(papi_job_t job) 692264Sjacobs { 702264Sjacobs papi_attribute_t **result = NULL; 712264Sjacobs job_t *j = job; 722264Sjacobs 732264Sjacobs if (j != NULL) 742264Sjacobs result = j->attributes; 752264Sjacobs 762264Sjacobs return (result); 772264Sjacobs } 782264Sjacobs 792264Sjacobs char * 802264Sjacobs papiJobGetPrinterName(papi_job_t job) 812264Sjacobs { 822264Sjacobs char *result = NULL; 832264Sjacobs job_t *j = job; 842264Sjacobs 852264Sjacobs if (j != NULL) 862264Sjacobs (void) papiAttributeListGetString(j->attributes, NULL, 872264Sjacobs "printer-name", &result); 882264Sjacobs 892264Sjacobs return (result); 902264Sjacobs } 912264Sjacobs 922264Sjacobs int32_t 932264Sjacobs papiJobGetId(papi_job_t job) 942264Sjacobs { 952264Sjacobs int32_t result = -1; 962264Sjacobs job_t *j = job; 972264Sjacobs 982264Sjacobs if (j != NULL) 992264Sjacobs (void) papiAttributeListGetInteger(j->attributes, NULL, 1002264Sjacobs "job-id", &result); 1012264Sjacobs 1022264Sjacobs return (result); 1032264Sjacobs } 1042264Sjacobs 1052264Sjacobs papi_job_ticket_t * 1062264Sjacobs papiJobGetJobTicket(papi_job_t job) 1072264Sjacobs { 1082264Sjacobs papi_job_ticket_t *result = NULL; 1092264Sjacobs 1102264Sjacobs return (result); 1112264Sjacobs } 1122264Sjacobs 1132264Sjacobs static void 1142264Sjacobs populate_job_request(service_t *svc, papi_attribute_t ***request, 1152264Sjacobs papi_attribute_t **attributes, char *printer, uint16_t type) 1162264Sjacobs { 1172264Sjacobs papi_attribute_t **operational = NULL, **job = NULL; 1182264Sjacobs static char *operational_names[] = { 1192264Sjacobs "job-name", "ipp-attribute-fidelity", "document-name", 1202264Sjacobs "compression", "document-format", "document-natural-language", 1212264Sjacobs "job-k-octets", "job-impressions", "job-media-sheets", NULL 1222264Sjacobs }; 1232264Sjacobs 1242264Sjacobs /* create the base IPP request */ 1252264Sjacobs ipp_initialize_request(svc, request, type); 1262264Sjacobs 1272264Sjacobs /* create an operational attributes group */ 128*3917Sjacobs ipp_initialize_operational_attributes(svc, &operational, printer, -1); 1292264Sjacobs 1302264Sjacobs /* split up the attributes into operational and job attributes */ 1312264Sjacobs split_and_copy_attributes(operational_names, attributes, 1322264Sjacobs &operational, &job); 1332264Sjacobs 1342264Sjacobs /* add the operational attributes group to the request */ 1352264Sjacobs papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, 1362264Sjacobs "operational-attributes-group", operational); 1372264Sjacobs papiAttributeListFree(operational); 1382264Sjacobs 1392264Sjacobs /* add the job attributes group to the request */ 1402264Sjacobs if (job != NULL) { 1412264Sjacobs papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, 1422264Sjacobs "job-attributes-group", job); 1432264Sjacobs papiAttributeListFree(job); 1442264Sjacobs } 1452264Sjacobs } 1462264Sjacobs 1472264Sjacobs static papi_status_t 1482264Sjacobs send_document_uri(service_t *svc, char *file, papi_attribute_t **attributes, 1492264Sjacobs char *printer, int32_t id, char last, uint16_t type) 1502264Sjacobs { 1512264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 1522264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 1532264Sjacobs 1542264Sjacobs /* create the base IPP request */ 1552264Sjacobs ipp_initialize_request(svc, &request, type); 1562264Sjacobs 1572264Sjacobs /* create an operational attributes group */ 158*3917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, id); 1592264Sjacobs 1602264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, "document-name", 1612264Sjacobs file); 1622264Sjacobs papiAttributeListAddBoolean(&op, PAPI_ATTR_REPLACE, "last-document", 1632264Sjacobs (last ? PAPI_TRUE : PAPI_FALSE)); 1642264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 1652264Sjacobs "operational-attributes-group", op); 1662264Sjacobs papiAttributeListFree(op); 1672264Sjacobs 1682264Sjacobs /* send the IPP request to the server */ 1692264Sjacobs result = ipp_send_request_with_file(svc, request, &response, file); 1702264Sjacobs papiAttributeListFree(request); 1712264Sjacobs papiAttributeListFree(response); 1722264Sjacobs 1732264Sjacobs return (result); 1742264Sjacobs } 1752264Sjacobs 1762264Sjacobs typedef enum {_WITH_DATA, _BY_REFERENCE, _VALIDATE} call_type_t; 1772264Sjacobs 1782264Sjacobs papi_status_t 1792264Sjacobs internal_job_submit(papi_service_t handle, char *printer, 1802264Sjacobs papi_attribute_t **job_attributes, 1812264Sjacobs papi_job_ticket_t *job_ticket, 1822264Sjacobs char **files, papi_job_t *job, 1832264Sjacobs call_type_t call_type) 1842264Sjacobs { 1852264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 1862264Sjacobs service_t *svc = handle; 1872264Sjacobs job_t *j = NULL; 1882264Sjacobs int i; 1892264Sjacobs uint16_t req_type = OPID_PRINT_JOB; 1902264Sjacobs uint16_t data_type = OPID_SEND_DOCUMENT; 1912264Sjacobs papi_attribute_t **request = NULL, **response = NULL; 1922264Sjacobs 1932264Sjacobs if ((svc == NULL) || (printer == NULL) || (job == NULL)) 1942264Sjacobs return (PAPI_BAD_ARGUMENT); 1952264Sjacobs 1962264Sjacobs switch (call_type) { 1972264Sjacobs case _BY_REFERENCE: 1982264Sjacobs #ifdef SOME_DAY_WE_WILL_BE_ABLE_TO_USE_URIS_FOR_JOB_DATA 1992264Sjacobs /* 2002264Sjacobs * For the time being, this is disabled. There are a number 2012264Sjacobs * of issues to be dealt with before we can send a URI 2022264Sjacobs * across the network to the server. For example, the file 2032264Sjacobs * name(s) passed in are most likely relative to the current 2042264Sjacobs * hosts filesystem. They also most likely will require some 2052264Sjacobs * form of authentication information to be passed with the 2062264Sjacobs * URI. 2072264Sjacobs */ 2082264Sjacobs req_type = OPID_PRINT_URI; 2092264Sjacobs req_type = OPID_SEND_URI; 2102264Sjacobs #endif 2112264Sjacobs /* fall-through */ 2122264Sjacobs case _WITH_DATA: 2132264Sjacobs if ((files == NULL) || (files[0] == NULL)) 2142264Sjacobs return (PAPI_BAD_ARGUMENT); 2152264Sjacobs 2162264Sjacobs if (files[1] != NULL) /* more than 1 file */ 2172264Sjacobs req_type = OPID_CREATE_JOB; 2182264Sjacobs 2192264Sjacobs break; 2202264Sjacobs case _VALIDATE: 2212264Sjacobs req_type = OPID_VALIDATE_JOB; 2222264Sjacobs /* if we have files, validate access to them */ 2232264Sjacobs if (files != NULL) { 2242264Sjacobs for (i = 0; files[i] != NULL; i++) 2252264Sjacobs if (access(files[i], R_OK) < 0) { 2262264Sjacobs detailed_error(svc, "%s: %s", files[i], 2272264Sjacobs strerror(errno)); 2282264Sjacobs return (PAPI_DOCUMENT_ACCESS_ERROR); 2292264Sjacobs } 2302264Sjacobs files = NULL; 2312264Sjacobs } 2322264Sjacobs break; 2332264Sjacobs } 2342264Sjacobs 2352264Sjacobs /* if we are already connected, use that connection. */ 2362264Sjacobs if (svc->connection == NULL) 2372264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 2382264Sjacobs return (result); 2392264Sjacobs 2402264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 2412264Sjacobs return (PAPI_TEMPORARY_ERROR); 2422264Sjacobs 2432264Sjacobs /* create IPP request */ 2442264Sjacobs populate_job_request(svc, &request, job_attributes, printer, req_type); 2452264Sjacobs 2462264Sjacobs switch (req_type) { 2472264Sjacobs case OPID_PRINT_JOB: 2482264Sjacobs result = ipp_send_request_with_file(svc, request, &response, 2492264Sjacobs files[0]); 2502264Sjacobs break; 2512264Sjacobs case OPID_CREATE_JOB: 2522264Sjacobs case OPID_VALIDATE_JOB: 2532264Sjacobs case OPID_PRINT_URI: 2542264Sjacobs result = ipp_send_request(svc, request, &response); 2552264Sjacobs break; 2562264Sjacobs } 2572264Sjacobs papiAttributeListFree(request); 2582264Sjacobs 2592264Sjacobs if (result == PAPI_OK) { 2602264Sjacobs papi_attribute_t **op = NULL; 2612264Sjacobs 2622264Sjacobs /* retrieve the job attributes */ 2632264Sjacobs papiAttributeListGetCollection(response, NULL, 2642264Sjacobs "job-attributes-group", &op); 2652264Sjacobs copy_attributes(&j->attributes, op); 2662264Sjacobs 2672264Sjacobs if (req_type == OPID_CREATE_JOB) { 2682264Sjacobs int32_t id = 0; 2692264Sjacobs 2702264Sjacobs papiAttributeListGetInteger(j->attributes, NULL, 2712264Sjacobs "job-id", &id); 2722264Sjacobs /* send each document */ 2732264Sjacobs for (i = 0; ((result == PAPI_OK) && (files[i] != NULL)); 2742264Sjacobs i++) 2752264Sjacobs result = send_document_uri(svc, files[i], 2762264Sjacobs job_attributes, 2772264Sjacobs printer, id, (files[i+1]?0:1), 2782264Sjacobs data_type); 2792264Sjacobs } 2802264Sjacobs } 2812264Sjacobs papiAttributeListFree(response); 2822264Sjacobs 2832264Sjacobs return (result); 2842264Sjacobs } 2852264Sjacobs 2862264Sjacobs papi_status_t 2872264Sjacobs papiJobSubmit(papi_service_t handle, char *printer, 2882264Sjacobs papi_attribute_t **job_attributes, 2892264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 2902264Sjacobs { 2912264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 2922264Sjacobs job_ticket, files, job, _WITH_DATA)); 2932264Sjacobs } 2942264Sjacobs 2952264Sjacobs papi_status_t 2962264Sjacobs papiJobSubmitByReference(papi_service_t handle, char *printer, 2972264Sjacobs papi_attribute_t **job_attributes, 2982264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 2992264Sjacobs { 3002264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 3012264Sjacobs job_ticket, files, job, _BY_REFERENCE)); 3022264Sjacobs } 3032264Sjacobs 3042264Sjacobs papi_status_t 3052264Sjacobs papiJobValidate(papi_service_t handle, char *printer, 3062264Sjacobs papi_attribute_t **job_attributes, 3072264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 3082264Sjacobs { 3092264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 3102264Sjacobs job_ticket, files, job, _VALIDATE)); 3112264Sjacobs } 3122264Sjacobs 3132264Sjacobs papi_status_t 3142264Sjacobs papiJobStreamOpen(papi_service_t handle, char *printer, 3152264Sjacobs papi_attribute_t **job_attributes, 3162264Sjacobs papi_job_ticket_t *job_ticket, papi_stream_t *stream) 3172264Sjacobs { 3182264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 3192264Sjacobs papi_attribute_t **request = NULL; 3202264Sjacobs service_t *svc = handle; 3212264Sjacobs 3222264Sjacobs if ((svc == NULL) || (printer == NULL) || (stream == NULL)) 3232264Sjacobs return (PAPI_BAD_ARGUMENT); 3242264Sjacobs 3252264Sjacobs /* if we are already connected, use that connection. */ 3262264Sjacobs if (svc->connection == NULL) 3272264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 3282264Sjacobs return (result); 3292264Sjacobs 3302264Sjacobs /* create job request */ 3312264Sjacobs populate_job_request(svc, &request, job_attributes, printer, 3322264Sjacobs OPID_PRINT_JOB); 3332264Sjacobs 3342264Sjacobs *stream = svc->connection; 3352264Sjacobs 3362264Sjacobs result = ipp_send_initial_request_block(svc, request, 0); 3372264Sjacobs papiAttributeListFree(request); 3382264Sjacobs 3392264Sjacobs return (result); 3402264Sjacobs } 3412264Sjacobs 3422264Sjacobs papi_status_t 3432264Sjacobs papiJobStreamWrite(papi_service_t handle, 3442264Sjacobs papi_stream_t stream, void *buffer, size_t buflen) 3452264Sjacobs { 3462264Sjacobs papi_status_t result = PAPI_OK; 3472264Sjacobs service_t *svc = handle; 3482264Sjacobs size_t rc; 3492264Sjacobs 3502264Sjacobs #ifdef DEBUG 3512264Sjacobs printf("papiJobStreamWrite(0x%8.8x, 0x%8.8x, 0x%8.8x, %d)\n", 3522264Sjacobs handle, stream, buffer, buflen); 3532264Sjacobs httpDumpData(stdout, "papiJobStreamWrite:", buffer, buflen); 3542264Sjacobs #endif 3552264Sjacobs 3562264Sjacobs if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || 3572264Sjacobs (buflen == 0)) 3582264Sjacobs return (PAPI_BAD_ARGUMENT); 3592264Sjacobs 3602264Sjacobs while ((result == PAPI_OK) && (buflen > 0)) { 3612264Sjacobs rc = ipp_request_write(svc, buffer, buflen); 3622264Sjacobs if (rc < 0) 3632264Sjacobs result = PAPI_TEMPORARY_ERROR; 3642264Sjacobs else { 3652264Sjacobs buffer = (char *)buffer + rc; 3662264Sjacobs buflen -= rc; 3672264Sjacobs } 3682264Sjacobs } 3692264Sjacobs 3702264Sjacobs #ifdef DEBUG 3712264Sjacobs printf("papiJobStreamWrite(): %s\n", papiStatusString(result)); 3722264Sjacobs #endif 3732264Sjacobs 3742264Sjacobs return (result); 3752264Sjacobs } 3762264Sjacobs 3772264Sjacobs papi_status_t 3782264Sjacobs papiJobStreamClose(papi_service_t handle, 3792264Sjacobs papi_stream_t stream, papi_job_t *job) 3802264Sjacobs { 3812264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 3822264Sjacobs http_status_t status = HTTP_CONTINUE; 3832264Sjacobs service_t *svc = handle; 3842264Sjacobs papi_attribute_t **response = NULL; 3852264Sjacobs job_t *j = NULL; 3862264Sjacobs 3872264Sjacobs if ((svc == NULL) || (stream == NULL) || (job == NULL)) 3882264Sjacobs return (PAPI_BAD_ARGUMENT); 3892264Sjacobs 3902264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 3912264Sjacobs return (PAPI_TEMPORARY_ERROR); 3922264Sjacobs 3932264Sjacobs (void) ipp_request_write(svc, "", 0); 3942264Sjacobs 3952264Sjacobs /* update our connection info */ 3962264Sjacobs while (status == HTTP_CONTINUE) 3972264Sjacobs status = httpUpdate(svc->connection); 3982264Sjacobs 3992264Sjacobs if (status != HTTP_OK) 4002264Sjacobs return (http_to_papi_status(status)); 4012264Sjacobs httpWait(svc->connection, 1000); 4022264Sjacobs 4032264Sjacobs /* read the IPP response */ 4042264Sjacobs result = ipp_read_message(&ipp_request_read, svc, &response, 4052264Sjacobs IPP_TYPE_RESPONSE); 4062264Sjacobs if (result == PAPI_OK) 4072264Sjacobs result = ipp_status_info(svc, response); 4082264Sjacobs 4092264Sjacobs if (result == PAPI_OK) { 4102264Sjacobs papi_attribute_t **op = NULL; 4112264Sjacobs 4122264Sjacobs papiAttributeListGetCollection(response, NULL, 4132264Sjacobs "job-attributes-group", &op); 4142264Sjacobs copy_attributes(&j->attributes, op); 4152264Sjacobs } 4162264Sjacobs papiAttributeListFree(response); 4172264Sjacobs 4182264Sjacobs return (result); 4192264Sjacobs } 4202264Sjacobs 4212264Sjacobs papi_status_t 4222264Sjacobs papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, 4232264Sjacobs char **requested_attrs, 4242264Sjacobs papi_job_t *job) 4252264Sjacobs { 4262264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4272264Sjacobs service_t *svc = handle; 4282264Sjacobs job_t *j = NULL; 4292264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 4302264Sjacobs 4312264Sjacobs if ((svc == NULL) || (printer == NULL)) 4322264Sjacobs return (PAPI_BAD_ARGUMENT); 4332264Sjacobs 4342264Sjacobs /* if we are already connected, use that connection. */ 4352264Sjacobs if (svc->connection == NULL) 4362264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 4372264Sjacobs return (result); 4382264Sjacobs 4392264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 4402264Sjacobs return (PAPI_TEMPORARY_ERROR); 4412264Sjacobs 4422264Sjacobs ipp_initialize_request(svc, &request, OPID_GET_JOB_ATTRIBUTES); 4432264Sjacobs 444*3917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 4452264Sjacobs 4462264Sjacobs if (requested_attrs != NULL) { 4472264Sjacobs int i; 4482264Sjacobs 4492264Sjacobs for (i = 0; requested_attrs[i] != NULL; i++) 4502264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 4512264Sjacobs "requested-attributes", requested_attrs[i]); 4522264Sjacobs } 4532264Sjacobs 4542264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 4552264Sjacobs "operational-attributes-group", op); 4562264Sjacobs papiAttributeListFree(op); 4572264Sjacobs result = ipp_send_request(svc, request, &response); 4582264Sjacobs papiAttributeListFree(request); 4592264Sjacobs 4602264Sjacobs op = NULL; 4612264Sjacobs papiAttributeListGetCollection(response, NULL, 4622264Sjacobs "job-attributes-group", &op); 4632264Sjacobs copy_attributes(&j->attributes, op); 4642264Sjacobs papiAttributeListFree(response); 4652264Sjacobs 4662264Sjacobs return (result); 4672264Sjacobs } 4682264Sjacobs 4692264Sjacobs /* papiJob{Cancel|Hold|Release|Restart|Promote} are all the same */ 4702264Sjacobs static papi_status_t 4712264Sjacobs _job_cancel_hold_release_restart_promote(papi_service_t handle, 4722264Sjacobs char *printer, int32_t job_id, uint16_t type) 4732264Sjacobs { 4742264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4752264Sjacobs service_t *svc = handle; 4762264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 4772264Sjacobs 4782264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0)) 4792264Sjacobs return (PAPI_BAD_ARGUMENT); 4802264Sjacobs 4812264Sjacobs /* if we are already connected, use that connection. */ 4822264Sjacobs if (svc->connection == NULL) 4832264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 4842264Sjacobs return (result); 4852264Sjacobs 4862264Sjacobs ipp_initialize_request(svc, &request, type); 4872264Sjacobs 488*3917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 4892264Sjacobs 4902264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 4912264Sjacobs "operational-attributes-group", op); 4922264Sjacobs papiAttributeListFree(op); 4932264Sjacobs result = ipp_send_request(svc, request, &response); 4942264Sjacobs papiAttributeListFree(request); 4952264Sjacobs papiAttributeListFree(response); 4962264Sjacobs 4972264Sjacobs return (result); 4982264Sjacobs } 4992264Sjacobs 5002264Sjacobs papi_status_t 5012264Sjacobs papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) 5022264Sjacobs { 5032264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5042264Sjacobs job_id, OPID_CANCEL_JOB)); 5052264Sjacobs } 5062264Sjacobs 5072264Sjacobs 5082264Sjacobs papi_status_t 5092264Sjacobs papiJobHold(papi_service_t handle, char *printer, int32_t job_id) 5102264Sjacobs { 5112264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5122264Sjacobs job_id, OPID_HOLD_JOB)); 5132264Sjacobs } 5142264Sjacobs 5152264Sjacobs papi_status_t 5162264Sjacobs papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) 5172264Sjacobs { 5182264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5192264Sjacobs job_id, OPID_RELEASE_JOB)); 5202264Sjacobs } 5212264Sjacobs 5222264Sjacobs papi_status_t 5232264Sjacobs papiJobRestart(papi_service_t handle, char *printer, int32_t job_id) 5242264Sjacobs { 5252264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5262264Sjacobs job_id, OPID_RESTART_JOB)); 5272264Sjacobs } 5282264Sjacobs 5292264Sjacobs papi_status_t 5302264Sjacobs papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) 5312264Sjacobs { 5322264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 5332264Sjacobs job_id, OPID_PROMOTE_JOB)); 5342264Sjacobs } 5352264Sjacobs 5362264Sjacobs papi_status_t 5372264Sjacobs papiJobMove(papi_service_t handle, char *printer, int32_t job_id, 5382264Sjacobs char *destination) 5392264Sjacobs { 5402264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 5412264Sjacobs service_t *svc = handle; 5422264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 5432264Sjacobs 5442264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 5452264Sjacobs (destination == NULL)) 5462264Sjacobs return (PAPI_BAD_ARGUMENT); 5472264Sjacobs 5482264Sjacobs /* if we are already connected, use that connection. */ 5492264Sjacobs if (svc->connection == NULL) 5502264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 5512264Sjacobs return (result); 5522264Sjacobs 5532264Sjacobs ipp_initialize_request(svc, &request, OPID_CUPS_MOVE_JOB); 5542264Sjacobs 555*3917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 5562264Sjacobs 5572264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 5582264Sjacobs "operational-attributes-group", op); 5592264Sjacobs papiAttributeListFree(op); 5602264Sjacobs 5612264Sjacobs op = NULL; 5622264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_EXCL, 5632264Sjacobs "job-printer-uri", destination); 5642264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 5652264Sjacobs "job-attributes-group", op); 5662264Sjacobs papiAttributeListFree(op); 5672264Sjacobs 5682264Sjacobs result = ipp_send_request(svc, request, &response); 5692264Sjacobs papiAttributeListFree(request); 5702264Sjacobs papiAttributeListFree(response); 5712264Sjacobs 5722264Sjacobs return (result); 5732264Sjacobs } 5742264Sjacobs 5752264Sjacobs papi_status_t 5762264Sjacobs papiJobModify(papi_service_t handle, char *printer, int32_t job_id, 5772264Sjacobs papi_attribute_t **attributes, papi_job_t *job) 5782264Sjacobs { 5792264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 5802264Sjacobs service_t *svc = handle; 5812264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 5822264Sjacobs job_t *j = NULL; 5832264Sjacobs 5842264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 5852264Sjacobs (attributes == NULL)) 5862264Sjacobs return (PAPI_BAD_ARGUMENT); 5872264Sjacobs 5882264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 5892264Sjacobs return (PAPI_TEMPORARY_ERROR); 5902264Sjacobs 5912264Sjacobs /* if we are already connected, use that connection. */ 5922264Sjacobs if (svc->connection == NULL) 5932264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 5942264Sjacobs return (result); 5952264Sjacobs 5962264Sjacobs ipp_initialize_request(svc, &request, OPID_SET_JOB_ATTRIBUTES); 5972264Sjacobs 598*3917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 5992264Sjacobs 6002264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6012264Sjacobs "operational-attributes-group", op); 6022264Sjacobs papiAttributeListFree(op); 6032264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 6042264Sjacobs "job-attributes-group", attributes); 6052264Sjacobs result = ipp_send_request(svc, request, &response); 6062264Sjacobs papiAttributeListFree(request); 6072264Sjacobs 6082264Sjacobs op = NULL; 6092264Sjacobs papiAttributeListGetCollection(response, NULL, 6102264Sjacobs "job-attributes-group", &op); 6112264Sjacobs copy_attributes(&j->attributes, op); 6122264Sjacobs papiAttributeListFree(response); 6132264Sjacobs 6142264Sjacobs return (result); 6152264Sjacobs } 616