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