1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 */ 27 28 /* $Id: send-document.c 146 2006-03-24 00:26:54Z njacobs $ */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <stdio.h> 33 #include <papi.h> 34 #include <ipp.h> 35 #include <ipp-listener.h> 36 37 /* 38 * When the PAPI supports papiJobCreate(), papiJobStreamAdd() and 39 * papiJobClose(), this will be much cleaner and more efficient, but in the 40 * meantime, we are using a private, non-standard interface to do this. 41 */ 42 papi_status_t 43 ipp_send_document(papi_service_t svc, papi_attribute_t **request, 44 papi_attribute_t ***response, ipp_reader_t iread, void *fd) 45 { 46 papi_status_t status; 47 papi_stream_t s = NULL; 48 papi_job_t j = NULL; 49 papi_attribute_t **operational = NULL; 50 papi_attribute_t **job_attributes = NULL; 51 char *queue = NULL; 52 ssize_t rc; 53 int id = -1; 54 char buf[BUFSIZ]; 55 char last = PAPI_FALSE; 56 char *keys[] = { "attributes-natural-language", "attributes-charset", 57 "printer-uri", "job-id", "job-uri", "last-document", 58 NULL }; 59 60 /* Get operational attributes from the request */ 61 (void) papiAttributeListGetCollection(request, NULL, 62 "operational-attributes-group", &operational); 63 64 /* 65 * the operational-attributes-group must contain: 66 * job-uri (or printer-uri/job-id) 67 * last-document 68 */ 69 get_printer_id(operational, &queue, &id); 70 if (id < 0) { 71 ipp_set_status(response, PAPI_BAD_REQUEST, 72 "missing job-uri or job-id"); 73 return (PAPI_BAD_REQUEST); 74 } else if (queue == NULL) { 75 ipp_set_status(response, PAPI_BAD_REQUEST, 76 "missing printer-uri or job-uri"); 77 return (PAPI_BAD_REQUEST); 78 } 79 80 status = papiAttributeListGetBoolean(operational, NULL, 81 "last-document", &last); 82 if (status != PAPI_OK) { 83 ipp_set_status(response, status, "last-document: %s", 84 papiStatusString(status)); 85 return (PAPI_BAD_REQUEST); 86 } 87 88 /* 89 * the operational-attributes-group may contain: 90 * document-name 91 * compression 92 * document-format 93 * document-natural-language 94 * Simply copy the entire contents of the operational-attributes-group 95 * for the PAPI call's possible use. 96 */ 97 split_and_copy_attributes(keys, operational, NULL, &job_attributes); 98 99 /* copy any job-attributes-group attributes for the PAPI call */ 100 if (papiAttributeListGetCollection(request, NULL, 101 "job-attributes-group", &operational) == PAPI_OK) 102 copy_attributes(&job_attributes, operational); 103 104 /* create a stream to write the document data on */ 105 status = papiJobStreamAdd(svc, queue, id, &s); 106 papiAttributeListFree(job_attributes); 107 if (status != PAPI_OK) { 108 ipp_set_status(response, status, "job submission: %s", 109 ipp_svc_status_mesg(svc, status)); 110 return (status); 111 } 112 113 /* copy the document data from the IPP connection to the stream */ 114 while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0)) 115 status = papiJobStreamWrite(svc, s, buf, rc); 116 if (status != PAPI_OK) { 117 ipp_set_status(response, status, "write job data: %s", 118 ipp_svc_status_mesg(svc, status)); 119 return (status); 120 } 121 122 /* close the stream */ 123 status = papiJobStreamClose(svc, s, &j); 124 if (status != PAPI_OK) { 125 ipp_set_status(response, status, "close job stream: %s", 126 ipp_svc_status_mesg(svc, status)); 127 papiJobFree(j); /* we shouldn't have a job, but just in case */ 128 return (status); 129 } 130 131 /* if it's the last document, commit the job */ 132 if (last == PAPI_TRUE) { 133 status = papiJobCommit(svc, queue, id); 134 } 135 136 /* add the job attributes to the response in a job-attributes-group */ 137 if (j != NULL) { 138 papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); 139 papiJobFree(j); 140 } 141 142 return (status); 143 } 144