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  2660  jacobs  * Common Development and Distribution License (the "License").
      6  2660  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  2660  jacobs 
     22     0  stevel /*
     23  2660  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  2660  jacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
     32     0  stevel 
     33     0  stevel #include "stdio.h"
     34     0  stevel #include "sys/types.h"
     35     0  stevel #include "memory.h"
     36     0  stevel #include "string.h"
     37     0  stevel #include "pwd.h"
     38     0  stevel #include "fcntl.h"
     39     0  stevel #include "errno.h"
     40     0  stevel #include "signal.h"
     41     0  stevel #include "unistd.h"
     42     0  stevel #include "stdlib.h"
     43     0  stevel 
     44     0  stevel #include "lp.h"
     45     0  stevel #include "access.h"
     46     0  stevel #include "form.h"
     47     0  stevel #include "requests.h"
     48     0  stevel #include "filters.h"
     49     0  stevel #include "printers.h"
     50     0  stevel #include "class.h"
     51     0  stevel #include "users.h"
     52     0  stevel #include "secure.h"
     53     0  stevel #include "msgs.h"
     54     0  stevel 
     55     0  stevel #include "nodes.h"
     56     0  stevel 
     57     0  stevel /**
     58     0  stevel  ** Defines:
     59     0  stevel  **/
     60     0  stevel 
     61     0  stevel /*
     62     0  stevel  * These are the fields in the PSTATUS and CSTATUS files,
     63     0  stevel  * found in the SYSTEM directory.
     64     0  stevel  */
     65     0  stevel 
     66     0  stevel #define PST_MAX	8
     67     0  stevel # define PST_BRK	0
     68     0  stevel # define PST_NAME	1
     69     0  stevel # define PST_STATUS	2
     70     0  stevel # define PST_DATE	3
     71     0  stevel # define PST_DISREAS	4
     72     0  stevel # define PST_REJREAS	5
     73     0  stevel # define PST_PWHEEL	6
     74     0  stevel # define PST_FORM	7
     75     0  stevel 
     76     0  stevel #define CST_MAX	5
     77     0  stevel # define CST_BRK	0
     78     0  stevel # define CST_NAME	1
     79     0  stevel # define CST_STATUS	2
     80     0  stevel # define CST_DATE	3
     81     0  stevel # define CST_REJREAS	4
     82     0  stevel 
     83     0  stevel /*
     84     0  stevel  * Exit codes from child processes:
     85     0  stevel  *
     86     0  stevel  *    0 <= exit <= 0177 (127) are reserved for ``normal'' exits.
     87     0  stevel  * 0200 <= exit <= 0377 (255) are reserved for special failures.
     88     0  stevel  *
     89     0  stevel  * If bit 0200 is set, then we have three sets of special error
     90     0  stevel  * codes available, with 32 values in each set (except the first):
     91     0  stevel  *
     92     0  stevel  *	0201 - 0237	Printer faults
     93     0  stevel  *	0240 - 0277	Dial problems
     94     0  stevel  *	0300 - 0337	Port problems
     95     0  stevel  *	0340 - 0377	Exec problems
     96     0  stevel  *
     97     0  stevel  *	0200		Interface received SIGTERM
     98     0  stevel  */
     99     0  stevel #define EXEC_EXIT_OKAY	0	/* success */
    100     0  stevel #define EXEC_EXIT_USER	0177	/* user exit codes, 7 bits */
    101     0  stevel #define EXEC_EXIT_NMASK	0340	/* mask to uncover reason bits */
    102     0  stevel #define EXEC_EXIT_FAULT	0201	/* printer fault */
    103     0  stevel #define EXEC_EXIT_HUP	0202	/* got hangup early in exec */
    104     0  stevel #define EXEC_EXIT_INTR	0203	/* got interrupt early in exec */
    105     0  stevel #define EXEC_EXIT_PIPE	0204	/* got close of FIFO early in exec */
    106     0  stevel #define EXEC_EXIT_EXIT	0237	/* interface used reserved exit code */
    107     0  stevel #define EXEC_EXIT_NDIAL	0240	/* can't dial, low 5 bits abs(dial()) */
    108     0  stevel #define EXEC_EXIT_NPORT	0300	/* can't open port */
    109     0  stevel #define EXEC_EXIT_TMOUT	0301	/* can't open port in N seconds */
    110     0  stevel #define EXEC_EXIT_NOPEN	0340	/* can't open input/output file */
    111     0  stevel #define EXEC_EXIT_NEXEC	0341	/* can't exec */
    112     0  stevel #define EXEC_EXIT_NOMEM	0342	/* malloc failed */
    113     0  stevel #define EXEC_EXIT_NFORK	0343	/* fork failed, must try again */
    114     0  stevel #define EXEC_EXIT_NPUSH 0344	/* could not push streams module(s) */
    115     0  stevel 
    116     0  stevel #define EXIT_RETRY	129	/* interface failed, try again */
    117     0  stevel 
    118     0  stevel /*
    119     0  stevel  * If killed, return signal, else 0.
    120     0  stevel  */
    121     0  stevel #define	KILLED(x) (!(x & 0xFF00)? (x & 0x7F) : 0)
    122     0  stevel 
    123     0  stevel /*
    124     0  stevel  * If exited, return exit code, else -1.
    125     0  stevel  */
    126     0  stevel #define	EXITED(x) (!(x & 0xFF)? ((x >> 8) & 0xFF) : -1)
    127     0  stevel 
    128     0  stevel /*
    129     0  stevel  * Events that can be scheduled:
    130     0  stevel  */
    131     0  stevel #define EV_SLOWF	1
    132     0  stevel #define	EV_INTERF	2
    133     0  stevel #define EV_NOTIFY	3
    134     0  stevel #define EV_LATER	4
    135     0  stevel #define EV_ALARM	5
    136     0  stevel #define	EV_MESSAGE	6
    137  3125  jacobs #define EV_ENABLE	7
    138  3125  jacobs #define	EV_FORM_MESSAGE	8
    139     0  stevel 
    140     0  stevel /*
    141     0  stevel  * How long to wait before retrying an event:
    142     0  stevel  * (For best results, make CLOCK_TICK a factor of 60.)
    143     0  stevel  */
    144     0  stevel #define CLOCK_TICK	10		/* no. seconds between alarms	*/
    145     0  stevel #define MINUTE		(60/CLOCK_TICK)	/* number of ticks per minute	*/
    146     0  stevel #define WHEN_FORK	(MINUTE)	/* retry forking child process	*/
    147     0  stevel #define WHEN_PRINTER	(1*MINUTE)	/* retry faulted printer	*/
    148     0  stevel 
    149     0  stevel /*
    150     0  stevel  * Alert types:
    151     0  stevel  */
    152     0  stevel #define	A_PRINTER	1
    153     0  stevel #define	A_PWHEEL	2
    154     0  stevel #define	A_FORM		3
    155     0  stevel 
    156     0  stevel /*
    157     0  stevel  * How to handle active requests when disabling a printer:
    158     0  stevel  */
    159     0  stevel #define DISABLE_STOP    0
    160     0  stevel #define DISABLE_FINISH  1
    161     0  stevel #define DISABLE_CANCEL  2
    162     0  stevel 
    163     0  stevel /*
    164     0  stevel  * validate_request() - VERIFY REQUEST CAN BE PRINTED
    165     0  stevel  * evaluate_request() - TRY REQUEST ON A PARTICULAR PRINTER
    166     0  stevel  * reevaluate_request() - TRY TO MOVE REQUEST TO ANOTHER PRINTER
    167     0  stevel  */
    168     0  stevel 
    169     0  stevel #define validate_request(PRS,PREFIXP,MOVING) \
    170     0  stevel 	_validate((PRS), (PSTATUS *)0, (PSTATUS *)0, (PREFIXP), (MOVING))
    171     0  stevel 
    172     0  stevel #define evaluate_request(PRS,PPS,MOVING) \
    173     0  stevel 	_validate((PRS), (PPS), (PSTATUS *)0, (char **)0, (MOVING))
    174     0  stevel 
    175     0  stevel #define reevaluate_request(PRS,PPS) \
    176     0  stevel 	_validate((PRS), (PSTATUS *)0, (PPS), (char **)0, 0)
    177     0  stevel 
    178     0  stevel /*
    179     0  stevel  * Request is ready to be slow-filtered:
    180     0  stevel  */
    181     0  stevel #define	NEEDS_FILTERING(PRS) \
    182     0  stevel 	((PRS)->slow && !((PRS)->request->outcome & RS_FILTERED))
    183     0  stevel 
    184     0  stevel /*
    185     0  stevel  * Misc:
    186     0  stevel  */
    187     0  stevel 
    188     0  stevel #define	isadmin(ID)		(!(ID) || (ID) == Lp_Uid)
    189     0  stevel 
    190     0  stevel #define makereqerr(PRS) \
    191     0  stevel 	makepath( \
    192  3125  jacobs 		Lp_Temp, \
    193     0  stevel 		getreqno((PRS)->secure->req_id), \
    194     0  stevel 		(char *)0 \
    195     0  stevel 	)
    196     0  stevel 
    197     0  stevel #define	EVER			;;
    198     0  stevel 
    199     0  stevel #define	DEFAULT_SHELL		"/bin/sh"
    200     0  stevel 
    201     0  stevel #define	BINMAIL			"/bin/mail"
    202     0  stevel #define	BINWRITE		"/bin/write"
    203     0  stevel 
    204     0  stevel #define RMCMD			"/usr/bin/rm -f"
    205     0  stevel 
    206     0  stevel 
    207     0  stevel #if	defined(MLISTENDEL_WORKS)
    208     0  stevel #define DROP_MD(MD)	if (MD) { \
    209     0  stevel 			        mlistendel (MD); \
    210     0  stevel 			        mdisconnect (MD); \
    211  3125  jacobs 				MD = 0; \
    212     0  stevel 			} else /*EMPTY*/
    213     0  stevel #else
    214     0  stevel #define DROP_MD(MD)	if (MD) { \
    215     0  stevel 				Close ((MD)->readfd); \
    216     0  stevel 				if ((MD)->writefd == (MD)->readfd) \
    217     0  stevel 					(MD)->writefd = -1; \
    218     0  stevel 				(MD)->readfd = -1; \
    219  3125  jacobs 				MD = 0; \
    220     0  stevel 			} else /*EMPTY*/
    221     0  stevel #endif
    222     0  stevel 
    223     0  stevel /**
    224     0  stevel  ** External routines:
    225     0  stevel  **/
    226     0  stevel 
    227     0  stevel typedef int (*qchk_fnc_type)( RSTATUS * );
    228     0  stevel 
    229     0  stevel CLASS *		Getclass ( char * );
    230     0  stevel 
    231     0  stevel extern void GetRequestFiles(REQUEST *req, char *buffer, int length);
    232     0  stevel 
    233     0  stevel 
    234     0  stevel PRINTER *	Getprinter ( char * );
    235     0  stevel 
    236     0  stevel PWHEEL *	Getpwheel ( char * );
    237     0  stevel 
    238     0  stevel 
    239     0  stevel REQUEST *	Getrequest ( char * );
    240     0  stevel 
    241     0  stevel RSTATUS *	request_by_id ( char * );
    242     0  stevel RSTATUS *	request_by_id_num ( long );
    243     0  stevel RSTATUS *	request_by_jobid ( char * , char * );
    244     0  stevel 
    245     0  stevel SECURE *	Getsecure ( char * );
    246     0  stevel 
    247     0  stevel USER *		Getuser ( char * );
    248     0  stevel 
    249     0  stevel _FORM *		Getform ( char * );
    250     0  stevel 
    251  3125  jacobs char *		_alloc_files ( int , char * , uid_t , gid_t);
    252     0  stevel char *		dispatchName(int);
    253     0  stevel char *		statusName(int);
    254     0  stevel char *		getreqno ( char * );
    255     0  stevel 
    256     0  stevel int		Loadfilters ( char * );
    257     0  stevel int		Putsecure(char *, SECURE *);
    258     0  stevel int		cancel ( RSTATUS * , int );
    259     0  stevel int		disable ( PSTATUS * , char * , int );
    260     0  stevel int		enable ( PSTATUS * );
    261     0  stevel int		exec ( int , ... );
    262     0  stevel int		one_printer_with_charsets ( RSTATUS * );
    263     0  stevel int		open_dialup ( char * , PRINTER * );
    264     0  stevel int		open_direct ( char * , PRINTER * );
    265     0  stevel int		qchk_filter ( RSTATUS * );
    266     0  stevel int		qchk_form ( RSTATUS * );
    267     0  stevel int		qchk_pwheel ( RSTATUS * );
    268     0  stevel int		qchk_waiting ( RSTATUS * );
    269     0  stevel int		queue_repel ( PSTATUS * , int , int (*)( RSTATUS * ) );
    270     0  stevel int		rsort ( RSTATUS ** , RSTATUS ** );
    271     0  stevel 
    272     0  stevel long		getkey ( void );
    273     0  stevel long		_alloc_req_id ( void );
    274     0  stevel 
    275     0  stevel off_t		chfiles ( char ** , uid_t , gid_t );
    276     0  stevel 
    277     0  stevel short		_validate ( RSTATUS * , PSTATUS * , PSTATUS * , char ** , int );
    278     0  stevel 
    279     0  stevel void		add_flt_act ( MESG * , ... );
    280     0  stevel void		alert ( int , ... );
    281     0  stevel void		cancel_alert ( int , ... );
    282     0  stevel void		check_children ( void );
    283     0  stevel void		check_form_alert ( FSTATUS * , _FORM * );
    284     0  stevel void		check_pwheel_alert ( PWSTATUS * , PWHEEL * );
    285     0  stevel void		check_request ( RSTATUS * );
    286     0  stevel void		del_flt_act ( MESG * , ... );
    287     0  stevel void		dial_problem ( PSTATUS * , RSTATUS * , int );
    288     0  stevel void		dispatch ( int , char * , MESG * );
    289     0  stevel void		dowait ( void );
    290     0  stevel void		dump_cstatus ( void );
    291     0  stevel void		dump_fault_status(PSTATUS *);
    292     0  stevel void		dump_pstatus ( void );
    293     0  stevel void		dump_status ( void );
    294     0  stevel void		execlog ( char * , ... );
    295     0  stevel void		fail ( char * , ... );
    296     0  stevel void		free_form ( _FORM * );
    297     0  stevel void		freerstatus ( register RSTATUS * );
    298     0  stevel void		init_memory ( void );
    299     0  stevel void		init_messages ( void );
    300     0  stevel void		insertr ( RSTATUS * );
    301     0  stevel void		load_sdn ( char ** , SCALED );
    302     0  stevel void		load_status ( void );
    303     0  stevel void		load_str ( char ** , char * );
    304     0  stevel void		lp_endpwent ( void );
    305     0  stevel void		lp_setpwent ( void );
    306     0  stevel void		lpfsck ( void );
    307     0  stevel void		lpshut ( int );
    308     0  stevel void		mallocfail ( void );
    309     0  stevel void		maybe_schedule ( RSTATUS * );
    310     0  stevel void		note ( char * ,	... );
    311     0  stevel void		notify ( RSTATUS * , char * , int , int , int );
    312     0  stevel void		printer_fault ( PSTATUS * , RSTATUS * , char * , int );
    313     0  stevel void		clear_printer_fault ( PSTATUS * ,  char * );
    314     0  stevel void		putjobfiles ( RSTATUS * );
    315     0  stevel void		queue_attract ( PSTATUS * , int (*)( RSTATUS * ) , int );
    316     0  stevel void		queue_check ( int (*)( RSTATUS * ) );
    317     0  stevel void		queue_form ( RSTATUS * , FSTATUS * );
    318     0  stevel void		queue_pwheel ( RSTATUS * , char * );
    319     0  stevel void		remount_form(register PSTATUS *, FSTATUS *, short);
    320     0  stevel void		remover ( RSTATUS * );
    321     0  stevel void		rmfiles ( RSTATUS * , int );
    322     0  stevel void		rmreq ( RSTATUS * );
    323     0  stevel void		schedule ( int , ... );
    324     0  stevel void		take_message ( void );
    325     0  stevel void		terminate ( EXEC * );
    326     0  stevel void		unload_list ( char *** );
    327     0  stevel void		unload_str ( char ** );
    328     0  stevel void		unqueue_form ( RSTATUS * );
    329     0  stevel void		unqueue_pwheel ( RSTATUS * );
    330     0  stevel void		update_req ( char * , long );
    331     0  stevel int		isFormMountedOnPrinter ( PSTATUS *, FSTATUS * );
    332     0  stevel int		isFormUsableOnPrinter ( PSTATUS *, FSTATUS * );
    333     0  stevel char		*allTraysWithForm ( PSTATUS *, FSTATUS * );
    334  3125  jacobs extern int		list_append(void ***, void *);
    335  3125  jacobs extern void		list_remove(void ***, void *);
    336  3125  jacobs 
    337  3125  jacobs extern RSTATUS	*new_rstatus(REQUEST *, SECURE *);
    338  3125  jacobs extern PSTATUS	*new_pstatus(PRINTER *);
    339  3125  jacobs extern CSTATUS	*new_cstatus(CLASS *);
    340  3125  jacobs extern FSTATUS	*new_fstatus(_FORM *f);
    341  3125  jacobs extern PWSTATUS	*new_pwstatus(PWHEEL *p);
    342  3125  jacobs extern ALERT	*new_alert(char *fmt, int i);
    343  3125  jacobs extern EXEC	*new_exec(int type, void *ex);
    344  3125  jacobs 
    345  3125  jacobs extern void	pstatus_add_printer(PSTATUS *, PRINTER *);
    346  3125  jacobs 
    347  3125  jacobs extern void	free_exec(EXEC *);
    348  3125  jacobs extern void	free_alert(ALERT *);
    349  3125  jacobs extern void	free_pwstatus(PWSTATUS *);
    350  3125  jacobs extern void	free_fstatus(FSTATUS *);
    351  3125  jacobs extern void	free_cstatus(CSTATUS *);
    352  3125  jacobs extern void	free_pstatus(PSTATUS *);
    353  3125  jacobs extern void	free_rstatus(RSTATUS *);
    354  3125  jacobs 
    355  3125  jacobs extern CSTATUS	*search_cstatus ( char * );
    356  3125  jacobs extern FSTATUS	*search_fptable(register char *);
    357  3125  jacobs extern FSTATUS	*search_fstatus ( char * );
    358  3125  jacobs extern PSTATUS	*search_pstatus ( char * );
    359  3125  jacobs extern PWSTATUS	*search_pwstatus ( char * );
    360     0  stevel 
    361     0  stevel /*
    362     0  stevel  * Things that can't be passed as parameters:
    363     0  stevel  */
    364     0  stevel 
    365     0  stevel extern FSTATUS		*form_in_question;
    366     0  stevel 
    367     0  stevel extern char		*pwheel_in_question;
    368     0  stevel 
    369     0  stevel /**
    370     0  stevel  ** External tables, lists:
    371     0  stevel  **/
    372     0  stevel 
    373  3125  jacobs extern CSTATUS		**CStatus;	/* Status of classes       */
    374  3125  jacobs extern PSTATUS		**PStatus;	/* Status of printers      */
    375  3125  jacobs extern FSTATUS		**FStatus;	/* Status of forms	   */
    376  3125  jacobs extern PWSTATUS		**PWStatus;	/* Status of print wheels  */
    377     0  stevel 
    378  3125  jacobs extern EXEC		**Exec_Table;	/* Running processes       */
    379  3125  jacobs extern EXEC		**Exec_Slow,	/* First slow filter exec  */
    380  3125  jacobs 			**Exec_Notify;	/* First notification exec */
    381     0  stevel 
    382     0  stevel extern RSTATUS		*Request_List;	/* Queue of print requests */
    383     0  stevel extern RSTATUS		*NewRequest;	/* Not in Request_List yet */
    384     0  stevel 
    385  3125  jacobs extern int		ET_SlowSize,	/* Number of filter execs  	*/
    386  3125  jacobs 			ET_NotifySize;	/* Number of notify execs  	*/
    387     0  stevel 
    388     0  stevel #if	defined(DEBUG)
    389     0  stevel #define DB_ABORT	0x00000008
    390     0  stevel #define DB_SDB		0x00000020
    391     0  stevel #define DB_ALL		0xFFFFFFFF
    392     0  stevel 
    393     0  stevel extern unsigned long	debug;
    394     0  stevel #endif
    395     0  stevel 
    396     0  stevel extern char		*Local_System,	/* Node name of local system	*/
    397     0  stevel 			*SHELL;		/* value of $SHELL, or default	*/
    398     0  stevel 
    399     0  stevel extern int		lock_fd;
    400     0  stevel 
    401     0  stevel extern uid_t		Lp_Uid;
    402     0  stevel 
    403     0  stevel extern gid_t		Lp_Gid;
    404     0  stevel 
    405     0  stevel extern int		Starting,
    406     0  stevel 			OpenMax,
    407     0  stevel 			Sig_Alrm,
    408     0  stevel 			DoneChildren,
    409     0  stevel 			am_in_background,
    410     0  stevel 			Shutdown;
    411     0  stevel 
    412     0  stevel extern unsigned long	chkprinter_result;
    413     0  stevel 
    414     0  stevel #if defined(MDL)
    415     0  stevel #include	"mdl.h"
    416     0  stevel #endif
    417     0  stevel # define	CLOSE_ON_EXEC(fd)	(void) Fcntl(fd, F_SETFD, 1)
    418