17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50a44ef6dSjacobs * Common Development and Distribution License (the "License").
60a44ef6dSjacobs * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
210a44ef6dSjacobs
227c478bd9Sstevel@tonic-gate /*
230a44ef6dSjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /* All Rights Reserved */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate #include "dispatch.h"
327c478bd9Sstevel@tonic-gate #include <syslog.h>
337c478bd9Sstevel@tonic-gate #include <time.h>
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate char *showForms(PSTATUS *);
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate /*
387c478bd9Sstevel@tonic-gate * untidbit_all() - CALL untidbit() FOR A LIST OF TYPES
397c478bd9Sstevel@tonic-gate */
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate static void
untidbit_all(char ** printer_types)427c478bd9Sstevel@tonic-gate untidbit_all (char **printer_types)
437c478bd9Sstevel@tonic-gate {
447c478bd9Sstevel@tonic-gate char ** pl;
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate for (pl = printer_types; *pl; pl++)
477c478bd9Sstevel@tonic-gate untidbit (*pl);
487c478bd9Sstevel@tonic-gate return;
497c478bd9Sstevel@tonic-gate }
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate /*
527c478bd9Sstevel@tonic-gate * s_load_printer()
537c478bd9Sstevel@tonic-gate */
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate void
s_load_printer(char * m,MESG * md)567c478bd9Sstevel@tonic-gate s_load_printer(char *m, MESG *md)
577c478bd9Sstevel@tonic-gate {
587c478bd9Sstevel@tonic-gate char *printer;
597c478bd9Sstevel@tonic-gate ushort status;
607c478bd9Sstevel@tonic-gate register PRINTER *pp;
617c478bd9Sstevel@tonic-gate register PSTATUS *pps;
627c478bd9Sstevel@tonic-gate char **paperDenied;
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate (void) getmessage(m, S_LOAD_PRINTER, &printer);
657c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "s_load_printer(%s)", (printer ? printer : "NULL"));
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate if (!*printer)
687c478bd9Sstevel@tonic-gate /* no printer */
697c478bd9Sstevel@tonic-gate status = MNODEST;
707c478bd9Sstevel@tonic-gate else if (!(pp = Getprinter(printer))) {
717c478bd9Sstevel@tonic-gate /* Strange or missing printer? */
727c478bd9Sstevel@tonic-gate switch (errno) {
737c478bd9Sstevel@tonic-gate case EBADF:
747c478bd9Sstevel@tonic-gate status = MERRDEST;
757c478bd9Sstevel@tonic-gate break;
767c478bd9Sstevel@tonic-gate case ENOENT:
777c478bd9Sstevel@tonic-gate default:
787c478bd9Sstevel@tonic-gate status = MNODEST;
797c478bd9Sstevel@tonic-gate break;
807c478bd9Sstevel@tonic-gate }
810a44ef6dSjacobs } else if ((pps = search_pstatus(printer))) {
827c478bd9Sstevel@tonic-gate /* Printer we know about already? */
830a44ef6dSjacobs PRINTER *op = pps->printer;
847c478bd9Sstevel@tonic-gate
850a44ef6dSjacobs pps->printer = pp;
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate /*
887c478bd9Sstevel@tonic-gate * Ensure that an old Terminfo type that's no longer
897c478bd9Sstevel@tonic-gate * needed gets freed, and that an existing type gets
907c478bd9Sstevel@tonic-gate * reloaded (in case it has been changed).
917c478bd9Sstevel@tonic-gate */
920a44ef6dSjacobs untidbit_all (op->printer_types);
937c478bd9Sstevel@tonic-gate untidbit_all (pp->printer_types);
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate /*
967c478bd9Sstevel@tonic-gate * Does an alert get affected?
977c478bd9Sstevel@tonic-gate * - Different command?
987c478bd9Sstevel@tonic-gate * - Different wait interval?
997c478bd9Sstevel@tonic-gate */
1007c478bd9Sstevel@tonic-gate if (pps->alert->active)
1017c478bd9Sstevel@tonic-gate if (!SAME(pp->fault_alert.shcmd,
1020a44ef6dSjacobs op->fault_alert.shcmd) ||
1030a44ef6dSjacobs pp->fault_alert.W != op->fault_alert.W) {
1047c478bd9Sstevel@tonic-gate /*
1057c478bd9Sstevel@tonic-gate * We can't use "cancel_alert()" here
1067c478bd9Sstevel@tonic-gate * because it will remove the message.
1077c478bd9Sstevel@tonic-gate * We'll do half of the cancel, then
1087c478bd9Sstevel@tonic-gate * check if we need to run the new alert,
1097c478bd9Sstevel@tonic-gate * and remove the message if not.
1107c478bd9Sstevel@tonic-gate */
1117c478bd9Sstevel@tonic-gate pps->alert->active = 0;
1127c478bd9Sstevel@tonic-gate terminate (pps->alert->exec);
1137c478bd9Sstevel@tonic-gate if (pp->fault_alert.shcmd)
1147c478bd9Sstevel@tonic-gate alert(A_PRINTER, pps, (RSTATUS *)0,
1157c478bd9Sstevel@tonic-gate (char *)0);
1167c478bd9Sstevel@tonic-gate else
1177c478bd9Sstevel@tonic-gate Unlink (pps->alert->msgfile);
1187c478bd9Sstevel@tonic-gate }
1190a44ef6dSjacobs freeprinter (op);
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate unload_list (&pps->users_allowed);
1227c478bd9Sstevel@tonic-gate unload_list (&pps->users_denied);
1237c478bd9Sstevel@tonic-gate unload_list (&pps->forms_allowed);
1247c478bd9Sstevel@tonic-gate unload_list (&pps->forms_denied);
1257c478bd9Sstevel@tonic-gate load_userprinter_access(pp->name, &pps->users_allowed,
1267c478bd9Sstevel@tonic-gate &pps->users_denied);
1277c478bd9Sstevel@tonic-gate load_formprinter_access(pp->name, &pps->forms_allowed,
1287c478bd9Sstevel@tonic-gate &pps->forms_denied);
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate unload_list (&pps->paper_allowed);
1317c478bd9Sstevel@tonic-gate load_paperprinter_access(pp->name, &pps->paper_allowed,
1327c478bd9Sstevel@tonic-gate &paperDenied);
1337c478bd9Sstevel@tonic-gate freelist(paperDenied);
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate load_sdn (&pps->cpi, pp->cpi);
1367c478bd9Sstevel@tonic-gate load_sdn (&pps->lpi, pp->lpi);
1377c478bd9Sstevel@tonic-gate load_sdn (&pps->plen, pp->plen);
1387c478bd9Sstevel@tonic-gate load_sdn (&pps->pwid, pp->pwid);
1397c478bd9Sstevel@tonic-gate
1407c478bd9Sstevel@tonic-gate pps->last_dial_rc = 0;
1417c478bd9Sstevel@tonic-gate pps->nretry = 0;
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate /*
1447c478bd9Sstevel@tonic-gate * Evaluate all requests queued for this printer,
1457c478bd9Sstevel@tonic-gate * to make sure they are still eligible. They will
1467c478bd9Sstevel@tonic-gate * get moved to another printer, get (re)filtered,
1477c478bd9Sstevel@tonic-gate * or get canceled.
1487c478bd9Sstevel@tonic-gate */
1497c478bd9Sstevel@tonic-gate (void) queue_repel(pps, 0, (qchk_fnc_type)0);
1507c478bd9Sstevel@tonic-gate
1517c478bd9Sstevel@tonic-gate status = MOK;
1527c478bd9Sstevel@tonic-gate } else if (pp->remote) {
1537c478bd9Sstevel@tonic-gate /* don't really load a remote printer */
1547c478bd9Sstevel@tonic-gate status = MOK;
1550a44ef6dSjacobs } else if ((pps = new_pstatus(pp))) {
1567c478bd9Sstevel@tonic-gate pps->status = PS_DISABLED | PS_REJECTED;
1577c478bd9Sstevel@tonic-gate load_str (&pps->dis_reason, CUZ_NEW_PRINTER);
1587c478bd9Sstevel@tonic-gate load_str (&pps->rej_reason, CUZ_NEW_DEST);
1597c478bd9Sstevel@tonic-gate load_str (&pps->fault_reason, CUZ_PRINTING_OK);
1607c478bd9Sstevel@tonic-gate time (&pps->dis_date);
1617c478bd9Sstevel@tonic-gate time (&pps->rej_date);
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate dump_pstatus ();
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate status = MOK;
1667c478bd9Sstevel@tonic-gate } else {
1677c478bd9Sstevel@tonic-gate freeprinter (pp);
1687c478bd9Sstevel@tonic-gate status = MNOSPACE;
1697c478bd9Sstevel@tonic-gate }
1707c478bd9Sstevel@tonic-gate
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate mputm (md, R_LOAD_PRINTER, status);
1737c478bd9Sstevel@tonic-gate return;
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate /*
1777c478bd9Sstevel@tonic-gate * s_unload_printer()
1787c478bd9Sstevel@tonic-gate */
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate static void
_unload_printer(PSTATUS * pps)1817c478bd9Sstevel@tonic-gate _unload_printer(PSTATUS *pps)
1827c478bd9Sstevel@tonic-gate {
1830a44ef6dSjacobs int i;
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate if (pps->alert->active)
1867c478bd9Sstevel@tonic-gate cancel_alert (A_PRINTER, pps);
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate /*
1897c478bd9Sstevel@tonic-gate * Remove this printer from the classes it may be in.
1907c478bd9Sstevel@tonic-gate * This is likely to be redundant, i.e. upon deleting
1917c478bd9Sstevel@tonic-gate * a printer the caller is SUPPOSED TO check all the
1927c478bd9Sstevel@tonic-gate * classes; any that contain the printer will be changed
1937c478bd9Sstevel@tonic-gate * and we should receive a S_LOAD_CLASS message for each
1947c478bd9Sstevel@tonic-gate * to reload the class.
1957c478bd9Sstevel@tonic-gate *
1967c478bd9Sstevel@tonic-gate * HOWEVER, this leaves a (small) window where someone
1977c478bd9Sstevel@tonic-gate * can sneak a request in destined for the CLASS. If
1987c478bd9Sstevel@tonic-gate * we have deleted the printer but still have it in the
1997c478bd9Sstevel@tonic-gate * class, we may have trouble!
2007c478bd9Sstevel@tonic-gate */
2010a44ef6dSjacobs for (i = 0; CStatus != NULL && CStatus[i] != NULL; i++)
2020a44ef6dSjacobs (void) dellist(&(CStatus[i]->class->members),
2030a44ef6dSjacobs pps->printer->name);
2047c478bd9Sstevel@tonic-gate
2050a44ef6dSjacobs free_pstatus(pps);
2060a44ef6dSjacobs /*
2070a44ef6dSjacobs * this is removed from the PStatus table by the caller
2080a44ef6dSjacobs * list_remove((void ***)&PStatus, (void *)pps);
2090a44ef6dSjacobs */
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate return;
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate void
s_unload_printer(char * m,MESG * md)2157c478bd9Sstevel@tonic-gate s_unload_printer(char *m, MESG *md)
2167c478bd9Sstevel@tonic-gate {
2177c478bd9Sstevel@tonic-gate char *printer;
2187c478bd9Sstevel@tonic-gate ushort status;
2197c478bd9Sstevel@tonic-gate register PSTATUS *pps;
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate (void) getmessage(m, S_UNLOAD_PRINTER, &printer);
2227c478bd9Sstevel@tonic-gate
2237c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "s_unload_printer(%s)",
2247c478bd9Sstevel@tonic-gate (printer ? printer : "NULL"));
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate if (!*printer || STREQU(printer, NAME_ALL))
2277c478bd9Sstevel@tonic-gate /* Unload ALL printers */
2287c478bd9Sstevel@tonic-gate if (!Request_List)
2297c478bd9Sstevel@tonic-gate /* If we have ANY requests queued, we can't do it. */
2307c478bd9Sstevel@tonic-gate status = MBUSY;
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate else {
2330a44ef6dSjacobs int i;
2340a44ef6dSjacobs for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++)
2350a44ef6dSjacobs _unload_printer (PStatus[i]);
2360a44ef6dSjacobs free(PStatus);
2370a44ef6dSjacobs PStatus = NULL;
2387c478bd9Sstevel@tonic-gate status = MOK;
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate
2410a44ef6dSjacobs else if (!(pps = search_pstatus(printer)))
2427c478bd9Sstevel@tonic-gate /* Have we seen this printer before */
2437c478bd9Sstevel@tonic-gate status = MNODEST;
2447c478bd9Sstevel@tonic-gate else {
2457c478bd9Sstevel@tonic-gate /*
2467c478bd9Sstevel@tonic-gate * Note: This routine WILL MOVE requests to another
2477c478bd9Sstevel@tonic-gate * printer. It will not stop until it has gone through
2487c478bd9Sstevel@tonic-gate * the entire list of requests, so all requests that
2497c478bd9Sstevel@tonic-gate * can be moved will be moved. If any couldn't move,
2507c478bd9Sstevel@tonic-gate * however, we don't unload the printer.
2517c478bd9Sstevel@tonic-gate */
2527c478bd9Sstevel@tonic-gate if (queue_repel(pps, 1, (qchk_fnc_type)0))
2537c478bd9Sstevel@tonic-gate status = MOK;
2547c478bd9Sstevel@tonic-gate else
2557c478bd9Sstevel@tonic-gate status = MBUSY;
2567c478bd9Sstevel@tonic-gate
2570a44ef6dSjacobs if (status == MOK) {
2587c478bd9Sstevel@tonic-gate _unload_printer (pps);
2590a44ef6dSjacobs list_remove((void ***)&PStatus, (void *)pps);
2600a44ef6dSjacobs }
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate if (status == MOK)
2647c478bd9Sstevel@tonic-gate dump_pstatus ();
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate mputm (md, R_UNLOAD_PRINTER, status);
2677c478bd9Sstevel@tonic-gate return;
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate
2707c478bd9Sstevel@tonic-gate /*
2717c478bd9Sstevel@tonic-gate * combineReasons()
2727c478bd9Sstevel@tonic-gate */
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate static char *
combineReasons(PSTATUS * pps,char * freeReason)2757c478bd9Sstevel@tonic-gate combineReasons(PSTATUS *pps, char *freeReason)
2767c478bd9Sstevel@tonic-gate {
2777c478bd9Sstevel@tonic-gate char *reason = NULL;
2787c478bd9Sstevel@tonic-gate
2797c478bd9Sstevel@tonic-gate if (pps->status & PS_FAULTED) {
2807c478bd9Sstevel@tonic-gate if ((pps->status & (PS_DISABLED | PS_LATER)) &&
2817c478bd9Sstevel@tonic-gate (!STREQU(pps->dis_reason, CUZ_STOPPED)) &&
2827c478bd9Sstevel@tonic-gate (addstring(&reason, "Fault reason: ") == 0) &&
2837c478bd9Sstevel@tonic-gate (addstring(&reason, pps->fault_reason) == 0) &&
2847c478bd9Sstevel@tonic-gate (addstring(&reason, "\n\tDisable reason: ") == 0) &&
2857c478bd9Sstevel@tonic-gate (addstring(&reason, pps->dis_reason) == 0))
2867c478bd9Sstevel@tonic-gate *freeReason = 1;
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate else {
2897c478bd9Sstevel@tonic-gate if (reason)
2907c478bd9Sstevel@tonic-gate /* memory allocation failed part way through */
2917c478bd9Sstevel@tonic-gate Free(reason);
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate reason = pps->fault_reason;
2947c478bd9Sstevel@tonic-gate *freeReason = 0;
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate } else {
2977c478bd9Sstevel@tonic-gate reason = pps->dis_reason;
2987c478bd9Sstevel@tonic-gate *freeReason = 0;
2997c478bd9Sstevel@tonic-gate }
3007c478bd9Sstevel@tonic-gate return (reason);
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate static void
local_printer_status(MESG * md,PSTATUS * pps,short status)3047c478bd9Sstevel@tonic-gate local_printer_status(MESG *md, PSTATUS *pps, short status)
3057c478bd9Sstevel@tonic-gate {
3067c478bd9Sstevel@tonic-gate char *reason = NULL;
3077c478bd9Sstevel@tonic-gate char freeReason = 0;
3087c478bd9Sstevel@tonic-gate char *formList = NULL;
3097c478bd9Sstevel@tonic-gate
3107c478bd9Sstevel@tonic-gate reason = combineReasons(pps, &freeReason);
3117c478bd9Sstevel@tonic-gate formList = showForms(pps);
3127c478bd9Sstevel@tonic-gate
3137c478bd9Sstevel@tonic-gate send(md, R_INQUIRE_PRINTER_STATUS, status, pps->printer->name,
3147c478bd9Sstevel@tonic-gate (formList ? formList : ""),
3157c478bd9Sstevel@tonic-gate (pps->pwheel_name ? pps->pwheel_name : ""),
3167c478bd9Sstevel@tonic-gate reason, pps->rej_reason, pps->status,
3177c478bd9Sstevel@tonic-gate (pps->request ? pps->request->secure->req_id : ""),
3187c478bd9Sstevel@tonic-gate pps->dis_date, pps->rej_date);
3197c478bd9Sstevel@tonic-gate
3207c478bd9Sstevel@tonic-gate if (formList)
3217c478bd9Sstevel@tonic-gate Free(formList);
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate if (freeReason)
3247c478bd9Sstevel@tonic-gate Free(reason);
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate
3277c478bd9Sstevel@tonic-gate /*
3287c478bd9Sstevel@tonic-gate * s_inquire_printer_status()
3297c478bd9Sstevel@tonic-gate */
3307c478bd9Sstevel@tonic-gate
3317c478bd9Sstevel@tonic-gate void
s_inquire_printer_status(char * m,MESG * md)3327c478bd9Sstevel@tonic-gate s_inquire_printer_status(char *m, MESG *md)
3337c478bd9Sstevel@tonic-gate {
3347c478bd9Sstevel@tonic-gate char *printer;
3350a44ef6dSjacobs register PSTATUS *pps;
3367c478bd9Sstevel@tonic-gate
3377c478bd9Sstevel@tonic-gate (void) getmessage(m, S_INQUIRE_PRINTER_STATUS, &printer);
3380a44ef6dSjacobs syslog(LOG_DEBUG, "s_inquire_printer_status(%s)", printer);
3397c478bd9Sstevel@tonic-gate
3407c478bd9Sstevel@tonic-gate if (!*printer || STREQU(printer, NAME_ALL)) {
3417c478bd9Sstevel@tonic-gate /* inquire about all printers */
3420a44ef6dSjacobs int i;
3430a44ef6dSjacobs
3440a44ef6dSjacobs for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++) {
3450a44ef6dSjacobs pps = PStatus[i];
3460a44ef6dSjacobs if (PStatus[i + 1] != NULL)
3477c478bd9Sstevel@tonic-gate local_printer_status(md, pps, MOKMORE);
3487c478bd9Sstevel@tonic-gate }
3497c478bd9Sstevel@tonic-gate } else
3507c478bd9Sstevel@tonic-gate /* inquire about a specific printer */
3510a44ef6dSjacobs pps = search_pstatus(printer);
3527c478bd9Sstevel@tonic-gate
3537c478bd9Sstevel@tonic-gate if (pps)
3547c478bd9Sstevel@tonic-gate local_printer_status(md, pps, MOK);
3557c478bd9Sstevel@tonic-gate else {
3567c478bd9Sstevel@tonic-gate mputm(md, R_INQUIRE_PRINTER_STATUS, MNODEST, "", "", "", "",
3577c478bd9Sstevel@tonic-gate "", 0, "", 0L, 0L);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate
3617c478bd9Sstevel@tonic-gate
3627c478bd9Sstevel@tonic-gate /*
3637c478bd9Sstevel@tonic-gate * s_load_class()
3647c478bd9Sstevel@tonic-gate */
3657c478bd9Sstevel@tonic-gate
3667c478bd9Sstevel@tonic-gate void
s_load_class(char * m,MESG * md)3677c478bd9Sstevel@tonic-gate s_load_class(char *m, MESG *md)
3687c478bd9Sstevel@tonic-gate {
3697c478bd9Sstevel@tonic-gate char *class;
3707c478bd9Sstevel@tonic-gate ushort status;
3717c478bd9Sstevel@tonic-gate register CLASS *pc;
372*c558d3b1SRobert Mustacchi register CLSTATUS *pcs;
3737c478bd9Sstevel@tonic-gate
3747c478bd9Sstevel@tonic-gate (void) getmessage(m, S_LOAD_CLASS, &class);
3757c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "s_load_class(%s)", (class ? class : "NULL"));
3767c478bd9Sstevel@tonic-gate
3777c478bd9Sstevel@tonic-gate if (!*class)
3787c478bd9Sstevel@tonic-gate /* no class defined */
3797c478bd9Sstevel@tonic-gate status = MNODEST;
3807c478bd9Sstevel@tonic-gate else if (!(pc = Getclass(class))) {
3817c478bd9Sstevel@tonic-gate /* Strange or missing class */
3827c478bd9Sstevel@tonic-gate switch (errno) {
3837c478bd9Sstevel@tonic-gate case EBADF:
3847c478bd9Sstevel@tonic-gate status = MERRDEST;
3857c478bd9Sstevel@tonic-gate break;
3867c478bd9Sstevel@tonic-gate case ENOENT:
3877c478bd9Sstevel@tonic-gate default:
3887c478bd9Sstevel@tonic-gate status = MNODEST;
3897c478bd9Sstevel@tonic-gate break;
3907c478bd9Sstevel@tonic-gate }
3917c478bd9Sstevel@tonic-gate
3920a44ef6dSjacobs } else if ((pcs = search_cstatus(class))) {
3937c478bd9Sstevel@tonic-gate /* Class we already know about */
3947c478bd9Sstevel@tonic-gate register RSTATUS *prs;
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate freeclass (pcs->class);
3970a44ef6dSjacobs pcs->class = pc;
3987c478bd9Sstevel@tonic-gate
3997c478bd9Sstevel@tonic-gate /*
4007c478bd9Sstevel@tonic-gate * Here we go through the list of requests
4017c478bd9Sstevel@tonic-gate * to see who gets affected.
4027c478bd9Sstevel@tonic-gate */
4030a44ef6dSjacobs for (prs = Request_List; prs != NULL; prs = prs->next)
4040a44ef6dSjacobs if (STREQU(prs->request->destination, class)) {
4057c478bd9Sstevel@tonic-gate /*
4067c478bd9Sstevel@tonic-gate * If not still eligible for this class...
4077c478bd9Sstevel@tonic-gate */
4087c478bd9Sstevel@tonic-gate switch (validate_request(prs, (char **)0, 1)) {
4097c478bd9Sstevel@tonic-gate case MOK:
4107c478bd9Sstevel@tonic-gate case MERRDEST: /* rejecting (shouldn't happen) */
4117c478bd9Sstevel@tonic-gate break;
4127c478bd9Sstevel@tonic-gate case MDENYDEST:
4137c478bd9Sstevel@tonic-gate case MNOMOUNT:
4147c478bd9Sstevel@tonic-gate case MNOMEDIA:
4157c478bd9Sstevel@tonic-gate case MNOFILTER:
4167c478bd9Sstevel@tonic-gate default:
4177c478bd9Sstevel@tonic-gate /*
4187c478bd9Sstevel@tonic-gate * ...then too bad!
4197c478bd9Sstevel@tonic-gate */
4207c478bd9Sstevel@tonic-gate cancel (prs, 1);
4217c478bd9Sstevel@tonic-gate break;
4227c478bd9Sstevel@tonic-gate }
4230a44ef6dSjacobs }
4240a44ef6dSjacobs
4257c478bd9Sstevel@tonic-gate status = MOK;
4260a44ef6dSjacobs } else if ((pcs = new_cstatus(pc))) {
4277c478bd9Sstevel@tonic-gate /* Room for new class? */
4287c478bd9Sstevel@tonic-gate pcs->status = CS_REJECTED;
4297c478bd9Sstevel@tonic-gate load_str (&pcs->rej_reason, CUZ_NEW_DEST);
4307c478bd9Sstevel@tonic-gate time (&pcs->rej_date);
4317c478bd9Sstevel@tonic-gate
4327c478bd9Sstevel@tonic-gate dump_cstatus ();
4337c478bd9Sstevel@tonic-gate
4347c478bd9Sstevel@tonic-gate status = MOK;
4357c478bd9Sstevel@tonic-gate } else {
4367c478bd9Sstevel@tonic-gate freeclass (pc);
4377c478bd9Sstevel@tonic-gate status = MNOSPACE;
4387c478bd9Sstevel@tonic-gate }
4397c478bd9Sstevel@tonic-gate
4407c478bd9Sstevel@tonic-gate
4417c478bd9Sstevel@tonic-gate mputm (md, R_LOAD_CLASS, status);
4427c478bd9Sstevel@tonic-gate return;
4437c478bd9Sstevel@tonic-gate }
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate /*
4467c478bd9Sstevel@tonic-gate * s_unload_class()
4477c478bd9Sstevel@tonic-gate */
4487c478bd9Sstevel@tonic-gate
4497c478bd9Sstevel@tonic-gate static void
_unload_class(CLSTATUS * pcs)450*c558d3b1SRobert Mustacchi _unload_class(CLSTATUS *pcs)
4517c478bd9Sstevel@tonic-gate {
4527c478bd9Sstevel@tonic-gate freeclass (pcs->class);
4530a44ef6dSjacobs if (pcs->rej_reason != NULL)
4540a44ef6dSjacobs Free (pcs->rej_reason);
4550a44ef6dSjacobs Free(pcs);
4567c478bd9Sstevel@tonic-gate
4577c478bd9Sstevel@tonic-gate return;
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate void
s_unload_class(char * m,MESG * md)4617c478bd9Sstevel@tonic-gate s_unload_class(char *m, MESG *md)
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate char *class;
4647c478bd9Sstevel@tonic-gate ushort status;
4657c478bd9Sstevel@tonic-gate RSTATUS *prs;
466*c558d3b1SRobert Mustacchi register CLSTATUS *pcs;
4677c478bd9Sstevel@tonic-gate
4687c478bd9Sstevel@tonic-gate (void) getmessage(m, S_UNLOAD_CLASS, &class);
4697c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "s_unload_class(%s)", (class ? class : "NULL"));
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate /*
4727c478bd9Sstevel@tonic-gate * Unload ALL classes?
4737c478bd9Sstevel@tonic-gate */
4747c478bd9Sstevel@tonic-gate if (!*class || STREQU(class, NAME_ALL)) {
4750a44ef6dSjacobs int i;
4767c478bd9Sstevel@tonic-gate /*
4777c478bd9Sstevel@tonic-gate * If we have a request queued for a member of ANY
4787c478bd9Sstevel@tonic-gate * class, we can't do it.
4797c478bd9Sstevel@tonic-gate */
4807c478bd9Sstevel@tonic-gate status = MOK;
4810a44ef6dSjacobs for (i = 0; ((CStatus[i] != NULL) && (status == MOK)); i++) {
4820a44ef6dSjacobs for (prs = Request_List; prs != NULL; prs = prs->next)
4830a44ef6dSjacobs if (STREQU(prs->request->destination,
4840a44ef6dSjacobs CStatus[i]->class->name)) {
4857c478bd9Sstevel@tonic-gate status = MBUSY;
4867c478bd9Sstevel@tonic-gate break;
4870a44ef6dSjacobs }
4880a44ef6dSjacobs }
4897c478bd9Sstevel@tonic-gate
4900a44ef6dSjacobs if (status == MOK) {
4910a44ef6dSjacobs for (i = 0; CStatus != NULL && CStatus[i] != NULL; i++)
4920a44ef6dSjacobs _unload_class (CStatus[i]);
4930a44ef6dSjacobs free(CStatus);
4940a44ef6dSjacobs CStatus = NULL;
4950a44ef6dSjacobs }
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate /*
4987c478bd9Sstevel@tonic-gate * Have we seen this class before?
4997c478bd9Sstevel@tonic-gate */
5000a44ef6dSjacobs } else if (!(pcs = search_cstatus(class)))
5017c478bd9Sstevel@tonic-gate status = MNODEST;
5027c478bd9Sstevel@tonic-gate
5037c478bd9Sstevel@tonic-gate /*
5047c478bd9Sstevel@tonic-gate * Is there even one request queued for this class?
5057c478bd9Sstevel@tonic-gate * If not, we can safely remove it.
5067c478bd9Sstevel@tonic-gate */
5077c478bd9Sstevel@tonic-gate else {
5087c478bd9Sstevel@tonic-gate status = MOK;
5090a44ef6dSjacobs for (prs = Request_List; prs != NULL; prs = prs->next)
5100a44ef6dSjacobs if (STREQU(prs->request->destination, class)) {
5117c478bd9Sstevel@tonic-gate status = MBUSY;
5127c478bd9Sstevel@tonic-gate break;
5130a44ef6dSjacobs }
5140a44ef6dSjacobs
5150a44ef6dSjacobs if (status == MOK) {
5167c478bd9Sstevel@tonic-gate _unload_class (pcs);
5170a44ef6dSjacobs list_remove((void ***)&CStatus, (void *)pcs);
5180a44ef6dSjacobs }
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate
5217c478bd9Sstevel@tonic-gate if (status == MOK)
5227c478bd9Sstevel@tonic-gate dump_cstatus ();
5237c478bd9Sstevel@tonic-gate
5247c478bd9Sstevel@tonic-gate mputm (md, R_UNLOAD_CLASS, status);
5257c478bd9Sstevel@tonic-gate return;
5267c478bd9Sstevel@tonic-gate }
5277c478bd9Sstevel@tonic-gate
5287c478bd9Sstevel@tonic-gate /*
5297c478bd9Sstevel@tonic-gate * s_inquire_class()
5307c478bd9Sstevel@tonic-gate */
5317c478bd9Sstevel@tonic-gate
5327c478bd9Sstevel@tonic-gate void
s_inquire_class(char * m,MESG * md)5337c478bd9Sstevel@tonic-gate s_inquire_class(char *m, MESG *md)
5347c478bd9Sstevel@tonic-gate {
5357c478bd9Sstevel@tonic-gate char *class;
536*c558d3b1SRobert Mustacchi register CLSTATUS *pcs;
5377c478bd9Sstevel@tonic-gate
5387c478bd9Sstevel@tonic-gate (void) getmessage(m, S_INQUIRE_CLASS, &class);
5397c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "s_inquire_class(%s)", (class ? class : "NULL"));
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate
5427c478bd9Sstevel@tonic-gate
5437c478bd9Sstevel@tonic-gate if (!*class || STREQU(class, NAME_ALL)) {
5447c478bd9Sstevel@tonic-gate /* inquire about ALL classes */
5450a44ef6dSjacobs int i;
5460a44ef6dSjacobs
5470a44ef6dSjacobs for (i = 0; CStatus != NULL && CStatus[i] != NULL; i++) {
5480a44ef6dSjacobs pcs = CStatus[i];
5490a44ef6dSjacobs if (CStatus[i + 1] != NULL)
5507c478bd9Sstevel@tonic-gate send(md, R_INQUIRE_CLASS, MOKMORE,
5517c478bd9Sstevel@tonic-gate pcs->class->name, pcs->status,
5527c478bd9Sstevel@tonic-gate pcs->rej_reason, pcs->rej_date);
5537c478bd9Sstevel@tonic-gate }
5547c478bd9Sstevel@tonic-gate } else
5557c478bd9Sstevel@tonic-gate /* inquire about a single class */
5560a44ef6dSjacobs pcs = search_cstatus(class);
5577c478bd9Sstevel@tonic-gate
5587c478bd9Sstevel@tonic-gate if (pcs)
5597c478bd9Sstevel@tonic-gate send(md, R_INQUIRE_CLASS, MOK, pcs->class->name, pcs->status,
5607c478bd9Sstevel@tonic-gate pcs->rej_reason, pcs->rej_date);
5617c478bd9Sstevel@tonic-gate else
5627c478bd9Sstevel@tonic-gate mputm (md, R_INQUIRE_CLASS, MNODEST, "", 0, "", 0L);
5637c478bd9Sstevel@tonic-gate
5647c478bd9Sstevel@tonic-gate return;
5657c478bd9Sstevel@tonic-gate }
5667c478bd9Sstevel@tonic-gate
5677c478bd9Sstevel@tonic-gate /*
5687c478bd9Sstevel@tonic-gate * s_paper_allowed()
5697c478bd9Sstevel@tonic-gate */
5707c478bd9Sstevel@tonic-gate
5717c478bd9Sstevel@tonic-gate void
s_paper_allowed(char * m,MESG * md)5727c478bd9Sstevel@tonic-gate s_paper_allowed(char *m, MESG *md)
5737c478bd9Sstevel@tonic-gate {
5747c478bd9Sstevel@tonic-gate char *printer;
5757c478bd9Sstevel@tonic-gate char *paperList = NULL;
5767c478bd9Sstevel@tonic-gate register PSTATUS *pps, *ppsnext;
5777c478bd9Sstevel@tonic-gate
5787c478bd9Sstevel@tonic-gate (void) getmessage(m, S_PAPER_ALLOWED, &printer);
5797c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "s_paper_allowed(%s)", (printer ? printer : "NULL"));
5807c478bd9Sstevel@tonic-gate
5817c478bd9Sstevel@tonic-gate
5827c478bd9Sstevel@tonic-gate if (!*printer || STREQU(printer, NAME_ALL)) {
5837c478bd9Sstevel@tonic-gate /* inquire about ALL printers */
5840a44ef6dSjacobs int i;
5850a44ef6dSjacobs
5860a44ef6dSjacobs for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++) {
5870a44ef6dSjacobs pps = PStatus[i];
5880a44ef6dSjacobs if (PStatus[i + 1] != NULL) {
5897c478bd9Sstevel@tonic-gate paperList = sprintlist(pps->paper_allowed);
5900a44ef6dSjacobs send(md, R_PAPER_ALLOWED, MOKMORE,
5910a44ef6dSjacobs pps->printer->name,
5927c478bd9Sstevel@tonic-gate (paperList ? paperList : ""));
5937c478bd9Sstevel@tonic-gate if (paperList)
5947c478bd9Sstevel@tonic-gate Free(paperList);
5950a44ef6dSjacobs }
5967c478bd9Sstevel@tonic-gate }
5977c478bd9Sstevel@tonic-gate } else
5987c478bd9Sstevel@tonic-gate /* inquire about a specific printer */
5990a44ef6dSjacobs pps = search_pstatus(printer);
6007c478bd9Sstevel@tonic-gate
6017c478bd9Sstevel@tonic-gate if (pps) {
6027c478bd9Sstevel@tonic-gate paperList = sprintlist(pps->paper_allowed);
6037c478bd9Sstevel@tonic-gate send(md, R_PAPER_ALLOWED, MOK, pps->printer->name,
6047c478bd9Sstevel@tonic-gate (paperList ? paperList : ""));
6057c478bd9Sstevel@tonic-gate if (paperList)
6067c478bd9Sstevel@tonic-gate Free(paperList);
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate } else {
6097c478bd9Sstevel@tonic-gate mputm(md, R_PAPER_ALLOWED, MNODEST, "", "");
6107c478bd9Sstevel@tonic-gate }
6117c478bd9Sstevel@tonic-gate }
612