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
papiJobFree(papi_job_t job)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
papiJobListFree(papi_job_t * jobs)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 **
papiJobGetAttributeList(papi_job_t job)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 *
papiJobGetPrinterName(papi_job_t job)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
papiJobGetId(papi_job_t job)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 *
papiJobGetJobTicket(papi_job_t job)1092264Sjacobs papiJobGetJobTicket(papi_job_t job)
1102264Sjacobs {
1112264Sjacobs papi_job_ticket_t *result = NULL;
1122264Sjacobs
1132264Sjacobs return (result);
1142264Sjacobs }
1152264Sjacobs
1162264Sjacobs static void
populate_job_request(service_t * svc,papi_attribute_t *** request,papi_attribute_t ** attributes,char * printer,uint16_t type)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
send_document_uri(service_t * svc,char * file,papi_attribute_t ** attributes,char * printer,int32_t id,char last,uint16_t type)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
internal_job_submit(papi_service_t handle,char * printer,papi_attribute_t ** job_attributes,papi_job_ticket_t * job_ticket,char ** files,papi_job_t * job,call_type_t call_type)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
papiJobSubmit(papi_service_t handle,char * printer,papi_attribute_t ** job_attributes,papi_job_ticket_t * job_ticket,char ** files,papi_job_t * job)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
papiJobSubmitByReference(papi_service_t handle,char * printer,papi_attribute_t ** job_attributes,papi_job_ticket_t * job_ticket,char ** files,papi_job_t * job)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
papiJobValidate(papi_service_t handle,char * printer,papi_attribute_t ** job_attributes,papi_job_ticket_t * job_ticket,char ** files,papi_job_t * job)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
papiJobStreamOpen(papi_service_t handle,char * printer,papi_attribute_t ** job_attributes,papi_job_ticket_t * job_ticket,papi_stream_t * stream)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
papiJobStreamWrite(papi_service_t handle,papi_stream_t stream,void * buffer,size_t buflen)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
papiJobStreamClose(papi_service_t handle,papi_stream_t stream,papi_job_t * job)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
papiJobQuery(papi_service_t handle,char * printer,int32_t job_id,char ** requested_attrs,papi_job_t * job)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
_job_cancel_hold_release_restart_promote(papi_service_t handle,char * printer,int32_t job_id,uint16_t type)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
papiJobCancel(papi_service_t handle,char * printer,int32_t job_id)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
papiJobHold(papi_service_t handle,char * printer,int32_t job_id)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
papiJobRelease(papi_service_t handle,char * printer,int32_t job_id)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
papiJobRestart(papi_service_t handle,char * printer,int32_t job_id)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
papiJobPromote(papi_service_t handle,char * printer,int32_t job_id)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
papiJobMove(papi_service_t handle,char * printer,int32_t job_id,char * destination)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
papiJobModify(papi_service_t handle,char * printer,int32_t job_id,papi_attribute_t ** attributes,papi_job_t * job)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