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 /*
239166SSonam.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 
739166SSonam.Gupta@Sun.COM 	/* before creating a control file add the job-name */
749166SSonam.Gupta@Sun.COM 	if ((files != NULL) && (files[0] != NULL))
759166SSonam.Gupta@Sun.COM 		papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL,
769166SSonam.Gupta@Sun.COM 		    "job-name", files[0]);
779166SSonam.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];
146*9410SKeerthi.Kondaka@Sun.COM 		char buf[256];
1472264Sjacobs 
1482264Sjacobs 		strcpy(dfname, "/tmp/stdin-XXXXX");
1492264Sjacobs 
1502264Sjacobs 		if ((s->fd = mkstemp(dfname)) >= 0)
1512264Sjacobs 			s->dfname = strdup(dfname);
152*9410SKeerthi.Kondaka@Sun.COM 		if (s->job->attributes)
153*9410SKeerthi.Kondaka@Sun.COM 			papiAttributeListFree(s->job->attributes);
154*9410SKeerthi.Kondaka@Sun.COM 		s->job->attributes = NULL;
155*9410SKeerthi.Kondaka@Sun.COM 		papiAttributeListToString(attributes, " ", buf, sizeof (buf));
156*9410SKeerthi.Kondaka@Sun.COM 		papiAttributeListFromString(&(s->job->attributes),
157*9410SKeerthi.Kondaka@Sun.COM 		    PAPI_ATTR_APPEND, buf);
1582264Sjacobs 	}
1592264Sjacobs 	s->metadata = metadata;
1602264Sjacobs 
1612264Sjacobs 	return (status);
1622264Sjacobs }
1632264Sjacobs 
1642264Sjacobs 
1652264Sjacobs papi_status_t
1662264Sjacobs papiJobStreamWrite(papi_service_t handle, papi_stream_t stream,
1672264Sjacobs 		void *buffer, size_t buflen)
1682264Sjacobs {
1692264Sjacobs 	service_t *svc = handle;
1702264Sjacobs 	stream_t *s = stream;
1712264Sjacobs 
1722264Sjacobs 	if ((svc == NULL) || (stream == NULL) || (buffer == NULL) ||
1732264Sjacobs 	    (buflen == 0))
1742264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1752264Sjacobs 
1762264Sjacobs 	if (write(s->fd, buffer, buflen) != buflen)
1772264Sjacobs 		return (PAPI_DEVICE_ERROR);
1782264Sjacobs 
1792264Sjacobs 	return (PAPI_OK);
1802264Sjacobs }
1812264Sjacobs 
1822264Sjacobs papi_status_t
1832264Sjacobs papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job)
1842264Sjacobs {
1852264Sjacobs 	papi_status_t status = PAPI_INTERNAL_ERROR;
1862264Sjacobs 	service_t *svc = handle;
1872264Sjacobs 	job_t *j = NULL;
1882264Sjacobs 	stream_t *s = stream;
1892264Sjacobs 	int ret;
1902264Sjacobs 
1912264Sjacobs 	if ((svc == NULL) || (stream == NULL) || (job == NULL))
1922264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1932264Sjacobs 
1942264Sjacobs 	close(s->fd);	/* close the stream */
1952264Sjacobs 
1962264Sjacobs 	if (s->dfname != NULL) {	/* if it is a tmpfile, print it */
1972264Sjacobs 		char *files[2];
1982264Sjacobs 
1992264Sjacobs 		files[0] = s->dfname;
2002264Sjacobs 		files[1] = NULL;
2012264Sjacobs 
2022264Sjacobs 		lpd_job_add_files(svc, s->job->attributes, files, &s->metadata,
2034390Sceastha 		    &(s->job->attributes));
2042264Sjacobs 		status = lpd_submit_job(svc, s->metadata,
2054390Sceastha 		    &(s->job->attributes), NULL);
2062264Sjacobs 		unlink(s->dfname);
2072264Sjacobs 		free(s->dfname);
2082264Sjacobs 	} else
2092264Sjacobs 		status = PAPI_OK;
2102264Sjacobs 
2112264Sjacobs 	if (s->metadata != NULL)
2122264Sjacobs 		free(s->metadata);
2132264Sjacobs 
2142264Sjacobs 	*job = s->job;
2152264Sjacobs 
2162264Sjacobs 	return (status);
2172264Sjacobs }
2182264Sjacobs 
2192264Sjacobs papi_status_t
2202264Sjacobs papiJobQuery(papi_service_t handle, char *name, int32_t job_id,
2212264Sjacobs 		char **job_attributes, papi_job_t *job)
2222264Sjacobs {
2232264Sjacobs 	papi_status_t status = PAPI_OK;
2242264Sjacobs 	service_t *svc = handle;
2252264Sjacobs 
2262264Sjacobs 	if ((svc == NULL) || (name == NULL) || job_id < 0)
2272264Sjacobs 		return (PAPI_BAD_ARGUMENT);
2282264Sjacobs 
2292264Sjacobs 	if ((status = service_fill_in(svc, name)) == PAPI_OK)
2302264Sjacobs 		status = lpd_find_job_info(svc, job_id, (job_t **)job);
2312264Sjacobs 
2322264Sjacobs 	return (status);
2332264Sjacobs }
2342264Sjacobs 
2352264Sjacobs papi_status_t
2362264Sjacobs papiJobCancel(papi_service_t handle, char *name, int32_t job_id)
2372264Sjacobs {
2382264Sjacobs 	papi_status_t status;
2392264Sjacobs 	service_t *svc = handle;
2402264Sjacobs 
2412264Sjacobs 	if ((svc == NULL) || (name == NULL) || (job_id < 0))
2422264Sjacobs 		return (PAPI_BAD_ARGUMENT);
2432264Sjacobs 
2442264Sjacobs 	if ((status = service_fill_in(svc, name)) == PAPI_OK)
2452264Sjacobs 		status = lpd_cancel_job(svc, job_id);
2462264Sjacobs 
2472264Sjacobs 	return (status);
2482264Sjacobs }
2492264Sjacobs 
2502264Sjacobs papi_attribute_t **
2512264Sjacobs papiJobGetAttributeList(papi_job_t job)
2522264Sjacobs {
2532264Sjacobs 	job_t *j = (job_t *)job;
2542264Sjacobs 
2552264Sjacobs 	if (j != NULL)
2562264Sjacobs 		return ((papi_attribute_t **)j->attributes);
2572264Sjacobs 
2582264Sjacobs 	return (NULL);
2592264Sjacobs }
2602264Sjacobs 
2612264Sjacobs char *
2622264Sjacobs papiJobGetPrinterName(papi_job_t job)
2632264Sjacobs {
2642264Sjacobs 	char *result = NULL;
2652264Sjacobs 	job_t *j = (job_t *)job;
2662264Sjacobs 
2672264Sjacobs 	if (j != NULL)
2682264Sjacobs 		papiAttributeListGetString(j->attributes, NULL,
2694390Sceastha 		    "printer-name", &result);
2702264Sjacobs 
2712264Sjacobs 	return (result);
2722264Sjacobs }
2732264Sjacobs 
2742264Sjacobs int
2752264Sjacobs papiJobGetId(papi_job_t job)
2762264Sjacobs {
2772264Sjacobs 	int result = -1;
2782264Sjacobs 	job_t *j = (job_t *)job;
2792264Sjacobs 
2802264Sjacobs 	if (j != NULL)
2812264Sjacobs 		papiAttributeListGetInteger(j->attributes, NULL,
2824390Sceastha 		    "job-id", &result);
2832264Sjacobs 
2842264Sjacobs 	return (result);
2852264Sjacobs }
2862264Sjacobs 
2872264Sjacobs void
2882264Sjacobs papiJobFree(papi_job_t job)
2892264Sjacobs {
2902264Sjacobs 	job_t *j = (job_t *)job;
2912264Sjacobs 
2922264Sjacobs 
2932264Sjacobs 	if (j != NULL) {
2942264Sjacobs 		papiAttributeListFree(j->attributes);
2952264Sjacobs 		free(j);
2962264Sjacobs 	}
2972264Sjacobs }
2982264Sjacobs 
2992264Sjacobs void
3002264Sjacobs papiJobListFree(papi_job_t *jobs)
3012264Sjacobs {
3022264Sjacobs 	if (jobs != NULL) {
3032264Sjacobs 		int i;
3042264Sjacobs 
3052264Sjacobs 		for (i = 0; jobs[i] != NULL; i++)
3062264Sjacobs 			papiJobFree(jobs[i]);
3072264Sjacobs 		free(jobs);
3082264Sjacobs 	}
3092264Sjacobs }
310