Home | History | Annotate | Download | only in lpsched
      1     0  stevel /*
      2     0  stevel  * CDDL HEADER START
      3     0  stevel  *
      4     0  stevel  * The contents of this file are subject to the terms of the
      5  3125  jacobs  * Common Development and Distribution License (the "License").
      6  3125  jacobs  * You may not use this file except in compliance with the License.
      7     0  stevel  *
      8     0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0  stevel  * or http://www.opensolaris.org/os/licensing.
     10     0  stevel  * See the License for the specific language governing permissions
     11     0  stevel  * and limitations under the License.
     12     0  stevel  *
     13     0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0  stevel  *
     19     0  stevel  * CDDL HEADER END
     20     0  stevel  */
     21  3125  jacobs 
     22     0  stevel /*
     23  3125  jacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     24     0  stevel  * Use is subject to license terms.
     25     0  stevel  */
     26     0  stevel 
     27     0  stevel /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28     0  stevel /*	  All Rights Reserved  	*/
     29     0  stevel 
     30     0  stevel 
     31  3125  jacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
     32     0  stevel 
     33     0  stevel #include	"dispatch.h"
     34     0  stevel #include <syslog.h>
     35     0  stevel #include <time.h>
     36     0  stevel 
     37     0  stevel char *showForms(PSTATUS *);
     38     0  stevel 
     39     0  stevel /*
     40     0  stevel  * untidbit_all() - CALL untidbit() FOR A LIST OF TYPES
     41     0  stevel  */
     42     0  stevel 
     43     0  stevel static void
     44     0  stevel untidbit_all (char **printer_types)
     45     0  stevel {
     46     0  stevel 	char **			pl;
     47     0  stevel 
     48     0  stevel 	for (pl = printer_types; *pl; pl++)
     49     0  stevel 		untidbit (*pl);
     50     0  stevel 	return;
     51     0  stevel }
     52     0  stevel 
     53     0  stevel /*
     54     0  stevel  * s_load_printer()
     55     0  stevel  */
     56     0  stevel 
     57     0  stevel void
     58     0  stevel s_load_printer(char *m, MESG *md)
     59     0  stevel {
     60     0  stevel 	char			*printer;
     61     0  stevel 	ushort			status;
     62     0  stevel 	register PRINTER	*pp;
     63     0  stevel 	register PSTATUS	*pps;
     64     0  stevel 	char **paperDenied;
     65     0  stevel 
     66     0  stevel 	(void) getmessage(m, S_LOAD_PRINTER, &printer);
     67     0  stevel 	syslog(LOG_DEBUG, "s_load_printer(%s)", (printer ? printer : "NULL"));
     68     0  stevel 
     69     0  stevel 	if (!*printer)
     70     0  stevel 		/* no printer */
     71     0  stevel 		status = MNODEST;
     72     0  stevel 	else if (!(pp = Getprinter(printer))) {
     73     0  stevel 		/* Strange or missing printer? */
     74     0  stevel 		switch (errno) {
     75     0  stevel 		case EBADF:
     76     0  stevel 			status = MERRDEST;
     77     0  stevel 			break;
     78     0  stevel 		case ENOENT:
     79     0  stevel 		default:
     80     0  stevel 			status = MNODEST;
     81     0  stevel 			break;
     82     0  stevel 		}
     83  3125  jacobs 	} else if ((pps = search_pstatus(printer))) {
     84     0  stevel 		/* Printer we know about already? */
     85  3125  jacobs 		PRINTER	*op = pps->printer;
     86     0  stevel 
     87  3125  jacobs 		pps->printer = pp;
     88     0  stevel 
     89     0  stevel 		/*
     90     0  stevel 		 * Ensure that an old Terminfo type that's no longer
     91     0  stevel 		 * needed gets freed, and that an existing type gets
     92     0  stevel 		 * reloaded (in case it has been changed).
     93     0  stevel 		 */
     94  3125  jacobs 		untidbit_all (op->printer_types);
     95     0  stevel 		untidbit_all (pp->printer_types);
     96     0  stevel 
     97     0  stevel 		/*
     98     0  stevel 		 * Does an alert get affected?
     99     0  stevel 		 *	- Different command?
    100     0  stevel 		 *	- Different wait interval?
    101     0  stevel 		 */
    102     0  stevel 		if (pps->alert->active)
    103     0  stevel 			if (!SAME(pp->fault_alert.shcmd,
    104  3125  jacobs 				  op->fault_alert.shcmd) ||
    105  3125  jacobs 			    pp->fault_alert.W != op->fault_alert.W) {
    106     0  stevel 				/*
    107     0  stevel 				 * We can't use "cancel_alert()" here
    108     0  stevel 				 * because it will remove the message.
    109     0  stevel 				 * We'll do half of the cancel, then
    110     0  stevel 				 * check if we need to run the new alert,
    111     0  stevel 				 * and remove the message if not.
    112     0  stevel 				 */
    113     0  stevel 				pps->alert->active = 0;
    114     0  stevel 				terminate (pps->alert->exec);
    115     0  stevel 				if (pp->fault_alert.shcmd)
    116     0  stevel 					alert(A_PRINTER, pps, (RSTATUS *)0,
    117     0  stevel 						(char *)0);
    118     0  stevel 				else
    119     0  stevel 					Unlink (pps->alert->msgfile);
    120     0  stevel 			}
    121  3125  jacobs 		freeprinter (op);
    122     0  stevel 
    123     0  stevel 		unload_list (&pps->users_allowed);
    124     0  stevel 		unload_list (&pps->users_denied);
    125     0  stevel 		unload_list (&pps->forms_allowed);
    126     0  stevel 		unload_list (&pps->forms_denied);
    127     0  stevel 		load_userprinter_access(pp->name, &pps->users_allowed,
    128     0  stevel 			&pps->users_denied);
    129     0  stevel 		load_formprinter_access(pp->name, &pps->forms_allowed,
    130     0  stevel 			&pps->forms_denied);
    131     0  stevel 
    132     0  stevel 		unload_list (&pps->paper_allowed);
    133     0  stevel 		load_paperprinter_access(pp->name, &pps->paper_allowed,
    134     0  stevel 			&paperDenied);
    135     0  stevel 		freelist(paperDenied);
    136     0  stevel 
    137     0  stevel 		load_sdn (&pps->cpi, pp->cpi);
    138     0  stevel 		load_sdn (&pps->lpi, pp->lpi);
    139     0  stevel 		load_sdn (&pps->plen, pp->plen);
    140     0  stevel 		load_sdn (&pps->pwid, pp->pwid);
    141     0  stevel 
    142     0  stevel 		pps->last_dial_rc = 0;
    143     0  stevel 		pps->nretry = 0;
    144     0  stevel 
    145     0  stevel 		/*
    146     0  stevel 		 * Evaluate all requests queued for this printer,
    147     0  stevel 		 * to make sure they are still eligible. They will
    148     0  stevel 		 * get moved to another printer, get (re)filtered,
    149     0  stevel 		 * or get canceled.
    150     0  stevel 		 */
    151     0  stevel 		(void) queue_repel(pps, 0, (qchk_fnc_type)0);
    152     0  stevel 
    153     0  stevel 		status = MOK;
    154     0  stevel         } else if (pp->remote) {
    155     0  stevel 		/* don't really load a remote printer */
    156     0  stevel 		status = MOK;
    157  3125  jacobs 	} else if ((pps = new_pstatus(pp))) {
    158     0  stevel 		pps->status = PS_DISABLED | PS_REJECTED;
    159     0  stevel 		load_str (&pps->dis_reason, CUZ_NEW_PRINTER);
    160     0  stevel 		load_str (&pps->rej_reason, CUZ_NEW_DEST);
    161     0  stevel 		load_str (&pps->fault_reason, CUZ_PRINTING_OK);
    162     0  stevel 		time (&pps->dis_date);
    163     0  stevel 		time (&pps->rej_date);
    164     0  stevel 
    165     0  stevel 		dump_pstatus ();
    166     0  stevel 
    167     0  stevel 		status = MOK;
    168     0  stevel 	} else {
    169     0  stevel 		freeprinter (pp);
    170     0  stevel 		status = MNOSPACE;
    171     0  stevel 	}
    172     0  stevel 
    173     0  stevel 
    174     0  stevel 	mputm (md, R_LOAD_PRINTER, status);
    175     0  stevel 	return;
    176     0  stevel }
    177     0  stevel 
    178     0  stevel /*
    179     0  stevel  * s_unload_printer()
    180     0  stevel  */
    181     0  stevel 
    182     0  stevel static void
    183     0  stevel _unload_printer(PSTATUS *pps)
    184     0  stevel {
    185  3125  jacobs 	int i;
    186     0  stevel 
    187     0  stevel 	if (pps->alert->active)
    188     0  stevel 		cancel_alert (A_PRINTER, pps);
    189     0  stevel 
    190     0  stevel 	/*
    191     0  stevel 	 * Remove this printer from the classes it may be in.
    192     0  stevel 	 * This is likely to be redundant, i.e. upon deleting
    193     0  stevel 	 * a printer the caller is SUPPOSED TO check all the
    194     0  stevel 	 * classes; any that contain the printer will be changed
    195     0  stevel 	 * and we should receive a S_LOAD_CLASS message for each
    196     0  stevel 	 * to reload the class.
    197     0  stevel 	 *
    198     0  stevel 	 * HOWEVER, this leaves a (small) window where someone
    199     0  stevel 	 * can sneak a request in destined for the CLASS. If
    200     0  stevel 	 * we have deleted the printer but still have it in the
    201     0  stevel 	 * class, we may have trouble!
    202     0  stevel 	 */
    203  3125  jacobs 	for (i = 0; CStatus != NULL && CStatus[i] != NULL; i++)
    204  3125  jacobs 		(void) dellist(&(CStatus[i]->class->members),
    205  3125  jacobs 				pps->printer->name);
    206     0  stevel 
    207  3125  jacobs 	free_pstatus(pps);
    208  3125  jacobs 	/*
    209  3125  jacobs 	 * this is removed from the PStatus table by the caller
    210  3125  jacobs 	 *   list_remove((void ***)&PStatus, (void *)pps);
    211  3125  jacobs 	 */
    212     0  stevel 
    213     0  stevel 	return;
    214     0  stevel }
    215     0  stevel 
    216     0  stevel void
    217     0  stevel s_unload_printer(char *m, MESG *md)
    218     0  stevel {
    219     0  stevel 	char			*printer;
    220     0  stevel 	ushort			status;
    221     0  stevel 	register PSTATUS	*pps;
    222     0  stevel 
    223     0  stevel 	(void) getmessage(m, S_UNLOAD_PRINTER, &printer);
    224     0  stevel 
    225     0  stevel 	syslog(LOG_DEBUG, "s_unload_printer(%s)",
    226     0  stevel 	       (printer ? printer : "NULL"));
    227     0  stevel 
    228     0  stevel 	if (!*printer || STREQU(printer, NAME_ALL))
    229     0  stevel 		/* Unload ALL printers */
    230     0  stevel 		if (!Request_List)
    231     0  stevel 			/*  If we have ANY requests queued, we can't do it. */
    232     0  stevel 			status = MBUSY;
    233     0  stevel 
    234     0  stevel 		else {
    235  3125  jacobs 			int i;
    236  3125  jacobs 			for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++)
    237  3125  jacobs 				_unload_printer (PStatus[i]);
    238  3125  jacobs 			free(PStatus);
    239  3125  jacobs 			PStatus = NULL;
    240     0  stevel 			status = MOK;
    241     0  stevel 		}
    242     0  stevel 
    243  3125  jacobs 	else if (!(pps = search_pstatus(printer)))
    244     0  stevel 		/* Have we seen this printer before */
    245     0  stevel 		status = MNODEST;
    246     0  stevel 	else {
    247     0  stevel 		/*
    248     0  stevel 		 * Note: This routine WILL MOVE requests to another
    249     0  stevel 		 * printer. It will not stop until it has gone through
    250     0  stevel 		 * the entire list of requests, so all requests that
    251     0  stevel 		 * can be moved will be moved. If any couldn't move,
    252     0  stevel 		 * however, we don't unload the printer.
    253     0  stevel 		 */
    254     0  stevel 		if (queue_repel(pps, 1, (qchk_fnc_type)0))
    255     0  stevel 			status = MOK;
    256     0  stevel 		else
    257     0  stevel 			status = MBUSY;
    258     0  stevel 
    259  3125  jacobs 		if (status == MOK) {
    260     0  stevel 			_unload_printer (pps);
    261  3125  jacobs 			list_remove((void ***)&PStatus, (void *)pps);
    262  3125  jacobs 		}
    263     0  stevel 	}
    264     0  stevel 
    265     0  stevel 	if (status == MOK)
    266     0  stevel 		dump_pstatus ();
    267     0  stevel 
    268     0  stevel 	mputm (md, R_UNLOAD_PRINTER, status);
    269     0  stevel 	return;
    270     0  stevel }
    271     0  stevel 
    272     0  stevel /*
    273     0  stevel  * combineReasons()
    274     0  stevel  */
    275     0  stevel 
    276     0  stevel static char *
    277     0  stevel combineReasons(PSTATUS *pps, char *freeReason)
    278     0  stevel {
    279     0  stevel 	char	*reason = NULL;
    280     0  stevel 
    281     0  stevel 	if (pps->status & PS_FAULTED) {
    282     0  stevel 		if ((pps->status & (PS_DISABLED | PS_LATER)) &&
    283     0  stevel 		    (!STREQU(pps->dis_reason, CUZ_STOPPED)) &&
    284     0  stevel 		    (addstring(&reason, "Fault reason: ") == 0) &&
    285     0  stevel 		    (addstring(&reason, pps->fault_reason) == 0) &&
    286     0  stevel 		    (addstring(&reason, "\n\tDisable reason: ") == 0) &&
    287     0  stevel 		    (addstring(&reason, pps->dis_reason) == 0))
    288     0  stevel 			*freeReason = 1;
    289     0  stevel 
    290     0  stevel 		else {
    291     0  stevel 			if (reason)
    292     0  stevel 				/* memory allocation failed part way through */
    293     0  stevel 				Free(reason);
    294     0  stevel 
    295     0  stevel 			reason = pps->fault_reason;
    296     0  stevel 			*freeReason = 0;
    297     0  stevel 		}
    298     0  stevel 	} else {
    299     0  stevel 		reason = pps->dis_reason;
    300     0  stevel 		*freeReason = 0;
    301     0  stevel 	}
    302     0  stevel 	return (reason);
    303     0  stevel }
    304     0  stevel 
    305     0  stevel static void
    306     0  stevel local_printer_status(MESG *md, PSTATUS *pps, short status)
    307     0  stevel {
    308     0  stevel 	char	*reason = NULL;
    309     0  stevel 	char	freeReason = 0;
    310     0  stevel 	char	*formList = NULL;
    311     0  stevel 
    312     0  stevel 	reason = combineReasons(pps, &freeReason);
    313     0  stevel 	formList = showForms(pps);
    314     0  stevel 
    315     0  stevel 	send(md, R_INQUIRE_PRINTER_STATUS, status, pps->printer->name,
    316     0  stevel 		(formList ? formList : ""),
    317     0  stevel 		(pps->pwheel_name ? pps->pwheel_name : ""),
    318     0  stevel 		reason, pps->rej_reason, pps->status,
    319     0  stevel 		(pps->request ? pps->request->secure->req_id : ""),
    320     0  stevel 		pps->dis_date, pps->rej_date);
    321     0  stevel 
    322     0  stevel 	if (formList)
    323     0  stevel 		Free(formList);
    324     0  stevel 
    325     0  stevel 	if (freeReason)
    326     0  stevel 		Free(reason);
    327     0  stevel }
    328     0  stevel 
    329     0  stevel /*
    330     0  stevel  * s_inquire_printer_status()
    331     0  stevel  */
    332     0  stevel 
    333     0  stevel void
    334     0  stevel s_inquire_printer_status(char *m, MESG *md)
    335     0  stevel {
    336     0  stevel 	char			*printer;
    337  3125  jacobs 	register PSTATUS	*pps;
    338     0  stevel 
    339     0  stevel 	(void) getmessage(m, S_INQUIRE_PRINTER_STATUS, &printer);
    340  3125  jacobs 	syslog(LOG_DEBUG, "s_inquire_printer_status(%s)", printer);
    341     0  stevel 
    342     0  stevel 	if (!*printer || STREQU(printer, NAME_ALL)) {
    343     0  stevel 		/* inquire about all printers */
    344  3125  jacobs 		int i;
    345  3125  jacobs 
    346  3125  jacobs 		for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++) {
    347  3125  jacobs 			pps = PStatus[i];
    348  3125  jacobs 			if (PStatus[i + 1] != NULL)
    349  3125  jacobs 				local_printer_status(md, pps, MOKMORE);
    350     0  stevel 		}
    351     0  stevel 	} else
    352     0  stevel 		/* inquire about a specific printer */
    353  3125  jacobs 		pps = search_pstatus(printer);
    354     0  stevel 
    355     0  stevel 	if (pps)
    356     0  stevel 		local_printer_status(md, pps, MOK);
    357     0  stevel 	else {
    358     0  stevel 		mputm(md, R_INQUIRE_PRINTER_STATUS, MNODEST, "", "", "", "",
    359     0  stevel 			"", 0, "", 0L, 0L);
    360     0  stevel 	}
    361     0  stevel }
    362     0  stevel 
    363     0  stevel 
    364     0  stevel /*
    365     0  stevel  * s_load_class()
    366     0  stevel  */
    367     0  stevel 
    368     0  stevel void
    369     0  stevel s_load_class(char *m, MESG *md)
    370     0  stevel {
    371     0  stevel 	char			*class;
    372     0  stevel 	ushort			status;
    373     0  stevel 	register CLASS		*pc;
    374     0  stevel 	register CSTATUS	*pcs;
    375     0  stevel 
    376     0  stevel 	(void) getmessage(m, S_LOAD_CLASS, &class);
    377     0  stevel 	syslog(LOG_DEBUG, "s_load_class(%s)", (class ? class : "NULL"));
    378     0  stevel 
    379     0  stevel 	if (!*class)
    380     0  stevel 		/* no class defined */
    381     0  stevel 		status = MNODEST;
    382     0  stevel 	else if (!(pc = Getclass(class))) {
    383     0  stevel 		/* Strange or missing class */
    384     0  stevel 		switch (errno) {
    385     0  stevel 		case EBADF:
    386     0  stevel 			status = MERRDEST;
    387     0  stevel 			break;
    388     0  stevel 		case ENOENT:
    389     0  stevel 		default:
    390     0  stevel 			status = MNODEST;
    391     0  stevel 			break;
    392     0  stevel 		}
    393     0  stevel 
    394  3125  jacobs 	} else if ((pcs = search_cstatus(class))) {
    395     0  stevel 		/* Class we already know about */
    396     0  stevel 		register RSTATUS	*prs;
    397     0  stevel 
    398     0  stevel 		freeclass (pcs->class);
    399  3125  jacobs 		pcs->class = pc;
    400     0  stevel 
    401     0  stevel 		/*
    402     0  stevel 		 * Here we go through the list of requests
    403     0  stevel 		 * to see who gets affected.
    404     0  stevel 		 */
    405  3125  jacobs 		for (prs = Request_List; prs != NULL; prs = prs->next)
    406  3125  jacobs 			if (STREQU(prs->request->destination, class)) {
    407     0  stevel 				/*
    408  3125  jacobs 			 	* If not still eligible for this class...
    409  3125  jacobs 			 	*/
    410  3125  jacobs 				switch (validate_request(prs, (char **)0, 1)) {
    411  3125  jacobs 				case MOK:
    412  3125  jacobs 				case MERRDEST:	/* rejecting (shouldn't happen) */
    413  3125  jacobs 					break;
    414  3125  jacobs 				case MDENYDEST:
    415  3125  jacobs 				case MNOMOUNT:
    416  3125  jacobs 				case MNOMEDIA:
    417  3125  jacobs 				case MNOFILTER:
    418  3125  jacobs 				default:
    419  3125  jacobs 					/*
    420  3125  jacobs 				 	* ...then too bad!
    421  3125  jacobs 				 	*/
    422  3125  jacobs 					cancel (prs, 1);
    423  3125  jacobs 					break;
    424  3125  jacobs 				}
    425     0  stevel 			}
    426  3125  jacobs 
    427     0  stevel 		status = MOK;
    428  3125  jacobs 	} else if ((pcs = new_cstatus(pc))) {
    429     0  stevel 		/* Room for new class? */
    430     0  stevel 		pcs->status = CS_REJECTED;
    431     0  stevel 		load_str (&pcs->rej_reason, CUZ_NEW_DEST);
    432     0  stevel 		time (&pcs->rej_date);
    433     0  stevel 
    434     0  stevel 		dump_cstatus ();
    435     0  stevel 
    436     0  stevel 		status = MOK;
    437     0  stevel 	} else {
    438     0  stevel 		freeclass (pc);
    439     0  stevel 		status = MNOSPACE;
    440     0  stevel 	}
    441     0  stevel 
    442     0  stevel 
    443     0  stevel 	mputm (md, R_LOAD_CLASS, status);
    444     0  stevel 	return;
    445     0  stevel }
    446     0  stevel 
    447     0  stevel /*
    448     0  stevel  * s_unload_class()
    449     0  stevel  */
    450     0  stevel 
    451     0  stevel static void
    452     0  stevel _unload_class(CSTATUS *pcs)
    453     0  stevel {
    454     0  stevel 	freeclass (pcs->class);
    455  3125  jacobs 	if (pcs->rej_reason != NULL)
    456  3125  jacobs 		Free (pcs->rej_reason);
    457  3125  jacobs 	Free(pcs);
    458     0  stevel 
    459     0  stevel 	return;
    460     0  stevel }
    461     0  stevel 
    462     0  stevel void
    463     0  stevel s_unload_class(char *m, MESG *md)
    464     0  stevel {
    465     0  stevel 	char			*class;
    466     0  stevel 	ushort			status;
    467  3125  jacobs 	RSTATUS 		*prs;
    468     0  stevel 	register CSTATUS	*pcs;
    469     0  stevel 
    470     0  stevel 	(void) getmessage(m, S_UNLOAD_CLASS, &class);
    471     0  stevel 	syslog(LOG_DEBUG, "s_unload_class(%s)", (class ? class : "NULL"));
    472     0  stevel 
    473     0  stevel 	/*
    474     0  stevel 	 * Unload ALL classes?
    475     0  stevel 	 */
    476     0  stevel 	if (!*class || STREQU(class, NAME_ALL)) {
    477  3125  jacobs 		int i;
    478     0  stevel 		/*
    479     0  stevel 		 * If we have a request queued for a member of ANY
    480     0  stevel 		 * class, we can't do it.
    481     0  stevel 		 */
    482     0  stevel 		status = MOK;
    483  3125  jacobs 		for (i = 0; ((CStatus[i] != NULL) && (status == MOK)); i++) {
    484  3125  jacobs 			for (prs = Request_List; prs != NULL; prs = prs->next)
    485  3125  jacobs 				if (STREQU(prs->request->destination,
    486  3125  jacobs 						CStatus[i]->class->name)) {
    487  3125  jacobs 					status = MBUSY;
    488  3125  jacobs 					break;
    489  3125  jacobs 				}
    490  3125  jacobs 		}
    491     0  stevel 
    492  3125  jacobs 		if (status == MOK) {
    493  3125  jacobs 			for (i = 0; CStatus != NULL && CStatus[i] != NULL; i++)
    494  3125  jacobs 				_unload_class (CStatus[i]);
    495  3125  jacobs 			free(CStatus);
    496  3125  jacobs 			CStatus = NULL;
    497  3125  jacobs 		}
    498     0  stevel 
    499     0  stevel 	/*
    500     0  stevel 	 * Have we seen this class before?
    501     0  stevel 	 */
    502  3125  jacobs 	} else if (!(pcs = search_cstatus(class)))
    503     0  stevel 		status = MNODEST;
    504     0  stevel 
    505     0  stevel 	/*
    506     0  stevel 	 * Is there even one request queued for this class?
    507     0  stevel 	 * If not, we can safely remove it.
    508     0  stevel 	 */
    509     0  stevel 	else {
    510     0  stevel 		status = MOK;
    511  3125  jacobs 		for (prs = Request_List; prs != NULL; prs = prs->next)
    512  3125  jacobs 			if (STREQU(prs->request->destination, class)) {
    513  3125  jacobs 				status = MBUSY;
    514  3125  jacobs 				break;
    515  3125  jacobs 			}
    516  3125  jacobs 
    517  3125  jacobs 		if (status == MOK) {
    518     0  stevel 			_unload_class (pcs);
    519  3125  jacobs 			list_remove((void ***)&CStatus, (void *)pcs);
    520  3125  jacobs 		}
    521     0  stevel 	}
    522     0  stevel 
    523     0  stevel 	if (status == MOK)
    524     0  stevel 		dump_cstatus ();
    525     0  stevel 
    526     0  stevel 	mputm (md, R_UNLOAD_CLASS, status);
    527     0  stevel 	return;
    528     0  stevel }
    529     0  stevel 
    530     0  stevel /*
    531     0  stevel  * s_inquire_class()
    532     0  stevel  */
    533     0  stevel 
    534     0  stevel void
    535     0  stevel s_inquire_class(char *m, MESG *md)
    536     0  stevel {
    537     0  stevel 	char			*class;
    538  3125  jacobs 	register CSTATUS	*pcs;
    539     0  stevel 
    540     0  stevel 	(void) getmessage(m, S_INQUIRE_CLASS, &class);
    541     0  stevel 	syslog(LOG_DEBUG, "s_inquire_class(%s)", (class ? class : "NULL"));
    542     0  stevel 
    543     0  stevel 
    544     0  stevel 
    545     0  stevel 	if (!*class || STREQU(class, NAME_ALL)) {
    546     0  stevel 		/* inquire about ALL classes */
    547  3125  jacobs 		int i;
    548  3125  jacobs 
    549  3125  jacobs 		for (i = 0; CStatus != NULL && CStatus[i] != NULL; i++) {
    550  3125  jacobs 			pcs = CStatus[i];
    551  3125  jacobs 			if (CStatus[i + 1] != NULL)
    552  3125  jacobs 				send(md, R_INQUIRE_CLASS, MOKMORE,
    553  3125  jacobs 			     		pcs->class->name, pcs->status,
    554  3125  jacobs 			     		pcs->rej_reason, pcs->rej_date);
    555     0  stevel 		}
    556     0  stevel 	} else
    557     0  stevel 		/* inquire about a single class */
    558  3125  jacobs 		pcs = search_cstatus(class);
    559     0  stevel 
    560     0  stevel 	if (pcs)
    561     0  stevel 		send(md, R_INQUIRE_CLASS, MOK, pcs->class->name, pcs->status,
    562     0  stevel 			pcs->rej_reason, pcs->rej_date);
    563     0  stevel 	else
    564     0  stevel 		mputm (md, R_INQUIRE_CLASS, MNODEST, "", 0, "", 0L);
    565     0  stevel 
    566     0  stevel 	return;
    567     0  stevel }
    568     0  stevel 
    569     0  stevel /*
    570     0  stevel  * s_paper_allowed()
    571     0  stevel  */
    572     0  stevel 
    573     0  stevel void
    574     0  stevel s_paper_allowed(char *m, MESG *md)
    575     0  stevel {
    576     0  stevel 	char			*printer;
    577     0  stevel 	char			*paperList = NULL;
    578     0  stevel 	register PSTATUS	*pps, *ppsnext;
    579     0  stevel 
    580     0  stevel 	(void) getmessage(m, S_PAPER_ALLOWED, &printer);
    581     0  stevel 	syslog(LOG_DEBUG, "s_paper_allowed(%s)", (printer ? printer : "NULL"));
    582     0  stevel 
    583     0  stevel 
    584     0  stevel 	if (!*printer || STREQU(printer, NAME_ALL)) {
    585     0  stevel 		/* inquire about ALL printers */
    586  3125  jacobs 		int i;
    587  3125  jacobs 
    588  3125  jacobs 		for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++) {
    589  3125  jacobs 			pps = PStatus[i];
    590  3125  jacobs 			if (PStatus[i + 1] != NULL) {
    591  3125  jacobs 				paperList = sprintlist(pps->paper_allowed);
    592  3125  jacobs 				send(md, R_PAPER_ALLOWED, MOKMORE,
    593  3125  jacobs 					pps->printer->name,
    594  3125  jacobs 					(paperList ? paperList : ""));
    595  3125  jacobs 				if (paperList)
    596  3125  jacobs 					Free(paperList);
    597  3125  jacobs 			}
    598     0  stevel 		}
    599     0  stevel 	} else
    600     0  stevel 		/* inquire about a specific printer */
    601  3125  jacobs 		pps = search_pstatus(printer);
    602     0  stevel 
    603     0  stevel 	if (pps) {
    604     0  stevel 		paperList = sprintlist(pps->paper_allowed);
    605     0  stevel 		send(md, R_PAPER_ALLOWED, MOK, pps->printer->name,
    606     0  stevel 			(paperList ? paperList : ""));
    607     0  stevel 		if (paperList)
    608     0  stevel 			Free(paperList);
    609     0  stevel 
    610     0  stevel 	} else {
    611     0  stevel 		mputm(md, R_PAPER_ALLOWED, MNODEST, "", "");
    612     0  stevel 	}
    613     0  stevel }
    614