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