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