xref: /illumos-gate/usr/src/cmd/lp/lib/papi/lpsched-msgs.c (revision 98f04078)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5355b4669Sjacobs  * Common Development and Distribution License (the "License").
6355b4669Sjacobs  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
210a44ef6dSjacobs 
227c478bd9Sstevel@tonic-gate /*
23*98f04078SGowtham Thommandra  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <stdarg.h>
327c478bd9Sstevel@tonic-gate #include <libintl.h>
337c478bd9Sstevel@tonic-gate #include <string.h>
347c478bd9Sstevel@tonic-gate #include <stdlib.h>
35355b4669Sjacobs #include <errno.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate /* lpsched include files */
397c478bd9Sstevel@tonic-gate #include "lp.h"
407c478bd9Sstevel@tonic-gate #include "msgs.h"
417c478bd9Sstevel@tonic-gate #include "printers.h"
42355b4669Sjacobs #include "class.h"
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate #include <papi_impl.h>
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /*
487c478bd9Sstevel@tonic-gate  * Format and send message to lpsched (die if any errors occur)
497c478bd9Sstevel@tonic-gate  */
507c478bd9Sstevel@tonic-gate /*VARARGS1*/
517c478bd9Sstevel@tonic-gate int
snd_msg(service_t * svc,int type,...)527c478bd9Sstevel@tonic-gate snd_msg(service_t *svc, int type, ...)
537c478bd9Sstevel@tonic-gate {
547c478bd9Sstevel@tonic-gate 	int rc = -1;
557c478bd9Sstevel@tonic-gate 	va_list	ap;
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate 	if (svc == NULL)
587c478bd9Sstevel@tonic-gate 		return (-1);
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate 	/* fill the message buffer */
617c478bd9Sstevel@tonic-gate 	va_start(ap, type);
627c478bd9Sstevel@tonic-gate 	rc = _putmessage(svc->msgbuf, type, ap);
637c478bd9Sstevel@tonic-gate 	va_end(ap);
647c478bd9Sstevel@tonic-gate 	if (rc < 0) {
657c478bd9Sstevel@tonic-gate 		detailed_error(svc,
66*98f04078SGowtham Thommandra 		    gettext("unable to build message for scheduler: %s"),
67*98f04078SGowtham Thommandra 		    strerror(errno));
687c478bd9Sstevel@tonic-gate 		return (rc);
697c478bd9Sstevel@tonic-gate 	}
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate 	/* write the message */
72*98f04078SGowtham Thommandra 	while (((rc = mwrite(svc->md, svc->msgbuf)) < 0) && (errno == EINTR)) {
73*98f04078SGowtham Thommandra 	}
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	if (rc < 0)
767c478bd9Sstevel@tonic-gate 		detailed_error(svc,
77*98f04078SGowtham Thommandra 		    gettext("unable to send message to scheduler: %s"),
78*98f04078SGowtham Thommandra 		    strerror(errno));
797c478bd9Sstevel@tonic-gate 	return (rc);
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate /*
837c478bd9Sstevel@tonic-gate  * Receive message from lpsched (die if any errors occur)
847c478bd9Sstevel@tonic-gate  */
857c478bd9Sstevel@tonic-gate int
rcv_msg(service_t * svc,int type,...)867c478bd9Sstevel@tonic-gate rcv_msg(service_t *svc, int type, ...)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate 	int rc = -1;
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	if (svc == NULL)
917c478bd9Sstevel@tonic-gate 		return (-1);
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	/* read the message */
947c478bd9Sstevel@tonic-gate 	while (((rc = mread(svc->md, svc->msgbuf, svc->msgbuf_size)) < 0) &&
95*98f04078SGowtham Thommandra 	    (errno == EINTR)) {
96*98f04078SGowtham Thommandra 	}
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 	if (rc < 0)
997c478bd9Sstevel@tonic-gate 		detailed_error(svc,
100*98f04078SGowtham Thommandra 		    gettext("unable to read message from scheduler: %s"),
101*98f04078SGowtham Thommandra 		    strerror(errno));
1027c478bd9Sstevel@tonic-gate 	else {
1037c478bd9Sstevel@tonic-gate 		va_list ap;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 		va_start(ap, type);
1067c478bd9Sstevel@tonic-gate 		rc = _getmessage(svc->msgbuf, type, ap);
1077c478bd9Sstevel@tonic-gate 		va_end(ap);
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 		if (rc < 0)
1107c478bd9Sstevel@tonic-gate 			detailed_error(svc,
1117c478bd9Sstevel@tonic-gate 			gettext("unable to parse message from scheduler: %s"),
112*98f04078SGowtham Thommandra 			    strerror(errno));
1137c478bd9Sstevel@tonic-gate 	}
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	return (rc);
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate papi_status_t
lpsched_status_to_papi_status(int status)1197c478bd9Sstevel@tonic-gate lpsched_status_to_papi_status(int status)
1207c478bd9Sstevel@tonic-gate {
1217c478bd9Sstevel@tonic-gate 	switch (status) {
1227c478bd9Sstevel@tonic-gate 	case MNOMEM:
1237c478bd9Sstevel@tonic-gate 		return (PAPI_TEMPORARY_ERROR);
1247c478bd9Sstevel@tonic-gate 	case MNOFILTER:
1257c478bd9Sstevel@tonic-gate 		return (PAPI_DOCUMENT_FORMAT_ERROR);
1267c478bd9Sstevel@tonic-gate 	case MNOOPEN:
1277c478bd9Sstevel@tonic-gate 		return (PAPI_DOCUMENT_ACCESS_ERROR);
1287c478bd9Sstevel@tonic-gate 	case MERRDEST:
1297c478bd9Sstevel@tonic-gate 	case MDENYDEST:
1307c478bd9Sstevel@tonic-gate 		return (PAPI_NOT_ACCEPTING);
1317c478bd9Sstevel@tonic-gate 	case MNOMEDIA:
1327c478bd9Sstevel@tonic-gate 		return (PAPI_PRINT_SUPPORT_FILE_NOT_FOUND);
1337c478bd9Sstevel@tonic-gate 	case MDENYMEDIA:
1347c478bd9Sstevel@tonic-gate 	case MNOPERM:
1357c478bd9Sstevel@tonic-gate 		return (PAPI_NOT_AUTHORIZED);
1367c478bd9Sstevel@tonic-gate 	case MUNKNOWN:
1377c478bd9Sstevel@tonic-gate 	case MNODEST:
1387c478bd9Sstevel@tonic-gate 	case MNOINFO:
1397c478bd9Sstevel@tonic-gate 		return (PAPI_NOT_FOUND);
1407c478bd9Sstevel@tonic-gate 	case MTRANSMITERR:
1417c478bd9Sstevel@tonic-gate 		return (PAPI_SERVICE_UNAVAILABLE);
1427c478bd9Sstevel@tonic-gate 	case M2LATE:
1437c478bd9Sstevel@tonic-gate 		return (PAPI_GONE);
144355b4669Sjacobs 	case MBUSY:
145355b4669Sjacobs 		return (PAPI_PRINTER_BUSY);
1467c478bd9Sstevel@tonic-gate 	case MOK:
1477c478bd9Sstevel@tonic-gate 	case MOKMORE:
1487c478bd9Sstevel@tonic-gate 		return (PAPI_OK);
1497c478bd9Sstevel@tonic-gate 	}
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	return (PAPI_INTERNAL_ERROR);
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate char *
lpsched_status_string(short status)1557c478bd9Sstevel@tonic-gate lpsched_status_string(short status)
1567c478bd9Sstevel@tonic-gate {
1577c478bd9Sstevel@tonic-gate 		switch (status) {
1587c478bd9Sstevel@tonic-gate 	case MNOMEM:
1597c478bd9Sstevel@tonic-gate 		return (gettext("lpsched: out of memory"));
1607c478bd9Sstevel@tonic-gate 	case MNOFILTER:
1617c478bd9Sstevel@tonic-gate 		return (gettext("No filter available to convert job"));
1627c478bd9Sstevel@tonic-gate 	case MNOOPEN:
1637c478bd9Sstevel@tonic-gate 		return (gettext("lpsched: could not open request"));
1647c478bd9Sstevel@tonic-gate 	case MERRDEST:
1650a44ef6dSjacobs 		return (gettext("queue disabled"));
1667c478bd9Sstevel@tonic-gate 	case MDENYDEST:
1677c478bd9Sstevel@tonic-gate 		return (gettext("destination denied request"));
1687c478bd9Sstevel@tonic-gate 	case MNOMEDIA:
1697c478bd9Sstevel@tonic-gate 		return (gettext("unknown form specified in job"));
1707c478bd9Sstevel@tonic-gate 	case MDENYMEDIA:
1717c478bd9Sstevel@tonic-gate 		return (gettext("access denied to form specified in job"));
1727c478bd9Sstevel@tonic-gate 	case MUNKNOWN:
1737c478bd9Sstevel@tonic-gate 		return (gettext("no such resource"));
1747c478bd9Sstevel@tonic-gate 	case MNODEST:
1757c478bd9Sstevel@tonic-gate 		return (gettext("unknown destination"));
1767c478bd9Sstevel@tonic-gate 	case MNOPERM:
1777c478bd9Sstevel@tonic-gate 		return (gettext("permission denied"));
1787c478bd9Sstevel@tonic-gate 	case MNOINFO:
1797c478bd9Sstevel@tonic-gate 		return (gettext("no information available"));
1807c478bd9Sstevel@tonic-gate 	case MTRANSMITERR:
1817c478bd9Sstevel@tonic-gate 		return (gettext("failure to communicate with lpsched"));
1827c478bd9Sstevel@tonic-gate 	default: {
1837c478bd9Sstevel@tonic-gate 		static char result[16];
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 		snprintf(result, sizeof (result), gettext("status: %d"),
186*98f04078SGowtham Thommandra 		    status);
1877c478bd9Sstevel@tonic-gate 		return (result);
1887c478bd9Sstevel@tonic-gate 		}
1897c478bd9Sstevel@tonic-gate 	}
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate papi_status_t
lpsched_alloc_files(papi_service_t svc,int number,char ** prefix)1937c478bd9Sstevel@tonic-gate lpsched_alloc_files(papi_service_t svc, int number, char **prefix)
1947c478bd9Sstevel@tonic-gate {
1957c478bd9Sstevel@tonic-gate 	papi_status_t result = PAPI_OK;
1967c478bd9Sstevel@tonic-gate 	short status = MOK;
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 	if ((svc == NULL) || (prefix == NULL))
1997c478bd9Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 	if ((snd_msg(svc, S_ALLOC_FILES, number) < 0) ||
2027c478bd9Sstevel@tonic-gate 	    (rcv_msg(svc, R_ALLOC_FILES, &status, prefix) < 0))
2037c478bd9Sstevel@tonic-gate 		status = MTRANSMITERR;
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	if (status != MOK) {
2067c478bd9Sstevel@tonic-gate 		detailed_error(svc,
2077c478bd9Sstevel@tonic-gate 		gettext("failed to allocate %d file(s) for request: %s"),
208*98f04078SGowtham Thommandra 		    number, lpsched_status_string(status));
2097c478bd9Sstevel@tonic-gate 		result = lpsched_status_to_papi_status(status);
2107c478bd9Sstevel@tonic-gate 	}
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 	return (result);
2137c478bd9Sstevel@tonic-gate }
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate papi_status_t
lpsched_commit_job(papi_service_t svc,char * job,char ** tmp)2167c478bd9Sstevel@tonic-gate lpsched_commit_job(papi_service_t svc, char *job, char **tmp)
2177c478bd9Sstevel@tonic-gate /* job is host/req-id */
2187c478bd9Sstevel@tonic-gate {
2197c478bd9Sstevel@tonic-gate 	papi_status_t result = PAPI_OK;
2207c478bd9Sstevel@tonic-gate 	short status = MOK;
2217c478bd9Sstevel@tonic-gate 	long bits;
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 	if ((svc == NULL) || (job == NULL) || (tmp == NULL))
2247c478bd9Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 	if ((snd_msg(svc, S_PRINT_REQUEST, job) < 0) ||
2277c478bd9Sstevel@tonic-gate 	    (rcv_msg(svc, R_PRINT_REQUEST, &status, tmp, &bits) < 0))
2287c478bd9Sstevel@tonic-gate 		status = MTRANSMITERR;
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	if (status != MOK) {
2317c478bd9Sstevel@tonic-gate 		detailed_error(svc, gettext("failed to commit job (%s): %s"),
2327c478bd9Sstevel@tonic-gate 			job, lpsched_status_string(status));
2337c478bd9Sstevel@tonic-gate 		result = lpsched_status_to_papi_status(status);
2347c478bd9Sstevel@tonic-gate 	}
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	return (result);
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate papi_status_t
lpsched_start_change(papi_service_t svc,char * printer,int32_t job_id,char ** tmp)240355b4669Sjacobs lpsched_start_change(papi_service_t svc, char *printer, int32_t job_id,
2417c478bd9Sstevel@tonic-gate 		char **tmp)
2427c478bd9Sstevel@tonic-gate {
2437c478bd9Sstevel@tonic-gate 	papi_status_t result = PAPI_OK;
2447c478bd9Sstevel@tonic-gate 	short status = MOK;
2457c478bd9Sstevel@tonic-gate 	char req[BUFSIZ];
2467c478bd9Sstevel@tonic-gate 	char *dest;
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 	if ((svc == NULL) || (printer == NULL) || (job_id < 0))
2497c478bd9Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	dest = printer_name_from_uri_id(printer, job_id);
2527c478bd9Sstevel@tonic-gate 	snprintf(req, sizeof (req), "%s-%d", dest, job_id);
2537c478bd9Sstevel@tonic-gate 	free(dest);
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 	if ((snd_msg(svc, S_START_CHANGE_REQUEST, req) < 0) ||
2567c478bd9Sstevel@tonic-gate 	    (rcv_msg(svc, R_START_CHANGE_REQUEST, &status, tmp) < 0))
2577c478bd9Sstevel@tonic-gate 		status = MTRANSMITERR;
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 	if (status != MOK) {
2607c478bd9Sstevel@tonic-gate 		detailed_error(svc,
2617c478bd9Sstevel@tonic-gate 		gettext("failed to initiate change for job (%s-%d): %s"),
262*98f04078SGowtham Thommandra 		    printer,
263*98f04078SGowtham Thommandra 		    job_id, lpsched_status_string(status));
2647c478bd9Sstevel@tonic-gate 		result = lpsched_status_to_papi_status(status);
2657c478bd9Sstevel@tonic-gate 	}
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 	return (result);
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate papi_status_t
lpsched_end_change(papi_service_t svc,char * printer,int32_t job_id)271355b4669Sjacobs lpsched_end_change(papi_service_t svc, char *printer, int32_t job_id)
2727c478bd9Sstevel@tonic-gate {
2737c478bd9Sstevel@tonic-gate 	papi_status_t result = PAPI_OK;
2747c478bd9Sstevel@tonic-gate 	short status = MOK;
2757c478bd9Sstevel@tonic-gate 	long bits;
2767c478bd9Sstevel@tonic-gate 	char req[BUFSIZ];
2777c478bd9Sstevel@tonic-gate 	char *dest;
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	if ((svc == NULL) || (printer == NULL) || (job_id < 0))
2807c478bd9Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 	dest = printer_name_from_uri_id(printer, job_id);
2837c478bd9Sstevel@tonic-gate 	snprintf(req, sizeof (req), "%s-%d", dest, job_id);
2847c478bd9Sstevel@tonic-gate 	free(dest);
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	if ((snd_msg(svc, S_END_CHANGE_REQUEST, req) < 0) ||
2877c478bd9Sstevel@tonic-gate 	    (rcv_msg(svc, R_END_CHANGE_REQUEST, &status, &bits) < 0))
2887c478bd9Sstevel@tonic-gate 		status = MTRANSMITERR;
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	if (status != MOK) {
2917c478bd9Sstevel@tonic-gate 		detailed_error(svc,
2927c478bd9Sstevel@tonic-gate 		gettext("failed to commit change for job (%s-%d): %s"), printer,
293*98f04078SGowtham Thommandra 		    job_id, lpsched_status_string(status));
2947c478bd9Sstevel@tonic-gate 		result = lpsched_status_to_papi_status(status);
2957c478bd9Sstevel@tonic-gate 	}
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	return (result);
2987c478bd9Sstevel@tonic-gate }
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate papi_status_t
lpsched_accept_printer(papi_service_t svc,char * printer)301355b4669Sjacobs lpsched_accept_printer(papi_service_t svc, char *printer)
302355b4669Sjacobs {
303355b4669Sjacobs 	papi_status_t result = PAPI_OK;
304*98f04078SGowtham Thommandra 	short	status = MOK;
305355b4669Sjacobs 	char	*req_id;
306355b4669Sjacobs 	char *dest;
307355b4669Sjacobs 
308355b4669Sjacobs 	if ((svc == NULL) || (printer == NULL))
309355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
310355b4669Sjacobs 
311355b4669Sjacobs 	dest = printer_name_from_uri_id(printer, -1);
312355b4669Sjacobs 	if ((snd_msg(svc, S_ACCEPT_DEST, dest) < 0) ||
313355b4669Sjacobs 	    (rcv_msg(svc, R_ACCEPT_DEST, &status, &req_id) < 0))
314355b4669Sjacobs 		status = MTRANSMITERR;
315355b4669Sjacobs 	free(dest);
316355b4669Sjacobs 
317355b4669Sjacobs 	if ((status != MOK) && (status != MERRDEST)) {
318355b4669Sjacobs 		detailed_error(svc, "%s: %s", printer,
319*98f04078SGowtham Thommandra 		    lpsched_status_string(status));
320355b4669Sjacobs 	}
321*98f04078SGowtham Thommandra 	result = lpsched_status_to_papi_status(status);
322355b4669Sjacobs 
323355b4669Sjacobs 	return (result);
324355b4669Sjacobs }
325355b4669Sjacobs 
326355b4669Sjacobs papi_status_t
lpsched_reject_printer(papi_service_t svc,char * printer,char * message)327355b4669Sjacobs lpsched_reject_printer(papi_service_t svc, char *printer, char *message)
328355b4669Sjacobs {
329355b4669Sjacobs 	papi_status_t result = PAPI_OK;
330*98f04078SGowtham Thommandra 	short	 status = MOK;
331355b4669Sjacobs 	char	*req_id;
332355b4669Sjacobs 	char *dest;
333355b4669Sjacobs 
334355b4669Sjacobs 	if ((svc == NULL) || (printer == NULL))
335355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
336355b4669Sjacobs 
337355b4669Sjacobs 	if (message == NULL)
338355b4669Sjacobs 		message = "stopped by user";
339355b4669Sjacobs 
340355b4669Sjacobs 	dest = printer_name_from_uri_id(printer, -1);
341355b4669Sjacobs 	if ((snd_msg(svc, S_REJECT_DEST, dest, message, 0) < 0) ||
342355b4669Sjacobs 	    (rcv_msg(svc, R_REJECT_DEST, &status, &req_id) < 0))
343355b4669Sjacobs 		status = MTRANSMITERR;
344355b4669Sjacobs 	free(dest);
345355b4669Sjacobs 
346355b4669Sjacobs 	if ((status != MOK) && (status != MERRDEST)) {
347355b4669Sjacobs 		detailed_error(svc, "%s: %s", printer,
348*98f04078SGowtham Thommandra 		    lpsched_status_string(status));
349355b4669Sjacobs 	}
350*98f04078SGowtham Thommandra 	result = lpsched_status_to_papi_status(status);
351355b4669Sjacobs 
352355b4669Sjacobs 	return (result);
353355b4669Sjacobs }
354355b4669Sjacobs 
355355b4669Sjacobs papi_status_t
lpsched_enable_printer(papi_service_t svc,char * printer)356355b4669Sjacobs lpsched_enable_printer(papi_service_t svc, char *printer)
3577c478bd9Sstevel@tonic-gate {
3587c478bd9Sstevel@tonic-gate 	papi_status_t result = PAPI_OK;
359*98f04078SGowtham Thommandra 	short	 status = MOK;
3607c478bd9Sstevel@tonic-gate 	char	*req_id;
3617c478bd9Sstevel@tonic-gate 	char *dest;
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 	if ((svc == NULL) || (printer == NULL))
3647c478bd9Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 	dest = printer_name_from_uri_id(printer, -1);
3677c478bd9Sstevel@tonic-gate 	if ((snd_msg(svc, S_ENABLE_DEST, dest) < 0) ||
3687c478bd9Sstevel@tonic-gate 	    (rcv_msg(svc, R_ENABLE_DEST, &status, &req_id) < 0))
3697c478bd9Sstevel@tonic-gate 		status = MTRANSMITERR;
3707c478bd9Sstevel@tonic-gate 	free(dest);
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 	if ((status != MOK) && (status != MERRDEST)) {
3737c478bd9Sstevel@tonic-gate 		detailed_error(svc, "%s: %s", printer,
374*98f04078SGowtham Thommandra 		    lpsched_status_string(status));
3757c478bd9Sstevel@tonic-gate 	}
376*98f04078SGowtham Thommandra 	result = lpsched_status_to_papi_status(status);
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 	return (result);
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate papi_status_t
lpsched_disable_printer(papi_service_t svc,char * printer,char * message)382355b4669Sjacobs lpsched_disable_printer(papi_service_t svc, char *printer, char *message)
3837c478bd9Sstevel@tonic-gate {
3847c478bd9Sstevel@tonic-gate 	papi_status_t result = PAPI_OK;
385*98f04078SGowtham Thommandra 	short	 status = MOK;
3867c478bd9Sstevel@tonic-gate 	char	*req_id;
3877c478bd9Sstevel@tonic-gate 	char *dest;
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 	if ((svc == NULL) || (printer == NULL))
3907c478bd9Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 	if (message == NULL)
3937c478bd9Sstevel@tonic-gate 		message = "stopped by user";
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 	dest = printer_name_from_uri_id(printer, -1);
3967c478bd9Sstevel@tonic-gate 	if ((snd_msg(svc, S_DISABLE_DEST, dest, message, 0) < 0) ||
3977c478bd9Sstevel@tonic-gate 	    (rcv_msg(svc, R_DISABLE_DEST, &status, &req_id) < 0))
3987c478bd9Sstevel@tonic-gate 		status = MTRANSMITERR;
3997c478bd9Sstevel@tonic-gate 	free(dest);
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate 	if ((status != MOK) && (status != MERRDEST)) {
4027c478bd9Sstevel@tonic-gate 		detailed_error(svc, "%s: %s", printer,
403*98f04078SGowtham Thommandra 		    lpsched_status_string(status));
4047c478bd9Sstevel@tonic-gate 	}
405*98f04078SGowtham Thommandra 	result = lpsched_status_to_papi_status(status);
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 	return (result);
4087c478bd9Sstevel@tonic-gate }
409355b4669Sjacobs 
410355b4669Sjacobs papi_status_t
lpsched_load_unload_dest(papi_service_t handle,char * dest,int type)411355b4669Sjacobs lpsched_load_unload_dest(papi_service_t handle, char *dest, int type)
412355b4669Sjacobs {
413355b4669Sjacobs 	service_t *svc = handle;
414355b4669Sjacobs 	papi_status_t result;
415355b4669Sjacobs 	short status = MOK;
416355b4669Sjacobs 
417355b4669Sjacobs 	/* tell the scheduler it's going */
418355b4669Sjacobs 	if (snd_msg(svc, type, dest, "", "") < 0)
419355b4669Sjacobs 		return (PAPI_SERVICE_UNAVAILABLE);
420355b4669Sjacobs 
421355b4669Sjacobs 	switch (type) {
422355b4669Sjacobs 	case S_LOAD_PRINTER:
423355b4669Sjacobs 		type = R_LOAD_PRINTER;
424355b4669Sjacobs 		break;
425355b4669Sjacobs 	case S_UNLOAD_PRINTER:
426355b4669Sjacobs 		type = R_UNLOAD_PRINTER;
427355b4669Sjacobs 		break;
428355b4669Sjacobs 	case S_LOAD_CLASS:
429355b4669Sjacobs 		type = R_LOAD_CLASS;
430355b4669Sjacobs 		break;
431355b4669Sjacobs 	case S_UNLOAD_CLASS:
432355b4669Sjacobs 		type = R_UNLOAD_CLASS;
433355b4669Sjacobs 	}
434355b4669Sjacobs 
435355b4669Sjacobs 	if (rcv_msg(svc, type, &status) < 0)
436355b4669Sjacobs 		return (PAPI_SERVICE_UNAVAILABLE);
437355b4669Sjacobs 
438355b4669Sjacobs 	result = lpsched_status_to_papi_status(status);
439355b4669Sjacobs 
440355b4669Sjacobs 	return (result);
441355b4669Sjacobs }
442355b4669Sjacobs 
443355b4669Sjacobs papi_status_t
lpsched_remove_class(papi_service_t handle,char * dest)444355b4669Sjacobs lpsched_remove_class(papi_service_t handle, char *dest)
445355b4669Sjacobs {
446355b4669Sjacobs 	papi_status_t result;
447355b4669Sjacobs 
448355b4669Sjacobs 	/* tell the scheduler it's going */
449355b4669Sjacobs 	result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_CLASS);
450355b4669Sjacobs 
451355b4669Sjacobs 	if (result == PAPI_OK) {
452355b4669Sjacobs 		/* remove the scheduler config files */
453355b4669Sjacobs 		if (delclass(dest) == -1)
454355b4669Sjacobs 			result = PAPI_SERVICE_UNAVAILABLE;
455355b4669Sjacobs 	}
456355b4669Sjacobs 
457355b4669Sjacobs 	return (result);
458355b4669Sjacobs }
459355b4669Sjacobs 
460355b4669Sjacobs static void
remove_from_class(papi_service_t handle,char * dest,CLASS * cls)461355b4669Sjacobs remove_from_class(papi_service_t handle, char *dest, CLASS *cls)
462355b4669Sjacobs {
463355b4669Sjacobs 	if (dellist(&cls->members, dest) == 0) {
464355b4669Sjacobs 		if (cls->members != NULL) {
465355b4669Sjacobs 			if (putclass(cls->name, cls) == 0)
466355b4669Sjacobs 				(void) lpsched_load_unload_dest(handle,
467*98f04078SGowtham Thommandra 				    cls->name, S_LOAD_CLASS);
468355b4669Sjacobs 		} else
469355b4669Sjacobs 			(void) lpsched_remove_class(handle, cls->name);
470355b4669Sjacobs 	}
471355b4669Sjacobs }
472355b4669Sjacobs 
473355b4669Sjacobs papi_status_t
lpsched_remove_printer(papi_service_t handle,char * dest)474355b4669Sjacobs lpsched_remove_printer(papi_service_t handle, char *dest)
475355b4669Sjacobs {
476355b4669Sjacobs 
477355b4669Sjacobs 	papi_status_t result;
478355b4669Sjacobs 
479355b4669Sjacobs 	/* tell the scheduler it's going */
480355b4669Sjacobs 	result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_PRINTER);
481355b4669Sjacobs 
482355b4669Sjacobs 	if (result == PAPI_OK) {
483355b4669Sjacobs 		CLASS *cls;
484355b4669Sjacobs 		char *dflt;
485355b4669Sjacobs 
486355b4669Sjacobs 		/* remove the scheduler config files */
487355b4669Sjacobs 		if (delprinter(dest) == -1)
488355b4669Sjacobs 			return (PAPI_SERVICE_UNAVAILABLE);
489355b4669Sjacobs 
490355b4669Sjacobs 		/* remove from any classes */
4910a44ef6dSjacobs 		while ((cls = getclass(NAME_ALL)) != NULL) {
492355b4669Sjacobs 			if (searchlist(dest, cls->members) != 0)
493355b4669Sjacobs 				remove_from_class(handle, dest, cls);
4940a44ef6dSjacobs 			freeclass(cls);
4950a44ef6dSjacobs 		}
496355b4669Sjacobs 
497355b4669Sjacobs 		/* reset the default if it needs to be done */
498355b4669Sjacobs 		if (((dflt = getdefault()) != NULL) &&
499355b4669Sjacobs 		    (strcmp(dflt, dest) == 0))
500355b4669Sjacobs 			putdefault(NAME_NONE);
501355b4669Sjacobs 	}
502355b4669Sjacobs 
503355b4669Sjacobs 	return (result);
504355b4669Sjacobs }
505355b4669Sjacobs 
506355b4669Sjacobs papi_status_t
lpsched_add_modify_class(papi_service_t handle,char * dest,papi_attribute_t ** attributes)507355b4669Sjacobs lpsched_add_modify_class(papi_service_t handle, char *dest,
508355b4669Sjacobs 		papi_attribute_t **attributes)
509355b4669Sjacobs {
510355b4669Sjacobs 	papi_status_t result;
511355b4669Sjacobs 	void *iter = NULL;
512355b4669Sjacobs 	char **members = NULL;
513355b4669Sjacobs 	char *member;
514355b4669Sjacobs 
515355b4669Sjacobs 	/*
516355b4669Sjacobs 	 * The only attribute that we can modify for a class is the set of
517355b4669Sjacobs 	 * members.  Anything else will be ignored.
518355b4669Sjacobs 	 */
519355b4669Sjacobs 	for (result = papiAttributeListGetString(attributes, &iter,
520*98f04078SGowtham Thommandra 	    "member-names", &member);
521355b4669Sjacobs 	    result == PAPI_OK;
522355b4669Sjacobs 	    result = papiAttributeListGetString(attributes, &iter,
523*98f04078SGowtham Thommandra 	    NULL, &member))
524355b4669Sjacobs 		addlist(&members, member);
525355b4669Sjacobs 
526355b4669Sjacobs 	if (members != NULL) {
527355b4669Sjacobs 		/* modify the configuration file */
528355b4669Sjacobs 		CLASS class;
529355b4669Sjacobs 
530355b4669Sjacobs 		memset(&class, 0, sizeof (class));
531355b4669Sjacobs 		class.name = dest;
532355b4669Sjacobs 		class.members = members;
533355b4669Sjacobs 
534355b4669Sjacobs 		if (putclass(dest, &class) == -1) {
535355b4669Sjacobs 			if ((errno == EPERM) || (errno == EACCES))
536355b4669Sjacobs 				result = PAPI_NOT_AUTHORIZED;
537355b4669Sjacobs 			else
538355b4669Sjacobs 				result = PAPI_NOT_POSSIBLE;
539355b4669Sjacobs 		} else
540355b4669Sjacobs 			result = PAPI_OK;
541355b4669Sjacobs 
542355b4669Sjacobs 		freelist(members);
543355b4669Sjacobs 	} else
544355b4669Sjacobs 		result = PAPI_ATTRIBUTES;
545355b4669Sjacobs 
546355b4669Sjacobs 	/* tell the scheduler about the changes */
547355b4669Sjacobs 	if (result == PAPI_OK)
548355b4669Sjacobs 		result = lpsched_load_unload_dest(handle, dest, S_LOAD_CLASS);
549355b4669Sjacobs 
550355b4669Sjacobs 	return (result);
551355b4669Sjacobs }
552355b4669Sjacobs 
553355b4669Sjacobs papi_status_t
lpsched_add_printer(papi_service_t handle,char * dest,papi_attribute_t ** attributes)554355b4669Sjacobs lpsched_add_printer(papi_service_t handle, char *dest,
555355b4669Sjacobs 		papi_attribute_t **attributes)
556355b4669Sjacobs {
557355b4669Sjacobs 	PRINTER *p;
558355b4669Sjacobs 	papi_status_t result = PAPI_TEMPORARY_ERROR;
559355b4669Sjacobs 
560355b4669Sjacobs 	if ((p = calloc(1, sizeof (*p))) != NULL) {
561355b4669Sjacobs 		p->name = strdup(dest);
562355b4669Sjacobs 		p->banner = BAN_ALWAYS;
563355b4669Sjacobs 		p->interface = strdup("/usr/lib/lp/model/uri");
564355b4669Sjacobs 		p->fault_alert.shcmd = strdup("mail");
565355b4669Sjacobs 
566355b4669Sjacobs 		attributes_to_printer(attributes, p);
567355b4669Sjacobs 
568355b4669Sjacobs 		if (putprinter(dest, p) == -1) {
569355b4669Sjacobs 			if ((errno == EPERM) || (errno == EACCES))
570355b4669Sjacobs 				result = PAPI_NOT_AUTHORIZED;
571355b4669Sjacobs 			else
572355b4669Sjacobs 				result = PAPI_NOT_POSSIBLE;
573355b4669Sjacobs 		} else
574355b4669Sjacobs 			result = PAPI_OK;
575355b4669Sjacobs 
576355b4669Sjacobs 		freeprinter(p);
577355b4669Sjacobs 	}
578355b4669Sjacobs 
579355b4669Sjacobs 	/* tell the scheduler about the changes */
580355b4669Sjacobs 	if (result == PAPI_OK)
581355b4669Sjacobs 		result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER);
582355b4669Sjacobs 
583355b4669Sjacobs 	return (result);
584355b4669Sjacobs }
585355b4669Sjacobs 
586355b4669Sjacobs papi_status_t
lpsched_add_modify_printer(papi_service_t handle,char * dest,papi_attribute_t ** attributes,int type)587355b4669Sjacobs lpsched_add_modify_printer(papi_service_t handle, char *dest,
588355b4669Sjacobs 		papi_attribute_t **attributes, int type)
589355b4669Sjacobs {
590355b4669Sjacobs 	PRINTER *p;
591355b4669Sjacobs 	papi_status_t result;
592355b4669Sjacobs 
593355b4669Sjacobs 	if (type == 0) {
594355b4669Sjacobs 		if ((p = calloc(1, sizeof (*p))) != NULL) {
595355b4669Sjacobs 			p->name = strdup(dest);
596355b4669Sjacobs 			p->banner = BAN_ALWAYS;
597355b4669Sjacobs 			p->interface = strdup("/usr/lib/lp/model/uri");
598355b4669Sjacobs 			p->fault_alert.shcmd = strdup("mail");
599355b4669Sjacobs 		}
600355b4669Sjacobs 	} else
601355b4669Sjacobs 		p = getprinter(dest);
602355b4669Sjacobs 
603355b4669Sjacobs 	if (p != NULL) {
604355b4669Sjacobs 		attributes_to_printer(attributes, p);
605355b4669Sjacobs 
606355b4669Sjacobs 		if (putprinter(dest, p) == -1) {
607355b4669Sjacobs 			if ((errno == EPERM) || (errno == EACCES))
608355b4669Sjacobs 				result = PAPI_NOT_AUTHORIZED;
609355b4669Sjacobs 			else
610355b4669Sjacobs 				result = PAPI_NOT_POSSIBLE;
611355b4669Sjacobs 		} else
612355b4669Sjacobs 			result = PAPI_OK;
613355b4669Sjacobs 
614355b4669Sjacobs 		freeprinter(p);
615355b4669Sjacobs 	} else
616355b4669Sjacobs 		result = PAPI_NOT_POSSIBLE;
617355b4669Sjacobs 
618355b4669Sjacobs 	/* tell the scheduler about the changes */
619355b4669Sjacobs 	if (result == PAPI_OK)
620355b4669Sjacobs 		result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER);
621355b4669Sjacobs 
622355b4669Sjacobs 	return (result);
623355b4669Sjacobs }
624