1*2264Sjacobs /*
2*2264Sjacobs  * CDDL HEADER START
3*2264Sjacobs  *
4*2264Sjacobs  * The contents of this file are subject to the terms of the
5*2264Sjacobs  * Common Development and Distribution License (the "License").
6*2264Sjacobs  * You may not use this file except in compliance with the License.
7*2264Sjacobs  *
8*2264Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2264Sjacobs  * or http://www.opensolaris.org/os/licensing.
10*2264Sjacobs  * See the License for the specific language governing permissions
11*2264Sjacobs  * and limitations under the License.
12*2264Sjacobs  *
13*2264Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14*2264Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2264Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16*2264Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17*2264Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18*2264Sjacobs  *
19*2264Sjacobs  * CDDL HEADER END
20*2264Sjacobs  */
21*2264Sjacobs 
22*2264Sjacobs /*
23*2264Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24*2264Sjacobs  * Use is subject to license terms.
25*2264Sjacobs  *
26*2264Sjacobs  */
27*2264Sjacobs 
28*2264Sjacobs /* $Id: job.c 155 2006-04-26 02:34:54Z ktou $ */
29*2264Sjacobs 
30*2264Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*2264Sjacobs 
32*2264Sjacobs #include <stdlib.h>
33*2264Sjacobs #include <stdio.h>
34*2264Sjacobs #include <string.h>
35*2264Sjacobs #include <errno.h>
36*2264Sjacobs #include <unistd.h>
37*2264Sjacobs #include <limits.h>
38*2264Sjacobs #include <libintl.h>
39*2264Sjacobs #include <sys/types.h>
40*2264Sjacobs #include <sys/stat.h>
41*2264Sjacobs #include <fcntl.h>
42*2264Sjacobs #include <papi_impl.h>
43*2264Sjacobs #include <uri.h>
44*2264Sjacobs 
45*2264Sjacobs /*
46*2264Sjacobs  * must copy files before leaving routine
47*2264Sjacobs  */
48*2264Sjacobs papi_status_t
49*2264Sjacobs papiJobSubmit(papi_service_t handle, char *name, papi_attribute_t **attributes,
50*2264Sjacobs 		papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
51*2264Sjacobs {
52*2264Sjacobs 	papi_status_t status = PAPI_OK;
53*2264Sjacobs 	service_t *svc = handle;
54*2264Sjacobs 	job_t *j = NULL;
55*2264Sjacobs 	char *metadata = NULL;
56*2264Sjacobs 
57*2264Sjacobs 	if ((svc == NULL) || (name == NULL) || (files == NULL) ||
58*2264Sjacobs 	    (job == NULL))
59*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
60*2264Sjacobs 
61*2264Sjacobs 	if (job_ticket != NULL) {
62*2264Sjacobs 		detailed_error(svc,
63*2264Sjacobs 			gettext("papiJobSubmit: job ticket not supported"));
64*2264Sjacobs 		return (PAPI_OPERATION_NOT_SUPPORTED);
65*2264Sjacobs 	}
66*2264Sjacobs 
67*2264Sjacobs 	if ((status = service_fill_in(svc, name)) != PAPI_OK)
68*2264Sjacobs 		return (status);
69*2264Sjacobs 
70*2264Sjacobs 	if ((*job = j = (job_t *)calloc(1, sizeof (*j))) == NULL) {
71*2264Sjacobs 		detailed_error(svc,
72*2264Sjacobs 			gettext("calloc() failed"));
73*2264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
74*2264Sjacobs 	}
75*2264Sjacobs 
76*2264Sjacobs 	/* create a control file */
77*2264Sjacobs 	status = lpd_job_add_attributes(svc, attributes, &metadata,
78*2264Sjacobs 				&j->attributes);
79*2264Sjacobs 	status = lpd_job_add_files(svc, attributes, files, &metadata,
80*2264Sjacobs 				&j->attributes);
81*2264Sjacobs 
82*2264Sjacobs 	/* send the job to the server */
83*2264Sjacobs 	status = lpd_submit_job(svc, metadata, &j->attributes, NULL);
84*2264Sjacobs 	free(metadata);
85*2264Sjacobs 
86*2264Sjacobs 	return (status);
87*2264Sjacobs 
88*2264Sjacobs }
89*2264Sjacobs 
90*2264Sjacobs 
91*2264Sjacobs papi_status_t
92*2264Sjacobs papiJobSubmitByReference(papi_service_t handle, char *name,
93*2264Sjacobs 		papi_attribute_t **job_attributes,
94*2264Sjacobs 		papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
95*2264Sjacobs {
96*2264Sjacobs 	return (papiJobSubmit(handle, name, job_attributes,
97*2264Sjacobs 		job_ticket, files, job));
98*2264Sjacobs }
99*2264Sjacobs 
100*2264Sjacobs papi_status_t
101*2264Sjacobs papiJobStreamOpen(papi_service_t handle, char *name,
102*2264Sjacobs 		papi_attribute_t **attributes,
103*2264Sjacobs 		papi_job_ticket_t *job_ticket, papi_stream_t *stream)
104*2264Sjacobs {
105*2264Sjacobs 	papi_status_t status = PAPI_OK;
106*2264Sjacobs 	service_t *svc = handle;
107*2264Sjacobs 	char *metadata = NULL;
108*2264Sjacobs 	stream_t *s = NULL;
109*2264Sjacobs 
110*2264Sjacobs 	if ((svc == NULL) || (name == NULL) || (stream == NULL))
111*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
112*2264Sjacobs 
113*2264Sjacobs 	if (job_ticket != NULL)
114*2264Sjacobs 		return (PAPI_OPERATION_NOT_SUPPORTED);
115*2264Sjacobs 
116*2264Sjacobs 	if ((status = service_fill_in(svc, name)) != PAPI_OK)
117*2264Sjacobs 		return (status);
118*2264Sjacobs 
119*2264Sjacobs 	/* create the stream container */
120*2264Sjacobs 	if ((*stream = s = calloc(1, sizeof (*s))) == NULL)
121*2264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
122*2264Sjacobs 
123*2264Sjacobs 	/* create the job */
124*2264Sjacobs 	if ((s->job = calloc(1, sizeof (*(s->job)))) == NULL)
125*2264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
126*2264Sjacobs 
127*2264Sjacobs 	/* process the attribute list */
128*2264Sjacobs 	lpd_job_add_attributes(svc, attributes, &metadata, &s->job->attributes);
129*2264Sjacobs 
130*2264Sjacobs 	/* if we can stream, do it */
131*2264Sjacobs 	if ((svc->uri->fragment != NULL) &&
132*2264Sjacobs 	    (strcasecmp(svc->uri->fragment, "streaming") == 0)) {
133*2264Sjacobs 		char *files[] = { "standard input", NULL };
134*2264Sjacobs 
135*2264Sjacobs 		lpd_job_add_files(svc, attributes, files, &metadata,
136*2264Sjacobs 				&(s->job->attributes));
137*2264Sjacobs 		status = lpd_submit_job(svc, metadata, &(s->job->attributes),
138*2264Sjacobs 				&s->fd);
139*2264Sjacobs 	} else {
140*2264Sjacobs 		char dfname[18];
141*2264Sjacobs 
142*2264Sjacobs 		strcpy(dfname, "/tmp/stdin-XXXXX");
143*2264Sjacobs 
144*2264Sjacobs 		if ((s->fd = mkstemp(dfname)) >= 0)
145*2264Sjacobs 			s->dfname = strdup(dfname);
146*2264Sjacobs 		s->job->attributes = attributes;
147*2264Sjacobs 	}
148*2264Sjacobs 	s->metadata = metadata;
149*2264Sjacobs 
150*2264Sjacobs 	return (status);
151*2264Sjacobs }
152*2264Sjacobs 
153*2264Sjacobs 
154*2264Sjacobs papi_status_t
155*2264Sjacobs papiJobStreamWrite(papi_service_t handle, papi_stream_t stream,
156*2264Sjacobs 		void *buffer, size_t buflen)
157*2264Sjacobs {
158*2264Sjacobs 	service_t *svc = handle;
159*2264Sjacobs 	stream_t *s = stream;
160*2264Sjacobs 
161*2264Sjacobs 	if ((svc == NULL) || (stream == NULL) || (buffer == NULL) ||
162*2264Sjacobs 	    (buflen == 0))
163*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
164*2264Sjacobs 
165*2264Sjacobs 	if (write(s->fd, buffer, buflen) != buflen)
166*2264Sjacobs 		return (PAPI_DEVICE_ERROR);
167*2264Sjacobs 
168*2264Sjacobs 	return (PAPI_OK);
169*2264Sjacobs }
170*2264Sjacobs 
171*2264Sjacobs papi_status_t
172*2264Sjacobs papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job)
173*2264Sjacobs {
174*2264Sjacobs 	papi_status_t status = PAPI_INTERNAL_ERROR;
175*2264Sjacobs 	service_t *svc = handle;
176*2264Sjacobs 	job_t *j = NULL;
177*2264Sjacobs 	stream_t *s = stream;
178*2264Sjacobs 	int ret;
179*2264Sjacobs 
180*2264Sjacobs 	if ((svc == NULL) || (stream == NULL) || (job == NULL))
181*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
182*2264Sjacobs 
183*2264Sjacobs 	close(s->fd);	/* close the stream */
184*2264Sjacobs 
185*2264Sjacobs 	if (s->dfname != NULL) {	/* if it is a tmpfile, print it */
186*2264Sjacobs 		char *files[2];
187*2264Sjacobs 
188*2264Sjacobs 		files[0] = s->dfname;
189*2264Sjacobs 		files[1] = NULL;
190*2264Sjacobs 
191*2264Sjacobs 		lpd_job_add_files(svc, s->job->attributes, files, &s->metadata,
192*2264Sjacobs 				&(s->job->attributes));
193*2264Sjacobs 		status = lpd_submit_job(svc, s->metadata,
194*2264Sjacobs 					&(s->job->attributes), NULL);
195*2264Sjacobs 		unlink(s->dfname);
196*2264Sjacobs 		free(s->dfname);
197*2264Sjacobs 	} else
198*2264Sjacobs 		status = PAPI_OK;
199*2264Sjacobs 
200*2264Sjacobs 	if (s->metadata != NULL)
201*2264Sjacobs 		free(s->metadata);
202*2264Sjacobs 
203*2264Sjacobs 	*job = s->job;
204*2264Sjacobs 
205*2264Sjacobs 	return (status);
206*2264Sjacobs }
207*2264Sjacobs 
208*2264Sjacobs papi_status_t
209*2264Sjacobs papiJobQuery(papi_service_t handle, char *name, int32_t job_id,
210*2264Sjacobs 		char **job_attributes, papi_job_t *job)
211*2264Sjacobs {
212*2264Sjacobs 	papi_status_t status = PAPI_OK;
213*2264Sjacobs 	service_t *svc = handle;
214*2264Sjacobs 
215*2264Sjacobs 	if ((svc == NULL) || (name == NULL) || job_id < 0)
216*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
217*2264Sjacobs 
218*2264Sjacobs 	if ((status = service_fill_in(svc, name)) == PAPI_OK)
219*2264Sjacobs 		status = lpd_find_job_info(svc, job_id, (job_t **)job);
220*2264Sjacobs 
221*2264Sjacobs 	return (status);
222*2264Sjacobs }
223*2264Sjacobs 
224*2264Sjacobs papi_status_t
225*2264Sjacobs papiJobCancel(papi_service_t handle, char *name, int32_t job_id)
226*2264Sjacobs {
227*2264Sjacobs 	papi_status_t status;
228*2264Sjacobs 	service_t *svc = handle;
229*2264Sjacobs 
230*2264Sjacobs 	if ((svc == NULL) || (name == NULL) || (job_id < 0))
231*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
232*2264Sjacobs 
233*2264Sjacobs 	if ((status = service_fill_in(svc, name)) == PAPI_OK)
234*2264Sjacobs 		status = lpd_cancel_job(svc, job_id);
235*2264Sjacobs 
236*2264Sjacobs 	return (status);
237*2264Sjacobs }
238*2264Sjacobs 
239*2264Sjacobs papi_attribute_t **
240*2264Sjacobs papiJobGetAttributeList(papi_job_t job)
241*2264Sjacobs {
242*2264Sjacobs 	job_t *j = (job_t *)job;
243*2264Sjacobs 
244*2264Sjacobs 	if (j != NULL)
245*2264Sjacobs 		return ((papi_attribute_t **)j->attributes);
246*2264Sjacobs 
247*2264Sjacobs 	return (NULL);
248*2264Sjacobs }
249*2264Sjacobs 
250*2264Sjacobs char *
251*2264Sjacobs papiJobGetPrinterName(papi_job_t job)
252*2264Sjacobs {
253*2264Sjacobs 	char *result = NULL;
254*2264Sjacobs 	job_t *j = (job_t *)job;
255*2264Sjacobs 
256*2264Sjacobs 	if (j != NULL)
257*2264Sjacobs 		papiAttributeListGetString(j->attributes, NULL,
258*2264Sjacobs 					"printer-name", &result);
259*2264Sjacobs 
260*2264Sjacobs 	return (result);
261*2264Sjacobs }
262*2264Sjacobs 
263*2264Sjacobs int
264*2264Sjacobs papiJobGetId(papi_job_t job)
265*2264Sjacobs {
266*2264Sjacobs 	int result = -1;
267*2264Sjacobs 	job_t *j = (job_t *)job;
268*2264Sjacobs 
269*2264Sjacobs 	if (j != NULL)
270*2264Sjacobs 		papiAttributeListGetInteger(j->attributes, NULL,
271*2264Sjacobs 					"job-id", &result);
272*2264Sjacobs 
273*2264Sjacobs 	return (result);
274*2264Sjacobs }
275*2264Sjacobs 
276*2264Sjacobs void
277*2264Sjacobs papiJobFree(papi_job_t job)
278*2264Sjacobs {
279*2264Sjacobs 	job_t *j = (job_t *)job;
280*2264Sjacobs 
281*2264Sjacobs 
282*2264Sjacobs 	if (j != NULL) {
283*2264Sjacobs 		papiAttributeListFree(j->attributes);
284*2264Sjacobs 		free(j);
285*2264Sjacobs 	}
286*2264Sjacobs }
287*2264Sjacobs 
288*2264Sjacobs void
289*2264Sjacobs papiJobListFree(papi_job_t *jobs)
290*2264Sjacobs {
291*2264Sjacobs 	if (jobs != NULL) {
292*2264Sjacobs 		int i;
293*2264Sjacobs 
294*2264Sjacobs 		for (i = 0; jobs[i] != NULL; i++)
295*2264Sjacobs 			papiJobFree(jobs[i]);
296*2264Sjacobs 		free(jobs);
297*2264Sjacobs 	}
298*2264Sjacobs }
299