xref: /illumos-gate/usr/src/cmd/lp/lib/papi/lpsched-msgs.c (revision 03831d35)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*LINTLIBRARY*/
30 
31 #include <stdio.h>
32 #include <stdarg.h>
33 #include <libintl.h>
34 #include <string.h>
35 #include <stdlib.h>
36 
37 
38 /* lpsched include files */
39 #include "lp.h"
40 #include "msgs.h"
41 #include "printers.h"
42 
43 #include <papi_impl.h>
44 
45 
46 /*
47  * Format and send message to lpsched (die if any errors occur)
48  */
49 /*VARARGS1*/
50 int
51 snd_msg(service_t *svc, int type, ...)
52 {
53 	int rc = -1;
54 	va_list	ap;
55 
56 	if (svc == NULL)
57 		return (-1);
58 
59 	/* fill the message buffer */
60 	va_start(ap, type);
61 	rc = _putmessage(svc->msgbuf, type, ap);
62 	va_end(ap);
63 	if (rc < 0) {
64 		detailed_error(svc,
65 			gettext("unable to build message for scheduler: %s"),
66 				strerror(errno));
67 		return (rc);
68 	}
69 
70 	/* write the message */
71 	while (((rc = mwrite(svc->md, svc->msgbuf)) < 0) && (errno == EINTR));
72 
73 	if (rc < 0)
74 		detailed_error(svc,
75 			gettext("unable to send message to scheduler: %s"),
76 				strerror(errno));
77 	return (rc);
78 }
79 
80 /*
81  * Receive message from lpsched (die if any errors occur)
82  */
83 int
84 rcv_msg(service_t *svc, int type, ...)
85 {
86 	int rc = -1;
87 
88 	if (svc == NULL)
89 		return (-1);
90 
91 	/* read the message */
92 	while (((rc = mread(svc->md, svc->msgbuf, svc->msgbuf_size)) < 0) &&
93 		(errno == EINTR));
94 
95 	if (rc < 0)
96 		detailed_error(svc,
97 			gettext("unable to read message from scheduler: %s"),
98 				strerror(errno));
99 	else {
100 		va_list ap;
101 
102 		va_start(ap, type);
103 		rc = _getmessage(svc->msgbuf, type, ap);
104 		va_end(ap);
105 
106 		if (rc < 0)
107 			detailed_error(svc,
108 			gettext("unable to parse message from scheduler: %s"),
109 				strerror(errno));
110 	}
111 
112 	return (rc);
113 }
114 
115 papi_status_t
116 lpsched_status_to_papi_status(int status)
117 {
118 	switch (status) {
119 	case MNOMEM:
120 		return (PAPI_TEMPORARY_ERROR);
121 	case MNOFILTER:
122 		return (PAPI_DOCUMENT_FORMAT_ERROR);
123 	case MNOOPEN:
124 		return (PAPI_DOCUMENT_ACCESS_ERROR);
125 	case MERRDEST:
126 		return (PAPI_DEVICE_ERROR);
127 	case MDENYDEST:
128 		return (PAPI_NOT_ACCEPTING);
129 	case MNOMEDIA:
130 		return (PAPI_PRINT_SUPPORT_FILE_NOT_FOUND);
131 	case MDENYMEDIA:
132 	case MNOPERM:
133 		return (PAPI_NOT_AUTHORIZED);
134 	case MUNKNOWN:
135 	case MNODEST:
136 	case MNOINFO:
137 		return (PAPI_NOT_FOUND);
138 	case MTRANSMITERR:
139 		return (PAPI_SERVICE_UNAVAILABLE);
140 	case M2LATE:
141 		return (PAPI_GONE);
142 	case MOK:
143 	case MOKMORE:
144 		return (PAPI_OK);
145 	}
146 
147 	return (PAPI_INTERNAL_ERROR);
148 }
149 
150 char *
151 lpsched_status_string(short status)
152 {
153 		switch (status) {
154 	case MNOMEM:
155 		return (gettext("lpsched: out of memory"));
156 	case MNOFILTER:
157 		return (gettext("No filter available to convert job"));
158 	case MNOOPEN:
159 		return (gettext("lpsched: could not open request"));
160 	case MERRDEST:
161 		return (gettext("An error occured in submission"));
162 	case MDENYDEST:
163 		return (gettext("destination denied request"));
164 	case MNOMEDIA:
165 		return (gettext("unknown form specified in job"));
166 	case MDENYMEDIA:
167 		return (gettext("access denied to form specified in job"));
168 	case MUNKNOWN:
169 		return (gettext("no such resource"));
170 	case MNODEST:
171 		return (gettext("unknown destination"));
172 	case MNOPERM:
173 		return (gettext("permission denied"));
174 	case MNOINFO:
175 		return (gettext("no information available"));
176 	case MTRANSMITERR:
177 		return (gettext("failure to communicate with lpsched"));
178 	default: {
179 		static char result[16];
180 
181 		snprintf(result, sizeof (result), gettext("status: %d"),
182 								status);
183 		return (result);
184 		}
185 	}
186 }
187 
188 papi_status_t
189 lpsched_alloc_files(papi_service_t svc, int number, char **prefix)
190 {
191 	papi_status_t result = PAPI_OK;
192 	short status = MOK;
193 
194 	if ((svc == NULL) || (prefix == NULL))
195 		return (PAPI_BAD_ARGUMENT);
196 
197 	if ((snd_msg(svc, S_ALLOC_FILES, number) < 0) ||
198 	    (rcv_msg(svc, R_ALLOC_FILES, &status, prefix) < 0))
199 		status = MTRANSMITERR;
200 
201 	if (status != MOK) {
202 		detailed_error(svc,
203 		gettext("failed to allocate %d file(s) for request: %s"),
204 			number, lpsched_status_string(status));
205 		result = lpsched_status_to_papi_status(status);
206 	}
207 
208 	return (result);
209 }
210 
211 papi_status_t
212 lpsched_commit_job(papi_service_t svc, char *job, char **tmp)
213 /* job is host/req-id */
214 {
215 	papi_status_t result = PAPI_OK;
216 	short status = MOK;
217 	long bits;
218 
219 	if ((svc == NULL) || (job == NULL) || (tmp == NULL))
220 		return (PAPI_BAD_ARGUMENT);
221 
222 	if ((snd_msg(svc, S_PRINT_REQUEST, job) < 0) ||
223 	    (rcv_msg(svc, R_PRINT_REQUEST, &status, tmp, &bits) < 0))
224 		status = MTRANSMITERR;
225 
226 	if (status != MOK) {
227 		detailed_error(svc, gettext("failed to commit job (%s): %s"),
228 			job, lpsched_status_string(status));
229 		result = lpsched_status_to_papi_status(status);
230 	}
231 
232 	return (result);
233 }
234 
235 papi_status_t
236 lpsched_start_change(papi_service_t svc, const char *printer, int32_t job_id,
237 		char **tmp)
238 {
239 	papi_status_t result = PAPI_OK;
240 	short status = MOK;
241 	char req[BUFSIZ];
242 	char *dest;
243 
244 	if ((svc == NULL) || (printer == NULL) || (job_id < 0))
245 		return (PAPI_BAD_ARGUMENT);
246 
247 	dest = printer_name_from_uri_id(printer, job_id);
248 	snprintf(req, sizeof (req), "%s-%d", dest, job_id);
249 	free(dest);
250 
251 	if ((snd_msg(svc, S_START_CHANGE_REQUEST, req) < 0) ||
252 	    (rcv_msg(svc, R_START_CHANGE_REQUEST, &status, tmp) < 0))
253 		status = MTRANSMITERR;
254 
255 	if (status != MOK) {
256 		detailed_error(svc,
257 		gettext("failed to initiate change for job (%s-%d): %s"),
258 			printer,
259 			job_id, lpsched_status_string(status));
260 		result = lpsched_status_to_papi_status(status);
261 	}
262 
263 	return (result);
264 }
265 
266 papi_status_t
267 lpsched_end_change(papi_service_t svc, const char *printer, int32_t job_id)
268 {
269 	papi_status_t result = PAPI_OK;
270 	short status = MOK;
271 	long bits;
272 	char req[BUFSIZ];
273 	char *dest;
274 
275 	if ((svc == NULL) || (printer == NULL) || (job_id < 0))
276 		return (PAPI_BAD_ARGUMENT);
277 
278 	dest = printer_name_from_uri_id(printer, job_id);
279 	snprintf(req, sizeof (req), "%s-%d", dest, job_id);
280 	free(dest);
281 
282 	if ((snd_msg(svc, S_END_CHANGE_REQUEST, req) < 0) ||
283 	    (rcv_msg(svc, R_END_CHANGE_REQUEST, &status, &bits) < 0))
284 		status = MTRANSMITERR;
285 
286 	if (status != MOK) {
287 		detailed_error(svc,
288 		gettext("failed to commit change for job (%s-%d): %s"), printer,
289 			job_id, lpsched_status_string(status));
290 		result = lpsched_status_to_papi_status(status);
291 	}
292 
293 	return (result);
294 }
295 
296 papi_status_t
297 lpsched_enable_printer(papi_service_t svc, const char *printer)
298 {
299 	papi_status_t result = PAPI_OK;
300 	short	 status;
301 	char	*req_id;
302 	char *dest;
303 
304 	if ((svc == NULL) || (printer == NULL))
305 		return (PAPI_BAD_ARGUMENT);
306 
307 	dest = printer_name_from_uri_id(printer, -1);
308 	if ((snd_msg(svc, S_ENABLE_DEST, dest) < 0) ||
309 	    (rcv_msg(svc, R_ENABLE_DEST, &status, &req_id) < 0))
310 		status = MTRANSMITERR;
311 	free(dest);
312 
313 	if ((status != MOK) && (status != MERRDEST)) {
314 		detailed_error(svc, "%s: %s", printer,
315 			lpsched_status_string(status));
316 		result = lpsched_status_to_papi_status(status);
317 	}
318 
319 	return (result);
320 }
321 
322 papi_status_t
323 lpsched_disable_printer(papi_service_t svc, const char *printer,
324 		const char *message)
325 {
326 	papi_status_t result = PAPI_OK;
327 	short	 status;
328 	char	*req_id;
329 	char *dest;
330 
331 	if ((svc == NULL) || (printer == NULL))
332 		return (PAPI_BAD_ARGUMENT);
333 
334 	if (message == NULL)
335 		message = "stopped by user";
336 
337 	dest = printer_name_from_uri_id(printer, -1);
338 	if ((snd_msg(svc, S_DISABLE_DEST, dest, message, 0) < 0) ||
339 	    (rcv_msg(svc, R_DISABLE_DEST, &status, &req_id) < 0))
340 		status = MTRANSMITERR;
341 	free(dest);
342 
343 	if ((status != MOK) && (status != MERRDEST)) {
344 		detailed_error(svc, "%s: %s", printer,
345 			lpsched_status_string(status));
346 		result = lpsched_status_to_papi_status(status);
347 	}
348 
349 	return (result);
350 }
351