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