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*8569SJonathan.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> 37*8569SJonathan.Ca@Sun.COM #include <fcntl.h> 38*8569SJonathan.Ca@Sun.COM #include <sys/types.h> 39*8569SJonathan.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, 89*8569SJonathan.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, 102*8569SJonathan.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, 134*8569SJonathan.Ca@Sun.COM &operational, &job); 1352264Sjacobs 1362264Sjacobs /* add the operational attributes group to the request */ 1372264Sjacobs papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, 138*8569SJonathan.Ca@Sun.COM "operational-attributes-group", operational); 1392264Sjacobs papiAttributeListFree(operational); 1402264Sjacobs 1412264Sjacobs /* add the job attributes group to the request */ 1422264Sjacobs if (job != NULL) { 1432264Sjacobs papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, 144*8569SJonathan.Ca@Sun.COM "job-attributes-group", job); 1452264Sjacobs papiAttributeListFree(job); 1462264Sjacobs } 1472264Sjacobs } 1482264Sjacobs 1492264Sjacobs static papi_status_t 1502264Sjacobs send_document_uri(service_t *svc, char *file, papi_attribute_t **attributes, 1512264Sjacobs char *printer, int32_t id, char last, uint16_t type) 1522264Sjacobs { 1532264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 1542264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 1552264Sjacobs 1562264Sjacobs /* create the base IPP request */ 1572264Sjacobs ipp_initialize_request(svc, &request, type); 1582264Sjacobs 1592264Sjacobs /* create an operational attributes group */ 1603917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, id); 1612264Sjacobs 1622264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, "document-name", 163*8569SJonathan.Ca@Sun.COM file); 1642264Sjacobs papiAttributeListAddBoolean(&op, PAPI_ATTR_REPLACE, "last-document", 165*8569SJonathan.Ca@Sun.COM (last ? PAPI_TRUE : PAPI_FALSE)); 1662264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 167*8569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 1682264Sjacobs papiAttributeListFree(op); 1692264Sjacobs 1702264Sjacobs /* send the IPP request to the server */ 1712264Sjacobs result = ipp_send_request_with_file(svc, request, &response, file); 1722264Sjacobs papiAttributeListFree(request); 1732264Sjacobs papiAttributeListFree(response); 1742264Sjacobs 1752264Sjacobs return (result); 1762264Sjacobs } 1772264Sjacobs 1782264Sjacobs typedef enum {_WITH_DATA, _BY_REFERENCE, _VALIDATE} call_type_t; 1792264Sjacobs 1802264Sjacobs papi_status_t 1812264Sjacobs internal_job_submit(papi_service_t handle, char *printer, 1822264Sjacobs papi_attribute_t **job_attributes, 1832264Sjacobs papi_job_ticket_t *job_ticket, 1842264Sjacobs char **files, papi_job_t *job, 1852264Sjacobs call_type_t call_type) 1862264Sjacobs { 1872264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 1882264Sjacobs service_t *svc = handle; 189*8569SJonathan.Ca@Sun.COM struct stat statbuf; 1902264Sjacobs job_t *j = NULL; 1912264Sjacobs int i; 1922264Sjacobs uint16_t req_type = OPID_PRINT_JOB; 1932264Sjacobs uint16_t data_type = OPID_SEND_DOCUMENT; 1942264Sjacobs papi_attribute_t **request = NULL, **response = NULL; 1952264Sjacobs 1962264Sjacobs if ((svc == NULL) || (printer == NULL) || (job == NULL)) 1972264Sjacobs return (PAPI_BAD_ARGUMENT); 1982264Sjacobs 1992264Sjacobs switch (call_type) { 2002264Sjacobs case _BY_REFERENCE: 2012264Sjacobs #ifdef SOME_DAY_WE_WILL_BE_ABLE_TO_USE_URIS_FOR_JOB_DATA 2022264Sjacobs /* 2032264Sjacobs * For the time being, this is disabled. There are a number 2042264Sjacobs * of issues to be dealt with before we can send a URI 2052264Sjacobs * across the network to the server. For example, the file 2062264Sjacobs * name(s) passed in are most likely relative to the current 2072264Sjacobs * hosts filesystem. They also most likely will require some 2082264Sjacobs * form of authentication information to be passed with the 2092264Sjacobs * URI. 2102264Sjacobs */ 2112264Sjacobs req_type = OPID_PRINT_URI; 2122264Sjacobs req_type = OPID_SEND_URI; 2132264Sjacobs #endif 2142264Sjacobs /* fall-through */ 2152264Sjacobs case _WITH_DATA: 2162264Sjacobs if ((files == NULL) || (files[0] == NULL)) 2172264Sjacobs return (PAPI_BAD_ARGUMENT); 2182264Sjacobs 2192264Sjacobs if (files[1] != NULL) /* more than 1 file */ 2202264Sjacobs req_type = OPID_CREATE_JOB; 2212264Sjacobs 2222264Sjacobs break; 2232264Sjacobs case _VALIDATE: 2242264Sjacobs req_type = OPID_VALIDATE_JOB; 2252264Sjacobs /* if we have files, validate access to them */ 2262264Sjacobs if (files != NULL) { 227*8569SJonathan.Ca@Sun.COM for (i = 0; files[i] != NULL; i++) { 2282264Sjacobs if (access(files[i], R_OK) < 0) { 2292264Sjacobs detailed_error(svc, "%s: %s", files[i], 230*8569SJonathan.Ca@Sun.COM strerror(errno)); 2312264Sjacobs return (PAPI_DOCUMENT_ACCESS_ERROR); 2322264Sjacobs } 233*8569SJonathan.Ca@Sun.COM 234*8569SJonathan.Ca@Sun.COM if (strcmp("standard input", files[i]) != 0) { 235*8569SJonathan.Ca@Sun.COM stat(files[i], &statbuf); 236*8569SJonathan.Ca@Sun.COM if (statbuf.st_size == 0) { 237*8569SJonathan.Ca@Sun.COM detailed_error(svc, 238*8569SJonathan.Ca@Sun.COM "Zero byte (empty) file: " 239*8569SJonathan.Ca@Sun.COM "%s", 240*8569SJonathan.Ca@Sun.COM files[i]); 241*8569SJonathan.Ca@Sun.COM return (PAPI_BAD_ARGUMENT); 242*8569SJonathan.Ca@Sun.COM } 243*8569SJonathan.Ca@Sun.COM } 244*8569SJonathan.Ca@Sun.COM } 2452264Sjacobs files = NULL; 2462264Sjacobs } 2472264Sjacobs break; 2482264Sjacobs } 2492264Sjacobs 2502264Sjacobs /* if we are already connected, use that connection. */ 2512264Sjacobs if (svc->connection == NULL) 2522264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 2532264Sjacobs return (result); 2542264Sjacobs 2552264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 2562264Sjacobs return (PAPI_TEMPORARY_ERROR); 2572264Sjacobs 2582264Sjacobs /* create IPP request */ 2592264Sjacobs populate_job_request(svc, &request, job_attributes, printer, req_type); 2602264Sjacobs 2612264Sjacobs switch (req_type) { 2622264Sjacobs case OPID_PRINT_JOB: 2632264Sjacobs result = ipp_send_request_with_file(svc, request, &response, 264*8569SJonathan.Ca@Sun.COM files[0]); 2652264Sjacobs break; 2662264Sjacobs case OPID_CREATE_JOB: 2672264Sjacobs case OPID_VALIDATE_JOB: 2682264Sjacobs case OPID_PRINT_URI: 2692264Sjacobs result = ipp_send_request(svc, request, &response); 2702264Sjacobs break; 2712264Sjacobs } 2722264Sjacobs papiAttributeListFree(request); 2732264Sjacobs 2742264Sjacobs if (result == PAPI_OK) { 2752264Sjacobs papi_attribute_t **op = NULL; 2762264Sjacobs 2772264Sjacobs /* retrieve the job attributes */ 2782264Sjacobs papiAttributeListGetCollection(response, NULL, 279*8569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 2802264Sjacobs copy_attributes(&j->attributes, op); 2812264Sjacobs 2822264Sjacobs if (req_type == OPID_CREATE_JOB) { 2832264Sjacobs int32_t id = 0; 2842264Sjacobs 2852264Sjacobs papiAttributeListGetInteger(j->attributes, NULL, 286*8569SJonathan.Ca@Sun.COM "job-id", &id); 2872264Sjacobs /* send each document */ 2882264Sjacobs for (i = 0; ((result == PAPI_OK) && (files[i] != NULL)); 289*8569SJonathan.Ca@Sun.COM i++) 2902264Sjacobs result = send_document_uri(svc, files[i], 291*8569SJonathan.Ca@Sun.COM job_attributes, 292*8569SJonathan.Ca@Sun.COM printer, id, (files[i+1]?0:1), 293*8569SJonathan.Ca@Sun.COM data_type); 2942264Sjacobs } 2952264Sjacobs } 2962264Sjacobs papiAttributeListFree(response); 2972264Sjacobs 2982264Sjacobs return (result); 2992264Sjacobs } 3002264Sjacobs 3012264Sjacobs papi_status_t 3022264Sjacobs papiJobSubmit(papi_service_t handle, char *printer, 3032264Sjacobs papi_attribute_t **job_attributes, 3042264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 3052264Sjacobs { 3062264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 307*8569SJonathan.Ca@Sun.COM job_ticket, files, job, _WITH_DATA)); 3082264Sjacobs } 3092264Sjacobs 3102264Sjacobs papi_status_t 3112264Sjacobs papiJobSubmitByReference(papi_service_t handle, char *printer, 3122264Sjacobs papi_attribute_t **job_attributes, 3132264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 3142264Sjacobs { 3152264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 316*8569SJonathan.Ca@Sun.COM job_ticket, files, job, _BY_REFERENCE)); 3172264Sjacobs } 3182264Sjacobs 3192264Sjacobs papi_status_t 3202264Sjacobs papiJobValidate(papi_service_t handle, char *printer, 3212264Sjacobs papi_attribute_t **job_attributes, 3222264Sjacobs papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 3232264Sjacobs { 3242264Sjacobs return (internal_job_submit(handle, printer, job_attributes, 325*8569SJonathan.Ca@Sun.COM job_ticket, files, job, _VALIDATE)); 3262264Sjacobs } 3272264Sjacobs 3282264Sjacobs papi_status_t 3292264Sjacobs papiJobStreamOpen(papi_service_t handle, char *printer, 3302264Sjacobs papi_attribute_t **job_attributes, 3312264Sjacobs papi_job_ticket_t *job_ticket, papi_stream_t *stream) 3322264Sjacobs { 3332264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 3342264Sjacobs papi_attribute_t **request = NULL; 3352264Sjacobs service_t *svc = handle; 3362264Sjacobs 3372264Sjacobs if ((svc == NULL) || (printer == NULL) || (stream == NULL)) 3382264Sjacobs return (PAPI_BAD_ARGUMENT); 3392264Sjacobs 3402264Sjacobs /* if we are already connected, use that connection. */ 3412264Sjacobs if (svc->connection == NULL) 3422264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 3432264Sjacobs return (result); 3442264Sjacobs 3452264Sjacobs /* create job request */ 3462264Sjacobs populate_job_request(svc, &request, job_attributes, printer, 347*8569SJonathan.Ca@Sun.COM OPID_PRINT_JOB); 3482264Sjacobs 3492264Sjacobs *stream = svc->connection; 3502264Sjacobs 3512264Sjacobs result = ipp_send_initial_request_block(svc, request, 0); 3522264Sjacobs papiAttributeListFree(request); 3532264Sjacobs 3542264Sjacobs return (result); 3552264Sjacobs } 3562264Sjacobs 3572264Sjacobs papi_status_t 3582264Sjacobs papiJobStreamWrite(papi_service_t handle, 3592264Sjacobs papi_stream_t stream, void *buffer, size_t buflen) 3602264Sjacobs { 3612264Sjacobs papi_status_t result = PAPI_OK; 3622264Sjacobs service_t *svc = handle; 3632264Sjacobs size_t rc; 3642264Sjacobs 3652264Sjacobs #ifdef DEBUG 3662264Sjacobs printf("papiJobStreamWrite(0x%8.8x, 0x%8.8x, 0x%8.8x, %d)\n", 367*8569SJonathan.Ca@Sun.COM handle, stream, buffer, buflen); 3682264Sjacobs httpDumpData(stdout, "papiJobStreamWrite:", buffer, buflen); 3692264Sjacobs #endif 3702264Sjacobs 3712264Sjacobs if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || 3722264Sjacobs (buflen == 0)) 3732264Sjacobs return (PAPI_BAD_ARGUMENT); 3742264Sjacobs 3752264Sjacobs while ((result == PAPI_OK) && (buflen > 0)) { 3762264Sjacobs rc = ipp_request_write(svc, buffer, buflen); 3772264Sjacobs if (rc < 0) 3782264Sjacobs result = PAPI_TEMPORARY_ERROR; 3792264Sjacobs else { 3802264Sjacobs buffer = (char *)buffer + rc; 3812264Sjacobs buflen -= rc; 3822264Sjacobs } 3832264Sjacobs } 3842264Sjacobs 3852264Sjacobs #ifdef DEBUG 3862264Sjacobs printf("papiJobStreamWrite(): %s\n", papiStatusString(result)); 3872264Sjacobs #endif 3882264Sjacobs 3892264Sjacobs return (result); 3902264Sjacobs } 3912264Sjacobs 3922264Sjacobs papi_status_t 3932264Sjacobs papiJobStreamClose(papi_service_t handle, 3942264Sjacobs papi_stream_t stream, papi_job_t *job) 3952264Sjacobs { 3962264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 3972264Sjacobs http_status_t status = HTTP_CONTINUE; 3982264Sjacobs service_t *svc = handle; 3992264Sjacobs papi_attribute_t **response = NULL; 4002264Sjacobs job_t *j = NULL; 4012264Sjacobs 4022264Sjacobs if ((svc == NULL) || (stream == NULL) || (job == NULL)) 4032264Sjacobs return (PAPI_BAD_ARGUMENT); 4042264Sjacobs 4052264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 4062264Sjacobs return (PAPI_TEMPORARY_ERROR); 4072264Sjacobs 4082264Sjacobs (void) ipp_request_write(svc, "", 0); 4092264Sjacobs 4102264Sjacobs /* update our connection info */ 4112264Sjacobs while (status == HTTP_CONTINUE) 4122264Sjacobs status = httpUpdate(svc->connection); 4132264Sjacobs 4142264Sjacobs if (status != HTTP_OK) 4152264Sjacobs return (http_to_papi_status(status)); 4162264Sjacobs httpWait(svc->connection, 1000); 4172264Sjacobs 4182264Sjacobs /* read the IPP response */ 4192264Sjacobs result = ipp_read_message(&ipp_request_read, svc, &response, 420*8569SJonathan.Ca@Sun.COM IPP_TYPE_RESPONSE); 4212264Sjacobs if (result == PAPI_OK) 4222264Sjacobs result = ipp_status_info(svc, response); 4232264Sjacobs 4242264Sjacobs if (result == PAPI_OK) { 4252264Sjacobs papi_attribute_t **op = NULL; 4262264Sjacobs 4272264Sjacobs papiAttributeListGetCollection(response, NULL, 428*8569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 4292264Sjacobs copy_attributes(&j->attributes, op); 4302264Sjacobs } 4312264Sjacobs papiAttributeListFree(response); 4322264Sjacobs 4332264Sjacobs return (result); 4342264Sjacobs } 4352264Sjacobs 4362264Sjacobs papi_status_t 4372264Sjacobs papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, 4382264Sjacobs char **requested_attrs, 4392264Sjacobs papi_job_t *job) 4402264Sjacobs { 4412264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4422264Sjacobs service_t *svc = handle; 4432264Sjacobs job_t *j = NULL; 4442264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 4452264Sjacobs 4462264Sjacobs if ((svc == NULL) || (printer == NULL)) 4472264Sjacobs return (PAPI_BAD_ARGUMENT); 4482264Sjacobs 4492264Sjacobs /* if we are already connected, use that connection. */ 4502264Sjacobs if (svc->connection == NULL) 4512264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 4522264Sjacobs return (result); 4532264Sjacobs 4542264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 4552264Sjacobs return (PAPI_TEMPORARY_ERROR); 4562264Sjacobs 4572264Sjacobs ipp_initialize_request(svc, &request, OPID_GET_JOB_ATTRIBUTES); 4582264Sjacobs 4593917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 4602264Sjacobs 4612264Sjacobs if (requested_attrs != NULL) { 4622264Sjacobs int i; 4632264Sjacobs 4642264Sjacobs for (i = 0; requested_attrs[i] != NULL; i++) 4652264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 466*8569SJonathan.Ca@Sun.COM "requested-attributes", requested_attrs[i]); 4672264Sjacobs } 4682264Sjacobs 4692264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 470*8569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 4712264Sjacobs papiAttributeListFree(op); 4722264Sjacobs result = ipp_send_request(svc, request, &response); 4732264Sjacobs papiAttributeListFree(request); 4742264Sjacobs 4752264Sjacobs op = NULL; 4762264Sjacobs papiAttributeListGetCollection(response, NULL, 477*8569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 4782264Sjacobs copy_attributes(&j->attributes, op); 4792264Sjacobs papiAttributeListFree(response); 4802264Sjacobs 4812264Sjacobs return (result); 4822264Sjacobs } 4832264Sjacobs 4842264Sjacobs /* papiJob{Cancel|Hold|Release|Restart|Promote} are all the same */ 4852264Sjacobs static papi_status_t 4862264Sjacobs _job_cancel_hold_release_restart_promote(papi_service_t handle, 4872264Sjacobs char *printer, int32_t job_id, uint16_t type) 4882264Sjacobs { 4892264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4902264Sjacobs service_t *svc = handle; 4912264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 4922264Sjacobs 4932264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0)) 4942264Sjacobs return (PAPI_BAD_ARGUMENT); 4952264Sjacobs 4962264Sjacobs /* if we are already connected, use that connection. */ 4972264Sjacobs if (svc->connection == NULL) 4982264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 4992264Sjacobs return (result); 5002264Sjacobs 5012264Sjacobs ipp_initialize_request(svc, &request, type); 5022264Sjacobs 5033917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 5042264Sjacobs 5052264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 506*8569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 5072264Sjacobs papiAttributeListFree(op); 5082264Sjacobs result = ipp_send_request(svc, request, &response); 5092264Sjacobs papiAttributeListFree(request); 5102264Sjacobs papiAttributeListFree(response); 5112264Sjacobs 5122264Sjacobs return (result); 5132264Sjacobs } 5142264Sjacobs 5152264Sjacobs papi_status_t 5162264Sjacobs papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) 5172264Sjacobs { 5182264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 519*8569SJonathan.Ca@Sun.COM job_id, OPID_CANCEL_JOB)); 5202264Sjacobs } 5212264Sjacobs 5222264Sjacobs 5232264Sjacobs papi_status_t 5242264Sjacobs papiJobHold(papi_service_t handle, char *printer, int32_t job_id) 5252264Sjacobs { 5262264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 527*8569SJonathan.Ca@Sun.COM job_id, OPID_HOLD_JOB)); 5282264Sjacobs } 5292264Sjacobs 5302264Sjacobs papi_status_t 5312264Sjacobs papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) 5322264Sjacobs { 5332264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 534*8569SJonathan.Ca@Sun.COM job_id, OPID_RELEASE_JOB)); 5352264Sjacobs } 5362264Sjacobs 5372264Sjacobs papi_status_t 5382264Sjacobs papiJobRestart(papi_service_t handle, char *printer, int32_t job_id) 5392264Sjacobs { 5402264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 541*8569SJonathan.Ca@Sun.COM job_id, OPID_RESTART_JOB)); 5422264Sjacobs } 5432264Sjacobs 5442264Sjacobs papi_status_t 5452264Sjacobs papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) 5462264Sjacobs { 5472264Sjacobs return (_job_cancel_hold_release_restart_promote(handle, printer, 548*8569SJonathan.Ca@Sun.COM job_id, OPID_PROMOTE_JOB)); 5492264Sjacobs } 5502264Sjacobs 5512264Sjacobs papi_status_t 5522264Sjacobs papiJobMove(papi_service_t handle, char *printer, int32_t job_id, 5532264Sjacobs char *destination) 5542264Sjacobs { 5552264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 5562264Sjacobs service_t *svc = handle; 5572264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 5582264Sjacobs 5592264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 5602264Sjacobs (destination == NULL)) 5612264Sjacobs return (PAPI_BAD_ARGUMENT); 5622264Sjacobs 5632264Sjacobs /* if we are already connected, use that connection. */ 5642264Sjacobs if (svc->connection == NULL) 5652264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 5662264Sjacobs return (result); 5672264Sjacobs 5682264Sjacobs ipp_initialize_request(svc, &request, OPID_CUPS_MOVE_JOB); 5692264Sjacobs 5703917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 5712264Sjacobs 5722264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 573*8569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 5742264Sjacobs papiAttributeListFree(op); 5752264Sjacobs 5762264Sjacobs op = NULL; 5772264Sjacobs papiAttributeListAddString(&op, PAPI_ATTR_EXCL, 578*8569SJonathan.Ca@Sun.COM "job-printer-uri", destination); 5792264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 580*8569SJonathan.Ca@Sun.COM "job-attributes-group", op); 5812264Sjacobs papiAttributeListFree(op); 5822264Sjacobs 5832264Sjacobs result = ipp_send_request(svc, request, &response); 5842264Sjacobs papiAttributeListFree(request); 5852264Sjacobs papiAttributeListFree(response); 5862264Sjacobs 5872264Sjacobs return (result); 5882264Sjacobs } 5892264Sjacobs 5902264Sjacobs papi_status_t 5912264Sjacobs papiJobModify(papi_service_t handle, char *printer, int32_t job_id, 5922264Sjacobs papi_attribute_t **attributes, papi_job_t *job) 5932264Sjacobs { 5942264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 5952264Sjacobs service_t *svc = handle; 5962264Sjacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 5972264Sjacobs job_t *j = NULL; 5982264Sjacobs 5992264Sjacobs if ((svc == NULL) || (printer == NULL) || (job_id < 0) || 6002264Sjacobs (attributes == NULL)) 6012264Sjacobs return (PAPI_BAD_ARGUMENT); 6022264Sjacobs 6032264Sjacobs if ((*job = j = calloc(1, sizeof (*j))) == NULL) 6042264Sjacobs return (PAPI_TEMPORARY_ERROR); 6052264Sjacobs 6062264Sjacobs /* if we are already connected, use that connection. */ 6072264Sjacobs if (svc->connection == NULL) 6082264Sjacobs if ((result = service_connect(svc, printer)) != PAPI_OK) 6092264Sjacobs return (result); 6102264Sjacobs 6112264Sjacobs ipp_initialize_request(svc, &request, OPID_SET_JOB_ATTRIBUTES); 6122264Sjacobs 6133917Sjacobs ipp_initialize_operational_attributes(svc, &op, printer, job_id); 6142264Sjacobs 6152264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 616*8569SJonathan.Ca@Sun.COM "operational-attributes-group", op); 6172264Sjacobs papiAttributeListFree(op); 6182264Sjacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 619*8569SJonathan.Ca@Sun.COM "job-attributes-group", attributes); 6202264Sjacobs result = ipp_send_request(svc, request, &response); 6212264Sjacobs papiAttributeListFree(request); 6222264Sjacobs 6232264Sjacobs op = NULL; 6242264Sjacobs papiAttributeListGetCollection(response, NULL, 625*8569SJonathan.Ca@Sun.COM "job-attributes-group", &op); 6262264Sjacobs copy_attributes(&j->attributes, op); 6272264Sjacobs papiAttributeListFree(response); 6282264Sjacobs 6292264Sjacobs return (result); 6302264Sjacobs } 631