lpsched-jobs.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.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*LINTLIBRARY*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include <pwd.h>
/* lpsched include files */
#include "lp.h"
#include "requests.h"
#include "printers.h"
#include <papi_impl.h>
papi_status_t
job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
papi_attribute_t **attributes)
{
papi_status_t status = PAPI_OK;
papi_attribute_t *attr;
papi_attribute_t **unmapped = NULL;
int i;
char *s;
char **options = NULL;
char **modes = NULL;
char pr_filter = 0;
char *pr_title = NULL;
int pr_width = -1;
int pr_indent = -1;
int numberUp = 0;
int orientation = 0;
int lower = 0;
int upper = 0;
char buf[256];
void *iterator = NULL;
char *mapped_keys[] = { "copies", "document-format", "form",
"job-class", "job-hold-until", "job-host", "job-name",
"job-originating-user-name", "job-printer",
"job-sheets", "lp-charset", "lp-modes", "number-up",
"orienttation-requested", "page-ranges", "pr-filter",
"pr-indent", "pr-title", "pr-width", "priority",
"requesting-user-name", NULL };
if (attributes == NULL)
return (PAPI_BAD_ARGUMENT);
/* replace the current destination */
papiAttributeListGetLPString(attributes,
"job-printer", &r->destination);
/* set the copies. We need at least 1 */
i = r->copies;
papiAttributeListGetInteger(attributes, NULL, "copies", &i);
if (i <= 0)
i = 1;
r->copies = i;
/*
* set the priority. PAPI/IPP uses 1-100, lpsched use 0-39, so we
* have to convert it.
*/
if (papiAttributeListGetInteger(attributes, NULL, "priority", &i)
== PAPI_OK) {
if ((i < 1) || (i > 100))
i = 50;
i = (i + 1) / 2.5;
r->priority = i;
}
if ((r->priority < 0) || (r->priority > 39))
r->priority = 20;
/* set the requested form to print on */
papiAttributeListGetLPString(attributes, "form", &r->form);
/* set the page range */
#ifndef LP_USE_PAPI_ATTR
papiAttributeListGetLPString(attributes, "page-ranges", &r->pages);
#else
for (status = papiAttributeListGetRange(attributes, &iterator,
"page-ranges", &lower, &upper);
status == PAPI_OK;
status = papiAttributeListGetRange(attributes, &iterator,
"page-ranges", &lower, &upper)) {
if (r->pages != NULL) {
snprintf(buf, sizeof (buf), "%s,%d-%d",
r->pages, lower, upper);
free(r->pages);
} else
snprintf(buf, sizeof (buf), "%d-%d", lower, upper);
r->pages = (char *)strdup(buf);
}
#endif
/*
* set the document format, converting to old format names as
* as needed.
*/
s = NULL;
papiAttributeListGetString(attributes, NULL, "document-format", &s);
if (s != NULL)
r->input_type = strdup(mime_type_to_lp_type(s));
/*
* If we don't have an owner, set one.
*/
if (r->user == NULL) {
uid_t uid = getuid();
struct passwd *pw;
char *user = "intruder";
char *host = NULL;
char buf[256];
if ((pw = getpwuid(uid)) != NULL)
user = pw->pw_name; /* default to the process owner */
if ((uid == 0) || (uid == 71)) { /* root/lp can forge this */
papiAttributeListGetString(attributes, NULL,
"job-host", &host);
papiAttributeListGetString(attributes, NULL,
"job-originating-user-name", &user);
papiAttributeListGetString(attributes, NULL,
"requesting-user-name", &user);
snprintf(buf, sizeof (buf), "%s%s%s", user,
(host ? "@" : ""), (host ? host : ""));
user = buf;
}
r->user = strdup(user);
}
/* set any held state */
s = NULL;
papiAttributeListGetString(attributes, NULL, "job-hold-until", &s);
if (s != NULL) {
if (strcmp(s, "immediate") == 0)
r->actions |= ACT_IMMEDIATE;
else if ((strcmp(s, "resume") == 0) ||
(strcmp(s, "no-hold") == 0))
r->actions |= ACT_RESUME;
else if ((strcmp(s, "hold") == 0) ||
(strcmp(s, "indefinite") == 0))
r->actions |= ACT_HOLD;
}
/* set lp charset/printwheel */
papiAttributeListGetLPString(attributes, "lp-charset", &r->charset);
/* legacy pr(1) filter related garbage "lpr -p" */
papiAttributeListGetBoolean(attributes, NULL, "pr-filter", &pr_filter);
papiAttributeListGetString(attributes, NULL, "pr-title", &pr_title);
papiAttributeListGetInteger(attributes, NULL, "pr-width", &pr_width);
papiAttributeListGetInteger(attributes, NULL, "pr-indent", &pr_indent);
if (pr_filter != 0) {
char buf[128];
if (pr_title != NULL) {
snprintf(buf, sizeof (buf), "prtitle='%s'", pr_title);
appendlist(&modes, buf);
}
if (pr_width > 0) {
snprintf(buf, sizeof (buf), "prwidth=%d", pr_width);
appendlist(&modes, buf);
}
if (pr_indent > 0) {
snprintf(buf, sizeof (buf), "indent=%d", pr_indent);
appendlist(&modes, buf);
}
} else if ((pr_title != NULL) || (pr_width >= 0) || (pr_indent >= 0))
detailed_error(svc, gettext(
"pr(1) filter options specified without enabling pr(1) filter"));
/* add burst page information */
s = NULL;
papiAttributeListGetString(attributes, NULL, "job-sheets", &s);
if ((s != NULL) && (strcasecmp(s, "none") == 0)) {
char buf[128];
char *class = NULL;
char *job_name = NULL;
papiAttributeListGetLPString(attributes, "job-class", &class);
papiAttributeListGetLPString(attributes, "job-name", &job_name);
/* burst page is enabled by default, add the title */
snprintf(buf, sizeof (buf), "%s%s%s",
(job_name ? job_name : ""),
(job_name && class ? "\\n#####\\n#####\\t\\t " : ""),
(class ? class : ""));
if (buf[0] != '\0') {
if (r->title != NULL)
free(r->title);
r->title = strdup(buf);
}
} else /* burst page is disabled via lp "option" */
appendlist(&options, "nobanner");
/* Convert attribute "number-up" to mode group=n */
papiAttributeListGetInteger(attributes, NULL, "number-up", &numberUp);
if ((numberUp >= 2) && ((numberUp % 2) == 0)) {
snprintf(buf, sizeof (buf), "group=%d", numberUp);
appendlist(&modes, buf);
}
/*
* Convert attribute "orientation-requested" to modes
* 'landscape', 'portrait', etc.
*/
papiAttributeListGetInteger(attributes, NULL,
"orientation-requested", &orientation);
if ((orientation >= 3) && (orientation <= 6)) {
switch (orientation) {
case 4: /* landscape */
case 5: /* reverse-landscape, use landscape instead */
appendlist(&modes, "landscape");
break;
case 3: /* portrait */
case 6: /* reverse-portrait, use portrait instead */
default:
appendlist(&modes, "portrait");
break;
}
}
/* add "lp -y" modes */
attr = papiAttributeListFind(attributes, "lp-modes");
if ((attr != NULL) && (attr->type == PAPI_STRING) &&
(attr->values != NULL)) {
int i;
for (i = 0; attr->values[i] != NULL; i++)
appendlist(&modes, attr->values[i]->string);
}
if (modes != NULL) {
if (r->modes == NULL)
free(r->modes);
r->modes = sprintlist(modes);
freelist(modes);
}
/* add any unconsumed attributes to the "options" list */
split_and_copy_attributes(mapped_keys, attributes, NULL, &unmapped);
if (unmapped != NULL) { /* convert them to lp options */
char *buf = malloc(1024);
ssize_t size = 1024;
while (papiAttributeListToString(unmapped, ", ", buf, size)
!= PAPI_OK) {
size += 1024;
buf = realloc(buf, size);
}
appendlist(&options, buf);
free(buf);
papiAttributeListFree(unmapped);
}
if (options != NULL) {
if (r->options != NULL)
free(r->options);
r->options = sprintlist(options);
freelist(options);
}
return (PAPI_OK);
}
/*
* Convert REQUEST->outcome (or R_REQUEST_* state) to the equivalent
* PAPI attribute representation.
*/
static void
lpsched_request_outcome_to_attributes(papi_attribute_t ***attributes,
unsigned short state)
{
if (attributes == NULL)
return;
if (state & (RS_HELD|RS_ADMINHELD)) {
papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
"job-state", 0x04); /* held */
papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
"job-state-reasons", "job-hold-until-specified");
} else if (state & RS_ACTIVE) {
papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
"job-state", 0x05);
if (state & RS_FILTERING)
papiAttributeListAddString(attributes,
PAPI_ATTR_REPLACE,
"job-state-reasons", "job-transforming");
else if (state & RS_PRINTING)
papiAttributeListAddString(attributes,
PAPI_ATTR_REPLACE,
"job-state-reasons", "job-printing");
else
papiAttributeListAddString(attributes,
PAPI_ATTR_REPLACE,
"job-state-reasons", "job-processing");
} else if (state & RS_CANCELLED) {
papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
"job-state", 0x07);
papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
"job-state-reasons", "job-canceled-by-user");
} else if (state & RS_PRINTED) {
papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
"job-state", 0x09);
papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
"job-state-reasons", "job-complete");
} else {
papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
"job-state", 0x03);
papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
"job-state-reasons", "job-queued");
}
papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
"job-hold-until",
((state & RS_HELD) ? "indefinite" : "no-hold"));
}
/*
* Convert REQUEST structure to the equivalent PAPI attribute representation.
*/
void
lpsched_request_to_job_attributes(REQUEST *r, job_t *j)
{
char *tmp;
int i;
/* copies */
papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
"copies", r->copies);
/* destination */
papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
"printer-name", r->destination);
/* form */
papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
"form", r->form);
/* options */
papiAttributeListFromString(&j->attributes, PAPI_ATTR_APPEND,
r->options);
tmp = (((r->options != NULL) && (strstr(r->options, "nobanner")
!= NULL)) ? "none" : "standard");
papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE,
"job-sheets", tmp);
tmp = (((r->options != NULL) && (strstr(r->options, "duplex")
!= NULL)) ? "two-sized" : "one-sided");
papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE,
"sides", tmp);
i = (((r->options != NULL) && (strstr(r->options, "landscape")
!= NULL)) ? 4 : 3);
papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
"orientation-requested", i);
/* priority (map 0-39 to 1-100) */
papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
"job-priority", (int)((r->priority + 1) * 2.5));
/* pages */
papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
"page-ranges", r->pages);
/* charset */
papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
"lp-charset", r->charset);
/* modes */
papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
"lp-modes", r->modes);
/* title */
papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
"job-name", r->title);
/* input_type */
/* user */
papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
"job-originating-user-name", r->user);
/* outcome */
lpsched_request_outcome_to_attributes(&j->attributes, r->outcome);
/* constants, (should be derived from options) */
papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
"number-up", 1);
papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE,
"multiple-document-handling",
"seperate-documents-collated-copies");
}
/*
* Convert R_REQUEST_* results to the equivalent PAPI attribute representation.
*/
void
job_status_to_attributes(job_t *job, char *req_id, char *user, char *slabel,
size_t size, time_t date, short state, char *destination,
char *form, char *charset, short rank, char *file)
{
char buf[BUFSIZ];
char *p;
papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE,
"job-originating-user-name", user);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"job-k-octets", size/1024);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"job-octets", size);
if ((p = strrchr(req_id, '-')) != NULL) {
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"job-id", atoi(++p));
}
snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s/%d",
destination, atoi(p));
papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
"job-uri", buf);
snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s",
destination);
papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
"job-printer-uri", buf);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"job-printer-up-time", time(NULL));
papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
"output-device-assigned", destination);
papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
"printer-name", destination);
papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE,
"form", form);
lpsched_request_outcome_to_attributes(&job->attributes, state);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"time-at-creation", date);
papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE,
"lpsched-request-id", req_id);
papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE,
"lp-charset", charset);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"lpsched-job-state", state);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"number-of-intervening-jobs", rank - 1);
papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE,
"lpsched-file", file);
papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_EXCL,
"job-name", file);
papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_EXCL,
"tsol-sensitivity-label", slabel);
}
void
lpsched_read_job_configuration(service_t *svc, job_t *j, char *file)
{
REQUEST *r;
if ((r = getrequest(file)) == NULL) {
detailed_error(svc, gettext("unable to read job data: %s"),
file);
return;
}
lpsched_request_to_job_attributes(r, j);
}