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 5*2264Sjacobs * Common Development and Distribution License (the "License"). 6*2264Sjacobs * 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 */ 210Sstevel@tonic-gate /* 22*2264Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate /*LINTLIBRARY*/ 290Sstevel@tonic-gate 300Sstevel@tonic-gate #include <stdio.h> 310Sstevel@tonic-gate #include <stdarg.h> 320Sstevel@tonic-gate #include <libintl.h> 330Sstevel@tonic-gate #include <string.h> 340Sstevel@tonic-gate #include <stdlib.h> 35*2264Sjacobs #include <errno.h> 360Sstevel@tonic-gate 370Sstevel@tonic-gate 380Sstevel@tonic-gate /* lpsched include files */ 390Sstevel@tonic-gate #include "lp.h" 400Sstevel@tonic-gate #include "msgs.h" 410Sstevel@tonic-gate #include "printers.h" 42*2264Sjacobs #include "class.h" 430Sstevel@tonic-gate 440Sstevel@tonic-gate #include <papi_impl.h> 450Sstevel@tonic-gate 460Sstevel@tonic-gate 470Sstevel@tonic-gate /* 480Sstevel@tonic-gate * Format and send message to lpsched (die if any errors occur) 490Sstevel@tonic-gate */ 500Sstevel@tonic-gate /*VARARGS1*/ 510Sstevel@tonic-gate int 520Sstevel@tonic-gate snd_msg(service_t *svc, int type, ...) 530Sstevel@tonic-gate { 540Sstevel@tonic-gate int rc = -1; 550Sstevel@tonic-gate va_list ap; 560Sstevel@tonic-gate 570Sstevel@tonic-gate if (svc == NULL) 580Sstevel@tonic-gate return (-1); 590Sstevel@tonic-gate 600Sstevel@tonic-gate /* fill the message buffer */ 610Sstevel@tonic-gate va_start(ap, type); 620Sstevel@tonic-gate rc = _putmessage(svc->msgbuf, type, ap); 630Sstevel@tonic-gate va_end(ap); 640Sstevel@tonic-gate if (rc < 0) { 650Sstevel@tonic-gate detailed_error(svc, 660Sstevel@tonic-gate gettext("unable to build message for scheduler: %s"), 670Sstevel@tonic-gate strerror(errno)); 680Sstevel@tonic-gate return (rc); 690Sstevel@tonic-gate } 700Sstevel@tonic-gate 710Sstevel@tonic-gate /* write the message */ 720Sstevel@tonic-gate while (((rc = mwrite(svc->md, svc->msgbuf)) < 0) && (errno == EINTR)); 730Sstevel@tonic-gate 740Sstevel@tonic-gate if (rc < 0) 750Sstevel@tonic-gate detailed_error(svc, 760Sstevel@tonic-gate gettext("unable to send message to scheduler: %s"), 770Sstevel@tonic-gate strerror(errno)); 780Sstevel@tonic-gate return (rc); 790Sstevel@tonic-gate } 800Sstevel@tonic-gate 810Sstevel@tonic-gate /* 820Sstevel@tonic-gate * Receive message from lpsched (die if any errors occur) 830Sstevel@tonic-gate */ 840Sstevel@tonic-gate int 850Sstevel@tonic-gate rcv_msg(service_t *svc, int type, ...) 860Sstevel@tonic-gate { 870Sstevel@tonic-gate int rc = -1; 880Sstevel@tonic-gate 890Sstevel@tonic-gate if (svc == NULL) 900Sstevel@tonic-gate return (-1); 910Sstevel@tonic-gate 920Sstevel@tonic-gate /* read the message */ 930Sstevel@tonic-gate while (((rc = mread(svc->md, svc->msgbuf, svc->msgbuf_size)) < 0) && 940Sstevel@tonic-gate (errno == EINTR)); 950Sstevel@tonic-gate 960Sstevel@tonic-gate if (rc < 0) 970Sstevel@tonic-gate detailed_error(svc, 980Sstevel@tonic-gate gettext("unable to read message from scheduler: %s"), 990Sstevel@tonic-gate strerror(errno)); 1000Sstevel@tonic-gate else { 1010Sstevel@tonic-gate va_list ap; 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate va_start(ap, type); 1040Sstevel@tonic-gate rc = _getmessage(svc->msgbuf, type, ap); 1050Sstevel@tonic-gate va_end(ap); 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate if (rc < 0) 1080Sstevel@tonic-gate detailed_error(svc, 1090Sstevel@tonic-gate gettext("unable to parse message from scheduler: %s"), 1100Sstevel@tonic-gate strerror(errno)); 1110Sstevel@tonic-gate } 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate return (rc); 1140Sstevel@tonic-gate } 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate papi_status_t 1170Sstevel@tonic-gate lpsched_status_to_papi_status(int status) 1180Sstevel@tonic-gate { 1190Sstevel@tonic-gate switch (status) { 1200Sstevel@tonic-gate case MNOMEM: 1210Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 1220Sstevel@tonic-gate case MNOFILTER: 1230Sstevel@tonic-gate return (PAPI_DOCUMENT_FORMAT_ERROR); 1240Sstevel@tonic-gate case MNOOPEN: 1250Sstevel@tonic-gate return (PAPI_DOCUMENT_ACCESS_ERROR); 1260Sstevel@tonic-gate case MERRDEST: 1270Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 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); 143*2264Sjacobs case MBUSY: 144*2264Sjacobs 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: 1640Sstevel@tonic-gate return (gettext("An error occured in submission")); 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 239*2264Sjacobs 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 270*2264Sjacobs 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 300*2264Sjacobs lpsched_accept_printer(papi_service_t svc, char *printer) 301*2264Sjacobs { 302*2264Sjacobs papi_status_t result = PAPI_OK; 303*2264Sjacobs short status; 304*2264Sjacobs char *req_id; 305*2264Sjacobs char *dest; 306*2264Sjacobs 307*2264Sjacobs if ((svc == NULL) || (printer == NULL)) 308*2264Sjacobs return (PAPI_BAD_ARGUMENT); 309*2264Sjacobs 310*2264Sjacobs dest = printer_name_from_uri_id(printer, -1); 311*2264Sjacobs if ((snd_msg(svc, S_ACCEPT_DEST, dest) < 0) || 312*2264Sjacobs (rcv_msg(svc, R_ACCEPT_DEST, &status, &req_id) < 0)) 313*2264Sjacobs status = MTRANSMITERR; 314*2264Sjacobs free(dest); 315*2264Sjacobs 316*2264Sjacobs if ((status != MOK) && (status != MERRDEST)) { 317*2264Sjacobs detailed_error(svc, "%s: %s", printer, 318*2264Sjacobs lpsched_status_string(status)); 319*2264Sjacobs result = lpsched_status_to_papi_status(status); 320*2264Sjacobs } 321*2264Sjacobs 322*2264Sjacobs return (result); 323*2264Sjacobs } 324*2264Sjacobs 325*2264Sjacobs papi_status_t 326*2264Sjacobs lpsched_reject_printer(papi_service_t svc, char *printer, char *message) 327*2264Sjacobs { 328*2264Sjacobs papi_status_t result = PAPI_OK; 329*2264Sjacobs short status; 330*2264Sjacobs char *req_id; 331*2264Sjacobs char *dest; 332*2264Sjacobs 333*2264Sjacobs if ((svc == NULL) || (printer == NULL)) 334*2264Sjacobs return (PAPI_BAD_ARGUMENT); 335*2264Sjacobs 336*2264Sjacobs if (message == NULL) 337*2264Sjacobs message = "stopped by user"; 338*2264Sjacobs 339*2264Sjacobs dest = printer_name_from_uri_id(printer, -1); 340*2264Sjacobs if ((snd_msg(svc, S_REJECT_DEST, dest, message, 0) < 0) || 341*2264Sjacobs (rcv_msg(svc, R_REJECT_DEST, &status, &req_id) < 0)) 342*2264Sjacobs status = MTRANSMITERR; 343*2264Sjacobs free(dest); 344*2264Sjacobs 345*2264Sjacobs if ((status != MOK) && (status != MERRDEST)) { 346*2264Sjacobs detailed_error(svc, "%s: %s", printer, 347*2264Sjacobs lpsched_status_string(status)); 348*2264Sjacobs result = lpsched_status_to_papi_status(status); 349*2264Sjacobs } 350*2264Sjacobs 351*2264Sjacobs return (result); 352*2264Sjacobs } 353*2264Sjacobs 354*2264Sjacobs papi_status_t 355*2264Sjacobs 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 381*2264Sjacobs 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 } 408*2264Sjacobs 409*2264Sjacobs papi_status_t 410*2264Sjacobs lpsched_load_unload_dest(papi_service_t handle, char *dest, int type) 411*2264Sjacobs { 412*2264Sjacobs service_t *svc = handle; 413*2264Sjacobs papi_status_t result; 414*2264Sjacobs short status = MOK; 415*2264Sjacobs 416*2264Sjacobs /* tell the scheduler it's going */ 417*2264Sjacobs if (snd_msg(svc, type, dest, "", "") < 0) 418*2264Sjacobs return (PAPI_SERVICE_UNAVAILABLE); 419*2264Sjacobs 420*2264Sjacobs switch (type) { 421*2264Sjacobs case S_LOAD_PRINTER: 422*2264Sjacobs type = R_LOAD_PRINTER; 423*2264Sjacobs break; 424*2264Sjacobs case S_UNLOAD_PRINTER: 425*2264Sjacobs type = R_UNLOAD_PRINTER; 426*2264Sjacobs break; 427*2264Sjacobs case S_LOAD_CLASS: 428*2264Sjacobs type = R_LOAD_CLASS; 429*2264Sjacobs break; 430*2264Sjacobs case S_UNLOAD_CLASS: 431*2264Sjacobs type = R_UNLOAD_CLASS; 432*2264Sjacobs } 433*2264Sjacobs 434*2264Sjacobs if (rcv_msg(svc, type, &status) < 0) 435*2264Sjacobs return (PAPI_SERVICE_UNAVAILABLE); 436*2264Sjacobs 437*2264Sjacobs result = lpsched_status_to_papi_status(status); 438*2264Sjacobs 439*2264Sjacobs return (result); 440*2264Sjacobs } 441*2264Sjacobs 442*2264Sjacobs papi_status_t 443*2264Sjacobs lpsched_remove_class(papi_service_t handle, char *dest) 444*2264Sjacobs { 445*2264Sjacobs papi_status_t result; 446*2264Sjacobs 447*2264Sjacobs /* tell the scheduler it's going */ 448*2264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_CLASS); 449*2264Sjacobs 450*2264Sjacobs if (result == PAPI_OK) { 451*2264Sjacobs /* remove the scheduler config files */ 452*2264Sjacobs if (delclass(dest) == -1) 453*2264Sjacobs result = PAPI_SERVICE_UNAVAILABLE; 454*2264Sjacobs } 455*2264Sjacobs 456*2264Sjacobs return (result); 457*2264Sjacobs } 458*2264Sjacobs 459*2264Sjacobs static void 460*2264Sjacobs remove_from_class(papi_service_t handle, char *dest, CLASS *cls) 461*2264Sjacobs { 462*2264Sjacobs if (dellist(&cls->members, dest) == 0) { 463*2264Sjacobs if (cls->members != NULL) { 464*2264Sjacobs if (putclass(cls->name, cls) == 0) 465*2264Sjacobs (void) lpsched_load_unload_dest(handle, 466*2264Sjacobs cls->name, S_LOAD_CLASS); 467*2264Sjacobs } else 468*2264Sjacobs (void) lpsched_remove_class(handle, cls->name); 469*2264Sjacobs } 470*2264Sjacobs } 471*2264Sjacobs 472*2264Sjacobs papi_status_t 473*2264Sjacobs lpsched_remove_printer(papi_service_t handle, char *dest) 474*2264Sjacobs { 475*2264Sjacobs 476*2264Sjacobs papi_status_t result; 477*2264Sjacobs 478*2264Sjacobs /* tell the scheduler it's going */ 479*2264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_PRINTER); 480*2264Sjacobs 481*2264Sjacobs if (result == PAPI_OK) { 482*2264Sjacobs CLASS *cls; 483*2264Sjacobs char *dflt; 484*2264Sjacobs 485*2264Sjacobs /* remove the scheduler config files */ 486*2264Sjacobs if (delprinter(dest) == -1) 487*2264Sjacobs return (PAPI_SERVICE_UNAVAILABLE); 488*2264Sjacobs 489*2264Sjacobs /* remove from any classes */ 490*2264Sjacobs while ((cls = getclass(NAME_ALL)) != NULL) 491*2264Sjacobs if (searchlist(dest, cls->members) != 0) 492*2264Sjacobs remove_from_class(handle, dest, cls); 493*2264Sjacobs 494*2264Sjacobs /* reset the default if it needs to be done */ 495*2264Sjacobs if (((dflt = getdefault()) != NULL) && 496*2264Sjacobs (strcmp(dflt, dest) == 0)) 497*2264Sjacobs putdefault(NAME_NONE); 498*2264Sjacobs } 499*2264Sjacobs 500*2264Sjacobs return (result); 501*2264Sjacobs } 502*2264Sjacobs 503*2264Sjacobs papi_status_t 504*2264Sjacobs lpsched_add_modify_class(papi_service_t handle, char *dest, 505*2264Sjacobs papi_attribute_t **attributes) 506*2264Sjacobs { 507*2264Sjacobs papi_status_t result; 508*2264Sjacobs void *iter = NULL; 509*2264Sjacobs char **members = NULL; 510*2264Sjacobs char *member; 511*2264Sjacobs 512*2264Sjacobs /* 513*2264Sjacobs * The only attribute that we can modify for a class is the set of 514*2264Sjacobs * members. Anything else will be ignored. 515*2264Sjacobs */ 516*2264Sjacobs for (result = papiAttributeListGetString(attributes, &iter, 517*2264Sjacobs "member-names", &member); 518*2264Sjacobs result == PAPI_OK; 519*2264Sjacobs result = papiAttributeListGetString(attributes, &iter, 520*2264Sjacobs NULL, &member)) 521*2264Sjacobs addlist(&members, member); 522*2264Sjacobs 523*2264Sjacobs if (members != NULL) { 524*2264Sjacobs /* modify the configuration file */ 525*2264Sjacobs CLASS class; 526*2264Sjacobs 527*2264Sjacobs memset(&class, 0, sizeof (class)); 528*2264Sjacobs class.name = dest; 529*2264Sjacobs class.members = members; 530*2264Sjacobs 531*2264Sjacobs if (putclass(dest, &class) == -1) { 532*2264Sjacobs if ((errno == EPERM) || (errno == EACCES)) 533*2264Sjacobs result = PAPI_NOT_AUTHORIZED; 534*2264Sjacobs else 535*2264Sjacobs result = PAPI_NOT_POSSIBLE; 536*2264Sjacobs } else 537*2264Sjacobs result = PAPI_OK; 538*2264Sjacobs 539*2264Sjacobs freelist(members); 540*2264Sjacobs } else 541*2264Sjacobs result = PAPI_ATTRIBUTES; 542*2264Sjacobs 543*2264Sjacobs /* tell the scheduler about the changes */ 544*2264Sjacobs if (result == PAPI_OK) 545*2264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_LOAD_CLASS); 546*2264Sjacobs 547*2264Sjacobs return (result); 548*2264Sjacobs } 549*2264Sjacobs 550*2264Sjacobs papi_status_t 551*2264Sjacobs lpsched_add_printer(papi_service_t handle, char *dest, 552*2264Sjacobs papi_attribute_t **attributes) 553*2264Sjacobs { 554*2264Sjacobs PRINTER *p; 555*2264Sjacobs papi_status_t result = PAPI_TEMPORARY_ERROR; 556*2264Sjacobs 557*2264Sjacobs if ((p = calloc(1, sizeof (*p))) != NULL) { 558*2264Sjacobs p->name = strdup(dest); 559*2264Sjacobs p->banner = BAN_ALWAYS; 560*2264Sjacobs p->interface = strdup("/usr/lib/lp/model/uri"); 561*2264Sjacobs p->fault_alert.shcmd = strdup("mail"); 562*2264Sjacobs 563*2264Sjacobs attributes_to_printer(attributes, p); 564*2264Sjacobs 565*2264Sjacobs if (putprinter(dest, p) == -1) { 566*2264Sjacobs if ((errno == EPERM) || (errno == EACCES)) 567*2264Sjacobs result = PAPI_NOT_AUTHORIZED; 568*2264Sjacobs else 569*2264Sjacobs result = PAPI_NOT_POSSIBLE; 570*2264Sjacobs } else 571*2264Sjacobs result = PAPI_OK; 572*2264Sjacobs 573*2264Sjacobs freeprinter(p); 574*2264Sjacobs } 575*2264Sjacobs 576*2264Sjacobs /* tell the scheduler about the changes */ 577*2264Sjacobs if (result == PAPI_OK) 578*2264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER); 579*2264Sjacobs 580*2264Sjacobs return (result); 581*2264Sjacobs } 582*2264Sjacobs 583*2264Sjacobs papi_status_t 584*2264Sjacobs lpsched_add_modify_printer(papi_service_t handle, char *dest, 585*2264Sjacobs papi_attribute_t **attributes, int type) 586*2264Sjacobs { 587*2264Sjacobs PRINTER *p; 588*2264Sjacobs papi_status_t result; 589*2264Sjacobs 590*2264Sjacobs if (type == 0) { 591*2264Sjacobs if ((p = calloc(1, sizeof (*p))) != NULL) { 592*2264Sjacobs p->name = strdup(dest); 593*2264Sjacobs p->banner = BAN_ALWAYS; 594*2264Sjacobs p->interface = strdup("/usr/lib/lp/model/uri"); 595*2264Sjacobs p->fault_alert.shcmd = strdup("mail"); 596*2264Sjacobs } 597*2264Sjacobs } else 598*2264Sjacobs p = getprinter(dest); 599*2264Sjacobs 600*2264Sjacobs if (p != NULL) { 601*2264Sjacobs attributes_to_printer(attributes, p); 602*2264Sjacobs 603*2264Sjacobs if (putprinter(dest, p) == -1) { 604*2264Sjacobs if ((errno == EPERM) || (errno == EACCES)) 605*2264Sjacobs result = PAPI_NOT_AUTHORIZED; 606*2264Sjacobs else 607*2264Sjacobs result = PAPI_NOT_POSSIBLE; 608*2264Sjacobs } else 609*2264Sjacobs result = PAPI_OK; 610*2264Sjacobs 611*2264Sjacobs freeprinter(p); 612*2264Sjacobs } else 613*2264Sjacobs result = PAPI_NOT_POSSIBLE; 614*2264Sjacobs 615*2264Sjacobs /* tell the scheduler about the changes */ 616*2264Sjacobs if (result == PAPI_OK) 617*2264Sjacobs result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER); 618*2264Sjacobs 619*2264Sjacobs return (result); 620*2264Sjacobs } 621