10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * 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.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
213125Sjacobs
220Sstevel@tonic-gate /*
23*9376SGowtham.Thommandra@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate
280Sstevel@tonic-gate /*LINTLIBRARY*/
290Sstevel@tonic-gate
300Sstevel@tonic-gate #include <stdio.h>
310Sstevel@tonic-gate #include <stdarg.h>
320Sstevel@tonic-gate #include <libintl.h>
330Sstevel@tonic-gate #include <string.h>
340Sstevel@tonic-gate #include <stdlib.h>
352264Sjacobs #include <errno.h>
360Sstevel@tonic-gate
370Sstevel@tonic-gate
380Sstevel@tonic-gate /* lpsched include files */
390Sstevel@tonic-gate #include "lp.h"
400Sstevel@tonic-gate #include "msgs.h"
410Sstevel@tonic-gate #include "printers.h"
422264Sjacobs #include "class.h"
430Sstevel@tonic-gate
440Sstevel@tonic-gate #include <papi_impl.h>
450Sstevel@tonic-gate
460Sstevel@tonic-gate
470Sstevel@tonic-gate /*
480Sstevel@tonic-gate * Format and send message to lpsched (die if any errors occur)
490Sstevel@tonic-gate */
500Sstevel@tonic-gate /*VARARGS1*/
510Sstevel@tonic-gate int
snd_msg(service_t * svc,int type,...)520Sstevel@tonic-gate snd_msg(service_t *svc, int type, ...)
530Sstevel@tonic-gate {
540Sstevel@tonic-gate int rc = -1;
550Sstevel@tonic-gate va_list ap;
560Sstevel@tonic-gate
570Sstevel@tonic-gate if (svc == NULL)
580Sstevel@tonic-gate return (-1);
590Sstevel@tonic-gate
600Sstevel@tonic-gate /* fill the message buffer */
610Sstevel@tonic-gate va_start(ap, type);
620Sstevel@tonic-gate rc = _putmessage(svc->msgbuf, type, ap);
630Sstevel@tonic-gate va_end(ap);
640Sstevel@tonic-gate if (rc < 0) {
650Sstevel@tonic-gate detailed_error(svc,
66*9376SGowtham.Thommandra@Sun.COM gettext("unable to build message for scheduler: %s"),
67*9376SGowtham.Thommandra@Sun.COM strerror(errno));
680Sstevel@tonic-gate return (rc);
690Sstevel@tonic-gate }
700Sstevel@tonic-gate
710Sstevel@tonic-gate /* write the message */
72*9376SGowtham.Thommandra@Sun.COM while (((rc = mwrite(svc->md, svc->msgbuf)) < 0) && (errno == EINTR)) {
73*9376SGowtham.Thommandra@Sun.COM }
740Sstevel@tonic-gate
750Sstevel@tonic-gate if (rc < 0)
760Sstevel@tonic-gate detailed_error(svc,
77*9376SGowtham.Thommandra@Sun.COM gettext("unable to send message to scheduler: %s"),
78*9376SGowtham.Thommandra@Sun.COM strerror(errno));
790Sstevel@tonic-gate return (rc);
800Sstevel@tonic-gate }
810Sstevel@tonic-gate
820Sstevel@tonic-gate /*
830Sstevel@tonic-gate * Receive message from lpsched (die if any errors occur)
840Sstevel@tonic-gate */
850Sstevel@tonic-gate int
rcv_msg(service_t * svc,int type,...)860Sstevel@tonic-gate rcv_msg(service_t *svc, int type, ...)
870Sstevel@tonic-gate {
880Sstevel@tonic-gate int rc = -1;
890Sstevel@tonic-gate
900Sstevel@tonic-gate if (svc == NULL)
910Sstevel@tonic-gate return (-1);
920Sstevel@tonic-gate
930Sstevel@tonic-gate /* read the message */
940Sstevel@tonic-gate while (((rc = mread(svc->md, svc->msgbuf, svc->msgbuf_size)) < 0) &&
95*9376SGowtham.Thommandra@Sun.COM (errno == EINTR)) {
96*9376SGowtham.Thommandra@Sun.COM }
970Sstevel@tonic-gate
980Sstevel@tonic-gate if (rc < 0)
990Sstevel@tonic-gate detailed_error(svc,
100*9376SGowtham.Thommandra@Sun.COM gettext("unable to read message from scheduler: %s"),
101*9376SGowtham.Thommandra@Sun.COM strerror(errno));
1020Sstevel@tonic-gate else {
1030Sstevel@tonic-gate va_list ap;
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate va_start(ap, type);
1060Sstevel@tonic-gate rc = _getmessage(svc->msgbuf, type, ap);
1070Sstevel@tonic-gate va_end(ap);
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate if (rc < 0)
1100Sstevel@tonic-gate detailed_error(svc,
1110Sstevel@tonic-gate gettext("unable to parse message from scheduler: %s"),
112*9376SGowtham.Thommandra@Sun.COM strerror(errno));
1130Sstevel@tonic-gate }
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate return (rc);
1160Sstevel@tonic-gate }
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate papi_status_t
lpsched_status_to_papi_status(int status)1190Sstevel@tonic-gate lpsched_status_to_papi_status(int status)
1200Sstevel@tonic-gate {
1210Sstevel@tonic-gate switch (status) {
1220Sstevel@tonic-gate case MNOMEM:
1230Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR);
1240Sstevel@tonic-gate case MNOFILTER:
1250Sstevel@tonic-gate return (PAPI_DOCUMENT_FORMAT_ERROR);
1260Sstevel@tonic-gate case MNOOPEN:
1270Sstevel@tonic-gate return (PAPI_DOCUMENT_ACCESS_ERROR);
1280Sstevel@tonic-gate case MERRDEST:
1290Sstevel@tonic-gate case MDENYDEST:
1300Sstevel@tonic-gate return (PAPI_NOT_ACCEPTING);
1310Sstevel@tonic-gate case MNOMEDIA:
1320Sstevel@tonic-gate return (PAPI_PRINT_SUPPORT_FILE_NOT_FOUND);
1330Sstevel@tonic-gate case MDENYMEDIA:
1340Sstevel@tonic-gate case MNOPERM:
1350Sstevel@tonic-gate return (PAPI_NOT_AUTHORIZED);
1360Sstevel@tonic-gate case MUNKNOWN:
1370Sstevel@tonic-gate case MNODEST:
1380Sstevel@tonic-gate case MNOINFO:
1390Sstevel@tonic-gate return (PAPI_NOT_FOUND);
1400Sstevel@tonic-gate case MTRANSMITERR:
1410Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE);
1420Sstevel@tonic-gate case M2LATE:
1430Sstevel@tonic-gate return (PAPI_GONE);
1442264Sjacobs case MBUSY:
1452264Sjacobs return (PAPI_PRINTER_BUSY);
1460Sstevel@tonic-gate case MOK:
1470Sstevel@tonic-gate case MOKMORE:
1480Sstevel@tonic-gate return (PAPI_OK);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate return (PAPI_INTERNAL_ERROR);
1520Sstevel@tonic-gate }
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate char *
lpsched_status_string(short status)1550Sstevel@tonic-gate lpsched_status_string(short status)
1560Sstevel@tonic-gate {
1570Sstevel@tonic-gate switch (status) {
1580Sstevel@tonic-gate case MNOMEM:
1590Sstevel@tonic-gate return (gettext("lpsched: out of memory"));
1600Sstevel@tonic-gate case MNOFILTER:
1610Sstevel@tonic-gate return (gettext("No filter available to convert job"));
1620Sstevel@tonic-gate case MNOOPEN:
1630Sstevel@tonic-gate return (gettext("lpsched: could not open request"));
1640Sstevel@tonic-gate case MERRDEST:
1653125Sjacobs return (gettext("queue disabled"));
1660Sstevel@tonic-gate case MDENYDEST:
1670Sstevel@tonic-gate return (gettext("destination denied request"));
1680Sstevel@tonic-gate case MNOMEDIA:
1690Sstevel@tonic-gate return (gettext("unknown form specified in job"));
1700Sstevel@tonic-gate case MDENYMEDIA:
1710Sstevel@tonic-gate return (gettext("access denied to form specified in job"));
1720Sstevel@tonic-gate case MUNKNOWN:
1730Sstevel@tonic-gate return (gettext("no such resource"));
1740Sstevel@tonic-gate case MNODEST:
1750Sstevel@tonic-gate return (gettext("unknown destination"));
1760Sstevel@tonic-gate case MNOPERM:
1770Sstevel@tonic-gate return (gettext("permission denied"));
1780Sstevel@tonic-gate case MNOINFO:
1790Sstevel@tonic-gate return (gettext("no information available"));
1800Sstevel@tonic-gate case MTRANSMITERR:
1810Sstevel@tonic-gate return (gettext("failure to communicate with lpsched"));
1820Sstevel@tonic-gate default: {
1830Sstevel@tonic-gate static char result[16];
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate snprintf(result, sizeof (result), gettext("status: %d"),
186*9376SGowtham.Thommandra@Sun.COM status);
1870Sstevel@tonic-gate return (result);
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate papi_status_t
lpsched_alloc_files(papi_service_t svc,int number,char ** prefix)1930Sstevel@tonic-gate lpsched_alloc_files(papi_service_t svc, int number, char **prefix)
1940Sstevel@tonic-gate {
1950Sstevel@tonic-gate papi_status_t result = PAPI_OK;
1960Sstevel@tonic-gate short status = MOK;
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate if ((svc == NULL) || (prefix == NULL))
1990Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT);
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate if ((snd_msg(svc, S_ALLOC_FILES, number) < 0) ||
2020Sstevel@tonic-gate (rcv_msg(svc, R_ALLOC_FILES, &status, prefix) < 0))
2030Sstevel@tonic-gate status = MTRANSMITERR;
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate if (status != MOK) {
2060Sstevel@tonic-gate detailed_error(svc,
2070Sstevel@tonic-gate gettext("failed to allocate %d file(s) for request: %s"),
208*9376SGowtham.Thommandra@Sun.COM number, lpsched_status_string(status));
2090Sstevel@tonic-gate result = lpsched_status_to_papi_status(status);
2100Sstevel@tonic-gate }
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate return (result);
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate papi_status_t
lpsched_commit_job(papi_service_t svc,char * job,char ** tmp)2160Sstevel@tonic-gate lpsched_commit_job(papi_service_t svc, char *job, char **tmp)
2170Sstevel@tonic-gate /* job is host/req-id */
2180Sstevel@tonic-gate {
2190Sstevel@tonic-gate papi_status_t result = PAPI_OK;
2200Sstevel@tonic-gate short status = MOK;
2210Sstevel@tonic-gate long bits;
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate if ((svc == NULL) || (job == NULL) || (tmp == NULL))
2240Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT);
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate if ((snd_msg(svc, S_PRINT_REQUEST, job) < 0) ||
2270Sstevel@tonic-gate (rcv_msg(svc, R_PRINT_REQUEST, &status, tmp, &bits) < 0))
2280Sstevel@tonic-gate status = MTRANSMITERR;
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate if (status != MOK) {
2310Sstevel@tonic-gate detailed_error(svc, gettext("failed to commit job (%s): %s"),
2320Sstevel@tonic-gate job, lpsched_status_string(status));
2330Sstevel@tonic-gate result = lpsched_status_to_papi_status(status);
2340Sstevel@tonic-gate }
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate return (result);
2370Sstevel@tonic-gate }
2380Sstevel@tonic-gate
2390Sstevel@tonic-gate papi_status_t
lpsched_start_change(papi_service_t svc,char * printer,int32_t job_id,char ** tmp)2402264Sjacobs lpsched_start_change(papi_service_t svc, char *printer, int32_t job_id,
2410Sstevel@tonic-gate char **tmp)
2420Sstevel@tonic-gate {
2430Sstevel@tonic-gate papi_status_t result = PAPI_OK;
2440Sstevel@tonic-gate short status = MOK;
2450Sstevel@tonic-gate char req[BUFSIZ];
2460Sstevel@tonic-gate char *dest;
2470Sstevel@tonic-gate
2480Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (job_id < 0))
2490Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT);
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, job_id);
2520Sstevel@tonic-gate snprintf(req, sizeof (req), "%s-%d", dest, job_id);
2530Sstevel@tonic-gate free(dest);
2540Sstevel@tonic-gate
2550Sstevel@tonic-gate if ((snd_msg(svc, S_START_CHANGE_REQUEST, req) < 0) ||
2560Sstevel@tonic-gate (rcv_msg(svc, R_START_CHANGE_REQUEST, &status, tmp) < 0))
2570Sstevel@tonic-gate status = MTRANSMITERR;
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate if (status != MOK) {
2600Sstevel@tonic-gate detailed_error(svc,
2610Sstevel@tonic-gate gettext("failed to initiate change for job (%s-%d): %s"),
262*9376SGowtham.Thommandra@Sun.COM printer,
263*9376SGowtham.Thommandra@Sun.COM job_id, lpsched_status_string(status));
2640Sstevel@tonic-gate result = lpsched_status_to_papi_status(status);
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate
2670Sstevel@tonic-gate return (result);
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate papi_status_t
lpsched_end_change(papi_service_t svc,char * printer,int32_t job_id)2712264Sjacobs lpsched_end_change(papi_service_t svc, char *printer, int32_t job_id)
2720Sstevel@tonic-gate {
2730Sstevel@tonic-gate papi_status_t result = PAPI_OK;
2740Sstevel@tonic-gate short status = MOK;
2750Sstevel@tonic-gate long bits;
2760Sstevel@tonic-gate char req[BUFSIZ];
2770Sstevel@tonic-gate char *dest;
2780Sstevel@tonic-gate
2790Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (job_id < 0))
2800Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT);
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, job_id);
2830Sstevel@tonic-gate snprintf(req, sizeof (req), "%s-%d", dest, job_id);
2840Sstevel@tonic-gate free(dest);
2850Sstevel@tonic-gate
2860Sstevel@tonic-gate if ((snd_msg(svc, S_END_CHANGE_REQUEST, req) < 0) ||
2870Sstevel@tonic-gate (rcv_msg(svc, R_END_CHANGE_REQUEST, &status, &bits) < 0))
2880Sstevel@tonic-gate status = MTRANSMITERR;
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate if (status != MOK) {
2910Sstevel@tonic-gate detailed_error(svc,
2920Sstevel@tonic-gate gettext("failed to commit change for job (%s-%d): %s"), printer,
293*9376SGowtham.Thommandra@Sun.COM job_id, lpsched_status_string(status));
2940Sstevel@tonic-gate result = lpsched_status_to_papi_status(status);
2950Sstevel@tonic-gate }
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate return (result);
2980Sstevel@tonic-gate }
2990Sstevel@tonic-gate
3000Sstevel@tonic-gate papi_status_t
lpsched_accept_printer(papi_service_t svc,char * printer)3012264Sjacobs lpsched_accept_printer(papi_service_t svc, char *printer)
3022264Sjacobs {
3032264Sjacobs papi_status_t result = PAPI_OK;
304*9376SGowtham.Thommandra@Sun.COM short status = MOK;
3052264Sjacobs char *req_id;
3062264Sjacobs char *dest;
3072264Sjacobs
3082264Sjacobs if ((svc == NULL) || (printer == NULL))
3092264Sjacobs return (PAPI_BAD_ARGUMENT);
3102264Sjacobs
3112264Sjacobs dest = printer_name_from_uri_id(printer, -1);
3122264Sjacobs if ((snd_msg(svc, S_ACCEPT_DEST, dest) < 0) ||
3132264Sjacobs (rcv_msg(svc, R_ACCEPT_DEST, &status, &req_id) < 0))
3142264Sjacobs status = MTRANSMITERR;
3152264Sjacobs free(dest);
3162264Sjacobs
3172264Sjacobs if ((status != MOK) && (status != MERRDEST)) {
3182264Sjacobs detailed_error(svc, "%s: %s", printer,
319*9376SGowtham.Thommandra@Sun.COM lpsched_status_string(status));
3202264Sjacobs }
321*9376SGowtham.Thommandra@Sun.COM result = lpsched_status_to_papi_status(status);
3222264Sjacobs
3232264Sjacobs return (result);
3242264Sjacobs }
3252264Sjacobs
3262264Sjacobs papi_status_t
lpsched_reject_printer(papi_service_t svc,char * printer,char * message)3272264Sjacobs lpsched_reject_printer(papi_service_t svc, char *printer, char *message)
3282264Sjacobs {
3292264Sjacobs papi_status_t result = PAPI_OK;
330*9376SGowtham.Thommandra@Sun.COM short status = MOK;
3312264Sjacobs char *req_id;
3322264Sjacobs char *dest;
3332264Sjacobs
3342264Sjacobs if ((svc == NULL) || (printer == NULL))
3352264Sjacobs return (PAPI_BAD_ARGUMENT);
3362264Sjacobs
3372264Sjacobs if (message == NULL)
3382264Sjacobs message = "stopped by user";
3392264Sjacobs
3402264Sjacobs dest = printer_name_from_uri_id(printer, -1);
3412264Sjacobs if ((snd_msg(svc, S_REJECT_DEST, dest, message, 0) < 0) ||
3422264Sjacobs (rcv_msg(svc, R_REJECT_DEST, &status, &req_id) < 0))
3432264Sjacobs status = MTRANSMITERR;
3442264Sjacobs free(dest);
3452264Sjacobs
3462264Sjacobs if ((status != MOK) && (status != MERRDEST)) {
3472264Sjacobs detailed_error(svc, "%s: %s", printer,
348*9376SGowtham.Thommandra@Sun.COM lpsched_status_string(status));
3492264Sjacobs }
350*9376SGowtham.Thommandra@Sun.COM result = lpsched_status_to_papi_status(status);
3512264Sjacobs
3522264Sjacobs return (result);
3532264Sjacobs }
3542264Sjacobs
3552264Sjacobs papi_status_t
lpsched_enable_printer(papi_service_t svc,char * printer)3562264Sjacobs lpsched_enable_printer(papi_service_t svc, char *printer)
3570Sstevel@tonic-gate {
3580Sstevel@tonic-gate papi_status_t result = PAPI_OK;
359*9376SGowtham.Thommandra@Sun.COM short status = MOK;
3600Sstevel@tonic-gate char *req_id;
3610Sstevel@tonic-gate char *dest;
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL))
3640Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT);
3650Sstevel@tonic-gate
3660Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, -1);
3670Sstevel@tonic-gate if ((snd_msg(svc, S_ENABLE_DEST, dest) < 0) ||
3680Sstevel@tonic-gate (rcv_msg(svc, R_ENABLE_DEST, &status, &req_id) < 0))
3690Sstevel@tonic-gate status = MTRANSMITERR;
3700Sstevel@tonic-gate free(dest);
3710Sstevel@tonic-gate
3720Sstevel@tonic-gate if ((status != MOK) && (status != MERRDEST)) {
3730Sstevel@tonic-gate detailed_error(svc, "%s: %s", printer,
374*9376SGowtham.Thommandra@Sun.COM lpsched_status_string(status));
3750Sstevel@tonic-gate }
376*9376SGowtham.Thommandra@Sun.COM result = lpsched_status_to_papi_status(status);
3770Sstevel@tonic-gate
3780Sstevel@tonic-gate return (result);
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate
3810Sstevel@tonic-gate papi_status_t
lpsched_disable_printer(papi_service_t svc,char * printer,char * message)3822264Sjacobs lpsched_disable_printer(papi_service_t svc, char *printer, char *message)
3830Sstevel@tonic-gate {
3840Sstevel@tonic-gate papi_status_t result = PAPI_OK;
385*9376SGowtham.Thommandra@Sun.COM short status = MOK;
3860Sstevel@tonic-gate char *req_id;
3870Sstevel@tonic-gate char *dest;
3880Sstevel@tonic-gate
3890Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL))
3900Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT);
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate if (message == NULL)
3930Sstevel@tonic-gate message = "stopped by user";
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, -1);
3960Sstevel@tonic-gate if ((snd_msg(svc, S_DISABLE_DEST, dest, message, 0) < 0) ||
3970Sstevel@tonic-gate (rcv_msg(svc, R_DISABLE_DEST, &status, &req_id) < 0))
3980Sstevel@tonic-gate status = MTRANSMITERR;
3990Sstevel@tonic-gate free(dest);
4000Sstevel@tonic-gate
4010Sstevel@tonic-gate if ((status != MOK) && (status != MERRDEST)) {
4020Sstevel@tonic-gate detailed_error(svc, "%s: %s", printer,
403*9376SGowtham.Thommandra@Sun.COM lpsched_status_string(status));
4040Sstevel@tonic-gate }
405*9376SGowtham.Thommandra@Sun.COM result = lpsched_status_to_papi_status(status);
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate return (result);
4080Sstevel@tonic-gate }
4092264Sjacobs
4102264Sjacobs papi_status_t
lpsched_load_unload_dest(papi_service_t handle,char * dest,int type)4112264Sjacobs lpsched_load_unload_dest(papi_service_t handle, char *dest, int type)
4122264Sjacobs {
4132264Sjacobs service_t *svc = handle;
4142264Sjacobs papi_status_t result;
4152264Sjacobs short status = MOK;
4162264Sjacobs
4172264Sjacobs /* tell the scheduler it's going */
4182264Sjacobs if (snd_msg(svc, type, dest, "", "") < 0)
4192264Sjacobs return (PAPI_SERVICE_UNAVAILABLE);
4202264Sjacobs
4212264Sjacobs switch (type) {
4222264Sjacobs case S_LOAD_PRINTER:
4232264Sjacobs type = R_LOAD_PRINTER;
4242264Sjacobs break;
4252264Sjacobs case S_UNLOAD_PRINTER:
4262264Sjacobs type = R_UNLOAD_PRINTER;
4272264Sjacobs break;
4282264Sjacobs case S_LOAD_CLASS:
4292264Sjacobs type = R_LOAD_CLASS;
4302264Sjacobs break;
4312264Sjacobs case S_UNLOAD_CLASS:
4322264Sjacobs type = R_UNLOAD_CLASS;
4332264Sjacobs }
4342264Sjacobs
4352264Sjacobs if (rcv_msg(svc, type, &status) < 0)
4362264Sjacobs return (PAPI_SERVICE_UNAVAILABLE);
4372264Sjacobs
4382264Sjacobs result = lpsched_status_to_papi_status(status);
4392264Sjacobs
4402264Sjacobs return (result);
4412264Sjacobs }
4422264Sjacobs
4432264Sjacobs papi_status_t
lpsched_remove_class(papi_service_t handle,char * dest)4442264Sjacobs lpsched_remove_class(papi_service_t handle, char *dest)
4452264Sjacobs {
4462264Sjacobs papi_status_t result;
4472264Sjacobs
4482264Sjacobs /* tell the scheduler it's going */
4492264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_CLASS);
4502264Sjacobs
4512264Sjacobs if (result == PAPI_OK) {
4522264Sjacobs /* remove the scheduler config files */
4532264Sjacobs if (delclass(dest) == -1)
4542264Sjacobs result = PAPI_SERVICE_UNAVAILABLE;
4552264Sjacobs }
4562264Sjacobs
4572264Sjacobs return (result);
4582264Sjacobs }
4592264Sjacobs
4602264Sjacobs static void
remove_from_class(papi_service_t handle,char * dest,CLASS * cls)4612264Sjacobs remove_from_class(papi_service_t handle, char *dest, CLASS *cls)
4622264Sjacobs {
4632264Sjacobs if (dellist(&cls->members, dest) == 0) {
4642264Sjacobs if (cls->members != NULL) {
4652264Sjacobs if (putclass(cls->name, cls) == 0)
4662264Sjacobs (void) lpsched_load_unload_dest(handle,
467*9376SGowtham.Thommandra@Sun.COM cls->name, S_LOAD_CLASS);
4682264Sjacobs } else
4692264Sjacobs (void) lpsched_remove_class(handle, cls->name);
4702264Sjacobs }
4712264Sjacobs }
4722264Sjacobs
4732264Sjacobs papi_status_t
lpsched_remove_printer(papi_service_t handle,char * dest)4742264Sjacobs lpsched_remove_printer(papi_service_t handle, char *dest)
4752264Sjacobs {
4762264Sjacobs
4772264Sjacobs papi_status_t result;
4782264Sjacobs
4792264Sjacobs /* tell the scheduler it's going */
4802264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_PRINTER);
4812264Sjacobs
4822264Sjacobs if (result == PAPI_OK) {
4832264Sjacobs CLASS *cls;
4842264Sjacobs char *dflt;
4852264Sjacobs
4862264Sjacobs /* remove the scheduler config files */
4872264Sjacobs if (delprinter(dest) == -1)
4882264Sjacobs return (PAPI_SERVICE_UNAVAILABLE);
4892264Sjacobs
4902264Sjacobs /* remove from any classes */
4913125Sjacobs while ((cls = getclass(NAME_ALL)) != NULL) {
4922264Sjacobs if (searchlist(dest, cls->members) != 0)
4932264Sjacobs remove_from_class(handle, dest, cls);
4943125Sjacobs freeclass(cls);
4953125Sjacobs }
4962264Sjacobs
4972264Sjacobs /* reset the default if it needs to be done */
4982264Sjacobs if (((dflt = getdefault()) != NULL) &&
4992264Sjacobs (strcmp(dflt, dest) == 0))
5002264Sjacobs putdefault(NAME_NONE);
5012264Sjacobs }
5022264Sjacobs
5032264Sjacobs return (result);
5042264Sjacobs }
5052264Sjacobs
5062264Sjacobs papi_status_t
lpsched_add_modify_class(papi_service_t handle,char * dest,papi_attribute_t ** attributes)5072264Sjacobs lpsched_add_modify_class(papi_service_t handle, char *dest,
5082264Sjacobs papi_attribute_t **attributes)
5092264Sjacobs {
5102264Sjacobs papi_status_t result;
5112264Sjacobs void *iter = NULL;
5122264Sjacobs char **members = NULL;
5132264Sjacobs char *member;
5142264Sjacobs
5152264Sjacobs /*
5162264Sjacobs * The only attribute that we can modify for a class is the set of
5172264Sjacobs * members. Anything else will be ignored.
5182264Sjacobs */
5192264Sjacobs for (result = papiAttributeListGetString(attributes, &iter,
520*9376SGowtham.Thommandra@Sun.COM "member-names", &member);
5212264Sjacobs result == PAPI_OK;
5222264Sjacobs result = papiAttributeListGetString(attributes, &iter,
523*9376SGowtham.Thommandra@Sun.COM NULL, &member))
5242264Sjacobs addlist(&members, member);
5252264Sjacobs
5262264Sjacobs if (members != NULL) {
5272264Sjacobs /* modify the configuration file */
5282264Sjacobs CLASS class;
5292264Sjacobs
5302264Sjacobs memset(&class, 0, sizeof (class));
5312264Sjacobs class.name = dest;
5322264Sjacobs class.members = members;
5332264Sjacobs
5342264Sjacobs if (putclass(dest, &class) == -1) {
5352264Sjacobs if ((errno == EPERM) || (errno == EACCES))
5362264Sjacobs result = PAPI_NOT_AUTHORIZED;
5372264Sjacobs else
5382264Sjacobs result = PAPI_NOT_POSSIBLE;
5392264Sjacobs } else
5402264Sjacobs result = PAPI_OK;
5412264Sjacobs
5422264Sjacobs freelist(members);
5432264Sjacobs } else
5442264Sjacobs result = PAPI_ATTRIBUTES;
5452264Sjacobs
5462264Sjacobs /* tell the scheduler about the changes */
5472264Sjacobs if (result == PAPI_OK)
5482264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_LOAD_CLASS);
5492264Sjacobs
5502264Sjacobs return (result);
5512264Sjacobs }
5522264Sjacobs
5532264Sjacobs papi_status_t
lpsched_add_printer(papi_service_t handle,char * dest,papi_attribute_t ** attributes)5542264Sjacobs lpsched_add_printer(papi_service_t handle, char *dest,
5552264Sjacobs papi_attribute_t **attributes)
5562264Sjacobs {
5572264Sjacobs PRINTER *p;
5582264Sjacobs papi_status_t result = PAPI_TEMPORARY_ERROR;
5592264Sjacobs
5602264Sjacobs if ((p = calloc(1, sizeof (*p))) != NULL) {
5612264Sjacobs p->name = strdup(dest);
5622264Sjacobs p->banner = BAN_ALWAYS;
5632264Sjacobs p->interface = strdup("/usr/lib/lp/model/uri");
5642264Sjacobs p->fault_alert.shcmd = strdup("mail");
5652264Sjacobs
5662264Sjacobs attributes_to_printer(attributes, p);
5672264Sjacobs
5682264Sjacobs if (putprinter(dest, p) == -1) {
5692264Sjacobs if ((errno == EPERM) || (errno == EACCES))
5702264Sjacobs result = PAPI_NOT_AUTHORIZED;
5712264Sjacobs else
5722264Sjacobs result = PAPI_NOT_POSSIBLE;
5732264Sjacobs } else
5742264Sjacobs result = PAPI_OK;
5752264Sjacobs
5762264Sjacobs freeprinter(p);
5772264Sjacobs }
5782264Sjacobs
5792264Sjacobs /* tell the scheduler about the changes */
5802264Sjacobs if (result == PAPI_OK)
5812264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER);
5822264Sjacobs
5832264Sjacobs return (result);
5842264Sjacobs }
5852264Sjacobs
5862264Sjacobs papi_status_t
lpsched_add_modify_printer(papi_service_t handle,char * dest,papi_attribute_t ** attributes,int type)5872264Sjacobs lpsched_add_modify_printer(papi_service_t handle, char *dest,
5882264Sjacobs papi_attribute_t **attributes, int type)
5892264Sjacobs {
5902264Sjacobs PRINTER *p;
5912264Sjacobs papi_status_t result;
5922264Sjacobs
5932264Sjacobs if (type == 0) {
5942264Sjacobs if ((p = calloc(1, sizeof (*p))) != NULL) {
5952264Sjacobs p->name = strdup(dest);
5962264Sjacobs p->banner = BAN_ALWAYS;
5972264Sjacobs p->interface = strdup("/usr/lib/lp/model/uri");
5982264Sjacobs p->fault_alert.shcmd = strdup("mail");
5992264Sjacobs }
6002264Sjacobs } else
6012264Sjacobs p = getprinter(dest);
6022264Sjacobs
6032264Sjacobs if (p != NULL) {
6042264Sjacobs attributes_to_printer(attributes, p);
6052264Sjacobs
6062264Sjacobs if (putprinter(dest, p) == -1) {
6072264Sjacobs if ((errno == EPERM) || (errno == EACCES))
6082264Sjacobs result = PAPI_NOT_AUTHORIZED;
6092264Sjacobs else
6102264Sjacobs result = PAPI_NOT_POSSIBLE;
6112264Sjacobs } else
6122264Sjacobs result = PAPI_OK;
6132264Sjacobs
6142264Sjacobs freeprinter(p);
6152264Sjacobs } else
6162264Sjacobs result = PAPI_NOT_POSSIBLE;
6172264Sjacobs
6182264Sjacobs /* tell the scheduler about the changes */
6192264Sjacobs if (result == PAPI_OK)
6202264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER);
6212264Sjacobs
6222264Sjacobs return (result);
6232264Sjacobs }
624