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