8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / lp / lib / papi / lpsched-msgs.c
blob2d64912d0815380a3ae2638a34d0adc8cd905683
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 /*LINTLIBRARY*/
30 #include <stdio.h>
31 #include <stdarg.h>
32 #include <libintl.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <errno.h>
38 /* lpsched include files */
39 #include "lp.h"
40 #include "msgs.h"
41 #include "printers.h"
42 #include "class.h"
44 #include <papi_impl.h>
48 * Format and send message to lpsched (die if any errors occur)
50 /*VARARGS1*/
51 int
52 snd_msg(service_t *svc, int type, ...)
54 int rc = -1;
55 va_list ap;
57 if (svc == NULL)
58 return (-1);
60 /* fill the message buffer */
61 va_start(ap, type);
62 rc = _putmessage(svc->msgbuf, type, ap);
63 va_end(ap);
64 if (rc < 0) {
65 detailed_error(svc,
66 gettext("unable to build message for scheduler: %s"),
67 strerror(errno));
68 return (rc);
71 /* write the message */
72 while (((rc = mwrite(svc->md, svc->msgbuf)) < 0) && (errno == EINTR)) {
75 if (rc < 0)
76 detailed_error(svc,
77 gettext("unable to send message to scheduler: %s"),
78 strerror(errno));
79 return (rc);
83 * Receive message from lpsched (die if any errors occur)
85 int
86 rcv_msg(service_t *svc, int type, ...)
88 int rc = -1;
90 if (svc == NULL)
91 return (-1);
93 /* read the message */
94 while (((rc = mread(svc->md, svc->msgbuf, svc->msgbuf_size)) < 0) &&
95 (errno == EINTR)) {
98 if (rc < 0)
99 detailed_error(svc,
100 gettext("unable to read message from scheduler: %s"),
101 strerror(errno));
102 else {
103 va_list ap;
105 va_start(ap, type);
106 rc = _getmessage(svc->msgbuf, type, ap);
107 va_end(ap);
109 if (rc < 0)
110 detailed_error(svc,
111 gettext("unable to parse message from scheduler: %s"),
112 strerror(errno));
115 return (rc);
118 papi_status_t
119 lpsched_status_to_papi_status(int status)
121 switch (status) {
122 case MNOMEM:
123 return (PAPI_TEMPORARY_ERROR);
124 case MNOFILTER:
125 return (PAPI_DOCUMENT_FORMAT_ERROR);
126 case MNOOPEN:
127 return (PAPI_DOCUMENT_ACCESS_ERROR);
128 case MERRDEST:
129 case MDENYDEST:
130 return (PAPI_NOT_ACCEPTING);
131 case MNOMEDIA:
132 return (PAPI_PRINT_SUPPORT_FILE_NOT_FOUND);
133 case MDENYMEDIA:
134 case MNOPERM:
135 return (PAPI_NOT_AUTHORIZED);
136 case MUNKNOWN:
137 case MNODEST:
138 case MNOINFO:
139 return (PAPI_NOT_FOUND);
140 case MTRANSMITERR:
141 return (PAPI_SERVICE_UNAVAILABLE);
142 case M2LATE:
143 return (PAPI_GONE);
144 case MBUSY:
145 return (PAPI_PRINTER_BUSY);
146 case MOK:
147 case MOKMORE:
148 return (PAPI_OK);
151 return (PAPI_INTERNAL_ERROR);
154 char *
155 lpsched_status_string(short status)
157 switch (status) {
158 case MNOMEM:
159 return (gettext("lpsched: out of memory"));
160 case MNOFILTER:
161 return (gettext("No filter available to convert job"));
162 case MNOOPEN:
163 return (gettext("lpsched: could not open request"));
164 case MERRDEST:
165 return (gettext("queue disabled"));
166 case MDENYDEST:
167 return (gettext("destination denied request"));
168 case MNOMEDIA:
169 return (gettext("unknown form specified in job"));
170 case MDENYMEDIA:
171 return (gettext("access denied to form specified in job"));
172 case MUNKNOWN:
173 return (gettext("no such resource"));
174 case MNODEST:
175 return (gettext("unknown destination"));
176 case MNOPERM:
177 return (gettext("permission denied"));
178 case MNOINFO:
179 return (gettext("no information available"));
180 case MTRANSMITERR:
181 return (gettext("failure to communicate with lpsched"));
182 default: {
183 static char result[16];
185 snprintf(result, sizeof (result), gettext("status: %d"),
186 status);
187 return (result);
192 papi_status_t
193 lpsched_alloc_files(papi_service_t svc, int number, char **prefix)
195 papi_status_t result = PAPI_OK;
196 short status = MOK;
198 if ((svc == NULL) || (prefix == NULL))
199 return (PAPI_BAD_ARGUMENT);
201 if ((snd_msg(svc, S_ALLOC_FILES, number) < 0) ||
202 (rcv_msg(svc, R_ALLOC_FILES, &status, prefix) < 0))
203 status = MTRANSMITERR;
205 if (status != MOK) {
206 detailed_error(svc,
207 gettext("failed to allocate %d file(s) for request: %s"),
208 number, lpsched_status_string(status));
209 result = lpsched_status_to_papi_status(status);
212 return (result);
215 papi_status_t
216 lpsched_commit_job(papi_service_t svc, char *job, char **tmp)
217 /* job is host/req-id */
219 papi_status_t result = PAPI_OK;
220 short status = MOK;
221 long bits;
223 if ((svc == NULL) || (job == NULL) || (tmp == NULL))
224 return (PAPI_BAD_ARGUMENT);
226 if ((snd_msg(svc, S_PRINT_REQUEST, job) < 0) ||
227 (rcv_msg(svc, R_PRINT_REQUEST, &status, tmp, &bits) < 0))
228 status = MTRANSMITERR;
230 if (status != MOK) {
231 detailed_error(svc, gettext("failed to commit job (%s): %s"),
232 job, lpsched_status_string(status));
233 result = lpsched_status_to_papi_status(status);
236 return (result);
239 papi_status_t
240 lpsched_start_change(papi_service_t svc, char *printer, int32_t job_id,
241 char **tmp)
243 papi_status_t result = PAPI_OK;
244 short status = MOK;
245 char req[BUFSIZ];
246 char *dest;
248 if ((svc == NULL) || (printer == NULL) || (job_id < 0))
249 return (PAPI_BAD_ARGUMENT);
251 dest = printer_name_from_uri_id(printer, job_id);
252 snprintf(req, sizeof (req), "%s-%d", dest, job_id);
253 free(dest);
255 if ((snd_msg(svc, S_START_CHANGE_REQUEST, req) < 0) ||
256 (rcv_msg(svc, R_START_CHANGE_REQUEST, &status, tmp) < 0))
257 status = MTRANSMITERR;
259 if (status != MOK) {
260 detailed_error(svc,
261 gettext("failed to initiate change for job (%s-%d): %s"),
262 printer,
263 job_id, lpsched_status_string(status));
264 result = lpsched_status_to_papi_status(status);
267 return (result);
270 papi_status_t
271 lpsched_end_change(papi_service_t svc, char *printer, int32_t job_id)
273 papi_status_t result = PAPI_OK;
274 short status = MOK;
275 long bits;
276 char req[BUFSIZ];
277 char *dest;
279 if ((svc == NULL) || (printer == NULL) || (job_id < 0))
280 return (PAPI_BAD_ARGUMENT);
282 dest = printer_name_from_uri_id(printer, job_id);
283 snprintf(req, sizeof (req), "%s-%d", dest, job_id);
284 free(dest);
286 if ((snd_msg(svc, S_END_CHANGE_REQUEST, req) < 0) ||
287 (rcv_msg(svc, R_END_CHANGE_REQUEST, &status, &bits) < 0))
288 status = MTRANSMITERR;
290 if (status != MOK) {
291 detailed_error(svc,
292 gettext("failed to commit change for job (%s-%d): %s"), printer,
293 job_id, lpsched_status_string(status));
294 result = lpsched_status_to_papi_status(status);
297 return (result);
300 papi_status_t
301 lpsched_accept_printer(papi_service_t svc, char *printer)
303 papi_status_t result = PAPI_OK;
304 short status = MOK;
305 char *req_id;
306 char *dest;
308 if ((svc == NULL) || (printer == NULL))
309 return (PAPI_BAD_ARGUMENT);
311 dest = printer_name_from_uri_id(printer, -1);
312 if ((snd_msg(svc, S_ACCEPT_DEST, dest) < 0) ||
313 (rcv_msg(svc, R_ACCEPT_DEST, &status, &req_id) < 0))
314 status = MTRANSMITERR;
315 free(dest);
317 if ((status != MOK) && (status != MERRDEST)) {
318 detailed_error(svc, "%s: %s", printer,
319 lpsched_status_string(status));
321 result = lpsched_status_to_papi_status(status);
323 return (result);
326 papi_status_t
327 lpsched_reject_printer(papi_service_t svc, char *printer, char *message)
329 papi_status_t result = PAPI_OK;
330 short status = MOK;
331 char *req_id;
332 char *dest;
334 if ((svc == NULL) || (printer == NULL))
335 return (PAPI_BAD_ARGUMENT);
337 if (message == NULL)
338 message = "stopped by user";
340 dest = printer_name_from_uri_id(printer, -1);
341 if ((snd_msg(svc, S_REJECT_DEST, dest, message, 0) < 0) ||
342 (rcv_msg(svc, R_REJECT_DEST, &status, &req_id) < 0))
343 status = MTRANSMITERR;
344 free(dest);
346 if ((status != MOK) && (status != MERRDEST)) {
347 detailed_error(svc, "%s: %s", printer,
348 lpsched_status_string(status));
350 result = lpsched_status_to_papi_status(status);
352 return (result);
355 papi_status_t
356 lpsched_enable_printer(papi_service_t svc, char *printer)
358 papi_status_t result = PAPI_OK;
359 short status = MOK;
360 char *req_id;
361 char *dest;
363 if ((svc == NULL) || (printer == NULL))
364 return (PAPI_BAD_ARGUMENT);
366 dest = printer_name_from_uri_id(printer, -1);
367 if ((snd_msg(svc, S_ENABLE_DEST, dest) < 0) ||
368 (rcv_msg(svc, R_ENABLE_DEST, &status, &req_id) < 0))
369 status = MTRANSMITERR;
370 free(dest);
372 if ((status != MOK) && (status != MERRDEST)) {
373 detailed_error(svc, "%s: %s", printer,
374 lpsched_status_string(status));
376 result = lpsched_status_to_papi_status(status);
378 return (result);
381 papi_status_t
382 lpsched_disable_printer(papi_service_t svc, char *printer, char *message)
384 papi_status_t result = PAPI_OK;
385 short status = MOK;
386 char *req_id;
387 char *dest;
389 if ((svc == NULL) || (printer == NULL))
390 return (PAPI_BAD_ARGUMENT);
392 if (message == NULL)
393 message = "stopped by user";
395 dest = printer_name_from_uri_id(printer, -1);
396 if ((snd_msg(svc, S_DISABLE_DEST, dest, message, 0) < 0) ||
397 (rcv_msg(svc, R_DISABLE_DEST, &status, &req_id) < 0))
398 status = MTRANSMITERR;
399 free(dest);
401 if ((status != MOK) && (status != MERRDEST)) {
402 detailed_error(svc, "%s: %s", printer,
403 lpsched_status_string(status));
405 result = lpsched_status_to_papi_status(status);
407 return (result);
410 papi_status_t
411 lpsched_load_unload_dest(papi_service_t handle, char *dest, int type)
413 service_t *svc = handle;
414 papi_status_t result;
415 short status = MOK;
417 /* tell the scheduler it's going */
418 if (snd_msg(svc, type, dest, "", "") < 0)
419 return (PAPI_SERVICE_UNAVAILABLE);
421 switch (type) {
422 case S_LOAD_PRINTER:
423 type = R_LOAD_PRINTER;
424 break;
425 case S_UNLOAD_PRINTER:
426 type = R_UNLOAD_PRINTER;
427 break;
428 case S_LOAD_CLASS:
429 type = R_LOAD_CLASS;
430 break;
431 case S_UNLOAD_CLASS:
432 type = R_UNLOAD_CLASS;
435 if (rcv_msg(svc, type, &status) < 0)
436 return (PAPI_SERVICE_UNAVAILABLE);
438 result = lpsched_status_to_papi_status(status);
440 return (result);
443 papi_status_t
444 lpsched_remove_class(papi_service_t handle, char *dest)
446 papi_status_t result;
448 /* tell the scheduler it's going */
449 result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_CLASS);
451 if (result == PAPI_OK) {
452 /* remove the scheduler config files */
453 if (delclass(dest) == -1)
454 result = PAPI_SERVICE_UNAVAILABLE;
457 return (result);
460 static void
461 remove_from_class(papi_service_t handle, char *dest, CLASS *cls)
463 if (dellist(&cls->members, dest) == 0) {
464 if (cls->members != NULL) {
465 if (putclass(cls->name, cls) == 0)
466 (void) lpsched_load_unload_dest(handle,
467 cls->name, S_LOAD_CLASS);
468 } else
469 (void) lpsched_remove_class(handle, cls->name);
473 papi_status_t
474 lpsched_remove_printer(papi_service_t handle, char *dest)
477 papi_status_t result;
479 /* tell the scheduler it's going */
480 result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_PRINTER);
482 if (result == PAPI_OK) {
483 CLASS *cls;
484 char *dflt;
486 /* remove the scheduler config files */
487 if (delprinter(dest) == -1)
488 return (PAPI_SERVICE_UNAVAILABLE);
490 /* remove from any classes */
491 while ((cls = getclass(NAME_ALL)) != NULL) {
492 if (searchlist(dest, cls->members) != 0)
493 remove_from_class(handle, dest, cls);
494 freeclass(cls);
497 /* reset the default if it needs to be done */
498 if (((dflt = getdefault()) != NULL) &&
499 (strcmp(dflt, dest) == 0))
500 putdefault(NAME_NONE);
503 return (result);
506 papi_status_t
507 lpsched_add_modify_class(papi_service_t handle, char *dest,
508 papi_attribute_t **attributes)
510 papi_status_t result;
511 void *iter = NULL;
512 char **members = NULL;
513 char *member;
516 * The only attribute that we can modify for a class is the set of
517 * members. Anything else will be ignored.
519 for (result = papiAttributeListGetString(attributes, &iter,
520 "member-names", &member);
521 result == PAPI_OK;
522 result = papiAttributeListGetString(attributes, &iter,
523 NULL, &member))
524 addlist(&members, member);
526 if (members != NULL) {
527 /* modify the configuration file */
528 CLASS class;
530 memset(&class, 0, sizeof (class));
531 class.name = dest;
532 class.members = members;
534 if (putclass(dest, &class) == -1) {
535 if ((errno == EPERM) || (errno == EACCES))
536 result = PAPI_NOT_AUTHORIZED;
537 else
538 result = PAPI_NOT_POSSIBLE;
539 } else
540 result = PAPI_OK;
542 freelist(members);
543 } else
544 result = PAPI_ATTRIBUTES;
546 /* tell the scheduler about the changes */
547 if (result == PAPI_OK)
548 result = lpsched_load_unload_dest(handle, dest, S_LOAD_CLASS);
550 return (result);
553 papi_status_t
554 lpsched_add_printer(papi_service_t handle, char *dest,
555 papi_attribute_t **attributes)
557 PRINTER *p;
558 papi_status_t result = PAPI_TEMPORARY_ERROR;
560 if ((p = calloc(1, sizeof (*p))) != NULL) {
561 p->name = strdup(dest);
562 p->banner = BAN_ALWAYS;
563 p->interface = strdup("/usr/lib/lp/model/uri");
564 p->fault_alert.shcmd = strdup("mail");
566 attributes_to_printer(attributes, p);
568 if (putprinter(dest, p) == -1) {
569 if ((errno == EPERM) || (errno == EACCES))
570 result = PAPI_NOT_AUTHORIZED;
571 else
572 result = PAPI_NOT_POSSIBLE;
573 } else
574 result = PAPI_OK;
576 freeprinter(p);
579 /* tell the scheduler about the changes */
580 if (result == PAPI_OK)
581 result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER);
583 return (result);
586 papi_status_t
587 lpsched_add_modify_printer(papi_service_t handle, char *dest,
588 papi_attribute_t **attributes, int type)
590 PRINTER *p;
591 papi_status_t result;
593 if (type == 0) {
594 if ((p = calloc(1, sizeof (*p))) != NULL) {
595 p->name = strdup(dest);
596 p->banner = BAN_ALWAYS;
597 p->interface = strdup("/usr/lib/lp/model/uri");
598 p->fault_alert.shcmd = strdup("mail");
600 } else
601 p = getprinter(dest);
603 if (p != NULL) {
604 attributes_to_printer(attributes, p);
606 if (putprinter(dest, p) == -1) {
607 if ((errno == EPERM) || (errno == EACCES))
608 result = PAPI_NOT_AUTHORIZED;
609 else
610 result = PAPI_NOT_POSSIBLE;
611 } else
612 result = PAPI_OK;
614 freeprinter(p);
615 } else
616 result = PAPI_NOT_POSSIBLE;
618 /* tell the scheduler about the changes */
619 if (result == PAPI_OK)
620 result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER);
622 return (result);