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*9166SSonam.Gupta@Sun.COM  * Copyright 2009 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 #include <stdlib.h>
302264Sjacobs #include <stdio.h>
312264Sjacobs #include <string.h>
322264Sjacobs #include <errno.h>
332264Sjacobs #include <unistd.h>
342264Sjacobs #include <limits.h>
352264Sjacobs #include <libintl.h>
362264Sjacobs #include <sys/types.h>
372264Sjacobs #include <sys/stat.h>
382264Sjacobs #include <fcntl.h>
392264Sjacobs #include <papi_impl.h>
402264Sjacobs #include <uri.h>
412264Sjacobs 
422264Sjacobs /*
432264Sjacobs  * must copy files before leaving routine
442264Sjacobs  */
452264Sjacobs papi_status_t
462264Sjacobs papiJobSubmit(papi_service_t handle, char *name, papi_attribute_t **attributes,
472264Sjacobs 		papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
482264Sjacobs {
492264Sjacobs 	papi_status_t status = PAPI_OK;
502264Sjacobs 	service_t *svc = handle;
512264Sjacobs 	job_t *j = NULL;
522264Sjacobs 	char *metadata = NULL;
532264Sjacobs 
542264Sjacobs 	if ((svc == NULL) || (name == NULL) || (files == NULL) ||
552264Sjacobs 	    (job == NULL))
562264Sjacobs 		return (PAPI_BAD_ARGUMENT);
572264Sjacobs 
582264Sjacobs 	if (job_ticket != NULL) {
592264Sjacobs 		detailed_error(svc,
604390Sceastha 		    gettext("papiJobSubmit: job ticket not supported"));
612264Sjacobs 		return (PAPI_OPERATION_NOT_SUPPORTED);
622264Sjacobs 	}
632264Sjacobs 
642264Sjacobs 	if ((status = service_fill_in(svc, name)) != PAPI_OK)
652264Sjacobs 		return (status);
662264Sjacobs 
672264Sjacobs 	if ((*job = j = (job_t *)calloc(1, sizeof (*j))) == NULL) {
682264Sjacobs 		detailed_error(svc,
694390Sceastha 		    gettext("calloc() failed"));
702264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
712264Sjacobs 	}
722264Sjacobs 
73*9166SSonam.Gupta@Sun.COM 	/* before creating a control file add the job-name */
74*9166SSonam.Gupta@Sun.COM 	if ((files != NULL) && (files[0] != NULL))
75*9166SSonam.Gupta@Sun.COM 		papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL,
76*9166SSonam.Gupta@Sun.COM 		    "job-name", files[0]);
77*9166SSonam.Gupta@Sun.COM 
782264Sjacobs 	/* create a control file */
794390Sceastha 	(void) lpd_job_add_attributes(svc, attributes, &metadata,
804390Sceastha 	    &j->attributes);
814390Sceastha 
824390Sceastha 	if ((status = lpd_job_add_files(svc, attributes, files, &metadata,
834390Sceastha 	    &j->attributes)) != PAPI_OK) {
844390Sceastha 		return (status);
854390Sceastha 	}
862264Sjacobs 
872264Sjacobs 	/* send the job to the server */
882264Sjacobs 	status = lpd_submit_job(svc, metadata, &j->attributes, NULL);
892264Sjacobs 	free(metadata);
902264Sjacobs 
912264Sjacobs 	return (status);
922264Sjacobs 
932264Sjacobs }
942264Sjacobs 
952264Sjacobs 
962264Sjacobs papi_status_t
972264Sjacobs papiJobSubmitByReference(papi_service_t handle, char *name,
982264Sjacobs 		papi_attribute_t **job_attributes,
992264Sjacobs 		papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
1002264Sjacobs {
1012264Sjacobs 	return (papiJobSubmit(handle, name, job_attributes,
1024390Sceastha 	    job_ticket, files, job));
1032264Sjacobs }
1042264Sjacobs 
1052264Sjacobs papi_status_t
1062264Sjacobs papiJobStreamOpen(papi_service_t handle, char *name,
1072264Sjacobs 		papi_attribute_t **attributes,
1082264Sjacobs 		papi_job_ticket_t *job_ticket, papi_stream_t *stream)
1092264Sjacobs {
1102264Sjacobs 	papi_status_t status = PAPI_OK;
1112264Sjacobs 	service_t *svc = handle;
1122264Sjacobs 	char *metadata = NULL;
1132264Sjacobs 	stream_t *s = NULL;
1142264Sjacobs 
1152264Sjacobs 	if ((svc == NULL) || (name == NULL) || (stream == NULL))
1162264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1172264Sjacobs 
1182264Sjacobs 	if (job_ticket != NULL)
1192264Sjacobs 		return (PAPI_OPERATION_NOT_SUPPORTED);
1202264Sjacobs 
1212264Sjacobs 	if ((status = service_fill_in(svc, name)) != PAPI_OK)
1222264Sjacobs 		return (status);
1232264Sjacobs 
1242264Sjacobs 	/* create the stream container */
1252264Sjacobs 	if ((*stream = s = calloc(1, sizeof (*s))) == NULL)
1262264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
1272264Sjacobs 
1282264Sjacobs 	/* create the job */
1292264Sjacobs 	if ((s->job = calloc(1, sizeof (*(s->job)))) == NULL)
1302264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
1312264Sjacobs 
1322264Sjacobs 	/* process the attribute list */
1332264Sjacobs 	lpd_job_add_attributes(svc, attributes, &metadata, &s->job->attributes);
1342264Sjacobs 
1352264Sjacobs 	/* if we can stream, do it */
1362264Sjacobs 	if ((svc->uri->fragment != NULL) &&
1372264Sjacobs 	    (strcasecmp(svc->uri->fragment, "streaming") == 0)) {
1382264Sjacobs 		char *files[] = { "standard input", NULL };
1392264Sjacobs 
1402264Sjacobs 		lpd_job_add_files(svc, attributes, files, &metadata,
1414390Sceastha 		    &(s->job->attributes));
1422264Sjacobs 		status = lpd_submit_job(svc, metadata, &(s->job->attributes),
1434390Sceastha 		    &s->fd);
1442264Sjacobs 	} else {
1452264Sjacobs 		char dfname[18];
1462264Sjacobs 
1472264Sjacobs 		strcpy(dfname, "/tmp/stdin-XXXXX");
1482264Sjacobs 
1492264Sjacobs 		if ((s->fd = mkstemp(dfname)) >= 0)
1502264Sjacobs 			s->dfname = strdup(dfname);
1512264Sjacobs 	}
1522264Sjacobs 	s->metadata = metadata;
1532264Sjacobs 
1542264Sjacobs 	return (status);
1552264Sjacobs }
1562264Sjacobs 
1572264Sjacobs 
1582264Sjacobs papi_status_t
1592264Sjacobs papiJobStreamWrite(papi_service_t handle, papi_stream_t stream,
1602264Sjacobs 		void *buffer, size_t buflen)
1612264Sjacobs {
1622264Sjacobs 	service_t *svc = handle;
1632264Sjacobs 	stream_t *s = stream;
1642264Sjacobs 
1652264Sjacobs 	if ((svc == NULL) || (stream == NULL) || (buffer == NULL) ||
1662264Sjacobs 	    (buflen == 0))
1672264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1682264Sjacobs 
1692264Sjacobs 	if (write(s->fd, buffer, buflen) != buflen)
1702264Sjacobs 		return (PAPI_DEVICE_ERROR);
1712264Sjacobs 
1722264Sjacobs 	return (PAPI_OK);
1732264Sjacobs }
1742264Sjacobs 
1752264Sjacobs papi_status_t
1762264Sjacobs papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job)
1772264Sjacobs {
1782264Sjacobs 	papi_status_t status = PAPI_INTERNAL_ERROR;
1792264Sjacobs 	service_t *svc = handle;
1802264Sjacobs 	job_t *j = NULL;
1812264Sjacobs 	stream_t *s = stream;
1822264Sjacobs 	int ret;
1832264Sjacobs 
1842264Sjacobs 	if ((svc == NULL) || (stream == NULL) || (job == NULL))
1852264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1862264Sjacobs 
1872264Sjacobs 	close(s->fd);	/* close the stream */
1882264Sjacobs 
1892264Sjacobs 	if (s->dfname != NULL) {	/* if it is a tmpfile, print it */
1902264Sjacobs 		char *files[2];
1912264Sjacobs 
1922264Sjacobs 		files[0] = s->dfname;
1932264Sjacobs 		files[1] = NULL;
1942264Sjacobs 
1952264Sjacobs 		lpd_job_add_files(svc, s->job->attributes, files, &s->metadata,
1964390Sceastha 		    &(s->job->attributes));
1972264Sjacobs 		status = lpd_submit_job(svc, s->metadata,
1984390Sceastha 		    &(s->job->attributes), NULL);
1992264Sjacobs 		unlink(s->dfname);
2002264Sjacobs 		free(s->dfname);
2012264Sjacobs 	} else
2022264Sjacobs 		status = PAPI_OK;
2032264Sjacobs 
2042264Sjacobs 	if (s->metadata != NULL)
2052264Sjacobs 		free(s->metadata);
2062264Sjacobs 
2072264Sjacobs 	*job = s->job;
2082264Sjacobs 
2092264Sjacobs 	return (status);
2102264Sjacobs }
2112264Sjacobs 
2122264Sjacobs papi_status_t
2132264Sjacobs papiJobQuery(papi_service_t handle, char *name, int32_t job_id,
2142264Sjacobs 		char **job_attributes, papi_job_t *job)
2152264Sjacobs {
2162264Sjacobs 	papi_status_t status = PAPI_OK;
2172264Sjacobs 	service_t *svc = handle;
2182264Sjacobs 
2192264Sjacobs 	if ((svc == NULL) || (name == NULL) || job_id < 0)
2202264Sjacobs 		return (PAPI_BAD_ARGUMENT);
2212264Sjacobs 
2222264Sjacobs 	if ((status = service_fill_in(svc, name)) == PAPI_OK)
2232264Sjacobs 		status = lpd_find_job_info(svc, job_id, (job_t **)job);
2242264Sjacobs 
2252264Sjacobs 	return (status);
2262264Sjacobs }
2272264Sjacobs 
2282264Sjacobs papi_status_t
2292264Sjacobs papiJobCancel(papi_service_t handle, char *name, int32_t job_id)
2302264Sjacobs {
2312264Sjacobs 	papi_status_t status;
2322264Sjacobs 	service_t *svc = handle;
2332264Sjacobs 
2342264Sjacobs 	if ((svc == NULL) || (name == NULL) || (job_id < 0))
2352264Sjacobs 		return (PAPI_BAD_ARGUMENT);
2362264Sjacobs 
2372264Sjacobs 	if ((status = service_fill_in(svc, name)) == PAPI_OK)
2382264Sjacobs 		status = lpd_cancel_job(svc, job_id);
2392264Sjacobs 
2402264Sjacobs 	return (status);
2412264Sjacobs }
2422264Sjacobs 
2432264Sjacobs papi_attribute_t **
2442264Sjacobs papiJobGetAttributeList(papi_job_t job)
2452264Sjacobs {
2462264Sjacobs 	job_t *j = (job_t *)job;
2472264Sjacobs 
2482264Sjacobs 	if (j != NULL)
2492264Sjacobs 		return ((papi_attribute_t **)j->attributes);
2502264Sjacobs 
2512264Sjacobs 	return (NULL);
2522264Sjacobs }
2532264Sjacobs 
2542264Sjacobs char *
2552264Sjacobs papiJobGetPrinterName(papi_job_t job)
2562264Sjacobs {
2572264Sjacobs 	char *result = NULL;
2582264Sjacobs 	job_t *j = (job_t *)job;
2592264Sjacobs 
2602264Sjacobs 	if (j != NULL)
2612264Sjacobs 		papiAttributeListGetString(j->attributes, NULL,
2624390Sceastha 		    "printer-name", &result);
2632264Sjacobs 
2642264Sjacobs 	return (result);
2652264Sjacobs }
2662264Sjacobs 
2672264Sjacobs int
2682264Sjacobs papiJobGetId(papi_job_t job)
2692264Sjacobs {
2702264Sjacobs 	int result = -1;
2712264Sjacobs 	job_t *j = (job_t *)job;
2722264Sjacobs 
2732264Sjacobs 	if (j != NULL)
2742264Sjacobs 		papiAttributeListGetInteger(j->attributes, NULL,
2754390Sceastha 		    "job-id", &result);
2762264Sjacobs 
2772264Sjacobs 	return (result);
2782264Sjacobs }
2792264Sjacobs 
2802264Sjacobs void
2812264Sjacobs papiJobFree(papi_job_t job)
2822264Sjacobs {
2832264Sjacobs 	job_t *j = (job_t *)job;
2842264Sjacobs 
2852264Sjacobs 
2862264Sjacobs 	if (j != NULL) {
2872264Sjacobs 		papiAttributeListFree(j->attributes);
2882264Sjacobs 		free(j);
2892264Sjacobs 	}
2902264Sjacobs }
2912264Sjacobs 
2922264Sjacobs void
2932264Sjacobs papiJobListFree(papi_job_t *jobs)
2942264Sjacobs {
2952264Sjacobs 	if (jobs != NULL) {
2962264Sjacobs 		int i;
2972264Sjacobs 
2982264Sjacobs 		for (i = 0; jobs[i] != NULL; i++)
2992264Sjacobs 			papiJobFree(jobs[i]);
3002264Sjacobs 		free(jobs);
3012264Sjacobs 	}
3022264Sjacobs }
303