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 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* $Id: job.c 179 2006-07-17 18:24:07Z njacobs $ */ 28 29 #include <stdlib.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <errno.h> 33 #include <unistd.h> 34 #include <limits.h> 35 #include <libintl.h> 36 #include <sys/types.h> 37 #include <sys/stat.h> 38 #include <fcntl.h> 39 #include <papi_impl.h> 40 #include <uri.h> 41 42 /* 43 * must copy files before leaving routine 44 */ 45 papi_status_t 46 papiJobSubmit(papi_service_t handle, char *name, papi_attribute_t **attributes, 47 papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 48 { 49 papi_status_t status = PAPI_OK; 50 service_t *svc = handle; 51 job_t *j = NULL; 52 char *metadata = NULL; 53 54 if ((svc == NULL) || (name == NULL) || (files == NULL) || 55 (job == NULL)) 56 return (PAPI_BAD_ARGUMENT); 57 58 if (job_ticket != NULL) { 59 detailed_error(svc, 60 gettext("papiJobSubmit: job ticket not supported")); 61 return (PAPI_OPERATION_NOT_SUPPORTED); 62 } 63 64 if ((status = service_fill_in(svc, name)) != PAPI_OK) 65 return (status); 66 67 if ((*job = j = (job_t *)calloc(1, sizeof (*j))) == NULL) { 68 detailed_error(svc, 69 gettext("calloc() failed")); 70 return (PAPI_TEMPORARY_ERROR); 71 } 72 73 /* before creating a control file add the job-name */ 74 if ((files != NULL) && (files[0] != NULL)) 75 papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL, 76 "job-name", files[0]); 77 78 /* create a control file */ 79 (void) lpd_job_add_attributes(svc, attributes, &metadata, 80 &j->attributes); 81 82 if ((status = lpd_job_add_files(svc, attributes, files, &metadata, 83 &j->attributes)) != PAPI_OK) { 84 return (status); 85 } 86 87 /* send the job to the server */ 88 status = lpd_submit_job(svc, metadata, &j->attributes, NULL); 89 free(metadata); 90 91 return (status); 92 93 } 94 95 96 papi_status_t 97 papiJobSubmitByReference(papi_service_t handle, char *name, 98 papi_attribute_t **job_attributes, 99 papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) 100 { 101 return (papiJobSubmit(handle, name, job_attributes, 102 job_ticket, files, job)); 103 } 104 105 papi_status_t 106 papiJobStreamOpen(papi_service_t handle, char *name, 107 papi_attribute_t **attributes, 108 papi_job_ticket_t *job_ticket, papi_stream_t *stream) 109 { 110 papi_status_t status = PAPI_OK; 111 service_t *svc = handle; 112 char *metadata = NULL; 113 stream_t *s = NULL; 114 115 if ((svc == NULL) || (name == NULL) || (stream == NULL)) 116 return (PAPI_BAD_ARGUMENT); 117 118 if (job_ticket != NULL) 119 return (PAPI_OPERATION_NOT_SUPPORTED); 120 121 if ((status = service_fill_in(svc, name)) != PAPI_OK) 122 return (status); 123 124 /* create the stream container */ 125 if ((*stream = s = calloc(1, sizeof (*s))) == NULL) 126 return (PAPI_TEMPORARY_ERROR); 127 128 /* create the job */ 129 if ((s->job = calloc(1, sizeof (*(s->job)))) == NULL) 130 return (PAPI_TEMPORARY_ERROR); 131 132 papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL, 133 "job-name", "standard input"); 134 135 /* process the attribute list */ 136 lpd_job_add_attributes(svc, attributes, &metadata, &s->job->attributes); 137 138 /* if we can stream, do it */ 139 if ((svc->uri->fragment != NULL) && 140 (strcasecmp(svc->uri->fragment, "streaming") == 0)) { 141 char *files[] = { "standard input", NULL }; 142 143 lpd_job_add_files(svc, attributes, files, &metadata, 144 &(s->job->attributes)); 145 status = lpd_submit_job(svc, metadata, &(s->job->attributes), 146 &s->fd); 147 } else { 148 char dfname[18]; 149 char buf[256]; 150 151 strcpy(dfname, "/tmp/stdin-XXXXX"); 152 153 if ((s->fd = mkstemp(dfname)) >= 0) 154 s->dfname = strdup(dfname); 155 if (s->job->attributes) 156 papiAttributeListFree(s->job->attributes); 157 s->job->attributes = NULL; 158 papiAttributeListToString(attributes, " ", buf, sizeof (buf)); 159 papiAttributeListFromString(&(s->job->attributes), 160 PAPI_ATTR_APPEND, buf); 161 } 162 s->metadata = metadata; 163 164 return (status); 165 } 166 167 168 papi_status_t 169 papiJobStreamWrite(papi_service_t handle, papi_stream_t stream, 170 void *buffer, size_t buflen) 171 { 172 service_t *svc = handle; 173 stream_t *s = stream; 174 175 if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || 176 (buflen == 0)) 177 return (PAPI_BAD_ARGUMENT); 178 179 if (write(s->fd, buffer, buflen) != buflen) 180 return (PAPI_DEVICE_ERROR); 181 182 return (PAPI_OK); 183 } 184 185 papi_status_t 186 papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job) 187 { 188 papi_status_t status = PAPI_INTERNAL_ERROR; 189 service_t *svc = handle; 190 job_t *j = NULL; 191 stream_t *s = stream; 192 int ret; 193 194 if ((svc == NULL) || (stream == NULL) || (job == NULL)) 195 return (PAPI_BAD_ARGUMENT); 196 197 close(s->fd); /* close the stream */ 198 199 if (s->dfname != NULL) { /* if it is a tmpfile, print it */ 200 char *files[2]; 201 202 files[0] = s->dfname; 203 files[1] = NULL; 204 205 lpd_job_add_files(svc, s->job->attributes, files, &s->metadata, 206 &(s->job->attributes)); 207 status = lpd_submit_job(svc, s->metadata, 208 &(s->job->attributes), NULL); 209 unlink(s->dfname); 210 free(s->dfname); 211 } else 212 status = PAPI_OK; 213 214 if (s->metadata != NULL) 215 free(s->metadata); 216 217 *job = s->job; 218 219 return (status); 220 } 221 222 papi_status_t 223 papiJobQuery(papi_service_t handle, char *name, int32_t job_id, 224 char **job_attributes, papi_job_t *job) 225 { 226 papi_status_t status = PAPI_OK; 227 service_t *svc = handle; 228 229 if ((svc == NULL) || (name == NULL) || job_id < 0) 230 return (PAPI_BAD_ARGUMENT); 231 232 if ((status = service_fill_in(svc, name)) == PAPI_OK) 233 status = lpd_find_job_info(svc, job_id, (job_t **)job); 234 235 return (status); 236 } 237 238 papi_status_t 239 papiJobCancel(papi_service_t handle, char *name, int32_t job_id) 240 { 241 papi_status_t status; 242 service_t *svc = handle; 243 244 if ((svc == NULL) || (name == NULL) || (job_id < 0)) 245 return (PAPI_BAD_ARGUMENT); 246 247 if ((status = service_fill_in(svc, name)) == PAPI_OK) 248 status = lpd_cancel_job(svc, job_id); 249 250 return (status); 251 } 252 253 papi_attribute_t ** 254 papiJobGetAttributeList(papi_job_t job) 255 { 256 job_t *j = (job_t *)job; 257 258 if (j != NULL) 259 return ((papi_attribute_t **)j->attributes); 260 261 return (NULL); 262 } 263 264 char * 265 papiJobGetPrinterName(papi_job_t job) 266 { 267 char *result = NULL; 268 job_t *j = (job_t *)job; 269 270 if (j != NULL) 271 papiAttributeListGetString(j->attributes, NULL, 272 "printer-name", &result); 273 274 return (result); 275 } 276 277 int 278 papiJobGetId(papi_job_t job) 279 { 280 int result = -1; 281 job_t *j = (job_t *)job; 282 283 if (j != NULL) 284 papiAttributeListGetInteger(j->attributes, NULL, 285 "job-id", &result); 286 287 return (result); 288 } 289 290 void 291 papiJobFree(papi_job_t job) 292 { 293 job_t *j = (job_t *)job; 294 295 296 if (j != NULL) { 297 papiAttributeListFree(j->attributes); 298 free(j); 299 } 300 } 301 302 void 303 papiJobListFree(papi_job_t *jobs) 304 { 305 if (jobs != NULL) { 306 int i; 307 308 for (i = 0; jobs[i] != NULL; i++) 309 papiJobFree(jobs[i]); 310 free(jobs); 311 } 312 } 313