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 */ 21*3125Sjacobs 220Sstevel@tonic-gate /* 232264Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 280Sstevel@tonic-gate 290Sstevel@tonic-gate /*LINTLIBRARY*/ 300Sstevel@tonic-gate 310Sstevel@tonic-gate #include <stdio.h> 320Sstevel@tonic-gate #include <stdarg.h> 330Sstevel@tonic-gate #include <libintl.h> 340Sstevel@tonic-gate #include <string.h> 350Sstevel@tonic-gate #include <stdlib.h> 362264Sjacobs #include <errno.h> 370Sstevel@tonic-gate 380Sstevel@tonic-gate 390Sstevel@tonic-gate /* lpsched include files */ 400Sstevel@tonic-gate #include "lp.h" 410Sstevel@tonic-gate #include "msgs.h" 420Sstevel@tonic-gate #include "printers.h" 432264Sjacobs #include "class.h" 440Sstevel@tonic-gate 450Sstevel@tonic-gate #include <papi_impl.h> 460Sstevel@tonic-gate 470Sstevel@tonic-gate 480Sstevel@tonic-gate /* 490Sstevel@tonic-gate * Format and send message to lpsched (die if any errors occur) 500Sstevel@tonic-gate */ 510Sstevel@tonic-gate /*VARARGS1*/ 520Sstevel@tonic-gate int 530Sstevel@tonic-gate snd_msg(service_t *svc, int type, ...) 540Sstevel@tonic-gate { 550Sstevel@tonic-gate int rc = -1; 560Sstevel@tonic-gate va_list ap; 570Sstevel@tonic-gate 580Sstevel@tonic-gate if (svc == NULL) 590Sstevel@tonic-gate return (-1); 600Sstevel@tonic-gate 610Sstevel@tonic-gate /* fill the message buffer */ 620Sstevel@tonic-gate va_start(ap, type); 630Sstevel@tonic-gate rc = _putmessage(svc->msgbuf, type, ap); 640Sstevel@tonic-gate va_end(ap); 650Sstevel@tonic-gate if (rc < 0) { 660Sstevel@tonic-gate detailed_error(svc, 670Sstevel@tonic-gate gettext("unable to build message for scheduler: %s"), 680Sstevel@tonic-gate strerror(errno)); 690Sstevel@tonic-gate return (rc); 700Sstevel@tonic-gate } 710Sstevel@tonic-gate 720Sstevel@tonic-gate /* write the message */ 730Sstevel@tonic-gate while (((rc = mwrite(svc->md, svc->msgbuf)) < 0) && (errno == EINTR)); 740Sstevel@tonic-gate 750Sstevel@tonic-gate if (rc < 0) 760Sstevel@tonic-gate detailed_error(svc, 770Sstevel@tonic-gate gettext("unable to send message to scheduler: %s"), 780Sstevel@tonic-gate 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 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) && 950Sstevel@tonic-gate (errno == EINTR)); 960Sstevel@tonic-gate 970Sstevel@tonic-gate if (rc < 0) 980Sstevel@tonic-gate detailed_error(svc, 990Sstevel@tonic-gate gettext("unable to read message from scheduler: %s"), 1000Sstevel@tonic-gate strerror(errno)); 1010Sstevel@tonic-gate else { 1020Sstevel@tonic-gate va_list ap; 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate va_start(ap, type); 1050Sstevel@tonic-gate rc = _getmessage(svc->msgbuf, type, ap); 1060Sstevel@tonic-gate va_end(ap); 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate if (rc < 0) 1090Sstevel@tonic-gate detailed_error(svc, 1100Sstevel@tonic-gate gettext("unable to parse message from scheduler: %s"), 1110Sstevel@tonic-gate strerror(errno)); 1120Sstevel@tonic-gate } 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate return (rc); 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate papi_status_t 1180Sstevel@tonic-gate lpsched_status_to_papi_status(int status) 1190Sstevel@tonic-gate { 1200Sstevel@tonic-gate switch (status) { 1210Sstevel@tonic-gate case MNOMEM: 1220Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 1230Sstevel@tonic-gate case MNOFILTER: 1240Sstevel@tonic-gate return (PAPI_DOCUMENT_FORMAT_ERROR); 1250Sstevel@tonic-gate case MNOOPEN: 1260Sstevel@tonic-gate return (PAPI_DOCUMENT_ACCESS_ERROR); 1270Sstevel@tonic-gate case MERRDEST: 1280Sstevel@tonic-gate case MDENYDEST: 1290Sstevel@tonic-gate return (PAPI_NOT_ACCEPTING); 1300Sstevel@tonic-gate case MNOMEDIA: 1310Sstevel@tonic-gate return (PAPI_PRINT_SUPPORT_FILE_NOT_FOUND); 1320Sstevel@tonic-gate case MDENYMEDIA: 1330Sstevel@tonic-gate case MNOPERM: 1340Sstevel@tonic-gate return (PAPI_NOT_AUTHORIZED); 1350Sstevel@tonic-gate case MUNKNOWN: 1360Sstevel@tonic-gate case MNODEST: 1370Sstevel@tonic-gate case MNOINFO: 1380Sstevel@tonic-gate return (PAPI_NOT_FOUND); 1390Sstevel@tonic-gate case MTRANSMITERR: 1400Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 1410Sstevel@tonic-gate case M2LATE: 1420Sstevel@tonic-gate return (PAPI_GONE); 1432264Sjacobs case MBUSY: 1442264Sjacobs return (PAPI_PRINTER_BUSY); 1450Sstevel@tonic-gate case MOK: 1460Sstevel@tonic-gate case MOKMORE: 1470Sstevel@tonic-gate return (PAPI_OK); 1480Sstevel@tonic-gate } 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate return (PAPI_INTERNAL_ERROR); 1510Sstevel@tonic-gate } 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate char * 1540Sstevel@tonic-gate lpsched_status_string(short status) 1550Sstevel@tonic-gate { 1560Sstevel@tonic-gate switch (status) { 1570Sstevel@tonic-gate case MNOMEM: 1580Sstevel@tonic-gate return (gettext("lpsched: out of memory")); 1590Sstevel@tonic-gate case MNOFILTER: 1600Sstevel@tonic-gate return (gettext("No filter available to convert job")); 1610Sstevel@tonic-gate case MNOOPEN: 1620Sstevel@tonic-gate return (gettext("lpsched: could not open request")); 1630Sstevel@tonic-gate case MERRDEST: 164*3125Sjacobs return (gettext("queue disabled")); 1650Sstevel@tonic-gate case MDENYDEST: 1660Sstevel@tonic-gate return (gettext("destination denied request")); 1670Sstevel@tonic-gate case MNOMEDIA: 1680Sstevel@tonic-gate return (gettext("unknown form specified in job")); 1690Sstevel@tonic-gate case MDENYMEDIA: 1700Sstevel@tonic-gate return (gettext("access denied to form specified in job")); 1710Sstevel@tonic-gate case MUNKNOWN: 1720Sstevel@tonic-gate return (gettext("no such resource")); 1730Sstevel@tonic-gate case MNODEST: 1740Sstevel@tonic-gate return (gettext("unknown destination")); 1750Sstevel@tonic-gate case MNOPERM: 1760Sstevel@tonic-gate return (gettext("permission denied")); 1770Sstevel@tonic-gate case MNOINFO: 1780Sstevel@tonic-gate return (gettext("no information available")); 1790Sstevel@tonic-gate case MTRANSMITERR: 1800Sstevel@tonic-gate return (gettext("failure to communicate with lpsched")); 1810Sstevel@tonic-gate default: { 1820Sstevel@tonic-gate static char result[16]; 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate snprintf(result, sizeof (result), gettext("status: %d"), 1850Sstevel@tonic-gate status); 1860Sstevel@tonic-gate return (result); 1870Sstevel@tonic-gate } 1880Sstevel@tonic-gate } 1890Sstevel@tonic-gate } 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate papi_status_t 1920Sstevel@tonic-gate lpsched_alloc_files(papi_service_t svc, int number, char **prefix) 1930Sstevel@tonic-gate { 1940Sstevel@tonic-gate papi_status_t result = PAPI_OK; 1950Sstevel@tonic-gate short status = MOK; 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate if ((svc == NULL) || (prefix == NULL)) 1980Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate if ((snd_msg(svc, S_ALLOC_FILES, number) < 0) || 2010Sstevel@tonic-gate (rcv_msg(svc, R_ALLOC_FILES, &status, prefix) < 0)) 2020Sstevel@tonic-gate status = MTRANSMITERR; 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate if (status != MOK) { 2050Sstevel@tonic-gate detailed_error(svc, 2060Sstevel@tonic-gate gettext("failed to allocate %d file(s) for request: %s"), 2070Sstevel@tonic-gate number, lpsched_status_string(status)); 2080Sstevel@tonic-gate result = lpsched_status_to_papi_status(status); 2090Sstevel@tonic-gate } 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate return (result); 2120Sstevel@tonic-gate } 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate papi_status_t 2150Sstevel@tonic-gate lpsched_commit_job(papi_service_t svc, char *job, char **tmp) 2160Sstevel@tonic-gate /* job is host/req-id */ 2170Sstevel@tonic-gate { 2180Sstevel@tonic-gate papi_status_t result = PAPI_OK; 2190Sstevel@tonic-gate short status = MOK; 2200Sstevel@tonic-gate long bits; 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate if ((svc == NULL) || (job == NULL) || (tmp == NULL)) 2230Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate if ((snd_msg(svc, S_PRINT_REQUEST, job) < 0) || 2260Sstevel@tonic-gate (rcv_msg(svc, R_PRINT_REQUEST, &status, tmp, &bits) < 0)) 2270Sstevel@tonic-gate status = MTRANSMITERR; 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate if (status != MOK) { 2300Sstevel@tonic-gate detailed_error(svc, gettext("failed to commit job (%s): %s"), 2310Sstevel@tonic-gate job, lpsched_status_string(status)); 2320Sstevel@tonic-gate result = lpsched_status_to_papi_status(status); 2330Sstevel@tonic-gate } 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate return (result); 2360Sstevel@tonic-gate } 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate papi_status_t 2392264Sjacobs lpsched_start_change(papi_service_t svc, char *printer, int32_t job_id, 2400Sstevel@tonic-gate char **tmp) 2410Sstevel@tonic-gate { 2420Sstevel@tonic-gate papi_status_t result = PAPI_OK; 2430Sstevel@tonic-gate short status = MOK; 2440Sstevel@tonic-gate char req[BUFSIZ]; 2450Sstevel@tonic-gate char *dest; 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (job_id < 0)) 2480Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 2490Sstevel@tonic-gate 2500Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, job_id); 2510Sstevel@tonic-gate snprintf(req, sizeof (req), "%s-%d", dest, job_id); 2520Sstevel@tonic-gate free(dest); 2530Sstevel@tonic-gate 2540Sstevel@tonic-gate if ((snd_msg(svc, S_START_CHANGE_REQUEST, req) < 0) || 2550Sstevel@tonic-gate (rcv_msg(svc, R_START_CHANGE_REQUEST, &status, tmp) < 0)) 2560Sstevel@tonic-gate status = MTRANSMITERR; 2570Sstevel@tonic-gate 2580Sstevel@tonic-gate if (status != MOK) { 2590Sstevel@tonic-gate detailed_error(svc, 2600Sstevel@tonic-gate gettext("failed to initiate change for job (%s-%d): %s"), 2610Sstevel@tonic-gate printer, 2620Sstevel@tonic-gate job_id, lpsched_status_string(status)); 2630Sstevel@tonic-gate result = lpsched_status_to_papi_status(status); 2640Sstevel@tonic-gate } 2650Sstevel@tonic-gate 2660Sstevel@tonic-gate return (result); 2670Sstevel@tonic-gate } 2680Sstevel@tonic-gate 2690Sstevel@tonic-gate papi_status_t 2702264Sjacobs lpsched_end_change(papi_service_t svc, char *printer, int32_t job_id) 2710Sstevel@tonic-gate { 2720Sstevel@tonic-gate papi_status_t result = PAPI_OK; 2730Sstevel@tonic-gate short status = MOK; 2740Sstevel@tonic-gate long bits; 2750Sstevel@tonic-gate char req[BUFSIZ]; 2760Sstevel@tonic-gate char *dest; 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL) || (job_id < 0)) 2790Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, job_id); 2820Sstevel@tonic-gate snprintf(req, sizeof (req), "%s-%d", dest, job_id); 2830Sstevel@tonic-gate free(dest); 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate if ((snd_msg(svc, S_END_CHANGE_REQUEST, req) < 0) || 2860Sstevel@tonic-gate (rcv_msg(svc, R_END_CHANGE_REQUEST, &status, &bits) < 0)) 2870Sstevel@tonic-gate status = MTRANSMITERR; 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate if (status != MOK) { 2900Sstevel@tonic-gate detailed_error(svc, 2910Sstevel@tonic-gate gettext("failed to commit change for job (%s-%d): %s"), printer, 2920Sstevel@tonic-gate job_id, lpsched_status_string(status)); 2930Sstevel@tonic-gate result = lpsched_status_to_papi_status(status); 2940Sstevel@tonic-gate } 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate return (result); 2970Sstevel@tonic-gate } 2980Sstevel@tonic-gate 2990Sstevel@tonic-gate papi_status_t 3002264Sjacobs lpsched_accept_printer(papi_service_t svc, char *printer) 3012264Sjacobs { 3022264Sjacobs papi_status_t result = PAPI_OK; 3032264Sjacobs short status; 3042264Sjacobs char *req_id; 3052264Sjacobs char *dest; 3062264Sjacobs 3072264Sjacobs if ((svc == NULL) || (printer == NULL)) 3082264Sjacobs return (PAPI_BAD_ARGUMENT); 3092264Sjacobs 3102264Sjacobs dest = printer_name_from_uri_id(printer, -1); 3112264Sjacobs if ((snd_msg(svc, S_ACCEPT_DEST, dest) < 0) || 3122264Sjacobs (rcv_msg(svc, R_ACCEPT_DEST, &status, &req_id) < 0)) 3132264Sjacobs status = MTRANSMITERR; 3142264Sjacobs free(dest); 3152264Sjacobs 3162264Sjacobs if ((status != MOK) && (status != MERRDEST)) { 3172264Sjacobs detailed_error(svc, "%s: %s", printer, 3182264Sjacobs lpsched_status_string(status)); 3192264Sjacobs result = lpsched_status_to_papi_status(status); 3202264Sjacobs } 3212264Sjacobs 3222264Sjacobs return (result); 3232264Sjacobs } 3242264Sjacobs 3252264Sjacobs papi_status_t 3262264Sjacobs lpsched_reject_printer(papi_service_t svc, char *printer, char *message) 3272264Sjacobs { 3282264Sjacobs papi_status_t result = PAPI_OK; 3292264Sjacobs short status; 3302264Sjacobs char *req_id; 3312264Sjacobs char *dest; 3322264Sjacobs 3332264Sjacobs if ((svc == NULL) || (printer == NULL)) 3342264Sjacobs return (PAPI_BAD_ARGUMENT); 3352264Sjacobs 3362264Sjacobs if (message == NULL) 3372264Sjacobs message = "stopped by user"; 3382264Sjacobs 3392264Sjacobs dest = printer_name_from_uri_id(printer, -1); 3402264Sjacobs if ((snd_msg(svc, S_REJECT_DEST, dest, message, 0) < 0) || 3412264Sjacobs (rcv_msg(svc, R_REJECT_DEST, &status, &req_id) < 0)) 3422264Sjacobs status = MTRANSMITERR; 3432264Sjacobs free(dest); 3442264Sjacobs 3452264Sjacobs if ((status != MOK) && (status != MERRDEST)) { 3462264Sjacobs detailed_error(svc, "%s: %s", printer, 3472264Sjacobs lpsched_status_string(status)); 3482264Sjacobs result = lpsched_status_to_papi_status(status); 3492264Sjacobs } 3502264Sjacobs 3512264Sjacobs return (result); 3522264Sjacobs } 3532264Sjacobs 3542264Sjacobs papi_status_t 3552264Sjacobs lpsched_enable_printer(papi_service_t svc, char *printer) 3560Sstevel@tonic-gate { 3570Sstevel@tonic-gate papi_status_t result = PAPI_OK; 3580Sstevel@tonic-gate short status; 3590Sstevel@tonic-gate char *req_id; 3600Sstevel@tonic-gate char *dest; 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL)) 3630Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 3640Sstevel@tonic-gate 3650Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, -1); 3660Sstevel@tonic-gate if ((snd_msg(svc, S_ENABLE_DEST, dest) < 0) || 3670Sstevel@tonic-gate (rcv_msg(svc, R_ENABLE_DEST, &status, &req_id) < 0)) 3680Sstevel@tonic-gate status = MTRANSMITERR; 3690Sstevel@tonic-gate free(dest); 3700Sstevel@tonic-gate 3710Sstevel@tonic-gate if ((status != MOK) && (status != MERRDEST)) { 3720Sstevel@tonic-gate detailed_error(svc, "%s: %s", printer, 3730Sstevel@tonic-gate lpsched_status_string(status)); 3740Sstevel@tonic-gate result = lpsched_status_to_papi_status(status); 3750Sstevel@tonic-gate } 3760Sstevel@tonic-gate 3770Sstevel@tonic-gate return (result); 3780Sstevel@tonic-gate } 3790Sstevel@tonic-gate 3800Sstevel@tonic-gate papi_status_t 3812264Sjacobs lpsched_disable_printer(papi_service_t svc, char *printer, char *message) 3820Sstevel@tonic-gate { 3830Sstevel@tonic-gate papi_status_t result = PAPI_OK; 3840Sstevel@tonic-gate short status; 3850Sstevel@tonic-gate char *req_id; 3860Sstevel@tonic-gate char *dest; 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate if ((svc == NULL) || (printer == NULL)) 3890Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 3900Sstevel@tonic-gate 3910Sstevel@tonic-gate if (message == NULL) 3920Sstevel@tonic-gate message = "stopped by user"; 3930Sstevel@tonic-gate 3940Sstevel@tonic-gate dest = printer_name_from_uri_id(printer, -1); 3950Sstevel@tonic-gate if ((snd_msg(svc, S_DISABLE_DEST, dest, message, 0) < 0) || 3960Sstevel@tonic-gate (rcv_msg(svc, R_DISABLE_DEST, &status, &req_id) < 0)) 3970Sstevel@tonic-gate status = MTRANSMITERR; 3980Sstevel@tonic-gate free(dest); 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate if ((status != MOK) && (status != MERRDEST)) { 4010Sstevel@tonic-gate detailed_error(svc, "%s: %s", printer, 4020Sstevel@tonic-gate lpsched_status_string(status)); 4030Sstevel@tonic-gate result = lpsched_status_to_papi_status(status); 4040Sstevel@tonic-gate } 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate return (result); 4070Sstevel@tonic-gate } 4082264Sjacobs 4092264Sjacobs papi_status_t 4102264Sjacobs lpsched_load_unload_dest(papi_service_t handle, char *dest, int type) 4112264Sjacobs { 4122264Sjacobs service_t *svc = handle; 4132264Sjacobs papi_status_t result; 4142264Sjacobs short status = MOK; 4152264Sjacobs 4162264Sjacobs /* tell the scheduler it's going */ 4172264Sjacobs if (snd_msg(svc, type, dest, "", "") < 0) 4182264Sjacobs return (PAPI_SERVICE_UNAVAILABLE); 4192264Sjacobs 4202264Sjacobs switch (type) { 4212264Sjacobs case S_LOAD_PRINTER: 4222264Sjacobs type = R_LOAD_PRINTER; 4232264Sjacobs break; 4242264Sjacobs case S_UNLOAD_PRINTER: 4252264Sjacobs type = R_UNLOAD_PRINTER; 4262264Sjacobs break; 4272264Sjacobs case S_LOAD_CLASS: 4282264Sjacobs type = R_LOAD_CLASS; 4292264Sjacobs break; 4302264Sjacobs case S_UNLOAD_CLASS: 4312264Sjacobs type = R_UNLOAD_CLASS; 4322264Sjacobs } 4332264Sjacobs 4342264Sjacobs if (rcv_msg(svc, type, &status) < 0) 4352264Sjacobs return (PAPI_SERVICE_UNAVAILABLE); 4362264Sjacobs 4372264Sjacobs result = lpsched_status_to_papi_status(status); 4382264Sjacobs 4392264Sjacobs return (result); 4402264Sjacobs } 4412264Sjacobs 4422264Sjacobs papi_status_t 4432264Sjacobs lpsched_remove_class(papi_service_t handle, char *dest) 4442264Sjacobs { 4452264Sjacobs papi_status_t result; 4462264Sjacobs 4472264Sjacobs /* tell the scheduler it's going */ 4482264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_CLASS); 4492264Sjacobs 4502264Sjacobs if (result == PAPI_OK) { 4512264Sjacobs /* remove the scheduler config files */ 4522264Sjacobs if (delclass(dest) == -1) 4532264Sjacobs result = PAPI_SERVICE_UNAVAILABLE; 4542264Sjacobs } 4552264Sjacobs 4562264Sjacobs return (result); 4572264Sjacobs } 4582264Sjacobs 4592264Sjacobs static void 4602264Sjacobs remove_from_class(papi_service_t handle, char *dest, CLASS *cls) 4612264Sjacobs { 4622264Sjacobs if (dellist(&cls->members, dest) == 0) { 4632264Sjacobs if (cls->members != NULL) { 4642264Sjacobs if (putclass(cls->name, cls) == 0) 4652264Sjacobs (void) lpsched_load_unload_dest(handle, 4662264Sjacobs cls->name, S_LOAD_CLASS); 4672264Sjacobs } else 4682264Sjacobs (void) lpsched_remove_class(handle, cls->name); 4692264Sjacobs } 4702264Sjacobs } 4712264Sjacobs 4722264Sjacobs papi_status_t 4732264Sjacobs lpsched_remove_printer(papi_service_t handle, char *dest) 4742264Sjacobs { 4752264Sjacobs 4762264Sjacobs papi_status_t result; 4772264Sjacobs 4782264Sjacobs /* tell the scheduler it's going */ 4792264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_PRINTER); 4802264Sjacobs 4812264Sjacobs if (result == PAPI_OK) { 4822264Sjacobs CLASS *cls; 4832264Sjacobs char *dflt; 4842264Sjacobs 4852264Sjacobs /* remove the scheduler config files */ 4862264Sjacobs if (delprinter(dest) == -1) 4872264Sjacobs return (PAPI_SERVICE_UNAVAILABLE); 4882264Sjacobs 4892264Sjacobs /* remove from any classes */ 490*3125Sjacobs while ((cls = getclass(NAME_ALL)) != NULL) { 4912264Sjacobs if (searchlist(dest, cls->members) != 0) 4922264Sjacobs remove_from_class(handle, dest, cls); 493*3125Sjacobs freeclass(cls); 494*3125Sjacobs } 4952264Sjacobs 4962264Sjacobs /* reset the default if it needs to be done */ 4972264Sjacobs if (((dflt = getdefault()) != NULL) && 4982264Sjacobs (strcmp(dflt, dest) == 0)) 4992264Sjacobs putdefault(NAME_NONE); 5002264Sjacobs } 5012264Sjacobs 5022264Sjacobs return (result); 5032264Sjacobs } 5042264Sjacobs 5052264Sjacobs papi_status_t 5062264Sjacobs lpsched_add_modify_class(papi_service_t handle, char *dest, 5072264Sjacobs papi_attribute_t **attributes) 5082264Sjacobs { 5092264Sjacobs papi_status_t result; 5102264Sjacobs void *iter = NULL; 5112264Sjacobs char **members = NULL; 5122264Sjacobs char *member; 5132264Sjacobs 5142264Sjacobs /* 5152264Sjacobs * The only attribute that we can modify for a class is the set of 5162264Sjacobs * members. Anything else will be ignored. 5172264Sjacobs */ 5182264Sjacobs for (result = papiAttributeListGetString(attributes, &iter, 5192264Sjacobs "member-names", &member); 5202264Sjacobs result == PAPI_OK; 5212264Sjacobs result = papiAttributeListGetString(attributes, &iter, 5222264Sjacobs NULL, &member)) 5232264Sjacobs addlist(&members, member); 5242264Sjacobs 5252264Sjacobs if (members != NULL) { 5262264Sjacobs /* modify the configuration file */ 5272264Sjacobs CLASS class; 5282264Sjacobs 5292264Sjacobs memset(&class, 0, sizeof (class)); 5302264Sjacobs class.name = dest; 5312264Sjacobs class.members = members; 5322264Sjacobs 5332264Sjacobs if (putclass(dest, &class) == -1) { 5342264Sjacobs if ((errno == EPERM) || (errno == EACCES)) 5352264Sjacobs result = PAPI_NOT_AUTHORIZED; 5362264Sjacobs else 5372264Sjacobs result = PAPI_NOT_POSSIBLE; 5382264Sjacobs } else 5392264Sjacobs result = PAPI_OK; 5402264Sjacobs 5412264Sjacobs freelist(members); 5422264Sjacobs } else 5432264Sjacobs result = PAPI_ATTRIBUTES; 5442264Sjacobs 5452264Sjacobs /* tell the scheduler about the changes */ 5462264Sjacobs if (result == PAPI_OK) 5472264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_LOAD_CLASS); 5482264Sjacobs 5492264Sjacobs return (result); 5502264Sjacobs } 5512264Sjacobs 5522264Sjacobs papi_status_t 5532264Sjacobs lpsched_add_printer(papi_service_t handle, char *dest, 5542264Sjacobs papi_attribute_t **attributes) 5552264Sjacobs { 5562264Sjacobs PRINTER *p; 5572264Sjacobs papi_status_t result = PAPI_TEMPORARY_ERROR; 5582264Sjacobs 5592264Sjacobs if ((p = calloc(1, sizeof (*p))) != NULL) { 5602264Sjacobs p->name = strdup(dest); 5612264Sjacobs p->banner = BAN_ALWAYS; 5622264Sjacobs p->interface = strdup("/usr/lib/lp/model/uri"); 5632264Sjacobs p->fault_alert.shcmd = strdup("mail"); 5642264Sjacobs 5652264Sjacobs attributes_to_printer(attributes, p); 5662264Sjacobs 5672264Sjacobs if (putprinter(dest, p) == -1) { 5682264Sjacobs if ((errno == EPERM) || (errno == EACCES)) 5692264Sjacobs result = PAPI_NOT_AUTHORIZED; 5702264Sjacobs else 5712264Sjacobs result = PAPI_NOT_POSSIBLE; 5722264Sjacobs } else 5732264Sjacobs result = PAPI_OK; 5742264Sjacobs 5752264Sjacobs freeprinter(p); 5762264Sjacobs } 5772264Sjacobs 5782264Sjacobs /* tell the scheduler about the changes */ 5792264Sjacobs if (result == PAPI_OK) 5802264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER); 5812264Sjacobs 5822264Sjacobs return (result); 5832264Sjacobs } 5842264Sjacobs 5852264Sjacobs papi_status_t 5862264Sjacobs lpsched_add_modify_printer(papi_service_t handle, char *dest, 5872264Sjacobs papi_attribute_t **attributes, int type) 5882264Sjacobs { 5892264Sjacobs PRINTER *p; 5902264Sjacobs papi_status_t result; 5912264Sjacobs 5922264Sjacobs if (type == 0) { 5932264Sjacobs if ((p = calloc(1, sizeof (*p))) != NULL) { 5942264Sjacobs p->name = strdup(dest); 5952264Sjacobs p->banner = BAN_ALWAYS; 5962264Sjacobs p->interface = strdup("/usr/lib/lp/model/uri"); 5972264Sjacobs p->fault_alert.shcmd = strdup("mail"); 5982264Sjacobs } 5992264Sjacobs } else 6002264Sjacobs p = getprinter(dest); 6012264Sjacobs 6022264Sjacobs if (p != NULL) { 6032264Sjacobs attributes_to_printer(attributes, p); 6042264Sjacobs 6052264Sjacobs if (putprinter(dest, p) == -1) { 6062264Sjacobs if ((errno == EPERM) || (errno == EACCES)) 6072264Sjacobs result = PAPI_NOT_AUTHORIZED; 6082264Sjacobs else 6092264Sjacobs result = PAPI_NOT_POSSIBLE; 6102264Sjacobs } else 6112264Sjacobs result = PAPI_OK; 6122264Sjacobs 6132264Sjacobs freeprinter(p); 6142264Sjacobs } else 6152264Sjacobs result = PAPI_NOT_POSSIBLE; 6162264Sjacobs 6172264Sjacobs /* tell the scheduler about the changes */ 6182264Sjacobs if (result == PAPI_OK) 6192264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER); 6202264Sjacobs 6212264Sjacobs return (result); 6222264Sjacobs } 623