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.10.1.8 */ 32 33 #include "lpsched.h" 34 #include <syslog.h> 35 36 CSTATUS *CStatus; /* Status of same */ 37 EXEC *Exec_Table; /* Running processes */ 38 EXEC *Exec_Slow; /* Slow filters */ 39 EXEC *Exec_Notify; /* Notifications */ 40 FSTATUS *FStatus; /* status of same */ 41 PSTATUS *PStatus; /* Status of same */ 42 PWSTATUS *PWStatus; /* Status of same */ 43 RSTATUS *Request_List; /* Queue of print requests */ 44 45 int CT_Size, 46 ET_Size, 47 ET_SlowSize = 1, 48 ET_NotifySize = 1, 49 FT_Size, 50 PT_Size, 51 PWT_Size; 52 53 static ALERT *Alert_Table; /* Printer fault alerts */ 54 static ALERT *FAlert_Table; /* Form mount alerts */ 55 static ALERT *PAlert_Table; /* PrintWheel mount alerts */ 56 static CLASS *Class_Table; /* Known classes */ 57 static _FORM *Form_Table; /* Known forms */ 58 static PRINTER *Printer_Table; /* Known printers */ 59 static PWHEEL *PrintWheel_Table; /* Known print wheels */ 60 61 /* 62 ** 63 ** CLRMEM clears memory pointed to by <addr> over the range of 64 ** <addr>[<cnt> .. <size>]. <datum> is the size of an element of <addr>. 65 ** 66 */ 67 # define CLRMEM(addr, cnt, size, datum) \ 68 (void) memset((char *)(addr + cnt), 0, \ 69 (int)((size - cnt ) * sizeof(datum))) 70 71 #define ACLUSTERSIZE 10 72 73 74 static void init_printers(), 75 init_classes(), 76 init_forms(), 77 init_pwheels(), 78 init_exec(); 79 80 81 static RSTATUS *init_requests(); 82 83 void 84 init_memory(void) 85 { 86 init_printers(); 87 init_classes(); 88 init_forms(); 89 init_pwheels(); 90 init_exec(); 91 92 /* 93 * Load the status after the basic structures have been loaded, 94 * but before loading requests still in the queue. This is so 95 * the requests can be compared against accurate status information 96 * (except rejection status--accept the jobs anyway). 97 */ 98 load_status(); 99 100 Loadfilters(Lp_A_Filters); 101 102 Request_List = init_requests(); 103 } 104 105 static void 106 init_printers() 107 { 108 PRINTER *p; 109 PRINTER *pt_pointer; 110 int pt_allocation; 111 int at_allocation; 112 int PT_Count; 113 int i; 114 char **paperDenied; 115 116 117 PT_Size = 10; 118 PT_Count = 0; 119 pt_allocation = PT_Size * sizeof(PRINTER); 120 121 Printer_Table = (PRINTER *)Malloc(pt_allocation); 122 123 CLRMEM(Printer_Table, PT_Count, PT_Size, PRINTER); 124 125 pt_pointer = Printer_Table; 126 127 while((p = Getprinter(NAME_ALL)) != NULL || errno != ENOENT) { 128 if (!p) 129 continue; 130 131 if (p->remote) /* this is remote, ignore it */ 132 continue; 133 134 syslog(LOG_DEBUG, "Loaded printer: %s\n", p->name); 135 136 *pt_pointer = *p; 137 pt_pointer++; 138 139 if (++PT_Count < PT_Size) 140 continue; 141 142 PT_Size += 10; 143 pt_allocation = PT_Size * sizeof(PRINTER); 144 145 Printer_Table = (PRINTER *)Realloc(Printer_Table, pt_allocation); 146 147 CLRMEM(Printer_Table, PT_Count, PT_Size, PRINTER); 148 149 pt_pointer = Printer_Table + PT_Count; 150 } 151 152 PT_Size = PT_Count + 40; 153 154 pt_allocation = PT_Size * sizeof(PRINTER); 155 156 Printer_Table = (PRINTER *)Realloc(Printer_Table, pt_allocation); 157 158 CLRMEM(Printer_Table, PT_Count, PT_Size, PRINTER); 159 160 at_allocation = PT_Size * sizeof(ALERT); 161 162 Alert_Table = (ALERT *)Malloc(at_allocation); 163 164 CLRMEM(Alert_Table, 0, PT_Size, ALERT); 165 166 pt_allocation = PT_Size * sizeof(PSTATUS); 167 168 PStatus = (PSTATUS *)Malloc(pt_allocation); 169 170 CLRMEM(PStatus, 0, PT_Size, PSTATUS); 171 172 for (i = 0; i < PT_Size; i++) 173 { 174 char buf[15]; 175 PSTATUS *psp; 176 177 psp = PStatus + i; 178 p = psp->printer = Printer_Table + i; 179 psp->alert = Alert_Table + i; 180 sprintf(buf, "A-%d", i); 181 Alert_Table[i].msgfile = makepath(Lp_Temp, buf, (char *)0); 182 (void) Unlink(Alert_Table[i].msgfile); 183 if (i < PT_Count) 184 { 185 load_userprinter_access ( 186 p->name, 187 &(psp->users_allowed), 188 &(psp->users_denied) 189 ); 190 load_formprinter_access ( 191 p->name, 192 &(psp->forms_allowed), 193 &(psp->forms_denied) 194 ); 195 load_paperprinter_access ( 196 p->name, 197 &psp->paper_allowed, 198 &paperDenied 199 ); 200 freelist(paperDenied); 201 load_sdn (&(psp->cpi), p->cpi); 202 load_sdn (&(psp->lpi), p->lpi); 203 load_sdn (&(psp->plen), p->plen); 204 load_sdn (&(psp->pwid), p->pwid); 205 } 206 } 207 } 208 209 static void 210 init_classes() 211 { 212 CLASS *p; 213 CLASS *ct_pointer; 214 int ct_allocation; 215 int CT_Count; 216 int i; 217 218 219 CT_Size = 10; 220 CT_Count = 0; 221 ct_allocation = CT_Size * sizeof(CLASS); 222 223 Class_Table = (CLASS *)Malloc(ct_allocation); 224 225 CLRMEM(Class_Table, CT_Count, CT_Size, CLASS); 226 227 ct_pointer = Class_Table; 228 229 while((p = Getclass(NAME_ALL)) != NULL || errno != ENOENT) 230 { 231 if (!p) 232 continue; 233 234 *ct_pointer = *p; 235 ct_pointer++; 236 237 if (++CT_Count < CT_Size) 238 continue; 239 240 CT_Size += 10; 241 ct_allocation = CT_Size * sizeof(CLASS); 242 243 Class_Table = (CLASS *)Realloc(Class_Table, ct_allocation); 244 245 CLRMEM(Class_Table, CT_Count, CT_Size, CLASS); 246 247 ct_pointer = Class_Table + CT_Count; 248 249 } 250 251 CT_Size = CT_Count + 40; 252 253 ct_allocation = CT_Size * sizeof(CLASS); 254 255 Class_Table = (CLASS *)Realloc(Class_Table, ct_allocation); 256 257 CLRMEM(Class_Table, CT_Count, CT_Size, CLASS); 258 259 ct_allocation = CT_Size * sizeof(CSTATUS); 260 261 CStatus = (CSTATUS *)Malloc(ct_allocation); 262 263 CLRMEM(CStatus, 0, CT_Size, CSTATUS); 264 265 for (i = 0; i < CT_Size; i++) 266 CStatus[i].class = Class_Table + i; 267 } 268 269 static void 270 init_forms() 271 { 272 _FORM *ft_pointer, 273 *f; 274 int at_allocation; 275 int ft_allocation; 276 int FT_Count; 277 int i; 278 279 280 FT_Size = 10; 281 FT_Count = 0; 282 ft_allocation = FT_Size * sizeof(_FORM); 283 284 Form_Table = (_FORM *)Malloc(ft_allocation); 285 286 CLRMEM(Form_Table, FT_Count, FT_Size, _FORM); 287 288 ft_pointer = Form_Table; 289 290 ft_pointer->plen.val = 0.0; 291 ft_pointer->plen.sc = 'i'; 292 ft_pointer->pwid.val = 0.0; 293 ft_pointer->pwid.sc = 'i'; 294 ft_pointer->lpi.val = 0.0; 295 ft_pointer->lpi.sc = 'i'; 296 ft_pointer->cpi.val = 0.0; 297 ft_pointer->cpi.sc = 'i'; 298 ft_pointer->np = 0; 299 ft_pointer->chset = NULL; 300 ft_pointer->mandatory = 0; 301 ft_pointer->rcolor = NULL; 302 ft_pointer->comment = NULL; 303 ft_pointer->conttype = NULL; 304 ft_pointer->name = NULL; 305 ft_pointer->alert.shcmd = NULL; 306 ft_pointer->alert.Q = 0; 307 ft_pointer->alert.W = 0; 308 ft_pointer->paper = NULL; 309 ft_pointer->isDefault = 0; 310 311 ft_pointer++; 312 FT_Count++; 313 314 while ((f = Getform(NAME_ALL)) != NULL) { 315 *(ft_pointer++) = *f; 316 317 if (++FT_Count < FT_Size) 318 continue; 319 320 FT_Size += 10; 321 ft_allocation = FT_Size * sizeof(_FORM); 322 323 Form_Table = (_FORM *)Realloc(Form_Table, ft_allocation); 324 325 CLRMEM(Form_Table, FT_Count, FT_Size, _FORM); 326 327 ft_pointer = Form_Table + FT_Count; 328 } 329 330 FT_Size = FT_Count + 40; 331 332 ft_allocation = FT_Size * sizeof(_FORM); 333 334 Form_Table = (_FORM *)Realloc(Form_Table, ft_allocation); 335 336 CLRMEM(Form_Table, FT_Count, FT_Size, _FORM); 337 338 at_allocation = FT_Size * sizeof(ALERT); 339 340 FAlert_Table = (ALERT *)Malloc(at_allocation); 341 342 CLRMEM(FAlert_Table, 0, FT_Size, ALERT); 343 344 ft_allocation = FT_Size * sizeof(FSTATUS); 345 346 FStatus = (FSTATUS *)Malloc(ft_allocation); 347 348 CLRMEM(FStatus, 0, FT_Size, FSTATUS); 349 350 for (i = 0; i < FT_Size; i++) { 351 char buf[15]; 352 353 FStatus[i].form = Form_Table + i; 354 FStatus[i].alert = FAlert_Table + i; 355 FStatus[i].trigger = Form_Table[i].alert.Q; 356 sprintf(buf, "F-%d", i); 357 FAlert_Table[i].msgfile = makepath(Lp_Temp, buf, (char *)0); 358 (void) Unlink(FAlert_Table[i].msgfile); 359 360 if (i < FT_Count) { 361 load_userform_access ( 362 Form_Table[i].name, 363 &(FStatus[i].users_allowed), 364 &(FStatus[i].users_denied) 365 ); 366 load_sdn (&(FStatus[i].cpi), Form_Table[i].cpi); 367 load_sdn (&(FStatus[i].lpi), Form_Table[i].lpi); 368 load_sdn (&(FStatus[i].plen), Form_Table[i].plen); 369 load_sdn (&(FStatus[i].pwid), Form_Table[i].pwid); 370 } 371 } 372 FStatus[0].users_denied = Calloc(2,sizeof(char *)); 373 /* for BSD_FORM, make sure it denies no one */ 374 } 375 376 static void 377 init_pwheels() 378 { 379 PWHEEL *pwt_pointer; 380 PWHEEL *p; 381 int at_allocation; 382 int pwt_allocation; 383 int PWT_Count; 384 int i; 385 386 387 PWT_Count = 0; 388 PWT_Size = 10; 389 pwt_allocation = PWT_Size * sizeof(PWHEEL); 390 391 PrintWheel_Table = (PWHEEL *)Malloc(pwt_allocation); 392 393 CLRMEM(PrintWheel_Table, PWT_Count, PWT_Size, PWHEEL); 394 395 pwt_pointer = PrintWheel_Table; 396 397 while((p = Getpwheel(NAME_ALL)) != NULL || errno != ENOENT) 398 { 399 if (!p) 400 continue; 401 402 *pwt_pointer = *p; 403 pwt_pointer++; 404 405 if (++PWT_Count < PWT_Size) 406 continue; 407 408 PWT_Size += 10; 409 pwt_allocation = PWT_Size * sizeof(PWHEEL); 410 411 PrintWheel_Table = (PWHEEL *)Realloc(PrintWheel_Table, pwt_allocation); 412 413 CLRMEM(PrintWheel_Table, PWT_Count, PWT_Size, PWHEEL); 414 415 pwt_pointer = &PrintWheel_Table[PWT_Count]; 416 417 } 418 419 PWT_Size = PWT_Count + 40; 420 421 pwt_allocation = PWT_Size * sizeof(PWHEEL); 422 423 PrintWheel_Table = (PWHEEL *)Realloc(PrintWheel_Table, pwt_allocation); 424 425 CLRMEM(PrintWheel_Table, PWT_Count, PWT_Size, PWHEEL); 426 427 at_allocation = PWT_Size * sizeof(ALERT); 428 429 PAlert_Table = (ALERT *)Malloc(at_allocation); 430 431 CLRMEM(PAlert_Table, 0, PWT_Size, ALERT); 432 433 pwt_allocation = PWT_Size * sizeof(PWSTATUS); 434 435 PWStatus = (PWSTATUS *)Malloc(pwt_allocation); 436 437 CLRMEM(PWStatus, 0, PWT_Size, PWSTATUS); 438 439 for (i = 0; i < PWT_Size; i++) 440 { 441 char buf[15]; 442 443 PWStatus[i].pwheel = PrintWheel_Table + i; 444 PWStatus[i].trigger = PrintWheel_Table[i].alert.Q; 445 PWStatus[i].alert = PAlert_Table + i; 446 sprintf(buf, "P-%d", i); 447 PAlert_Table[i].msgfile = makepath(Lp_Temp, buf, (char *)0); 448 (void) Unlink(PAlert_Table[i].msgfile); 449 } 450 } 451 452 static RSTATUS * 453 init_requests(void) 454 { 455 REQUEST *r; 456 RSTATUS **table; 457 RSTATUS *rp = NULL; 458 SECURE *s; 459 char *name; 460 char *sysdir; 461 char *sysname; 462 char *reqfile = NULL; 463 int count; 464 int i; 465 long addr = -1; 466 long sysaddr = -1; 467 unsigned long size; 468 short vr_ret; 469 470 size = 20; 471 count = 0; 472 473 474 table = (RSTATUS **)Malloc(size * sizeof(RSTATUS *)); 475 476 while((sysname = next_dir(Lp_Requests, &addr)) != NULL) { 477 478 sysdir = makepath(Lp_Requests, sysname, NULL); 479 480 while((name = next_file(sysdir, &sysaddr)) != NULL) { 481 table[count] = allocr(); 482 483 reqfile = makepath(sysname, name, NULL); 484 Free(name); 485 syslog(LOG_DEBUG, "Loaded request: %s\n", reqfile); 486 487 if ((s = Getsecure(reqfile)) == NULL) { 488 table[count]->req_file = reqfile; /* fix for 1103890 */ 489 reqfile = NULL; /* fix for 1103890 */ 490 rmfiles(table[count], 0); 491 freerstatus(table[count]); 492 continue; 493 } 494 *(table[count]->secure) = *s; 495 table[count]->secure->req_id = Strdup(s->req_id); 496 table[count]->secure->user = Strdup(s->user); 497 table[count]->secure->system = Strdup(s->system); 498 freesecure(s); 499 500 if((r = Getrequest(reqfile)) == NULL) { 501 rmfiles(table[count], 0); 502 freerstatus(table[count]); 503 Free(reqfile); 504 continue; 505 } 506 r->outcome &= ~RS_ACTIVE; /* it can't be! */ 507 *(table[count]->request) = *r; 508 509 table[count]->req_file = reqfile; 510 reqfile = NULL; 511 512 if ((r->outcome & (RS_CANCELLED|RS_FAILED)) && 513 !(r->outcome & RS_NOTIFY)) 514 { 515 rmfiles(table[count], 0); 516 freerstatus(table[count]); 517 continue; 518 } 519 520 /* 521 * So far, the only way RS_NOTIFY can be set without there 522 * being a notification file containing the message to the 523 * user, is if the request was cancelled. This is because 524 * cancelling a request does not cause the creation of the 525 * message if the request is currently printing or filtering. 526 * (The message is created after the child process dies.) 527 * Thus, we know what to say. 528 * 529 * If this behaviour changes, we may have to find another way 530 * of determining what to say in the message. 531 */ 532 if (r->outcome & RS_NOTIFY) { 533 char *file = makereqerr(table[count]); 534 535 if (Access(file, F_OK) == -1) { 536 if (!(r->outcome & RS_CANCELLED)) { 537 Free(file); 538 rmfiles(table[count], 0); 539 freerstatus(table[count]); 540 continue; 541 } 542 notify(table[count], NULL, 0, 0, 0); 543 } 544 Free(file); 545 } 546 547 /* fix for bugid 1103709. if validate_request returns 548 * MNODEST, then the printer for the request doesn't exist 549 * anymore! E.g. lpadmin -x was issued, and the request 550 * hasn't been cleaned up. In this case, the "printer" 551 * element of table[] will be NULL, and cancel will 552 * core dump! So we clean this up here. 553 */ 554 555 /* 556 * Well actually this happens with MDENYDEST too. The real problem 557 * is if the printer is NULL, so test for it 558 */ 559 560 if ((vr_ret=validate_request(table[count], NULL, 1)) != MOK) { 561 if (vr_ret == MNODEST || (table[count]->printer == NULL)) { 562 rmfiles(table[count], 0); 563 freerstatus(table[count]); 564 continue; 565 } 566 cancel(table[count], 1); 567 } 568 569 570 if (++count < size) 571 continue; 572 573 size += 20; 574 575 table = (RSTATUS **)Realloc((char *)table, size * sizeof(RSTATUS *)); 576 } 577 Free(sysdir); 578 Free(sysname); 579 sysaddr = -1; 580 } 581 582 if (!count) 583 Free ((char *)table); 584 else 585 if ((size = count) > 0) { 586 table = (RSTATUS **)Realloc((char *)table, 587 size * sizeof(RSTATUS *)); 588 589 qsort((void *)table, size, sizeof(RSTATUS *), 590 (int (*)(const void * , const void *))rsort); 591 592 for (i = 0; i < size - 1; i++) { 593 table[i]->next = table[i + 1]; 594 table[i + 1]->prev = table[i]; 595 } 596 597 table[0]->prev = 0; 598 table[size - 1]->next = 0; 599 600 rp = *table; 601 Free(table); 602 603 } 604 605 return(rp); 606 } 607 608 static void 609 init_exec() 610 { 611 EXEC *et_pointer; 612 int et_allocation; 613 int i; 614 615 ET_Size = ET_SlowSize 616 + ET_NotifySize 617 + PT_Size * 3 /* 1 each for interface, alert, fault msg */ 618 + PWT_Size 619 + FT_Size; 620 621 et_allocation = ET_Size * sizeof(EXEC); 622 623 Exec_Table = (EXEC *)Malloc(et_allocation); 624 625 CLRMEM(Exec_Table, 0, ET_Size, EXEC); 626 627 et_pointer = Exec_Table; 628 629 Exec_Slow = et_pointer; 630 for (i = 0; i < ET_SlowSize; i++) 631 (et_pointer++)->type = EX_SLOWF; 632 633 Exec_Notify = et_pointer; 634 for (i = 0; i < ET_NotifySize; i++) 635 (et_pointer++)->type = EX_NOTIFY; 636 637 for (i = 0; i < PT_Size; i++) { 638 PStatus[i].exec = et_pointer; 639 et_pointer->type = EX_INTERF; 640 et_pointer->ex.printer = PStatus + i; 641 et_pointer++; 642 643 PStatus[i].alert->exec = et_pointer; 644 et_pointer->type = EX_ALERT; 645 et_pointer->ex.printer = PStatus + i; 646 et_pointer++; 647 648 PStatus[i].fault_exec = et_pointer; 649 et_pointer->type = EX_FAULT_MESSAGE; 650 et_pointer->ex.printer = PStatus + i; 651 et_pointer++; 652 } 653 654 for (i = 0; i < PWT_Size; i++) { 655 PWStatus[i].alert->exec = et_pointer; 656 et_pointer->type = EX_PALERT; 657 et_pointer->ex.pwheel = PWStatus + i; 658 et_pointer++; 659 } 660 661 for (i = 0; i < FT_Size; i++) { 662 FStatus[i].alert->exec = et_pointer; 663 et_pointer->type = EX_FALERT; 664 et_pointer->ex.form = FStatus + i; 665 et_pointer++; 666 } 667 668 } 669