xref: /onnv-gate/usr/src/cmd/lp/lib/papi/lpsched-msgs.c (revision 9376:4f1a5ea2a016)
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