job.c revision 355b4669e025ff377602b6fc7caaf30dbc218371
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*/
/* $Id: job.c 155 2006-04-26 02:34:54Z ktou $ */
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include <libintl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <papi_impl.h>
#include <uri.h>
/*
* must copy files before leaving routine
*/
papi_status_t
papiJobSubmit(papi_service_t handle, char *name, papi_attribute_t **attributes,
papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
{
papi_status_t status = PAPI_OK;
service_t *svc = handle;
job_t *j = NULL;
char *metadata = NULL;
if ((svc == NULL) || (name == NULL) || (files == NULL) ||
(job == NULL))
return (PAPI_BAD_ARGUMENT);
if (job_ticket != NULL) {
detailed_error(svc,
gettext("papiJobSubmit: job ticket not supported"));
return (PAPI_OPERATION_NOT_SUPPORTED);
}
if ((status = service_fill_in(svc, name)) != PAPI_OK)
return (status);
if ((*job = j = (job_t *)calloc(1, sizeof (*j))) == NULL) {
detailed_error(svc,
gettext("calloc() failed"));
return (PAPI_TEMPORARY_ERROR);
}
/* create a control file */
status = lpd_job_add_attributes(svc, attributes, &metadata,
&j->attributes);
status = lpd_job_add_files(svc, attributes, files, &metadata,
&j->attributes);
/* send the job to the server */
status = lpd_submit_job(svc, metadata, &j->attributes, NULL);
free(metadata);
return (status);
}
papi_status_t
papiJobSubmitByReference(papi_service_t handle, char *name,
papi_attribute_t **job_attributes,
papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
{
return (papiJobSubmit(handle, name, job_attributes,
job_ticket, files, job));
}
papi_status_t
papiJobStreamOpen(papi_service_t handle, char *name,
papi_attribute_t **attributes,
papi_job_ticket_t *job_ticket, papi_stream_t *stream)
{
papi_status_t status = PAPI_OK;
service_t *svc = handle;
char *metadata = NULL;
stream_t *s = NULL;
if ((svc == NULL) || (name == NULL) || (stream == NULL))
return (PAPI_BAD_ARGUMENT);
if (job_ticket != NULL)
return (PAPI_OPERATION_NOT_SUPPORTED);
if ((status = service_fill_in(svc, name)) != PAPI_OK)
return (status);
/* create the stream container */
if ((*stream = s = calloc(1, sizeof (*s))) == NULL)
return (PAPI_TEMPORARY_ERROR);
/* create the job */
if ((s->job = calloc(1, sizeof (*(s->job)))) == NULL)
return (PAPI_TEMPORARY_ERROR);
/* process the attribute list */
lpd_job_add_attributes(svc, attributes, &metadata, &s->job->attributes);
/* if we can stream, do it */
if ((svc->uri->fragment != NULL) &&
(strcasecmp(svc->uri->fragment, "streaming") == 0)) {
char *files[] = { "standard input", NULL };
lpd_job_add_files(svc, attributes, files, &metadata,
&(s->job->attributes));
status = lpd_submit_job(svc, metadata, &(s->job->attributes),
&s->fd);
} else {
char dfname[18];
strcpy(dfname, "/tmp/stdin-XXXXX");
if ((s->fd = mkstemp(dfname)) >= 0)
s->dfname = strdup(dfname);
s->job->attributes = attributes;
}
s->metadata = metadata;
return (status);
}
papi_status_t
papiJobStreamWrite(papi_service_t handle, papi_stream_t stream,
void *buffer, size_t buflen)
{
service_t *svc = handle;
stream_t *s = stream;
if ((svc == NULL) || (stream == NULL) || (buffer == NULL) ||
(buflen == 0))
return (PAPI_BAD_ARGUMENT);
if (write(s->fd, buffer, buflen) != buflen)
return (PAPI_DEVICE_ERROR);
return (PAPI_OK);
}
papi_status_t
papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job)
{
papi_status_t status = PAPI_INTERNAL_ERROR;
service_t *svc = handle;
job_t *j = NULL;
stream_t *s = stream;
int ret;
if ((svc == NULL) || (stream == NULL) || (job == NULL))
return (PAPI_BAD_ARGUMENT);
close(s->fd); /* close the stream */
if (s->dfname != NULL) { /* if it is a tmpfile, print it */
char *files[2];
files[0] = s->dfname;
files[1] = NULL;
lpd_job_add_files(svc, s->job->attributes, files, &s->metadata,
&(s->job->attributes));
status = lpd_submit_job(svc, s->metadata,
&(s->job->attributes), NULL);
unlink(s->dfname);
free(s->dfname);
} else
status = PAPI_OK;
if (s->metadata != NULL)
free(s->metadata);
*job = s->job;
return (status);
}
papi_status_t
papiJobQuery(papi_service_t handle, char *name, int32_t job_id,
char **job_attributes, papi_job_t *job)
{
papi_status_t status = PAPI_OK;
service_t *svc = handle;
if ((svc == NULL) || (name == NULL) || job_id < 0)
return (PAPI_BAD_ARGUMENT);
if ((status = service_fill_in(svc, name)) == PAPI_OK)
status = lpd_find_job_info(svc, job_id, (job_t **)job);
return (status);
}
papi_status_t
papiJobCancel(papi_service_t handle, char *name, int32_t job_id)
{
papi_status_t status;
service_t *svc = handle;
if ((svc == NULL) || (name == NULL) || (job_id < 0))
return (PAPI_BAD_ARGUMENT);
if ((status = service_fill_in(svc, name)) == PAPI_OK)
status = lpd_cancel_job(svc, job_id);
return (status);
}
papi_attribute_t **
papiJobGetAttributeList(papi_job_t job)
{
job_t *j = (job_t *)job;
if (j != NULL)
return ((papi_attribute_t **)j->attributes);
return (NULL);
}
char *
papiJobGetPrinterName(papi_job_t job)
{
char *result = NULL;
job_t *j = (job_t *)job;
if (j != NULL)
papiAttributeListGetString(j->attributes, NULL,
"printer-name", &result);
return (result);
}
int
papiJobGetId(papi_job_t job)
{
int result = -1;
job_t *j = (job_t *)job;
if (j != NULL)
papiAttributeListGetInteger(j->attributes, NULL,
"job-id", &result);
return (result);
}
void
papiJobFree(papi_job_t job)
{
job_t *j = (job_t *)job;
if (j != NULL) {
papiAttributeListFree(j->attributes);
free(j);
}
}
void
papiJobListFree(papi_job_t *jobs)
{
if (jobs != NULL) {
int i;
for (i = 0; jobs[i] != NULL; i++)
papiJobFree(jobs[i]);
free(jobs);
}
}