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 char *user = NULL; 92 93 copy_attributes(&job_attributes, operational); 94 95 if (papiAttributeListGetString(operational, NULL, 96 "requesting-user-name", &user) == PAPI_OK) { 97 papiAttributeListAddString(&job_attributes, 98 PAPI_ATTR_REPLACE, "requesting-user-name", user); 99 } 100 } 101 102 /* Set "job-originating-host-name" attribute if not set */ 103 papiAttributeListGetString(job_attributes, NULL, 104 "job-originating-host-name", &host); 105 106 if (host == NULL) { 107 int fd = -1; 108 (void) papiAttributeListGetInteger(request, NULL, 109 "peer-socket", &fd); 110 111 if (fd != -1) { 112 struct sockaddr_in peer; 113 int peer_len; 114 115 peer_len = sizeof (peer); 116 if (getpeername(fd, (struct sockaddr *)&peer, 117 &peer_len) == 0) { 118 struct hostent *he; 119 int error_num; 120 121 he = getipnodebyaddr(&peer.sin_addr, 122 sizeof (peer.sin_addr), 123 peer.sin_family, &error_num); 124 125 if ((he != NULL) && (he->h_name != NULL)) { 126 papiAttributeListAddString( 127 &job_attributes, 128 PAPI_ATTR_REPLACE, 129 "job-originating-host-name", 130 he->h_name); 131 } else { 132 /* 133 * Node-name could not be read 134 * so set the ip-address 135 */ 136 papiAttributeListAddString( 137 &job_attributes, 138 PAPI_ATTR_REPLACE, 139 "job-originating-host-name", 140 inet_ntoa(peer.sin_addr)); 141 } 142 } 143 } 144 } 145 146 /* request job creation with a resulting stream that we can write to */ 147 status = papiJobStreamOpen(svc, queue, job_attributes, NULL, &s); 148 papiAttributeListFree(job_attributes); 149 if (status != PAPI_OK) { 150 ipp_set_status(response, status, "job submission: %s", 151 ipp_svc_status_mesg(svc, status)); 152 return (status); 153 } 154 155 /* copy the document data from the IPP connection to the stream */ 156 while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0)) 157 status = papiJobStreamWrite(svc, s, buf, rc); 158 if (status != PAPI_OK) { 159 ipp_set_status(response, status, "write job data: %s", 160 ipp_svc_status_mesg(svc, status)); 161 return (status); 162 } 163 164 /* close the stream, committing the job */ 165 status = papiJobStreamClose(svc, s, &j); 166 if (status != PAPI_OK) { 167 ipp_set_status(response, status, "close job stream: %s", 168 ipp_svc_status_mesg(svc, status)); 169 papiJobFree(j); /* we shouldn't have a job, but just in case */ 170 return (status); 171 } 172 173 /* add the job attributes to the response in a job-attributes-group */ 174 if (j != NULL) { 175 papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); 176 papiJobFree(j); 177 } 178 179 return (status); 180 } 181