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_CHECKCHILD 7 138 #define EV_SYSTEM 8 139 #define EV_ENABLE 9 140 #define EV_POLLBSDSYSTEMS 10 141 #define EV_FORM_MESSAGE 11 142 #define EV_STATUS 12 143 144 /* 145 * How long to wait before retrying an event: 146 * (For best results, make CLOCK_TICK a factor of 60.) 147 */ 148 #define CLOCK_TICK 10 /* no. seconds between alarms */ 149 #define MINUTE (60/CLOCK_TICK) /* number of ticks per minute */ 150 #define WHEN_FORK (MINUTE) /* retry forking child process */ 151 #define WHEN_PRINTER (1*MINUTE) /* retry faulted printer */ 152 153 /* 154 * Alert types: 155 */ 156 #define A_PRINTER 1 157 #define A_PWHEEL 2 158 #define A_FORM 3 159 160 /* 161 * How to handle active requests when disabling a printer: 162 */ 163 #define DISABLE_STOP 0 164 #define DISABLE_FINISH 1 165 #define DISABLE_CANCEL 2 166 167 /* 168 * validate_request() - VERIFY REQUEST CAN BE PRINTED 169 * evaluate_request() - TRY REQUEST ON A PARTICULAR PRINTER 170 * reevaluate_request() - TRY TO MOVE REQUEST TO ANOTHER PRINTER 171 */ 172 173 #define validate_request(PRS,PREFIXP,MOVING) \ 174 _validate((PRS), (PSTATUS *)0, (PSTATUS *)0, (PREFIXP), (MOVING)) 175 176 #define evaluate_request(PRS,PPS,MOVING) \ 177 _validate((PRS), (PPS), (PSTATUS *)0, (char **)0, (MOVING)) 178 179 #define reevaluate_request(PRS,PPS) \ 180 _validate((PRS), (PSTATUS *)0, (PPS), (char **)0, 0) 181 182 /* 183 * Request is ready to be slow-filtered: 184 */ 185 #define NEEDS_FILTERING(PRS) \ 186 ((PRS)->slow && !((PRS)->request->outcome & RS_FILTERED)) 187 188 /* 189 * Where requests are handled: 190 */ 191 192 #define PRINTING_AT(PRS,PSS) \ 193 ((PRS)->printer->system == (PSS)) 194 195 #define ORIGINATING_AT(PRS,PSS) \ 196 STREQU((PRS)->secure->system, (PSS)->system->name) 197 198 /* 199 * Misc: 200 */ 201 202 #define isadmin(ID) (!(ID) || (ID) == Lp_Uid) 203 204 #define makereqerr(PRS) \ 205 makepath( \ 206 Lp_Tmp, \ 207 (PRS)->secure->system, \ 208 getreqno((PRS)->secure->req_id), \ 209 (char *)0 \ 210 ) 211 212 #define EVER ;; 213 214 #define DEFAULT_SHELL "/bin/sh" 215 216 #define BINMAIL "/bin/mail" 217 #define BINWRITE "/bin/write" 218 219 #define RMCMD "/usr/bin/rm -f" 220 221 222 #if defined(MLISTENDEL_WORKS) 223 #define DROP_MD(MD) if (MD) { \ 224 mlistendel (MD); \ 225 mdisconnect (MD); \ 226 } else /*EMPTY*/ 227 #else 228 #define DROP_MD(MD) if (MD) { \ 229 Close ((MD)->readfd); \ 230 if ((MD)->writefd == (MD)->readfd) \ 231 (MD)->writefd = -1; \ 232 (MD)->readfd = -1; \ 233 } else /*EMPTY*/ 234 #endif 235 236 /** 237 ** External routines: 238 **/ 239 240 typedef int (*qchk_fnc_type)( RSTATUS * ); 241 242 CLASS * Getclass ( char * ); 243 244 CSTATUS * search_ctable ( char * ); 245 CSTATUS * walk_ctable ( int ); 246 247 248 FSTATUS * search_fptable(register char *); 249 FSTATUS * search_ftable ( char * ); 250 FSTATUS * walk_ftable ( int ); 251 252 extern void GetRequestFiles(REQUEST *req, char *buffer, int length); 253 254 255 PRINTER * Getprinter ( char * ); 256 257 PSTATUS * search_ptable ( char * ); 258 PSTATUS * walk_ptable ( int ); 259 260 PWHEEL * Getpwheel ( char * ); 261 262 PWSTATUS * search_pwtable ( char * ); 263 PWSTATUS * walk_pwtable ( int ); 264 265 REQUEST * Getrequest ( char * ); 266 267 RSTATUS * allocr ( void ); 268 RSTATUS * request_by_id ( char * ); 269 RSTATUS * request_by_id_num ( long ); 270 RSTATUS * request_by_jobid ( char * , char * ); 271 RSTATUS * walk_req_by_dest ( RSTATUS ** , char * ); 272 RSTATUS * walk_req_by_form ( RSTATUS ** , FSTATUS * ); 273 RSTATUS * walk_req_by_printer ( RSTATUS ** , PSTATUS * ); 274 RSTATUS * walk_req_by_pwheel ( RSTATUS ** , char * ); 275 276 SECURE * Getsecure ( char * ); 277 278 USER * Getuser ( char * ); 279 280 _FORM * Getform ( char * ); 281 282 char * _alloc_files ( int , char * , uid_t , gid_t, char * ); 283 char * dispatchName(int); 284 char * statusName(int); 285 char * getreqno ( char * ); 286 287 int Loadfilters ( char * ); 288 int Putsecure(char *, SECURE *); 289 int cancel ( RSTATUS * , int ); 290 int disable ( PSTATUS * , char * , int ); 291 int enable ( PSTATUS * ); 292 int exec ( int , ... ); 293 int one_printer_with_charsets ( RSTATUS * ); 294 int open_dialup ( char * , PRINTER * ); 295 int open_direct ( char * , PRINTER * ); 296 int qchk_filter ( RSTATUS * ); 297 int qchk_form ( RSTATUS * ); 298 int qchk_pwheel ( RSTATUS * ); 299 int qchk_waiting ( RSTATUS * ); 300 int queue_repel ( PSTATUS * , int , int (*)( RSTATUS * ) ); 301 int rsort ( RSTATUS ** , RSTATUS ** ); 302 303 long getkey ( void ); 304 long _alloc_req_id ( void ); 305 306 off_t chfiles ( char ** , uid_t , gid_t ); 307 308 short _validate ( RSTATUS * , PSTATUS * , PSTATUS * , char ** , int ); 309 310 void add_flt_act ( MESG * , ... ); 311 void alert ( int , ... ); 312 void cancel_alert ( int , ... ); 313 void check_children ( void ); 314 void check_form_alert ( FSTATUS * , _FORM * ); 315 void check_pwheel_alert ( PWSTATUS * , PWHEEL * ); 316 void check_request ( RSTATUS * ); 317 void del_flt_act ( MESG * , ... ); 318 void dial_problem ( PSTATUS * , RSTATUS * , int ); 319 void dispatch ( int , char * , MESG * ); 320 void dowait ( void ); 321 void dump_cstatus ( void ); 322 void dump_fault_status(PSTATUS *); 323 void dump_pstatus ( void ); 324 void dump_status ( void ); 325 void execlog ( char * , ... ); 326 void fail ( char * , ... ); 327 void free_form ( _FORM * ); 328 void freerstatus ( register RSTATUS * ); 329 void init_memory ( void ); 330 void init_messages ( void ); 331 void insertr ( RSTATUS * ); 332 void load_sdn ( char ** , SCALED ); 333 void load_status ( void ); 334 void load_str ( char ** , char * ); 335 void lp_endpwent ( void ); 336 void lp_setpwent ( void ); 337 void lpfsck ( void ); 338 void lpshut ( int ); 339 void mallocfail ( void ); 340 void maybe_schedule ( RSTATUS * ); 341 void note ( char * , ... ); 342 void notify ( RSTATUS * , char * , int , int , int ); 343 void printer_fault ( PSTATUS * , RSTATUS * , char * , int ); 344 void clear_printer_fault ( PSTATUS * , char * ); 345 void putjobfiles ( RSTATUS * ); 346 void queue_attract ( PSTATUS * , int (*)( RSTATUS * ) , int ); 347 void queue_check ( int (*)( RSTATUS * ) ); 348 void queue_form ( RSTATUS * , FSTATUS * ); 349 void queue_pwheel ( RSTATUS * , char * ); 350 void remount_form(register PSTATUS *, FSTATUS *, short); 351 void remover ( RSTATUS * ); 352 void rmfiles ( RSTATUS * , int ); 353 void rmreq ( RSTATUS * ); 354 void schedule ( int , ... ); 355 void take_message ( void ); 356 void terminate ( EXEC * ); 357 void unload_list ( char *** ); 358 void unload_str ( char ** ); 359 void unqueue_form ( RSTATUS * ); 360 void unqueue_pwheel ( RSTATUS * ); 361 void update_req ( char * , long ); 362 int isFormMountedOnPrinter ( PSTATUS *, FSTATUS * ); 363 int isFormUsableOnPrinter ( PSTATUS *, FSTATUS * ); 364 char *allTraysWithForm ( PSTATUS *, FSTATUS * ); 365 366 /* 367 * Things that can't be passed as parameters: 368 */ 369 370 extern FSTATUS *form_in_question; 371 372 extern char *pwheel_in_question; 373 374 /** 375 ** External tables, lists: 376 **/ 377 378 extern CSTATUS *CStatus; /* Status of classes */ 379 380 extern EXEC *Exec_Table; /* Running processes */ 381 382 extern FSTATUS *FStatus; /* Status of forms */ 383 384 extern PSTATUS *PStatus; /* Status of printers */ 385 386 extern PWSTATUS *PWStatus; /* Status of print wheels */ 387 388 extern RSTATUS *Request_List; /* Queue of print requests */ 389 extern RSTATUS *Status_List; /* Queue of fake requests */ 390 extern RSTATUS *NewRequest; /* Not in Request_List yet */ 391 392 extern EXEC *Exec_Slow, /* First slow filter exec */ 393 *Exec_Notify; /* First notification exec */ 394 395 extern int CT_Size, /* Size of class table */ 396 ET_Size, /* Size of exec table */ 397 ET_SlowSize, /* Number of filter execs */ 398 ET_NotifySize, /* Number of notify execs */ 399 FT_Size, /* Size of form table */ 400 PT_Size, /* Size of printer table */ 401 PWT_Size, /* Size of print wheel table */ 402 ST_Size, /* Size of system status table */ 403 ST_Count; /* No. active entries in above */ 404 405 #if defined(DEBUG) 406 #define DB_EXEC 0x00000001 407 #define DB_DONE 0x00000002 408 #define DB_INIT 0x00000004 409 #define DB_ABORT 0x00000008 410 #define DB_SCHEDLOG 0x00000010 411 #define DB_SDB 0x00000020 412 #define DB_MESSAGES 0x00000040 413 #define DB_MALLOC 0x00000080 414 #define DB_ALL 0xFFFFFFFF 415 416 extern unsigned long debug; 417 #endif 418 419 extern char *Local_System, /* Node name of local system */ 420 *SHELL; /* value of $SHELL, or default */ 421 422 extern int lock_fd; 423 424 extern uid_t Lp_Uid; 425 426 extern gid_t Lp_Gid; 427 428 extern int Starting, 429 OpenMax, 430 Sig_Alrm, 431 DoneChildren, 432 am_in_background, 433 Shutdown; 434 435 extern unsigned long chkprinter_result; 436 437 #if defined(MDL) 438 #include "mdl.h" 439 #endif 440 # define CLOSE_ON_EXEC(fd) (void) Fcntl(fd, F_SETFD, 1) 441