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
papiJobSubmit(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_job_ticket_t * job_ticket,char ** files,papi_job_t * job)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
papiJobSubmitByReference(papi_service_t handle,char * name,papi_attribute_t ** job_attributes,papi_job_ticket_t * job_ticket,char ** files,papi_job_t * job)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
papiJobStreamOpen(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_job_ticket_t * job_ticket,papi_stream_t * stream)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
papiJobStreamWrite(papi_service_t handle,papi_stream_t stream,void * buffer,size_t buflen)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
papiJobStreamClose(papi_service_t handle,papi_stream_t stream,papi_job_t * job)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
papiJobQuery(papi_service_t handle,char * name,int32_t job_id,char ** job_attributes,papi_job_t * job)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
papiJobCancel(papi_service_t handle,char * name,int32_t job_id)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 **
papiJobGetAttributeList(papi_job_t job)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 *
papiJobGetPrinterName(papi_job_t job)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
papiJobGetId(papi_job_t job)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
papiJobFree(papi_job_t job)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
papiJobListFree(papi_job_t * jobs)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