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 "lpsched.h"
     34     0  stevel #include <syslog.h>
     35     0  stevel 
     36  3125  jacobs CSTATUS		**CStatus = NULL;		/* Status of same          */
     37  3125  jacobs PSTATUS		**PStatus = NULL;		/* Status of same          */
     38  3125  jacobs FSTATUS		**FStatus = NULL;		/* status of same	   */
     39  3125  jacobs PWSTATUS	**PWStatus = NULL;		/* Status of same          */
     40  3125  jacobs EXEC		**Exec_Table = NULL;		/* Running processes       */
     41  3125  jacobs EXEC		**Exec_Slow = NULL;		/*   Slow filters	   */
     42  3125  jacobs EXEC		**Exec_Notify = NULL;		/*   Notifications	   */
     43  3125  jacobs RSTATUS		*Request_List = NULL;		/* Queue of print requests */
     44     0  stevel 
     45  3125  jacobs int		ET_SlowSize	= 1,
     46  3125  jacobs 		ET_NotifySize	= 1;
     47     0  stevel 
     48     0  stevel static void	init_printers(),
     49     0  stevel 		init_classes(),
     50     0  stevel 		init_forms(),
     51     0  stevel 		init_pwheels(),
     52     0  stevel 		init_exec();
     53     0  stevel 
     54     0  stevel 
     55  3125  jacobs static void	init_requests();
     56     0  stevel 
     57     0  stevel void
     58     0  stevel init_memory(void)
     59     0  stevel {
     60  3125  jacobs     init_exec();
     61     0  stevel     init_printers();
     62     0  stevel     init_classes();
     63     0  stevel     init_forms();
     64     0  stevel     init_pwheels();
     65     0  stevel 
     66     0  stevel     /*
     67     0  stevel      * Load the status after the basic structures have been loaded,
     68     0  stevel      * but before loading requests still in the queue. This is so
     69     0  stevel      * the requests can be compared against accurate status information
     70     0  stevel      * (except rejection status--accept the jobs anyway).
     71     0  stevel      */
     72     0  stevel     load_status();
     73     0  stevel 
     74     0  stevel     Loadfilters(Lp_A_Filters);
     75     0  stevel 
     76  3125  jacobs     init_requests();
     77     0  stevel }
     78     0  stevel 
     79     0  stevel static void
     80     0  stevel init_printers()
     81     0  stevel {
     82     0  stevel     PRINTER	*p;
     83  3125  jacobs     int i = 0;
     84     0  stevel 
     85     0  stevel     while((p = Getprinter(NAME_ALL)) != NULL || errno != ENOENT) {
     86  3125  jacobs 	if ((!p) || (p->remote))	/* NULL or this is remote, ignore it */
     87     0  stevel 		continue;
     88     0  stevel 
     89  3125  jacobs 	(void) new_pstatus(p);
     90  3125  jacobs 	syslog(LOG_DEBUG, "Loaded printer: %s", p->name);
     91     0  stevel     }
     92     0  stevel }
     93     0  stevel 
     94     0  stevel static void
     95     0  stevel init_classes()
     96     0  stevel {
     97  3125  jacobs     CLASS       *c;
     98     0  stevel 
     99  3125  jacobs     while((c = Getclass(NAME_ALL)) != NULL) {
    100  3125  jacobs 	(void) new_cstatus(c);
    101  3125  jacobs         syslog(LOG_DEBUG, "Loaded class: %s", c->name);
    102     0  stevel     }
    103     0  stevel }
    104     0  stevel 
    105     0  stevel static void
    106     0  stevel init_forms()
    107     0  stevel {
    108  3125  jacobs     _FORM	*f;
    109  3125  jacobs     int		i = 0;
    110     0  stevel 
    111     0  stevel     while ((f = Getform(NAME_ALL)) != NULL) {
    112  3125  jacobs 	(void) new_fstatus(f);
    113  3125  jacobs 	syslog(LOG_DEBUG, "Loaded form: %s", f->name);
    114     0  stevel     }
    115     0  stevel }
    116     0  stevel 
    117     0  stevel static void
    118     0  stevel init_pwheels()
    119     0  stevel {
    120     0  stevel     PWHEEL	*p;
    121  3125  jacobs     int i = 0;
    122     0  stevel 
    123     0  stevel     while((p = Getpwheel(NAME_ALL)) != NULL || errno != ENOENT)
    124     0  stevel     {
    125  3125  jacobs 	if (!p)			/* NULL, ignore it. */
    126     0  stevel 	    continue;
    127     0  stevel 
    128  3125  jacobs 	(void) new_pwstatus(p);
    129  3125  jacobs     	syslog(LOG_DEBUG, "Loaded print-wheel: %s", p->name);
    130     0  stevel     }
    131     0  stevel }
    132     0  stevel 
    133  3125  jacobs static void
    134     0  stevel init_requests(void)
    135     0  stevel {
    136  3125  jacobs     RSTATUS		**table = NULL;
    137     0  stevel     REQUEST		*r;
    138     0  stevel     SECURE		*s;
    139     0  stevel     char		*name;
    140     0  stevel     char		*sysdir;
    141     0  stevel     char		*sysname;
    142     0  stevel     char		*reqfile = NULL;
    143     0  stevel     long		addr = -1;
    144     0  stevel     long		sysaddr = -1;
    145     0  stevel     short		vr_ret;
    146     0  stevel 
    147  3125  jacobs     while((sysname = next_dir(Lp_Requests, &addr)) != NULL) {
    148  3125  jacobs     	RSTATUS		*rsp;
    149     0  stevel 
    150     0  stevel 	sysdir = makepath(Lp_Requests, sysname, NULL);
    151     0  stevel 
    152     0  stevel 	while((name = next_file(sysdir, &sysaddr)) != NULL) {
    153     0  stevel 	    reqfile = makepath(sysname, name, NULL);
    154     0  stevel 	    Free(name);
    155     0  stevel 
    156     0  stevel 	    if ((s = Getsecure(reqfile)) == NULL) {
    157  3125  jacobs 		RSTATUS tmp;
    158  3125  jacobs 
    159  3125  jacobs 		memset(&tmp, 0, sizeof (tmp));
    160  3125  jacobs 		tmp.req_file = reqfile;	/* fix for 1103890 */
    161  3125  jacobs 		rmfiles(&tmp, 0);
    162  3125  jacobs 		free(tmp.req_file);
    163     0  stevel 		continue;
    164     0  stevel 	    }
    165  3125  jacobs 	    syslog(LOG_DEBUG, "Loaded request: %s", reqfile);
    166     0  stevel 
    167     0  stevel 	    if((r = Getrequest(reqfile)) == NULL) {
    168  3125  jacobs 		RSTATUS tmp;
    169  3125  jacobs 
    170  3125  jacobs 		memset(&tmp, 0, sizeof (tmp));
    171  3125  jacobs 		tmp.req_file = reqfile;	/* fix for 1103890 */
    172  3125  jacobs 		rmfiles(&tmp, 0);
    173  3125  jacobs 		freesecure(s);
    174  3125  jacobs 		free(tmp.req_file);
    175     0  stevel 		continue;
    176     0  stevel 	    }
    177  3125  jacobs 	    syslog(LOG_DEBUG, "Loaded secure: %s", s->req_id);
    178  3125  jacobs 
    179  3125  jacobs 	    rsp = new_rstatus(r, s);
    180  3125  jacobs 
    181     0  stevel 	    r->outcome &= ~RS_ACTIVE;	/* it can't be! */
    182  3125  jacobs 	    rsp->req_file = reqfile;
    183     0  stevel 
    184     0  stevel 	    if ((r->outcome & (RS_CANCELLED|RS_FAILED)) &&
    185  3125  jacobs 		!(r->outcome & RS_NOTIFY)) {
    186  3125  jacobs 			rmfiles(rsp, 0);
    187  3125  jacobs 			free_rstatus(rsp);
    188  3125  jacobs 			continue;
    189     0  stevel 	    }
    190     0  stevel 
    191     0  stevel 	    /*
    192     0  stevel 	     * So far, the only way RS_NOTIFY can be set without there
    193     0  stevel 	     * being a notification file containing the message to the
    194     0  stevel 	     * user, is if the request was cancelled. This is because
    195     0  stevel 	     * cancelling a request does not cause the creation of the
    196     0  stevel 	     * message if the request is currently printing or filtering.
    197     0  stevel 	     * (The message is created after the child process dies.)
    198     0  stevel 	     * Thus, we know what to say.
    199     0  stevel 	     *
    200     0  stevel 	     * If this behaviour changes, we may have to find another way
    201     0  stevel 	     * of determining what to say in the message.
    202     0  stevel 	     */
    203     0  stevel 	    if (r->outcome & RS_NOTIFY) {
    204  3125  jacobs 		char	*file = makereqerr(rsp);
    205     0  stevel 
    206     0  stevel 		if (Access(file, F_OK) == -1) {
    207     0  stevel 		    if (!(r->outcome & RS_CANCELLED)) {
    208     0  stevel 			Free(file);
    209  3125  jacobs 			rmfiles(rsp, 0);
    210  3125  jacobs 			free_rstatus(rsp);
    211     0  stevel 			continue;
    212     0  stevel 		    }
    213  3125  jacobs 		    notify(rsp, NULL, 0, 0, 0);
    214     0  stevel 		}
    215     0  stevel 		Free(file);
    216     0  stevel 	    }
    217     0  stevel 
    218     0  stevel 	    /* fix for bugid 1103709. if validate_request returns
    219     0  stevel 	     * MNODEST, then the printer for the request doesn't exist
    220     0  stevel 	     * anymore! E.g. lpadmin -x was issued, and the request
    221     0  stevel 	     * hasn't been cleaned up. In this case, the "printer"
    222     0  stevel 	     * element of table[] will be NULL, and cancel will
    223     0  stevel 	     * core dump! So we clean this up here.
    224     0  stevel 	     */
    225     0  stevel 
    226     0  stevel 	    /*
    227     0  stevel 	     * Well actually this happens with MDENYDEST too. The real problem
    228     0  stevel 	     * is if the printer is NULL, so test for it
    229     0  stevel 	     */
    230     0  stevel 
    231  3125  jacobs 	    if ((vr_ret=validate_request(rsp, NULL, 1)) != MOK) {
    232  3125  jacobs 		if (vr_ret == MNODEST || (rsp->printer == NULL)) {
    233  3125  jacobs 			rmfiles(rsp, 0);
    234  3125  jacobs 			free_rstatus(rsp);
    235     0  stevel 			continue;
    236     0  stevel 		}
    237  3125  jacobs 		cancel(rsp, 1);
    238     0  stevel 	    }
    239     0  stevel 
    240  3125  jacobs 	    list_append((void ***)&table, (void *)rsp);
    241     0  stevel 	}
    242     0  stevel 	Free(sysdir);
    243     0  stevel 	Free(sysname);
    244     0  stevel 	sysaddr = -1;
    245     0  stevel     }
    246  3125  jacobs 
    247  3125  jacobs     if (table != NULL) {
    248  3125  jacobs 	unsigned long i;
    249     0  stevel 
    250  3125  jacobs 	for (i = 0; table[i] != NULL; i++);
    251  3125  jacobs 
    252  3125  jacobs 	qsort((void *)table, i, sizeof(RSTATUS *),
    253     0  stevel 			(int (*)(const void * , const void *))rsort);
    254     0  stevel 
    255  3125  jacobs 	for (i = 0; table[i] != NULL; i++) {
    256     0  stevel 		table[i]->next = table[i + 1];
    257  3125  jacobs 		if (table[i + 1] != NULL)
    258  3125  jacobs 			table[i + 1]->prev = table[i];
    259     0  stevel 	}
    260     0  stevel 
    261  3125  jacobs 	Request_List = *table;
    262  3125  jacobs 	Free(table);
    263  3125  jacobs     }
    264     0  stevel }
    265     0  stevel 
    266     0  stevel static void
    267     0  stevel init_exec()
    268     0  stevel {
    269  3125  jacobs     EXEC	*ep;
    270     0  stevel     int		i;
    271     0  stevel 
    272  3125  jacobs     for (i = 0; i < ET_SlowSize; i++) {
    273  3125  jacobs 	ep = new_exec(EX_SLOWF, NULL);
    274  3125  jacobs 	list_append((void ***)&Exec_Slow, (void *)ep);
    275     0  stevel     }
    276     0  stevel 
    277  3125  jacobs     for (i = 0; i < ET_NotifySize; i++) {
    278  3125  jacobs 	ep = new_exec(EX_NOTIFY, NULL);
    279  3125  jacobs 	list_append((void ***)&Exec_Notify, (void *)ep);
    280     0  stevel     }
    281     0  stevel }
    282