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