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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright (c) 2001 by Sun Microsystems, Inc. 28 * All rights reserved. 29 */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #include "stdlib.h" 34 #include "string.h" 35 #include "unistd.h" 36 #include <syslog.h> 37 38 #include "lpsched.h" 39 40 #define NCMP(X,Y) (STRNEQU((X), (Y), sizeof(Y)-1)) 41 42 extern char *LP_TRAY_UNMOUNT; 43 44 static void load_pstatus ( void ); 45 static void load_fault_status ( void ); 46 static void load_cstatus ( void ); 47 static void put_multi_line ( int , char * ); 48 static PFSTATUS * parseFormList ( char *,short *); 49 static void markFormsMounted( PSTATUS *); 50 51 52 #define FAULT_MESSAGE_FILE "faultMessage" 53 static char *pstatus = 0, 54 *cstatus = 0; 55 56 /** 57 ** load_status() - LOAD PRINTER/CLASS STATUS FILES 58 **/ 59 60 void 61 load_status(void) 62 { 63 load_pstatus (); 64 65 load_cstatus (); 66 load_fault_status (); 67 return; 68 } 69 70 /** 71 ** load_pstatus() - LOAD PRITNER STATUS FILE 72 **/ 73 74 static void 75 load_pstatus(void) 76 { 77 PSTATUS *pps; 78 79 char *rej_reason, 80 *dis_reason, 81 *pwheel_name, 82 buf[BUFSIZ], 83 *name, 84 *p; 85 86 time_t rej_date, 87 dis_date; 88 89 short status; 90 91 PFSTATUS *ppfs; 92 93 PWSTATUS *ppws; 94 95 int i, 96 len, 97 total; 98 99 time_t now; 100 101 int fd; 102 103 register int f; 104 short numForms; 105 106 107 (void) time(&now); 108 109 if (!pstatus) 110 pstatus = makepath(Lp_System, PSTATUSFILE, (char *)0); 111 if ((fd = open_locked(pstatus, "r", 0)) >= 0) { 112 char *tmp = pstatus; /* not NULL */ 113 114 while (tmp != NULL) { 115 status = 0; 116 total = 0; 117 name = 0; 118 rej_reason = 0; 119 dis_reason = 0; 120 ppfs = 0; 121 122 errno = 0; 123 for (f = 0; 124 (f < PST_MAX) && (tmp = fdgets(buf, BUFSIZ, fd)); 125 f++) { 126 if (p = strrchr(buf, '\n')) 127 *p = '\0'; 128 129 switch (f) { 130 case PST_BRK: 131 break; 132 133 case PST_NAME: 134 name = Strdup(buf); 135 break; 136 137 case PST_STATUS: 138 if (NCMP(buf, NAME_DISABLED)) 139 status |= PS_DISABLED; 140 p = strchr(buf, ' '); 141 if (!p || !*(++p)) 142 break; 143 if (NCMP(p, NAME_REJECTING)) 144 status |= PS_REJECTED; 145 break; 146 147 case PST_DATE: 148 dis_date = (time_t)atol(buf); 149 p = strchr(buf, ' '); 150 if (!p || !*(++p)) 151 break; 152 rej_date = (time_t)atol(p); 153 break; 154 155 case PST_DISREAS: 156 len = strlen(buf); 157 if (buf[len - 1] == '\\') { 158 buf[len - 1] = '\n'; 159 f--; 160 } 161 if (dis_reason) { 162 total += len; 163 dis_reason = Realloc( 164 dis_reason, 165 total+1 166 ); 167 strcat (dis_reason, buf); 168 } else { 169 dis_reason = Strdup(buf); 170 total = len; 171 } 172 break; 173 174 case PST_REJREAS: 175 len = strlen(buf); 176 if (buf[len - 1] == '\\') { 177 buf[len - 1] = '\n'; 178 f--; 179 } 180 if (rej_reason) { 181 total += len; 182 rej_reason = Realloc( 183 rej_reason, 184 total+1 185 ); 186 strcat (rej_reason, buf); 187 } else { 188 rej_reason = Strdup(buf); 189 total = len; 190 } 191 break; 192 193 case PST_PWHEEL: 194 if (*buf) { 195 ppws = search_pwtable(buf); 196 pwheel_name = Strdup(buf); 197 } else { 198 ppws = 0; 199 pwheel_name = 0; 200 } 201 break; 202 203 case PST_FORM: 204 ppfs = parseFormList (buf,&numForms); 205 break; 206 } 207 } 208 209 if ((errno != 0) || f && f != PST_MAX) { 210 close(fd); 211 note("Had trouble reading file %s", pstatus); 212 return; 213 } 214 215 if ((tmp != NULL) && name && 216 (pps = search_ptable(name))) { 217 pps->rej_date = rej_date; 218 pps->status |= status; 219 pps->forms = ppfs; 220 if (ppfs) markFormsMounted(pps); 221 pps->numForms = numForms; 222 pps->pwheel_name = pwheel_name; 223 if ((pps->pwheel = ppws) != NULL) 224 ppws->mounted++; 225 pps->rej_reason = rej_reason; 226 load_str(&pps->fault_reason, CUZ_PRINTING_OK); 227 if (pps->printer->login) { 228 pps->dis_date = now; 229 pps->dis_reason = 230 Strdup(CUZ_LOGIN_PRINTER); 231 } else { 232 pps->dis_date = dis_date; 233 pps->dis_reason = dis_reason; 234 } 235 236 } else { 237 if (ppfs) 238 Free(ppfs); 239 if (dis_reason) 240 Free (dis_reason); 241 if (rej_reason) 242 Free (rej_reason); 243 } 244 if (name) 245 Free (name); 246 } 247 } 248 249 if (fd >= 0) { 250 if (errno != 0) { 251 close(fd); 252 note("Had trouble reading file %s", pstatus); 253 return; 254 } 255 close(fd); 256 } 257 258 for (i = 0; i < PT_Size; i++) 259 if (PStatus[i].printer->name && !PStatus[i].rej_reason) { 260 PStatus[i].dis_reason = Strdup(CUZ_NEW_PRINTER); 261 PStatus[i].rej_reason = Strdup(CUZ_NEW_DEST); 262 PStatus[i].fault_reason = Strdup(CUZ_PRINTING_OK); 263 PStatus[i].dis_date = now; 264 PStatus[i].rej_date = now; 265 PStatus[i].status |= PS_DISABLED | PS_REJECTED; 266 } 267 268 return; 269 } 270 271 /** 272 ** load_fault_status() - LOAD PRITNER Fault STATUS FILE 273 **/ 274 275 static void 276 load_fault_status(void) 277 { 278 PSTATUS *pps; 279 280 char *fault_reason = NULL, 281 buf[BUFSIZ], 282 *fault_status, 283 *printerName, 284 *p; 285 286 int i, 287 len, 288 total; 289 290 291 int fd; 292 293 for (i = 0; i < PT_Size; i++) { 294 printerName = PStatus[i].printer->name; 295 if (printerName) { 296 fault_status = makepath(Lp_A_Printers, printerName, 297 FAULT_MESSAGE_FILE , (char *) 0); 298 fault_reason = NULL; 299 total = 0; 300 301 if ((fd = open_locked(fault_status, "r", 0)) >= 0) { 302 while (fdgets(buf, BUFSIZ, fd)) { 303 len = strlen(buf); 304 if (fault_reason) { 305 total += len; 306 fault_reason = 307 Realloc(fault_reason, 308 total+1); 309 strcat (fault_reason, buf); 310 } else { 311 fault_reason = Strdup(buf); 312 total = len; 313 } 314 } 315 316 if (fault_reason && 317 (pps = search_ptable(printerName))) { 318 p = fault_reason + strlen(fault_reason) 319 - 1; 320 if (*p == '\n') 321 *p = 0; 322 load_str(&pps->fault_reason, 323 fault_reason); 324 } 325 if (fault_reason) 326 Free(fault_reason); 327 328 close(fd); 329 } 330 Free(fault_status); 331 } 332 } 333 } 334 335 336 /** 337 ** load_cstatus() - LOAD CLASS STATUS FILE 338 **/ 339 340 static void 341 load_cstatus(void) 342 { 343 CSTATUS *pcs; 344 char *rej_reason, 345 buf[BUFSIZ], 346 *name, 347 *p; 348 time_t rej_date; 349 short status; 350 int i, 351 len, 352 total; 353 time_t now; 354 int fd; 355 register int f; 356 357 358 (void) time(&now); 359 360 if (!cstatus) 361 cstatus = makepath(Lp_System, CSTATUSFILE, (char *)0); 362 363 if ((fd = open_locked(cstatus, "r", 0)) >= 0) { 364 char *tmp = cstatus; /* not NULL */ 365 366 errno = 0; 367 while (tmp != NULL) { 368 status = 0; 369 370 total = 0; 371 name = 0; 372 373 rej_reason = 0; 374 for (f = 0; 375 (f < CST_MAX) && (tmp = fdgets(buf, BUFSIZ, fd)); 376 f++) { 377 if (p = strrchr(buf, '\n')) 378 *p = '\0'; 379 switch (f) { 380 case CST_BRK: 381 break; 382 383 case CST_NAME: 384 name = Strdup(buf); 385 break; 386 387 case CST_STATUS: 388 if (NCMP(buf, NAME_REJECTING)) 389 status |= PS_REJECTED; 390 break; 391 392 case CST_DATE: 393 rej_date = (time_t)atol(buf); 394 break; 395 396 case CST_REJREAS: 397 len = strlen(buf); 398 if (buf[len - 1] == '\\') { 399 buf[len - 1] = '\n'; 400 f--; 401 } 402 if (rej_reason) { 403 total += len; 404 rej_reason = Realloc( 405 rej_reason, 406 total+1 407 ); 408 strcat (rej_reason, buf); 409 } else { 410 rej_reason = Strdup(buf); 411 total = len; 412 } 413 break; 414 } 415 } 416 417 if ((errno != 0) || f && f != CST_MAX) { 418 close(fd); 419 note("Had trouble reading file %s", cstatus); 420 return; 421 } 422 423 if ((tmp != NULL) && name && 424 (pcs = search_ctable(name))) { 425 pcs->rej_reason = rej_reason; 426 pcs->rej_date = rej_date; 427 pcs->status |= status; 428 429 } else 430 if (rej_reason) 431 Free (rej_reason); 432 433 if (name) 434 Free (name); 435 } 436 } 437 438 if (fd >= 0) { 439 if (errno != 0) { 440 close(fd); 441 note("Had trouble reading file %s", cstatus); 442 return; 443 } 444 close(fd); 445 } 446 447 for (i = 0; i < CT_Size; i++) 448 if (CStatus[i].class->name && !CStatus[i].rej_reason) { 449 CStatus[i].status |= CS_REJECTED; 450 CStatus[i].rej_reason = Strdup(CUZ_NEW_DEST); 451 CStatus[i].rej_date = now; 452 } 453 454 return; 455 } 456 457 /** 458 ** showForms() 459 **/ 460 char * 461 showForms(PSTATUS *pps) 462 { 463 int i; 464 char *formList = NULL; 465 char buf[100]; 466 FSTATUS *pfs; 467 PFSTATUS *ppfs; 468 short numForms; 469 470 numForms = pps->numForms; 471 ppfs = pps->forms; 472 if (ppfs) { 473 for (i = 0; i < numForms; i++) { 474 pfs = ppfs[i].form; 475 snprintf(buf, sizeof (buf), "%s%c", 476 (pfs ? pfs->form->name : ""), *LP_SEP); 477 478 if (addstring(&formList,buf)) { /* allocation failed */ 479 if (formList) { 480 Free(formList); 481 formList = NULL; 482 } 483 return(NULL); 484 } 485 } 486 } 487 return(formList); 488 } 489 490 /** 491 ** markFormsMounted() 492 **/ 493 494 void 495 markFormsMounted(PSTATUS *pps) 496 { 497 int i; 498 int numTrays; 499 PFSTATUS *ppfs; 500 FSTATUS *pfs; 501 502 503 ppfs = pps->forms; 504 if (ppfs) { 505 numTrays = pps->numForms; 506 for (i = 0; i < numTrays; i++) { 507 pfs = ppfs[i].form; 508 if (pfs) 509 pfs->mounted++; 510 } 511 } 512 } 513 514 /** 515 ** parseFormList() 516 **/ 517 518 static PFSTATUS * 519 parseFormList(char *formList, short *num) 520 { 521 int i; 522 FSTATUS *pfs; 523 PFSTATUS *ppfs; 524 short numForms=0; 525 char *endPtr,*ptr; 526 527 528 ptr = strchr(formList,*LP_SEP); 529 while (ptr) { 530 numForms++; 531 ptr = strchr(ptr+1,*LP_SEP); 532 } 533 if ((numForms == 0) && (*formList)) 534 numForms = 1; 535 536 if (numForms && 537 (ppfs = (PFSTATUS *) Calloc(numForms, sizeof(PFSTATUS)))) { 538 endPtr = strchr(formList,*LP_SEP); 539 if (!endPtr) 540 endPtr = formList + strlen(formList); 541 542 ptr = formList; 543 for (i = 0; endPtr && (i < numForms); i++) { 544 *endPtr = 0; 545 ppfs[i].form = pfs = search_ftable(ptr); 546 ppfs[i].isAvailable = 547 ((pfs || (!LP_TRAY_UNMOUNT)) ? 1 : 0); 548 ptr = endPtr+1; 549 endPtr = strchr(ptr,*LP_SEP); 550 } 551 *num = numForms; 552 } else { 553 ppfs = NULL; 554 *num = 0; 555 } 556 return(ppfs); 557 } 558 559 /** 560 ** dump_pstatus() - DUMP PRINTER STATUS FILE 561 **/ 562 563 void 564 dump_pstatus(void) 565 { 566 PSTATUS *ppsend; 567 int fd; 568 register PSTATUS *pps; 569 register int f; 570 571 572 if (!pstatus) 573 pstatus = makepath(Lp_System, PSTATUSFILE, (char *)0); 574 if ((fd = open_locked(pstatus, "w", MODE_READ)) < 0) { 575 note ("Can't open file \"%s\" (%s).\n", pstatus, PERROR); 576 return; 577 } 578 579 for (pps = PStatus, ppsend = &PStatus[PT_Size]; pps < ppsend; pps++) 580 if (pps->printer->name) 581 for (f = 0; f < PST_MAX; f++) switch (f) { 582 case PST_BRK: 583 (void)fdprintf(fd, "+%s\n", STATUS_BREAK); 584 break; 585 case PST_NAME: 586 (void)fdprintf(fd, "%s\n", 587 NB(pps->printer->name)); 588 break; 589 case PST_STATUS: 590 (void)fdprintf(fd, "%s %s\n", 591 (pps->status & PS_DISABLED ? 592 NAME_DISABLED : NAME_ENABLED), 593 (pps->status & PS_REJECTED ? 594 NAME_REJECTING : NAME_ACCEPTING)); 595 break; 596 case PST_DATE: 597 (void)fdprintf(fd, "%ld %ld\n", pps->dis_date, 598 pps->rej_date); 599 break; 600 case PST_DISREAS: 601 put_multi_line(fd, pps->dis_reason); 602 break; 603 case PST_REJREAS: 604 put_multi_line(fd, pps->rej_reason); 605 break; 606 case PST_PWHEEL: 607 (void)fdprintf(fd, "%s\n", 608 NB(pps->pwheel_name)); 609 break; 610 case PST_FORM: { 611 char *list; 612 list = showForms(pps); 613 (void)fdprintf(fd, "%s\n", (list ? list : "")); 614 if (list) 615 Free(list); 616 break; 617 } 618 } 619 620 close(fd); 621 622 return; 623 } 624 625 /** 626 ** dump_fault_status() - DUMP PRINTER FAULT STATUS FILE 627 **/ 628 629 void 630 dump_fault_status(PSTATUS *pps) 631 { 632 int fd; 633 char *fault_status, *printerName; 634 635 printerName = pps->printer->name; 636 fault_status = makepath(Lp_A_Printers, printerName, FAULT_MESSAGE_FILE, 637 (char *) 0); 638 if ((fd = open_locked(fault_status, "w", MODE_READ)) < 0) { 639 syslog(LOG_DEBUG, "Can't open file %s (%m)\n", fault_status); 640 } else { 641 fdprintf(fd, "%s\n", pps->fault_reason); 642 close(fd); 643 } 644 645 Free(fault_status); 646 return; 647 } 648 649 650 /** 651 ** dump_cstatus() - DUMP CLASS STATUS FILE 652 **/ 653 654 void 655 dump_cstatus(void) 656 { 657 CSTATUS *pcsend; 658 int fd; 659 register CSTATUS *pcs; 660 register int f; 661 662 663 if (!cstatus) 664 cstatus = makepath(Lp_System, CSTATUSFILE, (char *)0); 665 if ((fd = open_locked(cstatus, "w", MODE_READ)) < 0) { 666 syslog(LOG_DEBUG, "Can't open file %s (%m)\n", cstatus); 667 return; 668 } 669 670 for (pcs = CStatus, pcsend = &CStatus[CT_Size]; pcs < pcsend; pcs++) 671 if (pcs->class->name) 672 for (f = 0; f < CST_MAX; f++) switch (f) { 673 case CST_BRK: 674 (void)fdprintf(fd, "%s\n", STATUS_BREAK); 675 break; 676 case CST_NAME: 677 (void)fdprintf(fd, "%s\n", 678 NB(pcs->class->name)); 679 break; 680 case CST_STATUS: 681 (void)fdprintf(fd, "%s\n", 682 (pcs->status & CS_REJECTED ? 683 NAME_REJECTING : NAME_ACCEPTING) 684 ); 685 break; 686 case CST_DATE: 687 (void)fdprintf(fd, "%ld\n", pcs->rej_date); 688 break; 689 case CST_REJREAS: 690 put_multi_line(fd, pcs->rej_reason); 691 break; 692 } 693 694 close(fd); 695 696 return; 697 } 698 699 /** 700 ** put_multi_line() - PRINT OUT MULTI-LINE TEXT 701 **/ 702 703 static void 704 put_multi_line(int fd, char *buf) 705 { 706 register char *cp, 707 *p; 708 709 if (!buf) { 710 (void)fdprintf(fd, "\n"); 711 return; 712 } 713 714 for (p = buf; (cp = strchr(p, '\n')); ) { 715 *cp++ = 0; 716 (void)fdprintf(fd, "%s\\\n", p); 717 p = cp; 718 } 719 (void)fdprintf(fd, "%s\n", p); 720 return; 721 } 722