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