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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1998 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" /* SVr4.0 1.13.1.8 */ 32 33 #include "time.h" 34 #include "dispatch.h" 35 #include <syslog.h> 36 37 38 extern char *LP_KILL_NO_PAPER; 39 40 #define PRINTER_ON_SYSTEM(PPS,PSS) \ 41 (((PPS)->status & PS_REMOTE) && (PPS)->system == (PSS)) 42 43 extern PSTATUS * search_ptable_remote(char * printer); 44 45 /** 46 ** s_accept_dest() 47 **/ 48 49 void 50 s_accept_dest(char *m, MESG *md) 51 { 52 char *destination; 53 ushort status; 54 register PSTATUS *pps; 55 register CSTATUS *pcs; 56 57 getmessage (m, S_ACCEPT_DEST, &destination); 58 syslog(LOG_DEBUG, "s_accept_dest(%s)", 59 (destination ? destination : "NULL")); 60 61 /* 62 * Have we seen this destination as a printer? 63 */ 64 if ((pps = search_ptable(destination))) 65 if ((pps->status & PS_REJECTED) == 0) 66 status = MERRDEST; 67 else { 68 pps->status &= ~PS_REJECTED; 69 (void) time (&pps->rej_date); 70 dump_pstatus (); 71 status = MOK; 72 } 73 74 /* 75 * Have we seen this destination as a class? 76 */ 77 else if ((pcs = search_ctable(destination))) 78 if ((pcs->status & CS_REJECTED) == 0) 79 status = MERRDEST; 80 else { 81 pcs->status &= ~CS_REJECTED; 82 (void) time (&pcs->rej_date); 83 dump_cstatus (); 84 status = MOK; 85 } 86 87 else 88 status = MNODEST; 89 90 mputm (md, R_ACCEPT_DEST, status); 91 return; 92 } 93 94 /** 95 ** s_reject_dest() 96 **/ 97 98 void 99 s_reject_dest(char *m, MESG *md) 100 { 101 char *destination, 102 *reason; 103 ushort status; 104 register PSTATUS *pps; 105 register CSTATUS *pcs; 106 107 108 getmessage (m, S_REJECT_DEST, &destination, &reason); 109 syslog(LOG_DEBUG, "s_reject_dest(%s, %s)", 110 (destination ? destination : "NULL"), 111 (reason ? reason : "NULL")); 112 113 /* 114 * Have we seen this destination as a printer? 115 */ 116 if ((pps = search_ptable(destination))) 117 if (pps->status & PS_REJECTED) 118 status = MERRDEST; 119 else { 120 pps->status |= PS_REJECTED; 121 (void) time (&pps->rej_date); 122 load_str (&pps->rej_reason, reason); 123 dump_pstatus (); 124 status = MOK; 125 } 126 127 /* 128 * Have we seen this destination as a class? 129 */ 130 else if ((pcs = search_ctable(destination))) 131 if (pcs->status & CS_REJECTED) 132 status = MERRDEST; 133 else { 134 pcs->status |= CS_REJECTED; 135 (void) time (&pcs->rej_date); 136 load_str (&pcs->rej_reason, reason); 137 dump_cstatus (); 138 status = MOK; 139 } 140 141 else 142 status = MNODEST; 143 144 mputm (md, R_REJECT_DEST, status); 145 return; 146 } 147 148 /** 149 ** s_enable_dest() 150 **/ 151 152 void 153 s_enable_dest(char *m, MESG *md) 154 { 155 char *printer; 156 ushort status; 157 register PSTATUS *pps; 158 159 160 getmessage (m, S_ENABLE_DEST, &printer); 161 syslog(LOG_DEBUG, "s_enable_dest(%s)", (printer ? printer : "NULL")); 162 163 /* 164 * Have we seen this printer before? 165 */ 166 if ((pps = search_ptable(printer))) 167 if (enable(pps) == -1) 168 status = MERRDEST; 169 else 170 status = MOK; 171 else 172 status = MNODEST; 173 174 mputm (md, R_ENABLE_DEST, status); 175 return; 176 } 177 178 /** 179 ** s_disable_dest() 180 **/ 181 182 void 183 s_disable_dest(char *m, MESG *md) 184 { 185 char *destination, 186 *reason, 187 *req_id = 0; 188 ushort when, 189 status; 190 register PSTATUS *pps; 191 192 getmessage (m, S_DISABLE_DEST, &destination, &reason, &when); 193 syslog(LOG_DEBUG, "s_disable_dest(%s, %s, %d)", 194 (destination ? destination : "NULL"), 195 (reason ? reason : "NULL"), when); 196 197 198 /* 199 * Have we seen this printer before? 200 */ 201 if ((pps = search_ptable(destination))) { 202 203 /* 204 * If we are to cancel a currently printing request, 205 * we will send back the request's ID. 206 * Save a copy of the ID before calling "disable()", 207 * in case the disabling loses it (e.g. the request 208 * might get attached to another printer). (Actually, 209 * the current implementation won't DETACH the request 210 * from this printer until the child process responds, 211 * but a future implementation might.) 212 */ 213 if (pps->request && when == 2) 214 req_id = Strdup(pps->request->secure->req_id); 215 216 if (disable(pps, reason, (int)when) == -1) { 217 if (req_id) { 218 Free (req_id); 219 req_id = 0; 220 } 221 status = MERRDEST; 222 } else 223 status = MOK; 224 225 } else 226 status = MNODEST; 227 228 mputm (md, R_DISABLE_DEST, status, NB(req_id)); 229 if (req_id) 230 Free (req_id); 231 232 return; 233 } 234 235 /** 236 ** s_load_filter_table() 237 **/ 238 239 void 240 s_load_filter_table(char *m, MESG *md) 241 { 242 ushort status; 243 244 syslog(LOG_DEBUG, "s_load_filter_table()"); 245 246 trash_filters (); 247 if (Loadfilters((char *)0) == -1) 248 status = MNOOPEN; 249 else { 250 /* 251 * This is what makes changing filters expensive! 252 */ 253 queue_check (qchk_filter); 254 255 status = MOK; 256 } 257 258 mputm (md, R_LOAD_FILTER_TABLE, status); 259 return; 260 } 261 262 /** 263 ** s_unload_filter_table() 264 **/ 265 266 void 267 s_unload_filter_table(char *m, MESG *md) 268 { 269 syslog(LOG_DEBUG, "s_unload_filter_table()"); 270 271 trash_filters (); 272 273 /* 274 * This is what makes changing filters expensive! 275 */ 276 queue_check (qchk_filter); 277 278 mputm (md, R_UNLOAD_FILTER_TABLE, MOK); 279 return; 280 } 281 282 /** 283 ** s_load_user_file() 284 **/ 285 286 void 287 s_load_user_file(char *m, MESG *md) 288 { 289 /* 290 * The first call to "getuser()" will load the whole file. 291 */ 292 syslog(LOG_DEBUG, "s_load_user_file()"); 293 294 trashusers (); 295 296 mputm (md, R_LOAD_USER_FILE, MOK); 297 return; 298 } 299 300 /** 301 ** s_unload_user_file() 302 **/ 303 304 void 305 s_unload_user_file(char *m, MESG *md) 306 { 307 syslog(LOG_DEBUG, "s_unload_user_file()"); 308 309 trashusers (); /* THIS WON'T DO TRUE UNLOAD, SORRY! */ 310 311 mputm (md, R_UNLOAD_USER_FILE, MOK); 312 return; 313 } 314 /** 315 ** s_shutdown() 316 **/ 317 318 void 319 s_shutdown(char *m, MESG *md) 320 { 321 ushort immediate; 322 323 (void)getmessage (m, S_SHUTDOWN, &immediate); 324 syslog(LOG_DEBUG, "s_shutdown(%d)", immediate); 325 326 switch (md->type) { 327 case MD_STREAM: 328 case MD_SYS_FIFO: 329 case MD_USR_FIFO: 330 mputm (md, R_SHUTDOWN, MOK); 331 lpshut (immediate); 332 /*NOTREACHED*/ 333 default: 334 syslog(LOG_DEBUG, 335 "Received S_SHUTDOWN on a type %d connection\n", 336 md->type); 337 } 338 339 return; 340 } 341 342 /** 343 ** s_quiet_alert() 344 **/ 345 346 void 347 s_quiet_alert(char *m, MESG *md) 348 { 349 char *name; 350 ushort type, 351 status; 352 register FSTATUS *pfs; 353 register PSTATUS *pps; 354 register PWSTATUS *ppws; 355 356 357 /* 358 * We quiet an alert by cancelling it with "cancel_alert()" 359 * and then resetting the active flag. This effectively just 360 * terminates the process running the alert but tricks the 361 * rest of the Spooler into thinking it is still active. 362 * The alert will be reactivated only AFTER "cancel_alert()" 363 * has been called (to clear the active flag) and then "alert()" 364 * is called again. Thus: 365 * 366 * For printer faults the alert will be reactivated when: 367 * - a fault is found after the current fault has been 368 * cleared (i.e. after successful print or after manually 369 * enabled). 370 * 371 * For forms/print-wheels the alert will be reactivated when: 372 * - the form/print-wheel becomes mounted and then unmounted 373 * again, with too many requests still pending; 374 * - the number of requests falls below the threshold and 375 * then rises above it again. 376 */ 377 378 (void)getmessage (m, S_QUIET_ALERT, &name, &type); 379 syslog(LOG_DEBUG, "s_quiet_alert(%s, %d)", (name ? name : "NULL"), 380 type); 381 382 if (!*name) 383 status = MNODEST; 384 385 else switch (type) { 386 case QA_FORM: 387 if (!(pfs = search_ftable(name))) 388 status = MNODEST; 389 390 else if (!pfs->alert->active) 391 status = MERRDEST; 392 393 else { 394 cancel_alert (A_FORM, pfs); 395 pfs->alert->active = 1; 396 status = MOK; 397 } 398 break; 399 400 case QA_PRINTER: 401 if (!(pps = search_ptable(name))) 402 status = MNODEST; 403 404 else if (!pps->alert->active) 405 status = MERRDEST; 406 407 else { 408 cancel_alert (A_PRINTER, pps); 409 pps->alert->active = 1; 410 status = MOK; 411 } 412 break; 413 414 case QA_PRINTWHEEL: 415 if (!(ppws = search_pwtable(name))) 416 status = MNODEST; 417 418 else if (!ppws->alert->active) 419 status = MERRDEST; 420 421 else { 422 cancel_alert (A_PWHEEL, ppws); 423 ppws->alert->active = 1; 424 status = MOK; 425 } 426 break; 427 } 428 429 mputm (md, R_QUIET_ALERT, status); 430 return; 431 } 432 433 /** 434 ** s_send_fault() 435 **/ 436 437 void 438 s_send_fault(char *m, MESG *md) 439 { 440 long key; 441 char *printerOrForm, *alert_text; 442 ushort status; 443 register PSTATUS *pps; 444 445 getmessage (m, S_SEND_FAULT, &printerOrForm, &key, &alert_text); 446 syslog(LOG_DEBUG, "s_send_fault(%s, %x, %s)", 447 (printerOrForm ? printerOrForm : "NULL"), key, 448 (alert_text ? alert_text : "NULL")); 449 450 if (!(pps = search_ptable(printerOrForm)) || (!pps->exec) || 451 pps->exec->key != key || !pps->request) { 452 status = MERRDEST; 453 } else { 454 printer_fault(pps, pps->request, alert_text, 0); 455 status = MOK; 456 } 457 458 mputm (md, R_SEND_FAULT, status); 459 } 460 461 /* 462 * s_clear_fault() 463 */ 464 void 465 s_clear_fault(char *m, MESG *md) 466 { 467 long key; 468 char *printerOrForm, *alert_text; 469 ushort status; 470 register PSTATUS *pps; 471 472 getmessage(m, S_CLEAR_FAULT, &printerOrForm, &key, &alert_text); 473 syslog(LOG_DEBUG, "s_clear_fault(%s, %x, %s)", 474 (printerOrForm ? printerOrForm : "NULL"), key, 475 (alert_text ? alert_text : "NULL")); 476 477 478 if (! (pps = search_ptable(printerOrForm)) || ((key > 0) && 479 ((!pps->exec) || pps->exec->key != key || !pps->request ))) { 480 status = MERRDEST; 481 } else { 482 clear_printer_fault(pps, alert_text); 483 status = MOK; 484 } 485 486 mputm (md, R_CLEAR_FAULT, status); 487 } 488 489 490 /* 491 * s_paper_changed() 492 */ 493 void 494 s_paper_changed(char *m, MESG *md) 495 { 496 short trayNum, mode, pagesPrinted; 497 char *printer, *paper; 498 ushort status; 499 short chgd = 0; 500 register PSTATUS *pps; 501 register FSTATUS *pfs,*pfsWas; 502 503 getmessage(m, S_PAPER_CHANGED, &printer, &trayNum, &paper, &mode, 504 &pagesPrinted); 505 syslog(LOG_DEBUG, "s_paper_changed(%s, %d, %s, %d, %d)", 506 (printer ? printer : "NULL"), trayNum, (paper ? paper : "NULL"), 507 mode, pagesPrinted); 508 509 if (!(pps = search_ptable(printer))) 510 status = MNODEST; 511 else if ((trayNum <=0) || (trayNum > pps->numForms)) 512 status = MNOTRAY; 513 else { 514 status = MOK; 515 if (*paper && (pfsWas = pps->forms[trayNum-1].form) && 516 (!STREQU(pfsWas->form->paper,paper))) { 517 pfs = search_fptable(paper); 518 if (pfs) { 519 remount_form(pps, pfs, trayNum); 520 chgd = 1; 521 } else 522 status = MNOMEDIA; 523 } 524 if ( status == MOK ) { 525 pps->forms[trayNum].isAvailable = mode; 526 if ((chgd || !mode) && (!pagesPrinted) && 527 LP_KILL_NO_PAPER && pps->exec) { 528 if (pps->request) 529 pps->request->request->outcome |= 530 RS_STOPPED; 531 terminate(pps->exec); 532 schedule(EV_LATER, 1, EV_INTERF, pps); 533 } 534 } 535 } 536 mputm(md, R_PAPER_CHANGED, status); 537 } 538 539