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     0  stevel #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 
     36     0  stevel /**
     37     0  stevel  ** remount_form() - MOUNT A FORM WHERE ANOTHER WAS MOUNTED
     38     0  stevel  **/
     39     0  stevel 
     40     0  stevel void
     41     0  stevel remount_form(register PSTATUS *pps, FSTATUS *pfs, short trayNum)
     42     0  stevel {
     43     0  stevel 	trayNum--; /* make zero based */
     44     0  stevel 	if (pps->forms && (pps->forms[trayNum].form == pfs)) {
     45  3125  jacobs 		pps->forms[trayNum].isAvailable = (pfs ? 1 : 0);
     46     0  stevel 					 /* force it */
     47     0  stevel 		return;	/* nothing to do */
     48     0  stevel 	} else if ((!pps->forms) && (!pfs)) {
     49     0  stevel 		return;	/* nothing to do */
     50     0  stevel 	}
     51     0  stevel 
     52     0  stevel 	/*
     53     0  stevel 	 * Unmount the old form.
     54     0  stevel 	 */
     55     0  stevel 	if (pps->forms && pps->forms[trayNum].form) {
     56     0  stevel 		register FSTATUS	*Opfs	= pps->forms[trayNum].form;
     57     0  stevel 
     58     0  stevel 		pps->forms[trayNum].form = 0;
     59  3125  jacobs 		pps->forms[trayNum].isAvailable = 0;
     60     0  stevel 		Opfs->mounted--;
     61     0  stevel 
     62     0  stevel 		/*
     63     0  stevel 		 * Unmounting the form may make some print requests
     64     0  stevel 		 * no longer printable, because they were accepted
     65     0  stevel 		 * only because the form was already mounted.
     66     0  stevel 		 * Unmounting the form will also force some requests
     67     0  stevel 		 * to another printer (where the form is mounted)
     68     0  stevel 		 * so they can print.
     69     0  stevel 		 */
     70     0  stevel 		form_in_question = Opfs;
     71     0  stevel 		(void)queue_repel (pps, 0, qchk_form);
     72     0  stevel 
     73     0  stevel 		/*
     74     0  stevel 		 * Maybe an alert is due.
     75     0  stevel 		 */
     76     0  stevel 		check_form_alert (Opfs, (_FORM *)0);
     77     0  stevel 	}
     78     0  stevel 
     79     0  stevel 	/*
     80     0  stevel 	 * Mount the new form?
     81     0  stevel 	 */
     82     0  stevel 	if (pfs) {
     83     0  stevel 		syslog(LOG_DEBUG, "remount_form add %x(%s) to tray %d\n",
     84     0  stevel 			 pfs, (pfs ? pfs->form->name : "NULL"), trayNum);
     85     0  stevel 
     86     0  stevel 		if (pps && !pps->forms) {
     87     0  stevel                         pps->forms = (PFSTATUS *)calloc((trayNum +1),
     88     0  stevel 							sizeof(PFSTATUS));
     89     0  stevel 			pps->numForms = trayNum + 1;
     90     0  stevel 		}
     91     0  stevel 
     92     0  stevel 		if (pps && pps->forms && (pps->numForms > trayNum)) {
     93     0  stevel 			pps->forms[trayNum].form = pfs;
     94     0  stevel 			pps->forms[trayNum].isAvailable = 1;
     95     0  stevel 			pfs->mounted++;
     96     0  stevel 		} else {
     97     0  stevel 			return; /* nothing to do, can't mount form,
     98     0  stevel 				   so no need to pretend we did */
     99     0  stevel 		}
    100     0  stevel 
    101     0  stevel 
    102     0  stevel 		/*
    103     0  stevel 		 * Attract all the requests needing this newly mounted
    104     0  stevel 		 * form. This may cause some unnecessary shuffling, but
    105     0  stevel 		 * we have to ensure requests aren't assigned to a printer
    106     0  stevel 		 * without the form mounted, so that the alert check is
    107     0  stevel 		 * correct.
    108     0  stevel 		 */
    109     0  stevel 		if (pfs->requests) {
    110     0  stevel 			form_in_question = pfs;
    111     0  stevel 			queue_attract (pps, qchk_form, 0);
    112     0  stevel 
    113     0  stevel 			/*
    114     0  stevel 			 * Maybe an alert can be shut off.
    115     0  stevel 			 */
    116     0  stevel 			check_form_alert (pfs, (_FORM *)0);
    117     0  stevel 		}
    118     0  stevel 
    119     0  stevel 	} else {
    120     0  stevel 		/*
    121     0  stevel 		 * Attract first request that doesn't need a form mounted.
    122     0  stevel 		 * We only need to get one request printing, because it
    123     0  stevel 		 * completing will cause the next request to be attracted.
    124     0  stevel 		 */
    125     0  stevel 		form_in_question = 0;
    126     0  stevel 		queue_attract (pps, qchk_form, 1);
    127     0  stevel 	}
    128     0  stevel 
    129     0  stevel 	dump_pstatus ();
    130     0  stevel 
    131     0  stevel 	return;
    132     0  stevel }
    133     0  stevel 
    134     0  stevel /**
    135     0  stevel  ** remount_pwheel() - MOUNT A PRINT-WHEEL WHERE ANOTHER WAS MOUNTED
    136     0  stevel  **/
    137     0  stevel 
    138     0  stevel static void
    139     0  stevel remount_pwheel(register PSTATUS *pps, char *pwheel_name)
    140     0  stevel {
    141     0  stevel 	PWSTATUS		*ppws;
    142     0  stevel 
    143     0  stevel 	if (SAME(pps->pwheel_name, pwheel_name))
    144     0  stevel 		return;	/* nothing to do */
    145     0  stevel 
    146     0  stevel 	/*
    147     0  stevel 	 * Unmount the old print wheel
    148     0  stevel 	 */
    149     0  stevel 	if (pps->pwheel_name) {
    150     0  stevel 		register PWSTATUS	*Oppws	= pps->pwheel;
    151     0  stevel 
    152     0  stevel 		pps->pwheel = 0;
    153     0  stevel 		if (Oppws)
    154     0  stevel 			Oppws->mounted--;
    155     0  stevel 
    156     0  stevel 		/*
    157     0  stevel 		 * Unmounting the print wheel may make some print
    158     0  stevel 		 * requests no longer printable, because they were
    159     0  stevel 		 * accepted only because the print wheel was already
    160     0  stevel 		 * mounted. Unmounting the print wheel will also force
    161     0  stevel 		 * some requests to another printer (where the print wheel
    162     0  stevel 		 * is mounted) so they can print.
    163     0  stevel 		 */
    164     0  stevel 		pwheel_in_question = pps->pwheel_name;
    165     0  stevel 		(void)queue_repel (pps, 0, qchk_pwheel);
    166     0  stevel 
    167     0  stevel 		unload_str (&pps->pwheel_name);
    168     0  stevel 
    169     0  stevel 		/*
    170     0  stevel 		 * Maybe an alert is due.
    171     0  stevel 		 */
    172     0  stevel 		if (Oppws)
    173     0  stevel 			check_pwheel_alert (Oppws, (PWHEEL *)0);
    174     0  stevel 	}
    175     0  stevel 
    176     0  stevel 	/*
    177     0  stevel 	 * Mount the new print wheel?
    178     0  stevel 	 */
    179     0  stevel 	if (pwheel_name) {
    180     0  stevel 		load_str (&pps->pwheel_name, pwheel_name);
    181  3125  jacobs 		if (ppws = search_pwstatus(pwheel_name)) {
    182     0  stevel 			pps->pwheel = ppws;
    183     0  stevel 			ppws->mounted++;
    184     0  stevel 
    185     0  stevel 			/*
    186     0  stevel 			 * Attract all requests needing this newly
    187     0  stevel 			 * mounted print wheel. This may cause some
    188     0  stevel 			 * unnecessary shuffling, but we have to ensure
    189     0  stevel 			 * requests aren't assigned to a printer without
    190     0  stevel 			 * the print-wheel mounted, so that the alert
    191     0  stevel 			 * check is correct.
    192     0  stevel 			 */
    193     0  stevel 			if (ppws->requests) {
    194     0  stevel 				pwheel_in_question = pwheel_name;
    195     0  stevel 				queue_attract (pps, qchk_pwheel, 0);
    196     0  stevel 
    197     0  stevel 				/*
    198     0  stevel 				 * Maybe an alert can be shut off.
    199     0  stevel 				 */
    200     0  stevel 				check_pwheel_alert (ppws, (PWHEEL *)0);
    201     0  stevel 			}
    202     0  stevel 
    203     0  stevel 		} else {
    204     0  stevel 			/*
    205     0  stevel 			 * Attract the first request that needs this newly
    206     0  stevel 			 * mounted print wheel. If no alert has been
    207     0  stevel 			 * defined for the print wheel, we don't know how
    208     0  stevel 			 * many requests are queued waiting for it, so we
    209     0  stevel 			 * have to do this unconditionally.
    210     0  stevel 			 */
    211     0  stevel 			pwheel_in_question = pwheel_name;
    212     0  stevel 			queue_attract (pps, qchk_pwheel, 1);
    213     0  stevel 		}
    214     0  stevel 
    215     0  stevel 	} else {
    216     0  stevel 		/*
    217     0  stevel 		 * Attract the first request that doesn't need a
    218     0  stevel 		 * print wheel mounted.
    219     0  stevel 		 * We only need to get one request printing, because it
    220     0  stevel 		 * completing will cause the next request to be attracted.
    221     0  stevel 		 */
    222     0  stevel 		pwheel_in_question = 0;
    223     0  stevel 		queue_attract (pps, qchk_pwheel, 1);
    224     0  stevel 	}
    225     0  stevel 
    226     0  stevel 	dump_pstatus ();
    227     0  stevel 
    228     0  stevel 	return;
    229     0  stevel }
    230     0  stevel 
    231     0  stevel #define MAX_TRAYS 100
    232     0  stevel 
    233     0  stevel /**
    234     0  stevel  ** s_max_trays()
    235     0  stevel  **/
    236     0  stevel 
    237     0  stevel void
    238     0  stevel s_max_trays(char *m, MESG *md)
    239     0  stevel {
    240     0  stevel 	char			*printer;
    241     0  stevel 	ushort			status;
    242     0  stevel 	short numTrays;
    243     0  stevel 	register PSTATUS	*pps;
    244     0  stevel 	register PFSTATUS	*ppfs;
    245     0  stevel 
    246     0  stevel 	(void) getmessage(m, S_MAX_TRAYS, &printer, &numTrays);
    247     0  stevel 	syslog(LOG_DEBUG, "s_max_trays(%s, %d)", (printer ? printer : "NULL"),
    248     0  stevel 	       numTrays);
    249     0  stevel 
    250     0  stevel 	/* Have we seen this printer before? */
    251  3125  jacobs 	if (!*printer || !(pps = search_pstatus(printer)))
    252     0  stevel 		status = MNODEST;
    253     0  stevel 
    254     0  stevel 	/* How about the tray? */
    255     0  stevel 	else if ((numTrays <=0) || (numTrays > MAX_TRAYS))
    256     0  stevel 		status = MNOTRAY;
    257     0  stevel 
    258     0  stevel 	/* If the printer is currently printing, we can't disturb it. */
    259     0  stevel 	else if (pps->request)
    260     0  stevel 		    status = MBUSY;
    261     0  stevel 
    262     0  stevel 	else if (pps->forms) {
    263     0  stevel 		if (!(ppfs = Realloc(pps->forms,numTrays * sizeof(PFSTATUS))))
    264     0  stevel 			status = MNOMEM;
    265     0  stevel 		else {
    266     0  stevel 			int i;
    267     0  stevel 
    268     0  stevel 			for (i = pps->numForms; i < numTrays; i++) {
    269     0  stevel 				ppfs[i].form = NULL;
    270  3125  jacobs 				ppfs[i].isAvailable = 0;
    271     0  stevel 			}
    272     0  stevel 			pps->forms = ppfs;
    273     0  stevel 			pps->numForms = numTrays;
    274     0  stevel 			status = MOK;
    275     0  stevel 		}
    276     0  stevel 	} else if (!(ppfs = Calloc(numTrays,sizeof(PFSTATUS)))) {
    277     0  stevel 		status = MNOMEM;
    278     0  stevel 	} else  {
    279     0  stevel 		pps->forms = ppfs;
    280     0  stevel 		pps->numForms = numTrays;
    281     0  stevel 		status = MOK;
    282     0  stevel 	}
    283     0  stevel 	dump_pstatus();
    284     0  stevel 	mputm(md, R_MAX_TRAYS, status);
    285     0  stevel }
    286     0  stevel 
    287     0  stevel /**
    288     0  stevel  ** s_mount()
    289     0  stevel  **/
    290     0  stevel 
    291     0  stevel void
    292     0  stevel s_mount(char *m, MESG *md)
    293     0  stevel {
    294     0  stevel 	char			*printer, *form, *pwheel_name;
    295     0  stevel 	ushort			status;
    296     0  stevel 	register PSTATUS	*pps;
    297     0  stevel 	register FSTATUS	*pfs;
    298     0  stevel 
    299     0  stevel 	(void) getmessage(m, S_MOUNT, &printer, &form, &pwheel_name);
    300     0  stevel 	syslog(LOG_DEBUG, "s_mount(%s, %s, %s)", (printer ? printer : "NULL"),
    301     0  stevel 	       (form ? form : "NULL"), (pwheel_name ? pwheel_name : "NULL"));
    302     0  stevel 
    303     0  stevel 	if (!*form && !*pwheel_name)
    304     0  stevel 		status = MNOMEDIA;
    305     0  stevel 
    306     0  stevel 	/* Have we seen this printer before? */
    307  3125  jacobs 	else if (!*printer || !(pps = search_pstatus(printer)))
    308     0  stevel 		status = MNODEST;
    309     0  stevel 
    310     0  stevel 	/* How about the form? */
    311  3125  jacobs 	else if (*form && !(pfs = search_fstatus(form)))
    312     0  stevel 		status = MNOMEDIA;
    313     0  stevel 
    314     0  stevel 	/* If the printer is currently printing, we can't disturb it. */
    315     0  stevel 	else if (pps->request)
    316     0  stevel 		    status = MBUSY;
    317     0  stevel 
    318     0  stevel 	else {
    319     0  stevel 		/*
    320     0  stevel 		 * Mount them.
    321     0  stevel 		 */
    322     0  stevel 		if (*form)
    323     0  stevel 			remount_form (pps, pfs,1);
    324     0  stevel 		if (*pwheel_name)
    325     0  stevel 			remount_pwheel(pps, pwheel_name);
    326     0  stevel 
    327     0  stevel 		status = MOK;
    328     0  stevel 	}
    329     0  stevel 
    330     0  stevel 	mputm(md, R_MOUNT, status);
    331     0  stevel }
    332     0  stevel 
    333     0  stevel /*
    334     0  stevel  * s_mount_tray()
    335     0  stevel  */
    336     0  stevel 
    337     0  stevel void
    338     0  stevel s_mount_tray(char *m, MESG *md)
    339     0  stevel {
    340     0  stevel 	char			*printer, *form, *pwheel_name;
    341     0  stevel 	ushort			status;
    342     0  stevel 	short			trayNum;
    343     0  stevel 	register PSTATUS	*pps;
    344     0  stevel 	register FSTATUS	*pfs;
    345     0  stevel 
    346     0  stevel 	(void) getmessage(m, S_MOUNT_TRAY, &printer, &form, &pwheel_name,
    347     0  stevel 		&trayNum);
    348     0  stevel 	syslog(LOG_DEBUG, "s_mount_tray(%s, %s, %s, %d)",
    349     0  stevel 	       (printer ? printer : "NULL"), (form ? form : "NULL"),
    350     0  stevel 	       (pwheel_name ? pwheel_name : "NULL"), trayNum);
    351     0  stevel 
    352     0  stevel 	if (!*form && !*pwheel_name)
    353     0  stevel 		status = MNOMEDIA;
    354     0  stevel 
    355     0  stevel 	/* Have we seen this printer before? */
    356  3125  jacobs 	else if (!*printer || !(pps = search_pstatus(printer)))
    357     0  stevel 		status = MNODEST;
    358     0  stevel 
    359     0  stevel 	/* How about the form? */
    360  3125  jacobs 	else if (*form && !(pfs = search_fstatus(form)))
    361     0  stevel 		status = MNOMEDIA;
    362     0  stevel 
    363     0  stevel 	/* How about the tray? */
    364     0  stevel 	else if ((trayNum <=0) || (trayNum > pps->numForms))
    365     0  stevel 		status = MNOTRAY;
    366     0  stevel 
    367     0  stevel 	/* If the printer is currently printing, we can't disturb it. */
    368     0  stevel 	else if (pps->request)
    369     0  stevel 		    status = MBUSY;
    370     0  stevel 
    371     0  stevel 	else {
    372     0  stevel 		/*
    373     0  stevel 		 * Mount them.
    374     0  stevel 		 */
    375     0  stevel 		if (*form)
    376     0  stevel 			remount_form(pps, pfs,trayNum);
    377     0  stevel 		if (*pwheel_name)
    378     0  stevel 			remount_pwheel(pps, pwheel_name);
    379     0  stevel 
    380     0  stevel 		status = MOK;
    381     0  stevel 	}
    382     0  stevel 
    383     0  stevel 	mputm (md, R_MOUNT_TRAY, status);
    384     0  stevel }
    385     0  stevel 
    386     0  stevel /**
    387     0  stevel  ** s_unmount()
    388     0  stevel  **/
    389     0  stevel 
    390     0  stevel void
    391     0  stevel s_unmount(char *m, MESG *md)
    392     0  stevel {
    393     0  stevel 	char			*printer,
    394     0  stevel 				*form,
    395     0  stevel 				*pwheel_name;
    396     0  stevel 	ushort			status;
    397     0  stevel 	register PSTATUS	*pps;
    398     0  stevel 
    399     0  stevel 	(void)getmessage (m, S_UNMOUNT, &printer, &form, &pwheel_name);
    400     0  stevel 	syslog(LOG_DEBUG, "s_unmount(%s, %s, %s)",
    401     0  stevel 	       (printer ? printer : "NULL"), (form ? form : "NULL"),
    402     0  stevel 	       (pwheel_name ? pwheel_name : "NULL"));
    403     0  stevel 
    404     0  stevel 	if (!*form && !*pwheel_name)
    405     0  stevel 		status = MNOMEDIA;
    406     0  stevel 
    407     0  stevel 	/*
    408     0  stevel 	 * Have we seen this printer before?
    409     0  stevel 	 */
    410  3125  jacobs 	else if (!*printer || !(pps = search_pstatus(printer)))
    411     0  stevel 		status = MNODEST;
    412     0  stevel 
    413     0  stevel 
    414     0  stevel 	/*
    415     0  stevel 	 * If the printer is currently printing a request,
    416     0  stevel 	 * we can't unmount the current form/pwheel.
    417     0  stevel 	 */
    418     0  stevel 	else if (pps->request)
    419     0  stevel 		status = MBUSY;
    420     0  stevel 
    421     0  stevel 	else {
    422     0  stevel 		/*
    423     0  stevel 		 * Unmount them.
    424     0  stevel 		 */
    425     0  stevel 		if (*form)
    426     0  stevel 			remount_form (pps, (FSTATUS *)0,1);
    427     0  stevel 		if (*pwheel_name)
    428     0  stevel 			remount_pwheel (pps, (char *)0);
    429     0  stevel 
    430     0  stevel 		status = MOK;
    431     0  stevel 	}
    432     0  stevel 
    433     0  stevel 	mputm (md, R_UNMOUNT, status);
    434     0  stevel 	return;
    435     0  stevel }
    436     0  stevel /**
    437     0  stevel  ** s_unmount_tray()
    438     0  stevel  **/
    439     0  stevel 
    440     0  stevel void
    441     0  stevel s_unmount_tray(char *m, MESG *md)
    442     0  stevel {
    443     0  stevel 	char			*printer,
    444     0  stevel 				*form,
    445     0  stevel 				*pwheel_name;
    446     0  stevel 
    447     0  stevel 	ushort			status;
    448     0  stevel 	short			trayNum;
    449     0  stevel 
    450     0  stevel 	register PSTATUS	*pps;
    451     0  stevel 
    452     0  stevel 	(void)getmessage (m, S_UNMOUNT_TRAY, &printer, &form, &pwheel_name,
    453     0  stevel 		&trayNum);
    454     0  stevel 	syslog(LOG_DEBUG, "s_unmount_tray(%s, %s, %s, %d)",
    455     0  stevel 	       (printer ? printer : "NULL"), (form ? form : "NULL"),
    456     0  stevel 	       (pwheel_name ? pwheel_name : "NULL"), trayNum);
    457     0  stevel 
    458     0  stevel 
    459     0  stevel 	if (!*form && !*pwheel_name)
    460     0  stevel 		status = MNOMEDIA;
    461     0  stevel 
    462  3125  jacobs 	else if (!*printer || !(pps = search_pstatus(printer)))
    463     0  stevel 		/* haven't seen this printer before */
    464     0  stevel 		status = MNODEST;
    465     0  stevel 	else if ((trayNum <=0) || (trayNum > pps->numForms))
    466     0  stevel 		/* haven't seen the tray before */
    467     0  stevel 		status = MNOTRAY;
    468     0  stevel 	else if (pps->request)
    469     0  stevel 		/* is the printer busy */
    470     0  stevel 		status = MBUSY;
    471     0  stevel 	else {
    472     0  stevel 		/* Unmount them. */
    473     0  stevel 		if (*form)
    474     0  stevel 			remount_form (pps, (FSTATUS *)0,trayNum);
    475     0  stevel 		if (*pwheel_name)
    476     0  stevel 			remount_pwheel (pps, (char *)0);
    477     0  stevel 
    478     0  stevel 		status = MOK;
    479     0  stevel 	}
    480     0  stevel 
    481     0  stevel 	mputm (md, R_UNMOUNT_TRAY, status);
    482     0  stevel 	return;
    483     0  stevel }
    484     0  stevel 
    485     0  stevel /**
    486     0  stevel  ** s_load_form()
    487     0  stevel  **/
    488     0  stevel 
    489     0  stevel void
    490     0  stevel s_load_form(char *m, MESG *md)
    491     0  stevel {
    492     0  stevel 	char			*form;
    493     0  stevel 	ushort			status;
    494     0  stevel 	register _FORM		*pf;
    495     0  stevel 	register FSTATUS	*pfs;
    496     0  stevel 
    497     0  stevel 	(void)getmessage (m, S_LOAD_FORM, &form);
    498     0  stevel 	syslog(LOG_DEBUG, "s_load_form(%s)", (form ? form : "NULL"));
    499     0  stevel 
    500     0  stevel 	if (!*form)
    501     0  stevel 		/* no form specified */
    502     0  stevel 		status = MNODEST;
    503     0  stevel 	else if (!(pf = Getform(form))) {
    504     0  stevel 		/* strange or missing form */
    505     0  stevel 		switch (errno) {
    506     0  stevel 		case EBADF:
    507     0  stevel 			status = MERRDEST;
    508     0  stevel 			break;
    509     0  stevel 		case ENOENT:
    510     0  stevel 		default:
    511     0  stevel 			status = MNODEST;
    512     0  stevel 			break;
    513     0  stevel 		}
    514     0  stevel 
    515  3125  jacobs 	} else if ((pfs = search_fstatus(form))) {
    516     0  stevel 		/* Have we seen this form before? */
    517     0  stevel 		unload_list (&pfs->users_allowed);
    518     0  stevel 		unload_list (&pfs->users_denied);
    519     0  stevel 		load_userform_access (
    520     0  stevel 			pf->name,
    521     0  stevel 			&pfs->users_allowed,
    522     0  stevel 			&pfs->users_denied
    523     0  stevel 		);
    524     0  stevel 
    525     0  stevel 		load_sdn (&pfs->cpi, pf->cpi);
    526     0  stevel 		load_sdn (&pfs->lpi, pf->lpi);
    527     0  stevel 		load_sdn (&pfs->plen, pf->plen);
    528     0  stevel 		load_sdn (&pfs->pwid, pf->pwid);
    529     0  stevel 
    530     0  stevel 
    531     0  stevel 		/*
    532     0  stevel 		 * These have to be done in the order shown,
    533     0  stevel 		 * and after the assignments above, so that all
    534     0  stevel 		 * the new information is in place for the
    535     0  stevel 		 * checks. An unfortunate side effect is that
    536     0  stevel 		 * it is possible for the alert to shut off
    537     0  stevel 		 * and then come on again, if (1) enough requests
    538     0  stevel 		 * are canceled to drop the level below the old
    539     0  stevel 		 * alert threshold, but (2) the new alert threshold
    540     0  stevel 		 * is even lower. The final alert will be correct,
    541     0  stevel 		 * though.
    542     0  stevel 		 */
    543     0  stevel 
    544     0  stevel 		form_in_question = pfs;
    545     0  stevel 		queue_check (qchk_form);
    546     0  stevel 
    547     0  stevel 		check_form_alert (pfs, pf);
    548     0  stevel 
    549     0  stevel 
    550     0  stevel 		status = MOK;
    551     0  stevel 
    552     0  stevel 	/*
    553     0  stevel 	 * Room for a new form?
    554     0  stevel 	 */
    555  3125  jacobs 	} else if ((pfs = new_fstatus(pf))) {
    556     0  stevel 		/*
    557     0  stevel 		 * No alert is possible for a new form, of course,
    558     0  stevel 		 * but this routine does a bit more than just check
    559     0  stevel 		 * the alert.
    560     0  stevel 		 */
    561     0  stevel 		check_form_alert (pfs, pf);
    562     0  stevel 		status = MOK;
    563     0  stevel 	} else {
    564     0  stevel 		free_form (pf);
    565     0  stevel 		status = MNOSPACE;
    566     0  stevel 	}
    567     0  stevel 
    568     0  stevel 	mputm (md, R_LOAD_FORM, status);
    569     0  stevel 	return;
    570     0  stevel }
    571     0  stevel 
    572     0  stevel /**
    573     0  stevel  ** s_unload_form()
    574     0  stevel  **/
    575     0  stevel 
    576     0  stevel static void
    577     0  stevel _unload_form(register FSTATUS *pfs)
    578     0  stevel {
    579     0  stevel 	int i;
    580     0  stevel 	short numForms;
    581     0  stevel 	PFSTATUS *ppfs;
    582     0  stevel 
    583     0  stevel 	/*
    584     0  stevel 	 * Unmount this form everywhere and get rid of it.
    585     0  stevel 	 */
    586  3125  jacobs 	for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++)
    587  3125  jacobs 		if (((ppfs = PStatus[i]->forms) != NULL) &&
    588  3125  jacobs 		    ((numForms = PStatus[i]->numForms) > 0)) {
    589  3125  jacobs 			int j;
    590  3125  jacobs 			for ( j = 0 ; j < numForms ; j++ )
    591  3125  jacobs 				if (ppfs[j].form == pfs) ppfs[j].form= NULL;
    592  3125  jacobs 		}
    593     0  stevel 
    594     0  stevel 	return;
    595     0  stevel }
    596     0  stevel 
    597     0  stevel void
    598     0  stevel s_unload_form(char *m, MESG *md)
    599     0  stevel {
    600     0  stevel 	char			*form;
    601     0  stevel 	ushort			status;
    602     0  stevel 	RSTATUS			*prs;
    603     0  stevel 	register FSTATUS	*pfs;
    604     0  stevel 
    605     0  stevel 	(void)getmessage (m, S_UNLOAD_FORM, &form);
    606     0  stevel 	syslog(LOG_DEBUG, "s_unload_form(%s)", (form ? form : "NULL"));
    607     0  stevel 
    608     0  stevel 	if (!*form || STREQU(form, NAME_ALL)) {
    609  3125  jacobs 		int i;
    610     0  stevel 		/* If we have a request queued for ANY form, we can't do it. */
    611     0  stevel 		status = MOK;
    612  3125  jacobs 		for (i = 0; FStatus != NULL && FStatus[i] != NULL &&
    613  3125  jacobs 			    status == MOK; i++) {
    614  3125  jacobs 			for (prs = Request_List; prs != NULL; prs = prs->next)
    615  3125  jacobs 				if (prs->form == FStatus[i]) {
    616  3125  jacobs 					status = MBUSY;
    617  3125  jacobs 					break;
    618  3125  jacobs 				}
    619  3125  jacobs 		}
    620     0  stevel 
    621  3125  jacobs 		if (status == MOK) {
    622  3125  jacobs 			for (i = 0; FStatus != NULL && FStatus[i] != NULL; i++)
    623  3125  jacobs 				_unload_form (FStatus[i]);
    624  3125  jacobs 			free(FStatus);
    625  3125  jacobs 			FStatus = NULL;
    626  3125  jacobs 		}
    627  3125  jacobs 
    628  3125  jacobs 	} else if (!*form || !(pfs = search_fstatus(form)))
    629     0  stevel 		/* Have we seen this form before? */
    630     0  stevel 		status = MNODEST;
    631     0  stevel 	else {
    632     0  stevel 		/* Is there even one request waiting for this form? */
    633     0  stevel 		status = MOK;
    634  3125  jacobs 		for (prs = Request_List; prs != NULL; prs = prs->next)
    635  3125  jacobs 			if (prs->form == pfs) {
    636  3125  jacobs 				status = MBUSY;
    637  3125  jacobs 				break;
    638  3125  jacobs 			}
    639  3125  jacobs 
    640  3125  jacobs 		if (status == MOK) {
    641     0  stevel 			_unload_form (pfs);
    642  3125  jacobs 			list_remove((void ***)&FStatus, (void *)pfs);
    643  3125  jacobs 		}
    644     0  stevel 	}
    645     0  stevel 
    646     0  stevel 	mputm (md, R_UNLOAD_FORM, status);
    647     0  stevel 	return;
    648     0  stevel }
    649     0  stevel 
    650     0  stevel /**
    651     0  stevel  ** s_load_printwheel()
    652     0  stevel  **/
    653     0  stevel 
    654     0  stevel void
    655     0  stevel s_load_printwheel(char *m, MESG *md)
    656     0  stevel {
    657     0  stevel 	char			*pwheel_name;
    658     0  stevel 	ushort			status;
    659     0  stevel 	register PWHEEL		*ppw;
    660     0  stevel 	register PWSTATUS	*ppws;
    661     0  stevel 
    662     0  stevel 	(void)getmessage (m, S_LOAD_PRINTWHEEL, &pwheel_name);
    663     0  stevel 	syslog(LOG_DEBUG, "s_load_printwheel(%s)",
    664     0  stevel 	       (pwheel_name ? pwheel_name : "NULL"));
    665     0  stevel 
    666     0  stevel 	if (!*pwheel_name)
    667     0  stevel 		/* no printwheel specified */
    668     0  stevel 		status = MNODEST;
    669     0  stevel 	else if (!(ppw = Getpwheel(pwheel_name))) {
    670     0  stevel 		/* Strange or missing print wheel? */
    671     0  stevel 		switch (errno) {
    672     0  stevel 		case EBADF:
    673     0  stevel 			status = MERRDEST;
    674     0  stevel 			break;
    675     0  stevel 		case ENOENT:
    676     0  stevel 		default:
    677     0  stevel 			status = MNODEST;
    678     0  stevel 			break;
    679     0  stevel 		}
    680  3125  jacobs 	} else if ((ppws = search_pwstatus(pwheel_name))) {
    681     0  stevel 		/* Print wheel we already know about? */
    682     0  stevel 		check_pwheel_alert (ppws, ppw);
    683     0  stevel 		status = MOK;
    684  3125  jacobs 	} else if ((ppws = new_pwstatus(ppw))) {
    685     0  stevel 		/* Room for a new print wheel? */
    686  3125  jacobs 		register RSTATUS 	*prs;
    687     0  stevel 
    688     0  stevel 		/*
    689     0  stevel 		 * Because of the quirky nature of the print wheel
    690     0  stevel 		 * structures, i.e. no structure unless an alert has
    691     0  stevel 		 * been defined, we have to run through the requests
    692     0  stevel 		 * and see which ones are waiting for this print wheel,
    693     0  stevel 		 * so we can assign alerts and count pending requests.
    694     0  stevel 		 */
    695  3125  jacobs 		for (prs = Request_List; prs != NULL; prs = prs->next)
    696  3125  jacobs 			if ((prs->pwheel_name == pwheel_name) &&
    697  3125  jacobs 			    (!one_printer_with_charsets(prs))) {
    698     0  stevel 				prs->pwheel = ppws;
    699     0  stevel 				ppws->requests++;
    700     0  stevel 			}
    701     0  stevel 		check_pwheel_alert (ppws, ppw);
    702     0  stevel 
    703     0  stevel 		status = MOK;
    704     0  stevel 	} else {
    705     0  stevel 		freepwheel (ppw);
    706     0  stevel 		status = MNOSPACE;
    707     0  stevel 	}
    708     0  stevel 
    709     0  stevel 	mputm (md, R_LOAD_PRINTWHEEL, status);
    710     0  stevel 	return;
    711     0  stevel }
    712     0  stevel 
    713     0  stevel /**
    714     0  stevel  ** s_unload_printwheel()
    715     0  stevel  **/
    716     0  stevel 
    717     0  stevel static void
    718     0  stevel _unload_pwheel(register PWSTATUS *ppws)
    719     0  stevel {
    720  3125  jacobs 	register PSTATUS		*pps;
    721  3125  jacobs 	register RSTATUS		*prs;
    722  3125  jacobs 	int i;
    723     0  stevel 
    724     0  stevel 
    725     0  stevel 	/*
    726     0  stevel 	 * ``Unmount'' the alert part of this print wheel everywhere.
    727     0  stevel 	 * THIS IS NOT A COMPLETE UNMOUNT, JUST THE ALERT STRUCTURE
    728     0  stevel 	 * IS REMOVED.
    729     0  stevel 	 */
    730  3125  jacobs 	for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++)
    731  3125  jacobs 		if (PStatus[i]->pwheel == ppws)
    732  3125  jacobs 			PStatus[i]->pwheel = 0;
    733     0  stevel 
    734     0  stevel 	/*
    735     0  stevel 	 * Remove the alert part from all requests.
    736     0  stevel 	 */
    737     0  stevel 	for (prs = Request_List; prs; prs = prs->next)
    738     0  stevel 		if (prs->pwheel == ppws)
    739     0  stevel 			prs->pwheel = 0;
    740     0  stevel 
    741     0  stevel 	/*
    742     0  stevel 	 * Cancel any alert pending. Here we're different from the
    743     0  stevel 	 * similar code for unloading a form, because, to be able to
    744     0  stevel 	 * unload a form we first require NO requests pending. If no
    745     0  stevel 	 * requests are pending there should be no alert to cancel.
    746     0  stevel 	 * Print wheels, on the other hand, only exist as names and
    747     0  stevel 	 * alerts. We can always unload a ``print wheel'' because
    748     0  stevel 	 * all we're really unloading is an alert. Thus, there can
    749     0  stevel 	 * be requests queued for the print wheel (the name), and
    750     0  stevel 	 * thus there can be an alert running.
    751     0  stevel 	 */
    752     0  stevel 	if (ppws->alert->active)
    753     0  stevel 		cancel_alert (A_PWHEEL, ppws);
    754     0  stevel 
    755  3125  jacobs 	free_pwstatus(ppws);
    756     0  stevel 
    757     0  stevel 	return;
    758     0  stevel }
    759     0  stevel 
    760     0  stevel void
    761     0  stevel s_unload_printwheel(char *m, MESG *md)
    762     0  stevel {
    763     0  stevel 	char			*pwheel_name;
    764     0  stevel 
    765     0  stevel 	ushort			status;
    766     0  stevel 
    767     0  stevel 	register PWSTATUS	*ppws;
    768     0  stevel 
    769     0  stevel 
    770     0  stevel 	/*
    771     0  stevel 	 * We don't care if any requests are waiting for the print
    772     0  stevel 	 * wheel(s)--what we're removing here is (are) just the alert(s)!
    773     0  stevel 	 */
    774     0  stevel 
    775     0  stevel 	(void)getmessage (m, S_UNLOAD_PRINTWHEEL, &pwheel_name);
    776     0  stevel 	syslog(LOG_DEBUG, "s_unload_printwheel(%s)",
    777     0  stevel 	       (pwheel_name ? pwheel_name : "NULL"));
    778     0  stevel 
    779     0  stevel 
    780     0  stevel 	/*
    781     0  stevel 	 * Remove all print wheel alerts?
    782     0  stevel 	 */
    783     0  stevel 	if (!*pwheel_name || STREQU(pwheel_name, NAME_ALL)) {
    784  3125  jacobs 		int i;
    785  3125  jacobs 
    786  3125  jacobs 		for (i = 0; PWStatus != NULL && PWStatus[i] != NULL; i++)
    787  3125  jacobs 			_unload_pwheel (PWStatus[i]);
    788  3125  jacobs 		free(PWStatus);
    789  3125  jacobs 		PWStatus = NULL;
    790     0  stevel 		status = MOK;
    791     0  stevel 
    792     0  stevel 	/*
    793     0  stevel 	 * Have we seen this print wheel before?
    794     0  stevel 	 */
    795  3125  jacobs 	} else if (!(ppws = search_pwstatus(pwheel_name)))
    796     0  stevel 		status = MNODEST;
    797     0  stevel 
    798     0  stevel 	else {
    799     0  stevel 		_unload_pwheel (ppws);
    800  3125  jacobs 		list_remove((void ***)&PWStatus, (void *)ppws);
    801     0  stevel 		status = MOK;
    802     0  stevel 
    803     0  stevel 	}
    804     0  stevel 
    805     0  stevel 	mputm (md, R_UNLOAD_PRINTWHEEL, status);
    806     0  stevel 	return;
    807     0  stevel }
    808