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 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 */ 27 28 /* $Id: print-job.c 146 2006-03-24 00:26:54Z njacobs $ */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <netdb.h> 33 #include <sys/types.h> 34 #include <sys/socket.h> 35 #include <netinet/in.h> 36 #include <arpa/inet.h> 37 #include <papi.h> 38 #include <ipp.h> 39 #include <ipp-listener.h> 40 41 papi_status_t 42 ipp_print_job(papi_service_t svc, papi_attribute_t **request, 43 papi_attribute_t ***response, ipp_reader_t iread, void *fd) 44 { 45 papi_status_t status; 46 papi_stream_t s = NULL; 47 papi_job_t j = NULL; 48 papi_attribute_t **operational = NULL; 49 papi_attribute_t **job_attributes = NULL; 50 char *queue = NULL; 51 ssize_t rc; 52 char buf[BUFSIZ]; 53 char *host = NULL; 54 char *keys[] = { "attributes-natural-language", "attributes-charset", 55 "printer-uri", NULL }; 56 57 /* Get operational attributes from the request */ 58 (void) papiAttributeListGetCollection(request, NULL, 59 "operational-attributes-group", &operational); 60 61 /* 62 * The operational-attributes-group must contain: 63 * printer-uri 64 */ 65 get_printer_id(operational, &queue, NULL); 66 if (queue == NULL) { 67 ipp_set_status(response, status, "printer-uri: %s", 68 papiStatusString(status)); 69 return (PAPI_BAD_REQUEST); 70 } 71 72 /* 73 * The operational-attributes-group may contain: 74 * job-name 75 * ipp-attribute-fidelity 76 * document-name 77 * compression 78 * document-format 79 * document-natural-language 80 * job-k-octets 81 * job-impressions 82 * job-media-sheets 83 * Simply copy the entire contents of the operational-attributes-group 84 * for the PAPI call's possible use. 85 */ 86 split_and_copy_attributes(keys, operational, NULL, &job_attributes); 87 88 /* copy any job-attributes-group attributes for the PAPI call */ 89 if (papiAttributeListGetCollection(request, NULL, 90 "job-attributes-group", &operational) == PAPI_OK) 91 copy_attributes(&job_attributes, operational); 92 93 /* Set "job-originating-host-name" attribute if not set */ 94 papiAttributeListGetString(job_attributes, NULL, 95 "job-originating-host-name", &host); 96 97 if (host == NULL) { 98 int fd = -1; 99 (void) papiAttributeListGetInteger(request, NULL, 100 "peer-socket", &fd); 101 102 if (fd != -1) { 103 struct sockaddr_in peer; 104 int peer_len; 105 106 peer_len = sizeof (peer); 107 if (getpeername(fd, (struct sockaddr *)&peer, 108 &peer_len) == 0) { 109 struct hostent *he; 110 int error_num; 111 112 he = getipnodebyaddr(&peer.sin_addr, 113 sizeof (peer.sin_addr), 114 peer.sin_family, &error_num); 115 116 if ((he != NULL) && (he->h_name != NULL)) { 117 papiAttributeListAddString( 118 &job_attributes, 119 PAPI_ATTR_REPLACE, 120 "job-originating-host-name", 121 he->h_name); 122 } else { 123 /* 124 * Node-name could not be read 125 * so set the ip-address 126 */ 127 papiAttributeListAddString( 128 &job_attributes, 129 PAPI_ATTR_REPLACE, 130 "job-originating-host-name", 131 inet_ntoa(peer.sin_addr)); 132 } 133 } 134 } 135 } 136 137 /* request job creation with a resulting stream that we can write to */ 138 status = papiJobStreamOpen(svc, queue, job_attributes, NULL, &s); 139 papiAttributeListFree(job_attributes); 140 if (status != PAPI_OK) { 141 ipp_set_status(response, status, "job submission: %s", 142 ipp_svc_status_mesg(svc, status)); 143 return (status); 144 } 145 146 /* copy the document data from the IPP connection to the stream */ 147 while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0)) 148 status = papiJobStreamWrite(svc, s, buf, rc); 149 if (status != PAPI_OK) { 150 ipp_set_status(response, status, "write job data: %s", 151 ipp_svc_status_mesg(svc, status)); 152 return (status); 153 } 154 155 /* close the stream, committing the job */ 156 status = papiJobStreamClose(svc, s, &j); 157 if (status != PAPI_OK) { 158 ipp_set_status(response, status, "close job stream: %s", 159 ipp_svc_status_mesg(svc, status)); 160 papiJobFree(j); /* we shouldn't have a job, but just in case */ 161 return (status); 162 } 163 164 /* add the job attributes to the response in a job-attributes-group */ 165 if (j != NULL) { 166 papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); 167 papiJobFree(j); 168 } 169 170 return (status); 171 } 172