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