cancel_job.c revision 45916cd2fec6e79bca5dee0421bd39e3c2910d1e
/*
* 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"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/systeminfo.h>
#include <string.h>
#include <libintl.h>
#include <netdb.h>
#include <syslog.h>
/* lpsched include files */
#include "lp.h"
#include "msgs.h"
#include "printers.h"
#include "class.h"
#include "misc.h"
/* print NS include */
#include <print/ns.h>
static char *
cancel_requestor(const char *printer, const char *user, const char *host)
{
static char buf[BUFSIZ]; /* This is larger than necessary */
char *tmp, *s;
ns_printer_t *pobj;
if (((pobj = ns_printer_get_name(printer, NULL)) != NULL) &&
((tmp = ns_get_value_string("user-equivalence", pobj)) != NULL) &&
(strcasecmp(tmp, "true") == 0) && ((strcmp(user, "root") != 0) ||
(strcmp(user, "lp") != 0)))
host = "all";
tmp = strdup(user);
while ((s = strpbrk(tmp, "()")) != NULL)
*s = '_';
user = tmp;
if ((strcmp(user, "root") == 0) || (strcmp(user, "lp") == 0)) {
user = "all"; /* root/lp can cancel any request */
if (strcmp(host, "all") != 0) {
char thost[MAXHOSTNAMELEN];
sysinfo(SI_HOSTNAME, thost, sizeof (thost));
if ((strcasecmp(host, thost) == 0) ||
((strcasecmp(host, "localhost") == 0)))
host = "all"; /* cancel from anywhere */
}
}
snprintf(buf, sizeof (buf), "%s@%s", user, host);
return (buf);
}
/*
* lpsched_cancel_job() attempts to cancel an lpsched requests that match the
* passed in criteria. a message is written for each cancelation or
* attempted cancelation
*/
int
lpsched_cancel_job(const char *printer, FILE *ofp, const char *requestor,
const char *host, const char **list)
{
short status;
char **job_list = NULL;
char *cancel_name;
int first_job_only = 0;
syslog(LOG_DEBUG, "cancel_job(%s, %d, %s, %s, 0x%x)",
(printer ? printer : "NULL"), ofp, requestor, host, list);
if ((printer == NULL) || (requestor == NULL) || (host == NULL) ||
(list == NULL))
return (-1);
/* if list is empty, then cancel only the first job */
if ((*list == NULL) && (strcmp(requestor, "-all") != 0))
first_job_only = 1;
if (!isprinter((char *)printer) && !isclass((char *)printer)) {
fprintf(ofp, gettext("unknown printer/class"));
return (-1);
}
if (snd_msg(S_INQUIRE_REQUEST, "", printer, "", "", "") < 0) {
fprintf(ofp, gettext("Failure to communicate with lpsched\n"));
return (-1);
}
do {
size_t size;
time_t date;
short outcome;
char *dest, *slabel, *form, *pwheel, *file, *owner, *reqid;
const char **list_ptr = list;
char buf[BUFSIZ];
if (rcv_msg(R_INQUIRE_REQUEST, &status, &reqid, &owner, &slabel,
&size, &date, &outcome, &dest, &form, &pwheel,
&file) < 0) {
fprintf(ofp,
gettext("Failure to communicate with lpsched\n"));
return (-1);
}
switch (status) {
case MOK:
case MOKMORE:
/*
* if cancelling only the fist job, then add
* the first job to job_list and increment
* first_job_only so no more jobs get added
*/
if (first_job_only == 1) {
snprintf(buf, sizeof (buf), "%s %s", owner,
reqid);
appendlist(&job_list, buf);
first_job_only++;
break;
} else if (first_job_only > 1)
break;
if (strcasecmp(requestor, "-all") == 0) {
snprintf(buf, sizeof (buf), "%s %s", owner,
reqid);
appendlist(&job_list, buf);
break;
}
while ((list_ptr != NULL) && (*list_ptr != NULL)) {
char *user = (char *)user_name(owner);
int rid = id_no(reqid);
int id = atoi(*list_ptr++);
if ((rid == id) ||
(strcmp(user, list_ptr[-1]) == 0)) {
snprintf(buf, sizeof (buf), "%s %s",
owner, reqid);
appendlist(&job_list, buf);
}
}
break;
default:
break;
}
} while (status == MOKMORE);
if (strcasecmp(requestor, "-all") == 0)
requestor = "root";
cancel_name = cancel_requestor(printer, requestor, host);
while ((job_list != NULL) && (*job_list != NULL)) {
char *user = strtok(*job_list, " ");
char *reqid = strtok(NULL, " ");
syslog(LOG_DEBUG,
"cancel %s, owned by %s, on %s, requested by %s\n",
reqid, user, printer, cancel_name);
if (snd_msg(S_CANCEL, printer, cancel_name, reqid) < 0) {
fprintf(ofp,
gettext("Failure to communicate with lpsched\n"));
return (-1);
}
do {
int status2;
char *job_name = "unknown";
if (rcv_msg(R_CANCEL, &status, &status2,
&job_name) < 0) {
fprintf(ofp,
gettext("Failure to communicate with lpsched\n"));
return (-1);
}
switch (status2) {
case MOK:
case MOKMORE:
fprintf(ofp, gettext("%s: cancelled\n"),
job_name);
break;
case MUNKNOWN:
case MNOPERM:
fprintf(ofp, gettext("%s: permission denied\n"),
reqid);
break;
break;
case M2LATE:
fprintf(ofp, gettext("cannot dequeue %s\n"),
job_name);
break;
default:
fprintf(ofp,
gettext("%s: cancel failed (%d)\n"),
reqid, status2);
break;
}
} while (status == MOKMORE);
job_list++;
}
return (0);
}