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