12264Sjacobs /*
22264Sjacobs  * CDDL HEADER START
32264Sjacobs  *
42264Sjacobs  * The contents of this file are subject to the terms of the
52264Sjacobs  * Common Development and Distribution License (the "License").
62264Sjacobs  * You may not use this file except in compliance with the License.
72264Sjacobs  *
82264Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92264Sjacobs  * or http://www.opensolaris.org/os/licensing.
102264Sjacobs  * See the License for the specific language governing permissions
112264Sjacobs  * and limitations under the License.
122264Sjacobs  *
132264Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
142264Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152264Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
162264Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
172264Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
182264Sjacobs  *
192264Sjacobs  * CDDL HEADER END
202264Sjacobs  */
212264Sjacobs 
222264Sjacobs /*
23*4390Sceastha  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
242264Sjacobs  * Use is subject to license terms.
252264Sjacobs  */
262264Sjacobs 
272383Sjacobs /* $Id: job.c 179 2006-07-17 18:24:07Z njacobs $ */
282264Sjacobs 
292264Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
302264Sjacobs 
312264Sjacobs #include <stdlib.h>
322264Sjacobs #include <stdio.h>
332264Sjacobs #include <string.h>
342264Sjacobs #include <errno.h>
352264Sjacobs #include <unistd.h>
362264Sjacobs #include <limits.h>
372264Sjacobs #include <libintl.h>
382264Sjacobs #include <sys/types.h>
392264Sjacobs #include <sys/stat.h>
402264Sjacobs #include <fcntl.h>
412264Sjacobs #include <papi_impl.h>
422264Sjacobs #include <uri.h>
432264Sjacobs 
442264Sjacobs /*
452264Sjacobs  * must copy files before leaving routine
462264Sjacobs  */
472264Sjacobs papi_status_t
482264Sjacobs papiJobSubmit(papi_service_t handle, char *name, papi_attribute_t **attributes,
492264Sjacobs 		papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
502264Sjacobs {
512264Sjacobs 	papi_status_t status = PAPI_OK;
522264Sjacobs 	service_t *svc = handle;
532264Sjacobs 	job_t *j = NULL;
542264Sjacobs 	char *metadata = NULL;
552264Sjacobs 
562264Sjacobs 	if ((svc == NULL) || (name == NULL) || (files == NULL) ||
572264Sjacobs 	    (job == NULL))
582264Sjacobs 		return (PAPI_BAD_ARGUMENT);
592264Sjacobs 
602264Sjacobs 	if (job_ticket != NULL) {
612264Sjacobs 		detailed_error(svc,
62*4390Sceastha 		    gettext("papiJobSubmit: job ticket not supported"));
632264Sjacobs 		return (PAPI_OPERATION_NOT_SUPPORTED);
642264Sjacobs 	}
652264Sjacobs 
662264Sjacobs 	if ((status = service_fill_in(svc, name)) != PAPI_OK)
672264Sjacobs 		return (status);
682264Sjacobs 
692264Sjacobs 	if ((*job = j = (job_t *)calloc(1, sizeof (*j))) == NULL) {
702264Sjacobs 		detailed_error(svc,
71*4390Sceastha 		    gettext("calloc() failed"));
722264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
732264Sjacobs 	}
742264Sjacobs 
752264Sjacobs 	/* create a control file */
76*4390Sceastha 	(void) lpd_job_add_attributes(svc, attributes, &metadata,
77*4390Sceastha 	    &j->attributes);
78*4390Sceastha 
79*4390Sceastha 	if ((status = lpd_job_add_files(svc, attributes, files, &metadata,
80*4390Sceastha 	    &j->attributes)) != PAPI_OK) {
81*4390Sceastha 		return (status);
82*4390Sceastha 	}
832264Sjacobs 
842264Sjacobs 	/* send the job to the server */
852264Sjacobs 	status = lpd_submit_job(svc, metadata, &j->attributes, NULL);
862264Sjacobs 	free(metadata);
872264Sjacobs 
882264Sjacobs 	return (status);
892264Sjacobs 
902264Sjacobs }
912264Sjacobs 
922264Sjacobs 
932264Sjacobs papi_status_t
942264Sjacobs papiJobSubmitByReference(papi_service_t handle, char *name,
952264Sjacobs 		papi_attribute_t **job_attributes,
962264Sjacobs 		papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
972264Sjacobs {
982264Sjacobs 	return (papiJobSubmit(handle, name, job_attributes,
99*4390Sceastha 	    job_ticket, files, job));
1002264Sjacobs }
1012264Sjacobs 
1022264Sjacobs papi_status_t
1032264Sjacobs papiJobStreamOpen(papi_service_t handle, char *name,
1042264Sjacobs 		papi_attribute_t **attributes,
1052264Sjacobs 		papi_job_ticket_t *job_ticket, papi_stream_t *stream)
1062264Sjacobs {
1072264Sjacobs 	papi_status_t status = PAPI_OK;
1082264Sjacobs 	service_t *svc = handle;
1092264Sjacobs 	char *metadata = NULL;
1102264Sjacobs 	stream_t *s = NULL;
1112264Sjacobs 
1122264Sjacobs 	if ((svc == NULL) || (name == NULL) || (stream == NULL))
1132264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1142264Sjacobs 
1152264Sjacobs 	if (job_ticket != NULL)
1162264Sjacobs 		return (PAPI_OPERATION_NOT_SUPPORTED);
1172264Sjacobs 
1182264Sjacobs 	if ((status = service_fill_in(svc, name)) != PAPI_OK)
1192264Sjacobs 		return (status);
1202264Sjacobs 
1212264Sjacobs 	/* create the stream container */
1222264Sjacobs 	if ((*stream = s = calloc(1, sizeof (*s))) == NULL)
1232264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
1242264Sjacobs 
1252264Sjacobs 	/* create the job */
1262264Sjacobs 	if ((s->job = calloc(1, sizeof (*(s->job)))) == NULL)
1272264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
1282264Sjacobs 
1292264Sjacobs 	/* process the attribute list */
1302264Sjacobs 	lpd_job_add_attributes(svc, attributes, &metadata, &s->job->attributes);
1312264Sjacobs 
1322264Sjacobs 	/* if we can stream, do it */
1332264Sjacobs 	if ((svc->uri->fragment != NULL) &&
1342264Sjacobs 	    (strcasecmp(svc->uri->fragment, "streaming") == 0)) {
1352264Sjacobs 		char *files[] = { "standard input", NULL };
1362264Sjacobs 
1372264Sjacobs 		lpd_job_add_files(svc, attributes, files, &metadata,
138*4390Sceastha 		    &(s->job->attributes));
1392264Sjacobs 		status = lpd_submit_job(svc, metadata, &(s->job->attributes),
140*4390Sceastha 		    &s->fd);
1412264Sjacobs 	} else {
1422264Sjacobs 		char dfname[18];
1432264Sjacobs 
1442264Sjacobs 		strcpy(dfname, "/tmp/stdin-XXXXX");
1452264Sjacobs 
1462264Sjacobs 		if ((s->fd = mkstemp(dfname)) >= 0)
1472264Sjacobs 			s->dfname = strdup(dfname);
1482264Sjacobs 	}
1492264Sjacobs 	s->metadata = metadata;
1502264Sjacobs 
1512264Sjacobs 	return (status);
1522264Sjacobs }
1532264Sjacobs 
1542264Sjacobs 
1552264Sjacobs papi_status_t
1562264Sjacobs papiJobStreamWrite(papi_service_t handle, papi_stream_t stream,
1572264Sjacobs 		void *buffer, size_t buflen)
1582264Sjacobs {
1592264Sjacobs 	service_t *svc = handle;
1602264Sjacobs 	stream_t *s = stream;
1612264Sjacobs 
1622264Sjacobs 	if ((svc == NULL) || (stream == NULL) || (buffer == NULL) ||
1632264Sjacobs 	    (buflen == 0))
1642264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1652264Sjacobs 
1662264Sjacobs 	if (write(s->fd, buffer, buflen) != buflen)
1672264Sjacobs 		return (PAPI_DEVICE_ERROR);
1682264Sjacobs 
1692264Sjacobs 	return (PAPI_OK);
1702264Sjacobs }
1712264Sjacobs 
1722264Sjacobs papi_status_t
1732264Sjacobs papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job)
1742264Sjacobs {
1752264Sjacobs 	papi_status_t status = PAPI_INTERNAL_ERROR;
1762264Sjacobs 	service_t *svc = handle;
1772264Sjacobs 	job_t *j = NULL;
1782264Sjacobs 	stream_t *s = stream;
1792264Sjacobs 	int ret;
1802264Sjacobs 
1812264Sjacobs 	if ((svc == NULL) || (stream == NULL) || (job == NULL))
1822264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1832264Sjacobs 
1842264Sjacobs 	close(s->fd);	/* close the stream */
1852264Sjacobs 
1862264Sjacobs 	if (s->dfname != NULL) {	/* if it is a tmpfile, print it */
1872264Sjacobs 		char *files[2];
1882264Sjacobs 
1892264Sjacobs 		files[0] = s->dfname;
1902264Sjacobs 		files[1] = NULL;
1912264Sjacobs 
1922264Sjacobs 		lpd_job_add_files(svc, s->job->attributes, files, &s->metadata,
193*4390Sceastha 		    &(s->job->attributes));
1942264Sjacobs 		status = lpd_submit_job(svc, s->metadata,
195*4390Sceastha 		    &(s->job->attributes), NULL);
1962264Sjacobs 		unlink(s->dfname);
1972264Sjacobs 		free(s->dfname);
1982264Sjacobs 	} else
1992264Sjacobs 		status = PAPI_OK;
2002264Sjacobs 
2012264Sjacobs 	if (s->metadata != NULL)
2022264Sjacobs 		free(s->metadata);
2032264Sjacobs 
2042264Sjacobs 	*job = s->job;
2052264Sjacobs 
2062264Sjacobs 	return (status);
2072264Sjacobs }
2082264Sjacobs 
2092264Sjacobs papi_status_t
2102264Sjacobs papiJobQuery(papi_service_t handle, char *name, int32_t job_id,
2112264Sjacobs 		char **job_attributes, papi_job_t *job)
2122264Sjacobs {
2132264Sjacobs 	papi_status_t status = PAPI_OK;
2142264Sjacobs 	service_t *svc = handle;
2152264Sjacobs 
2162264Sjacobs 	if ((svc == NULL) || (name == NULL) || job_id < 0)
2172264Sjacobs 		return (PAPI_BAD_ARGUMENT);
2182264Sjacobs 
2192264Sjacobs 	if ((status = service_fill_in(svc, name)) == PAPI_OK)
2202264Sjacobs 		status = lpd_find_job_info(svc, job_id, (job_t **)job);
2212264Sjacobs 
2222264Sjacobs 	return (status);
2232264Sjacobs }
2242264Sjacobs 
2252264Sjacobs papi_status_t
2262264Sjacobs papiJobCancel(papi_service_t handle, char *name, int32_t job_id)
2272264Sjacobs {
2282264Sjacobs 	papi_status_t status;
2292264Sjacobs 	service_t *svc = handle;
2302264Sjacobs 
2312264Sjacobs 	if ((svc == NULL) || (name == NULL) || (job_id < 0))
2322264Sjacobs 		return (PAPI_BAD_ARGUMENT);
2332264Sjacobs 
2342264Sjacobs 	if ((status = service_fill_in(svc, name)) == PAPI_OK)
2352264Sjacobs 		status = lpd_cancel_job(svc, job_id);
2362264Sjacobs 
2372264Sjacobs 	return (status);
2382264Sjacobs }
2392264Sjacobs 
2402264Sjacobs papi_attribute_t **
2412264Sjacobs papiJobGetAttributeList(papi_job_t job)
2422264Sjacobs {
2432264Sjacobs 	job_t *j = (job_t *)job;
2442264Sjacobs 
2452264Sjacobs 	if (j != NULL)
2462264Sjacobs 		return ((papi_attribute_t **)j->attributes);
2472264Sjacobs 
2482264Sjacobs 	return (NULL);
2492264Sjacobs }
2502264Sjacobs 
2512264Sjacobs char *
2522264Sjacobs papiJobGetPrinterName(papi_job_t job)
2532264Sjacobs {
2542264Sjacobs 	char *result = NULL;
2552264Sjacobs 	job_t *j = (job_t *)job;
2562264Sjacobs 
2572264Sjacobs 	if (j != NULL)
2582264Sjacobs 		papiAttributeListGetString(j->attributes, NULL,
259*4390Sceastha 		    "printer-name", &result);
2602264Sjacobs 
2612264Sjacobs 	return (result);
2622264Sjacobs }
2632264Sjacobs 
2642264Sjacobs int
2652264Sjacobs papiJobGetId(papi_job_t job)
2662264Sjacobs {
2672264Sjacobs 	int result = -1;
2682264Sjacobs 	job_t *j = (job_t *)job;
2692264Sjacobs 
2702264Sjacobs 	if (j != NULL)
2712264Sjacobs 		papiAttributeListGetInteger(j->attributes, NULL,
272*4390Sceastha 		    "job-id", &result);
2732264Sjacobs 
2742264Sjacobs 	return (result);
2752264Sjacobs }
2762264Sjacobs 
2772264Sjacobs void
2782264Sjacobs papiJobFree(papi_job_t job)
2792264Sjacobs {
2802264Sjacobs 	job_t *j = (job_t *)job;
2812264Sjacobs 
2822264Sjacobs 
2832264Sjacobs 	if (j != NULL) {
2842264Sjacobs 		papiAttributeListFree(j->attributes);
2852264Sjacobs 		free(j);
2862264Sjacobs 	}
2872264Sjacobs }
2882264Sjacobs 
2892264Sjacobs void
2902264Sjacobs papiJobListFree(papi_job_t *jobs)
2912264Sjacobs {
2922264Sjacobs 	if (jobs != NULL) {
2932264Sjacobs 		int i;
2942264Sjacobs 
2952264Sjacobs 		for (i = 0; jobs[i] != NULL; i++)
2962264Sjacobs 			papiJobFree(jobs[i]);
2972264Sjacobs 		free(jobs);
2982264Sjacobs 	}
2992264Sjacobs }
300