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 int fp = -1; 55 char *keys[] = { "attributes-natural-language", "attributes-charset", 56 "printer-uri", NULL }; 57 58 /* Get operational attributes from the request */ 59 (void) papiAttributeListGetCollection(request, NULL, 60 "operational-attributes-group", &operational); 61 62 /* 63 * The operational-attributes-group must contain: 64 * printer-uri 65 */ 66 get_printer_id(operational, &queue, NULL); 67 if (queue == NULL) { 68 ipp_set_status(response, status, "printer-uri: %s", 69 papiStatusString(status)); 70 return (PAPI_BAD_REQUEST); 71 } 72 73 /* 74 * The operational-attributes-group may contain: 75 * job-name 76 * ipp-attribute-fidelity 77 * document-name 78 * compression 79 * document-format 80 * document-natural-language 81 * job-k-octets 82 * job-impressions 83 * job-media-sheets 84 * Simply copy the entire contents of the operational-attributes-group 85 * for the PAPI call's possible use. 86 */ 87 split_and_copy_attributes(keys, operational, NULL, &job_attributes); 88 89 /* copy any job-attributes-group attributes for the PAPI call */ 90 if (papiAttributeListGetCollection(request, NULL, 91 "job-attributes-group", &operational) == PAPI_OK) { 92 char *user = NULL; 93 94 copy_attributes(&job_attributes, operational); 95 96 if (papiAttributeListGetString(operational, NULL, 97 "requesting-user-name", &user) == PAPI_OK) { 98 papiAttributeListAddString(&job_attributes, 99 PAPI_ATTR_REPLACE, "requesting-user-name", user); 100 } 101 } 102 103 /* Set "job-originating-host-name" in next block */ 104 (void) papiAttributeListGetInteger(request, NULL, 105 "peer-socket", &fp); 106 107 if (fp != -1) { 108 struct sockaddr_in peer; 109 socklen_t peer_len = sizeof (peer); 110 111 /* who is our peer ? */ 112 if (getpeername(fp, (struct sockaddr *)&peer, 113 &peer_len) == 0) { 114 struct hostent *he; 115 int error_num; 116 117 /* 118 * get their name or return a string containing 119 * their address 120 */ 121 if ((he = getipnodebyaddr((const char *)&peer.sin_addr, 122 sizeof (peer.sin_addr), peer.sin_family, 123 &error_num)) == NULL) { 124 char tmp_buf[INET6_ADDRSTRLEN]; 125 papiAttributeListAddString( 126 &job_attributes, 127 PAPI_ATTR_REPLACE, 128 "job-originating-host-name", 129 (char *)inet_ntop(peer.sin_family, 130 &peer.sin_addr, tmp_buf, 131 sizeof (tmp_buf))); 132 133 } else { 134 if (is_localhost(he->h_name) != 0) 135 papiAttributeListAddString( 136 &job_attributes, 137 PAPI_ATTR_REPLACE, 138 "job-originating-host-name", 139 "localhost"); 140 else if (he->h_name != NULL) 141 papiAttributeListAddString( 142 &job_attributes, 143 PAPI_ATTR_REPLACE, 144 "job-originating-host-name", 145 he->h_name); 146 } 147 } 148 } 149 150 /* request job creation with a resulting stream that we can write to */ 151 status = papiJobStreamOpen(svc, queue, job_attributes, NULL, &s); 152 papiAttributeListFree(job_attributes); 153 if (status != PAPI_OK) { 154 ipp_set_status(response, status, "job submission: %s", 155 ipp_svc_status_mesg(svc, status)); 156 return (status); 157 } 158 159 /* copy the document data from the IPP connection to the stream */ 160 while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0)) 161 status = papiJobStreamWrite(svc, s, buf, rc); 162 if (status != PAPI_OK) { 163 ipp_set_status(response, status, "write job data: %s", 164 ipp_svc_status_mesg(svc, status)); 165 return (status); 166 } 167 168 /* close the stream, committing the job */ 169 status = papiJobStreamClose(svc, s, &j); 170 if (status != PAPI_OK) { 171 ipp_set_status(response, status, "close job stream: %s", 172 ipp_svc_status_mesg(svc, status)); 173 papiJobFree(j); /* we shouldn't have a job, but just in case */ 174 return (status); 175 } 176 177 /* add the job attributes to the response in a job-attributes-group */ 178 if (j != NULL) { 179 papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); 180 papiJobFree(j); 181 } 182 183 return (status); 184 } 185