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 2005 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 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */ 33 34 #include "unistd.h" 35 #include "sys/types.h" 36 #include "sys/stat.h" 37 #include "errno.h" 38 #include "fcntl.h" 39 #include "stdlib.h" 40 #include "string.h" 41 42 #include "lpsched.h" 43 44 /** 45 ** walk_ptable() - WALK PRINTER TABLE, RETURNING ACTIVE ENTRIES 46 ** walk_ftable() - WALK FORMS TABLE, RETURNING ACTIVE ENTRIES 47 ** walk_ctable() - WALK CLASS TABLE, RETURNING ACTIVE ENTRIES 48 ** walk_pwtable() - WALK PRINT WHEEL TABLE, RETURNING ACTIVE ENTRIES 49 **/ 50 51 52 PSTATUS * 53 walk_ptable(int start) 54 { 55 static PSTATUS *psend, 56 *ps = 0; 57 58 if (start || !ps) { 59 ps = PStatus; 60 psend = PStatus + PT_Size; 61 } 62 63 while (ps < psend && !ps->printer->name) 64 ps++; 65 66 if (ps >= psend) 67 return (ps = 0); 68 else 69 return (ps++); 70 } 71 72 FSTATUS * 73 walk_ftable(int start) 74 { 75 static FSTATUS *psend, 76 *ps = 0; 77 78 if (start || !ps) { 79 ps = FStatus; 80 psend = FStatus + FT_Size; 81 } 82 83 while (ps < psend && !ps->form->name) 84 ps++; 85 86 if (ps >= psend) 87 return (ps = 0); 88 else 89 return (ps++); 90 } 91 92 CSTATUS * 93 walk_ctable (int start) 94 { 95 static CSTATUS *psend, 96 *ps = 0; 97 98 if (start || !ps) { 99 ps = CStatus; 100 psend = CStatus + CT_Size; 101 } 102 103 while (ps < psend && !ps->class->name) 104 ps++; 105 106 if (ps >= psend) 107 return (ps = 0); 108 else 109 return (ps++); 110 } 111 112 PWSTATUS * 113 walk_pwtable(int start) 114 { 115 static PWSTATUS *psend, 116 *ps = 0; 117 118 if (start || !ps) { 119 ps = PWStatus; 120 psend = PWStatus + PWT_Size; 121 } 122 123 while (ps < psend && !ps->pwheel->name) 124 ps++; 125 126 if (ps >= psend) 127 return (ps = 0); 128 else 129 return (ps++); 130 } 131 132 133 /** 134 ** search_ptable() - SEARCH PRINTER TABLE 135 ** search_ftable() - SEARCH FORMS TABLE 136 ** search_ctable() - SEARCH CLASS TABLE 137 ** search_pwtable() - SEARCH PRINT WHEEL TABLE 138 **/ 139 140 PSTATUS * 141 search_ptable(register char *name) 142 { 143 register PSTATUS *ps, 144 *psend; 145 146 for ( 147 ps = & PStatus[0], psend = & PStatus[PT_Size]; 148 ps < psend && !SAME(ps->printer->name, name); 149 ps++ 150 ) 151 ; 152 153 if (ps >= psend) 154 ps = 0; 155 156 return (ps); 157 } 158 159 160 FSTATUS * 161 search_ftable(register char *name) 162 { 163 register FSTATUS *ps, *psend; 164 165 for (ps = & FStatus[0], psend = & FStatus[FT_Size]; 166 ps < psend && !SAME(ps->form->name, name); ps++); 167 168 if (ps >= psend) 169 ps = 0; 170 171 return (ps); 172 } 173 174 FSTATUS * 175 search_fptable(register char *paper) 176 { 177 register FSTATUS *ps,*cand, *psend; 178 179 cand = NULL; 180 for (ps = & FStatus[0], psend = & FStatus[FT_Size]; ps < psend; ps++) 181 if (SAME(ps->form->paper, paper)) { 182 if (ps->form->isDefault) { 183 cand = ps; 184 break; 185 } else if (!cand) 186 cand = ps; 187 } 188 189 return (cand); 190 } 191 192 CSTATUS * 193 search_ctable(register char *name) 194 { 195 register CSTATUS *ps, 196 *psend; 197 198 for ( 199 ps = & CStatus[0], psend = & CStatus[CT_Size]; 200 ps < psend && !SAME(ps->class->name, name); 201 ps++ 202 ) 203 ; 204 205 if (ps >= psend) 206 ps = 0; 207 208 return (ps); 209 } 210 211 PWSTATUS * 212 search_pwtable(register char *name) 213 { 214 register PWSTATUS *ps, 215 *psend; 216 217 for ( 218 ps = & PWStatus[0], psend = & PWStatus[PWT_Size]; 219 ps < psend && !SAME(ps->pwheel->name, name); 220 ps++ 221 ) 222 ; 223 224 if (ps >= psend) 225 ps = 0; 226 227 return (ps); 228 } 229 230 231 /** 232 ** load_str() - LOAD STRING WHERE ALLOC'D STRING MAY BE 233 ** unload_str() - REMOVE POSSIBLE ALLOC'D STRING 234 **/ 235 236 void 237 load_str(char **pdst, char *src) 238 { 239 if (*pdst) 240 Free (*pdst); 241 *pdst = Strdup(src); 242 return; 243 } 244 245 void 246 unload_str(char **pdst) 247 { 248 if (*pdst) 249 Free (*pdst); 250 *pdst = 0; 251 return; 252 } 253 254 /** 255 ** unload_list() - REMOVE POSSIBLE ALLOC'D LIST 256 **/ 257 258 void 259 unload_list(char ***plist) 260 { 261 if (*plist) 262 freelist (*plist); 263 *plist = 0; 264 return; 265 } 266 267 /** 268 ** load_sdn() - LOAD STRING WITH ASCII VERSION OF SCALED DECIMAL NUMBER 269 **/ 270 271 void 272 load_sdn(char **p, SCALED sdn) 273 { 274 if (!p) 275 return; 276 277 if (*p) 278 Free (*p); 279 *p = 0; 280 281 if (sdn.val <= 0 || 999999 < sdn.val) 282 return; 283 284 *p = Malloc(sizeof("999999.999x")); 285 sprintf ( 286 *p, 287 "%.3f%s", 288 sdn.val, 289 (sdn.sc == 'c'? "c" : (sdn.sc == 'i'? "i" : "")) 290 ); 291 292 return; 293 } 294 295 /** 296 ** Getform() - EASIER INTERFACE TO "getform()" 297 **/ 298 299 _FORM * 300 Getform(char *form) 301 { 302 static _FORM _formbuf; 303 304 FORM formbuf; 305 306 FALERT alertbuf; 307 308 int ret; 309 310 311 while ( 312 (ret = getform(form, &formbuf, &alertbuf, (FILE **)0)) == -1 313 && errno == EINTR 314 ) 315 ; 316 if (ret == -1) 317 return (0); 318 319 _formbuf.plen = formbuf.plen; 320 _formbuf.pwid = formbuf.pwid; 321 _formbuf.lpi = formbuf.lpi; 322 _formbuf.cpi = formbuf.cpi; 323 _formbuf.np = formbuf.np; 324 _formbuf.chset = formbuf.chset; 325 _formbuf.mandatory = formbuf.mandatory; 326 _formbuf.rcolor = formbuf.rcolor; 327 _formbuf.comment = formbuf.comment; 328 _formbuf.conttype = formbuf.conttype; 329 _formbuf.name = formbuf.name; 330 _formbuf.paper = formbuf.paper; 331 _formbuf.isDefault = formbuf.isDefault; 332 333 if ((_formbuf.alert.shcmd = alertbuf.shcmd) != NULL) { 334 _formbuf.alert.Q = alertbuf.Q; 335 _formbuf.alert.W = alertbuf.W; 336 } else { 337 _formbuf.alert.Q = 0; 338 _formbuf.alert.W = 0; 339 } 340 341 return (&_formbuf); 342 } 343 344 /** 345 ** Getprinter() 346 ** Getrequest() 347 ** Getuser() 348 ** Getclass() 349 ** Getpwheel() 350 ** Getsecure() 351 ** Getsystem() 352 ** Loadfilters() 353 **/ 354 355 PRINTER * 356 Getprinter(char *name) 357 { 358 register PRINTER *ret; 359 360 while (!(ret = getprinter(name)) && errno == EINTR) 361 ; 362 return (ret); 363 } 364 365 REQUEST * 366 Getrequest(char *file) 367 { 368 register REQUEST *ret; 369 370 while (!(ret = getrequest(file)) && errno == EINTR) 371 ; 372 return (ret); 373 } 374 375 USER * 376 Getuser(char *name) 377 { 378 register USER *ret; 379 380 while (!(ret = getuser(name)) && errno == EINTR) 381 ; 382 return (ret); 383 } 384 385 CLASS * 386 Getclass(char *name) 387 { 388 register CLASS *ret; 389 390 while (!(ret = getclass(name)) && errno == EINTR) 391 ; 392 return (ret); 393 } 394 395 PWHEEL * 396 Getpwheel(char *name) 397 { 398 register PWHEEL *ret; 399 400 while (!(ret = getpwheel(name)) && errno == EINTR) 401 ; 402 return (ret); 403 } 404 405 SECURE * 406 Getsecure(char *file) 407 { 408 register SECURE *ret; 409 410 while (!(ret = getsecure(file)) && errno == EINTR) 411 ; 412 return ((SECURE *) ret); 413 } 414 415 416 int 417 Loadfilters(char *file) 418 { 419 register int ret; 420 421 while ((ret = loadfilters(file)) == -1 && errno == EINTR) 422 ; 423 return (ret); 424 } 425 426 /** 427 ** free_form() - FREE MEMORY ALLOCATED FOR _FORM STRUCTURE 428 **/ 429 430 void 431 free_form(register _FORM *pf) 432 { 433 if (!pf) 434 return; 435 if (pf->chset) 436 Free (pf->chset); 437 if (pf->rcolor) 438 Free (pf->rcolor); 439 if (pf->comment) 440 Free (pf->comment); 441 if (pf->conttype) 442 Free (pf->conttype); 443 if (pf->name) 444 Free (pf->name); 445 if (pf->paper) 446 Free (pf->paper); 447 pf->name = 0; 448 if (pf->alert.shcmd) 449 Free (pf->alert.shcmd); 450 return; 451 } 452 453 /** 454 ** getreqno() - GET NUMBER PART OF REQUEST ID 455 **/ 456 457 char * 458 getreqno(char *req_id) 459 { 460 register char *cp; 461 462 463 if (!(cp = strrchr(req_id, '-'))) 464 cp = req_id; 465 else 466 cp++; 467 return (cp); 468 } 469 470 /* Putsecure(): Insurance for writing out the secure request file. 471 * input: char ptr to name of the request file, 472 * ptr to the SECURE structure to be written. 473 * ouput: 0 if successful, -1 otherwise. 474 * 475 * Description: 476 * The normal call to putsecure() is woefully lacking. 477 * The bottom line here is that there 478 * is no way to make sure that the file has been written out 479 * as expected. This can cause rude behaviour later on. 480 * 481 * This routine calls putsecure(), and then does a getsecure(). 482 * The results are compared to the original structure. If the 483 * info obtained by getsecure() doesn't match, we retry a few 484 * times before giving up (presumably something is very seriously 485 * wrong at that point). 486 */ 487 488 489 int 490 Putsecure(char *file, SECURE *secbufp) 491 { 492 SECURE *pls; 493 int retries = 5; /* # of attempts */ 494 int status; /* 0 = success, nonzero otherwise */ 495 496 497 while (retries--) { 498 status = 1; /* assume the worst, hope for the best */ 499 if (putsecure(file, secbufp) == -1) { 500 rmsecure(file); 501 continue; 502 } 503 504 if ((pls = getsecure(file)) == (SECURE *) NULL) { 505 rmsecure(file); 506 status = 2; 507 continue; 508 } 509 510 /* now compare each field */ 511 512 /* 513 * A comparison is only valid if secbufp and pls point to 514 * different locations. In reality getsecure() will have 515 * already been called, allocating the same STATIC memory 516 * location to both structures making the following compare 517 * meaningless. 518 * Therefore test for this condition to prevent us from 519 * calling freesecure which will destroy uid, system and 520 * req_id fields in the strucure 521 */ 522 523 status = 0; 524 if (secbufp != pls) { 525 if (strcmp(pls->req_id, secbufp->req_id) != 0) { 526 rmsecure(file); 527 status = 3; 528 continue; 529 } 530 531 if (pls->uid != secbufp->uid) { 532 rmsecure(file); 533 status = 4; 534 continue; 535 } 536 537 if (strcmp(pls->user, secbufp->user) != 0) { 538 rmsecure(file); 539 status = 5; 540 continue; 541 } 542 543 if (pls->gid != secbufp->gid) { 544 rmsecure(file); 545 status = 6; 546 continue; 547 } 548 549 if (pls->size != secbufp->size) { 550 rmsecure(file); 551 status = 7; 552 continue; 553 } 554 555 if (pls->date != secbufp->date) { 556 rmsecure(file); 557 status = 8; 558 continue; 559 } 560 561 if (strcmp(pls->system, secbufp->system) != 0) { 562 rmsecure(file); 563 status = 9; 564 continue; 565 } 566 freesecure(pls); 567 } 568 break; 569 } 570 571 if (status != 0) { 572 note("Putsecure failed, status=%d\n", status); 573 return -1; 574 } 575 576 return 0; 577 } 578 579 void GetRequestFiles(REQUEST *req, char *buffer, int length) 580 { 581 char buf[BUFSIZ]; 582 583 memset(buf, 0, sizeof(buf)); 584 585 if (req->title) { 586 char *r = req->title; 587 char *ptr = buf; 588 589 while ( *r && strncmp(r,"\\n",2)) { 590 *ptr++ = *r++; 591 } 592 } else if (req->file_list) 593 strlcpy(buf, *req->file_list, sizeof (buf)); 594 595 if (*buf == NULL || !strncmp(buf, SPOOLDIR, sizeof(SPOOLDIR)-1)) 596 strcpy(buf, "<File name not available>"); 597 598 if (strlen(buf) > (size_t) 24) { 599 char *r; 600 601 if (r = strrchr(buf, '/')) 602 r++; 603 else 604 r = buf; 605 606 snprintf(buffer, length, "%-.24s", r); 607 } else 608 strlcpy(buffer, buf, length); 609 return; 610 } 611 612 613 /** 614 ** _Malloc() 615 ** _Realloc() 616 ** _Calloc() 617 ** _Strdup() 618 ** _Free() 619 **/ 620 621 void (*lp_alloc_fail_handler)( void ) = 0; 622 623 typedef void *alloc_type; 624 625 alloc_type 626 _Malloc(size_t size, const char *file, int line) 627 { 628 alloc_type ret; 629 630 ret = malloc(size); 631 if (!ret) { 632 if (lp_alloc_fail_handler) 633 (*lp_alloc_fail_handler)(); 634 errno = ENOMEM; 635 } 636 return (ret); 637 } 638 639 alloc_type 640 _Realloc(void *ptr, size_t size, const char *file, int line) 641 { 642 alloc_type ret = realloc(ptr, size); 643 644 if (!ret) { 645 if (lp_alloc_fail_handler) 646 (*lp_alloc_fail_handler)(); 647 errno = ENOMEM; 648 } 649 return (ret); 650 } 651 652 alloc_type 653 _Calloc(size_t nelem, size_t elsize, const char *file, int line) 654 { 655 alloc_type ret = calloc(nelem, elsize); 656 657 if (!ret) { 658 if (lp_alloc_fail_handler) 659 (*lp_alloc_fail_handler)(); 660 errno = ENOMEM; 661 } 662 return (ret); 663 } 664 665 char * 666 _Strdup(const char *s, const char *file, int line) 667 { 668 char * ret; 669 670 if (!s) 671 return( (char *) 0); 672 673 ret = strdup(s); 674 675 if (!ret) { 676 if (lp_alloc_fail_handler) 677 (*lp_alloc_fail_handler)(); 678 errno = ENOMEM; 679 } 680 return (ret); 681 } 682 683 void 684 _Free(void *ptr, const char *file, int line) 685 { 686 free (ptr); 687 return; 688 } 689