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]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
38 /* lpsched include files */
44 #include <papi_impl.h>
48 * Format and send message to lpsched (die if any errors occur)
52 snd_msg(service_t
*svc
, int type
, ...)
60 /* fill the message buffer */
62 rc
= _putmessage(svc
->msgbuf
, type
, ap
);
66 gettext("unable to build message for scheduler: %s"),
71 /* write the message */
72 while (((rc
= mwrite(svc
->md
, svc
->msgbuf
)) < 0) && (errno
== EINTR
)) {
77 gettext("unable to send message to scheduler: %s"),
83 * Receive message from lpsched (die if any errors occur)
86 rcv_msg(service_t
*svc
, int type
, ...)
93 /* read the message */
94 while (((rc
= mread(svc
->md
, svc
->msgbuf
, svc
->msgbuf_size
)) < 0) &&
100 gettext("unable to read message from scheduler: %s"),
106 rc
= _getmessage(svc
->msgbuf
, type
, ap
);
111 gettext("unable to parse message from scheduler: %s"),
119 lpsched_status_to_papi_status(int status
)
123 return (PAPI_TEMPORARY_ERROR
);
125 return (PAPI_DOCUMENT_FORMAT_ERROR
);
127 return (PAPI_DOCUMENT_ACCESS_ERROR
);
130 return (PAPI_NOT_ACCEPTING
);
132 return (PAPI_PRINT_SUPPORT_FILE_NOT_FOUND
);
135 return (PAPI_NOT_AUTHORIZED
);
139 return (PAPI_NOT_FOUND
);
141 return (PAPI_SERVICE_UNAVAILABLE
);
145 return (PAPI_PRINTER_BUSY
);
151 return (PAPI_INTERNAL_ERROR
);
155 lpsched_status_string(short status
)
159 return (gettext("lpsched: out of memory"));
161 return (gettext("No filter available to convert job"));
163 return (gettext("lpsched: could not open request"));
165 return (gettext("queue disabled"));
167 return (gettext("destination denied request"));
169 return (gettext("unknown form specified in job"));
171 return (gettext("access denied to form specified in job"));
173 return (gettext("no such resource"));
175 return (gettext("unknown destination"));
177 return (gettext("permission denied"));
179 return (gettext("no information available"));
181 return (gettext("failure to communicate with lpsched"));
183 static char result
[16];
185 snprintf(result
, sizeof (result
), gettext("status: %d"),
193 lpsched_alloc_files(papi_service_t svc
, int number
, char **prefix
)
195 papi_status_t result
= PAPI_OK
;
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
;
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
);
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
;
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
;
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
);
240 lpsched_start_change(papi_service_t svc
, char *printer
, int32_t job_id
,
243 papi_status_t result
= PAPI_OK
;
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
);
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
;
261 gettext("failed to initiate change for job (%s-%d): %s"),
263 job_id
, lpsched_status_string(status
));
264 result
= lpsched_status_to_papi_status(status
);
271 lpsched_end_change(papi_service_t svc
, char *printer
, int32_t job_id
)
273 papi_status_t result
= PAPI_OK
;
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
);
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
;
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
);
301 lpsched_accept_printer(papi_service_t svc
, char *printer
)
303 papi_status_t result
= PAPI_OK
;
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
;
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
);
327 lpsched_reject_printer(papi_service_t svc
, char *printer
, char *message
)
329 papi_status_t result
= PAPI_OK
;
334 if ((svc
== NULL
) || (printer
== NULL
))
335 return (PAPI_BAD_ARGUMENT
);
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
;
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
);
356 lpsched_enable_printer(papi_service_t svc
, char *printer
)
358 papi_status_t result
= PAPI_OK
;
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
;
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
);
382 lpsched_disable_printer(papi_service_t svc
, char *printer
, char *message
)
384 papi_status_t result
= PAPI_OK
;
389 if ((svc
== NULL
) || (printer
== NULL
))
390 return (PAPI_BAD_ARGUMENT
);
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
;
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
);
411 lpsched_load_unload_dest(papi_service_t handle
, char *dest
, int type
)
413 service_t
*svc
= handle
;
414 papi_status_t result
;
417 /* tell the scheduler it's going */
418 if (snd_msg(svc
, type
, dest
, "", "") < 0)
419 return (PAPI_SERVICE_UNAVAILABLE
);
423 type
= R_LOAD_PRINTER
;
425 case S_UNLOAD_PRINTER
:
426 type
= R_UNLOAD_PRINTER
;
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
);
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
;
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
);
469 (void) lpsched_remove_class(handle
, cls
->name
);
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
) {
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
);
497 /* reset the default if it needs to be done */
498 if (((dflt
= getdefault()) != NULL
) &&
499 (strcmp(dflt
, dest
) == 0))
500 putdefault(NAME_NONE
);
507 lpsched_add_modify_class(papi_service_t handle
, char *dest
,
508 papi_attribute_t
**attributes
)
510 papi_status_t result
;
512 char **members
= NULL
;
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
);
522 result
= papiAttributeListGetString(attributes
, &iter
,
524 addlist(&members
, member
);
526 if (members
!= NULL
) {
527 /* modify the configuration file */
530 memset(&class, 0, sizeof (class));
532 class.members
= members
;
534 if (putclass(dest
, &class) == -1) {
535 if ((errno
== EPERM
) || (errno
== EACCES
))
536 result
= PAPI_NOT_AUTHORIZED
;
538 result
= PAPI_NOT_POSSIBLE
;
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
);
554 lpsched_add_printer(papi_service_t handle
, char *dest
,
555 papi_attribute_t
**attributes
)
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
;
572 result
= PAPI_NOT_POSSIBLE
;
579 /* tell the scheduler about the changes */
580 if (result
== PAPI_OK
)
581 result
= lpsched_load_unload_dest(handle
, dest
, S_LOAD_PRINTER
);
587 lpsched_add_modify_printer(papi_service_t handle
, char *dest
,
588 papi_attribute_t
**attributes
, int type
)
591 papi_status_t result
;
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");
601 p
= getprinter(dest
);
604 attributes_to_printer(attributes
, p
);
606 if (putprinter(dest
, p
) == -1) {
607 if ((errno
== EPERM
) || (errno
== EACCES
))
608 result
= PAPI_NOT_AUTHORIZED
;
610 result
= PAPI_NOT_POSSIBLE
;
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
);