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 /* 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 static int __list_increment = 16; 45 46 int 47 list_append(void ***list, void *item) 48 { 49 int count; 50 51 if ((list == NULL) || (item == NULL)) { 52 errno = EINVAL; 53 return (-1); 54 } 55 56 if (item != NULL) { 57 if (*list == NULL) 58 *list = (void **)calloc(__list_increment, 59 sizeof (void *)); 60 61 if (*list == NULL) 62 return (-1); 63 64 for (count = 0; (*list)[count] != NULL; count++); 65 66 if ((count + 1) % __list_increment == 0) { /* expand the list */ void **new_list = NULL; 67 int new_size = (((count + 1) / __list_increment) + 1) * 68 __list_increment; 69 70 new_list = (void **)calloc(new_size, sizeof (void *)); 71 if (new_list == NULL) 72 return (-1); 73 74 for (count = 0; (*list)[count] != NULL; count++) 75 new_list[count] = (*list)[count]; 76 free(*list); 77 *list = new_list; 78 } 79 80 (*list)[count] = item; 81 } 82 83 return (0); 84 } 85 86 void 87 list_remove(void ***list, void *item) 88 { 89 int i, count; 90 void **tmp = NULL; 91 92 if ((list == NULL) || (*list == NULL) || (item == NULL)) 93 return; 94 95 for (count = 0; (*list)[count] != NULL; count++) 96 ; 97 98 if (count > 0) { 99 int new_size = (((count + 1) / __list_increment) + 1) * 100 __list_increment; 101 102 if ((tmp = (void **)calloc(new_size, sizeof (void *))) == NULL) 103 tmp = *list; 104 105 /* copy up to item */ 106 for (i = 0; (((*list)[i] != NULL) && ((*list)[i] != item)); i++) 107 tmp[i] = (*list)[i]; 108 /* copy after item */ 109 if ((*list)[i] == item) 110 for (++i; ((*list)[i] != NULL); i++) 111 tmp[i-1] = (*list)[i]; 112 } 113 114 /* replace the list */ 115 if (tmp != *list) { 116 free(*list); 117 *list = tmp; 118 } 119 } 120 121 void 122 free_exec(EXEC *ep) 123 { 124 if (ep != NULL) { 125 free(ep); 126 list_remove((void ***)&Exec_Table, (void *)ep); 127 } 128 } 129 130 EXEC * 131 new_exec(int type, void *ex) 132 { 133 EXEC *result = calloc(1, sizeof (*result)); 134 135 if (result != NULL) { 136 result->type = type; 137 switch (type) { 138 case EX_ALERT: 139 case EX_INTERF: 140 case EX_FAULT_MESSAGE: 141 result->ex.printer = ex; 142 break; 143 case EX_FALERT: 144 result->ex.form = ex; 145 break; 146 case EX_PALERT: 147 result->ex.pwheel = ex; 148 break; 149 case EX_SLOWF: 150 case EX_NOTIFY: 151 break; 152 } 153 list_append((void ***)&Exec_Table, (void *)result); 154 } 155 156 return (result); 157 } 158 159 void 160 free_alert(ALERT *ap) 161 { 162 if (ap != NULL) { 163 if (ap->msgfile != NULL) 164 free(ap->msgfile); 165 if (ap->exec != NULL) 166 free_exec(ap->exec); 167 free(ap); 168 } 169 } 170 171 ALERT * 172 new_alert(char *fmt, int i) 173 { 174 ALERT *result = calloc(1, sizeof (*result)); 175 176 if (result != NULL) { 177 char buf[15]; 178 179 snprintf(buf, sizeof (buf), fmt, i); 180 result->msgfile = makepath(Lp_Temp, buf, (char *)0); 181 (void) Unlink(result->msgfile); 182 } 183 184 return (result); 185 } 186 187 void 188 free_pstatus(PSTATUS *psp) 189 { 190 if (psp != NULL) { 191 if (psp->alert != NULL) 192 free_alert(psp->alert); 193 if (psp->exec != NULL) 194 free_exec(psp->exec); 195 if (psp->fault_exec != NULL) 196 free_exec(psp->fault_exec); 197 if (psp->printer != NULL) 198 freeprinter(psp->printer); 199 if (psp->pwheel_name != NULL) 200 free(psp->pwheel_name); 201 if (psp->dis_reason != NULL) 202 free(psp->dis_reason); 203 if (psp->rej_reason != NULL) 204 free(psp->rej_reason); 205 if (psp->users_allowed != NULL) 206 unload_list(&psp->users_allowed); 207 if (psp->users_denied != NULL) 208 unload_list(&psp->users_denied); 209 if (psp->forms_allowed != NULL) 210 unload_list(&psp->forms_allowed); 211 if (psp->forms_denied != NULL) 212 unload_list(&psp->forms_denied); 213 if (psp->cpi != NULL) 214 free(psp->cpi); 215 if (psp->lpi != NULL) 216 free(psp->lpi); 217 if (psp->plen != NULL) 218 free(psp->plen); 219 if (psp->pwid != NULL) 220 free(psp->pwid); 221 if (psp->fault_reason != NULL) 222 free(psp->fault_reason); 223 if (psp->paper_allowed != NULL) 224 unload_list(&psp->paper_allowed); 225 free(psp); 226 } 227 } 228 229 void 230 pstatus_add_printer(PSTATUS *ps, PRINTER *p) 231 { 232 if ((ps != NULL) && (p != NULL)) { 233 char **paperDenied = NULL; 234 235 ps->printer = p; 236 load_userprinter_access(p->name, &(ps->users_allowed), 237 &(ps->users_denied)); 238 load_formprinter_access(p->name, &(ps->forms_allowed), 239 &(ps->forms_denied)); 240 load_paperprinter_access(p->name, &ps->paper_allowed, 241 &paperDenied); 242 freelist(paperDenied); 243 load_sdn(&(ps->cpi), p->cpi); 244 load_sdn(&(ps->lpi), p->lpi); 245 load_sdn(&(ps->plen), p->plen); 246 load_sdn(&(ps->pwid), p->pwid); 247 } 248 } 249 250 PSTATUS * 251 new_pstatus(PRINTER *p) 252 { 253 PSTATUS *result = calloc(1, sizeof (*result)); 254 255 if (result != NULL) { 256 static int i = 0; 257 char **paperDenied = NULL; 258 259 result->alert = new_alert("A-%d", i++); 260 result->alert->exec = new_exec(EX_ALERT, result); 261 result->exec = new_exec(EX_INTERF, result); 262 result->fault_exec = new_exec(EX_FAULT_MESSAGE, result); 263 264 if (p != NULL) 265 pstatus_add_printer(result, p); 266 267 list_append((void ***)&PStatus, (void *)result); 268 } 269 270 return (result); 271 } 272 273 void 274 free_cstatus(CSTATUS *csp) 275 { 276 if (csp != NULL) { 277 if (csp->rej_reason != NULL) 278 free(csp->rej_reason); 279 if (csp->class != NULL) 280 freeclass(csp->class); 281 free(csp); 282 } 283 } 284 285 CSTATUS * 286 new_cstatus(CLASS *c) 287 { 288 CSTATUS *result = calloc(1, sizeof (*result)); 289 290 if (result != NULL) { 291 if (c != NULL) 292 result->class = c; 293 else 294 result->class = calloc(1, sizeof (CLASS)); 295 296 list_append((void ***)&CStatus, result); 297 } 298 299 return (result); 300 } 301 302 void 303 free_fstatus(FSTATUS *fsp) 304 { 305 if (fsp != NULL) { 306 if (fsp->form != NULL) 307 free_form(fsp->form); 308 if (fsp->alert != NULL) 309 free_alert(fsp->alert); 310 if (fsp->users_allowed != NULL) 311 unload_list(&fsp->users_allowed); 312 if (fsp->users_denied != NULL) 313 unload_list(&fsp->users_denied); 314 if (fsp->cpi != NULL) 315 free(fsp->cpi); 316 if (fsp->lpi != NULL) 317 free(fsp->lpi); 318 if (fsp->plen != NULL) 319 free(fsp->plen); 320 if (fsp->pwid != NULL) 321 free(fsp->pwid); 322 free(fsp); 323 } 324 } 325 326 FSTATUS * 327 new_fstatus(_FORM *f) 328 { 329 FSTATUS *result = calloc(1, sizeof (*result)); 330 331 if (result != NULL) { 332 static int i = 0; 333 334 if (f != NULL) 335 result->form = f; 336 else 337 result->form = calloc(1, sizeof (_FORM)); 338 339 result->alert = new_alert("F-%d", i++); 340 result->alert->exec = new_exec(EX_FALERT, result); 341 result->trigger = result->form->alert.Q; 342 343 if (f != NULL) { 344 load_userform_access(f->name, &(result->users_allowed), 345 &(result->users_denied)); 346 load_sdn (&(result->cpi), f->cpi); 347 load_sdn (&(result->lpi), f->lpi); 348 load_sdn (&(result->plen), f->plen); 349 load_sdn (&(result->pwid), f->pwid); 350 } 351 352 list_append((void ***)&FStatus, (void *)result); 353 } 354 355 return (result); 356 } 357 358 void 359 free_pwstatus(PWSTATUS *pwp) 360 { 361 if (pwp != NULL) { 362 if (pwp->pwheel) 363 freepwheel(pwp->pwheel); 364 if (pwp->alert != NULL) 365 free_alert(pwp->alert); 366 free(pwp); 367 } 368 } 369 370 PWSTATUS * 371 new_pwstatus(PWHEEL *p) 372 { 373 PWSTATUS *result = calloc(1, sizeof (*result)); 374 375 if (result != NULL) { 376 static int i = 0; 377 378 if (p != NULL) 379 result->pwheel = p; 380 else 381 result->pwheel = calloc(1, sizeof (*result)); 382 383 result->alert = new_alert("P-%d", i++); 384 result->alert->exec = new_exec(EX_PALERT, result); 385 result->trigger = result->pwheel->alert.Q; 386 387 list_append((void ***)&PWStatus, (void *)result); 388 } 389 390 return (result); 391 } 392 393 void 394 free_rstatus(RSTATUS *rsp) 395 { 396 if (rsp != NULL) { 397 remover(rsp); 398 399 if (rsp->request != NULL) 400 freerequest(rsp->request); 401 if (rsp->secure != NULL) 402 freesecure(rsp->secure); 403 if (rsp->req_file) 404 Free (rsp->req_file); 405 if (rsp->slow) 406 Free (rsp->slow); 407 if (rsp->fast) 408 Free (rsp->fast); 409 if (rsp->pwheel_name) 410 Free (rsp->pwheel_name); 411 if (rsp->printer_type) 412 Free (rsp->printer_type); 413 if (rsp->output_type) 414 Free (rsp->output_type); 415 if (rsp->cpi) 416 Free (rsp->cpi); 417 if (rsp->lpi) 418 Free (rsp->lpi); 419 if (rsp->plen) 420 Free (rsp->plen); 421 if (rsp->pwid) 422 Free (rsp->pwid); 423 free(rsp); 424 } 425 } 426 427 RSTATUS * 428 new_rstatus(REQUEST *r, SECURE *s) 429 { 430 RSTATUS *result = calloc(1, sizeof (*result)); 431 432 if (result != NULL) { 433 if ((result->request = r) == NULL) 434 result->request = calloc(1, sizeof (REQUEST)); 435 if ((result->secure = s) == NULL) 436 result->secure = calloc(1, sizeof (SECURE)); 437 } 438 439 return (result); 440 } 441 442 /** 443 ** search_pstatus() - SEARCH PRINTER TABLE 444 ** search_fstatus() - SEARCH FORMS TABLE 445 ** search_cstatus() - SEARCH CLASS TABLE 446 ** search_pwstatus() - SEARCH PRINT WHEEL TABLE 447 **/ 448 449 PSTATUS * 450 search_pstatus(register char *name) 451 { 452 PSTATUS *ps = NULL; 453 454 if (name != NULL) { 455 if (PStatus != NULL) { 456 int i; 457 458 for (i = 0; ((PStatus[i] != NULL) && (ps == NULL)); i++) 459 if (SAME(PStatus[i]->printer->name, name)) 460 ps = PStatus[i]; 461 } 462 } else 463 ps = new_pstatus(NULL); 464 465 return (ps); 466 } 467 468 469 FSTATUS * 470 search_fstatus(register char *name) 471 { 472 FSTATUS *ps = NULL; 473 474 if (name != NULL) { 475 if (FStatus != NULL) { 476 int i; 477 478 for (i = 0; ((FStatus[i] != NULL) && (ps == NULL)); i++) 479 if (SAME(FStatus[i]->form->name, name)) 480 ps = FStatus[i]; 481 } 482 } else 483 ps = new_fstatus(NULL); 484 485 return (ps); 486 } 487 488 FSTATUS * 489 search_fptable(register char *paper) 490 { 491 FSTATUS *ps = NULL; 492 int i; 493 494 if (FStatus != NULL) { 495 for (i = 0; ((FStatus[i] != NULL) && (ps == NULL)); i++) 496 if (SAME(FStatus[i]->form->paper, paper)) { 497 if (ps->form->isDefault) 498 ps = FStatus[i]; 499 } 500 } 501 502 return (ps); 503 } 504 505 CSTATUS * 506 search_cstatus(register char *name) 507 { 508 CSTATUS *ps = NULL; 509 510 if (name != NULL) { 511 if (CStatus != NULL) { 512 int i; 513 514 for (i = 0; ((CStatus[i] != NULL) && (ps == NULL)); i++) 515 if (SAME(CStatus[i]->class->name, name)) 516 ps = CStatus[i]; 517 } 518 } else 519 ps = new_cstatus(NULL); 520 521 return (ps); 522 } 523 524 PWSTATUS * 525 search_pwstatus(register char *name) 526 { 527 PWSTATUS *ps = NULL; 528 529 if (name != NULL) { 530 if (PWStatus != NULL) { 531 int i; 532 533 for (i = 0; ((PWStatus[i] != NULL) && (ps == NULL)); i++) 534 if (SAME(PWStatus[i]->pwheel->name, name)) 535 ps = PWStatus[i]; 536 } 537 } else 538 ps = new_pwstatus(NULL); 539 540 return (ps); 541 } 542 543 544 /** 545 ** load_str() - LOAD STRING WHERE ALLOC'D STRING MAY BE 546 ** unload_str() - REMOVE POSSIBLE ALLOC'D STRING 547 **/ 548 549 void 550 load_str(char **pdst, char *src) 551 { 552 if (*pdst) 553 Free (*pdst); 554 *pdst = Strdup(src); 555 return; 556 } 557 558 void 559 unload_str(char **pdst) 560 { 561 if (*pdst) 562 Free (*pdst); 563 *pdst = 0; 564 return; 565 } 566 567 /** 568 ** unload_list() - REMOVE POSSIBLE ALLOC'D LIST 569 **/ 570 571 void 572 unload_list(char ***plist) 573 { 574 if (*plist) 575 freelist (*plist); 576 *plist = 0; 577 return; 578 } 579 580 /** 581 ** load_sdn() - LOAD STRING WITH ASCII VERSION OF SCALED DECIMAL NUMBER 582 **/ 583 584 void 585 load_sdn(char **p, SCALED sdn) 586 { 587 if (!p) 588 return; 589 590 if (*p) 591 Free (*p); 592 *p = 0; 593 594 if (sdn.val <= 0 || 999999 < sdn.val) 595 return; 596 597 *p = Malloc(sizeof("999999.999x")); 598 sprintf ( 599 *p, 600 "%.3f%s", 601 sdn.val, 602 (sdn.sc == 'c'? "c" : (sdn.sc == 'i'? "i" : "")) 603 ); 604 605 return; 606 } 607 608 /** 609 ** Getform() - EASIER INTERFACE TO "getform()" 610 **/ 611 612 _FORM * 613 Getform(char *form) 614 { 615 _FORM *_form; 616 617 FORM formbuf; 618 619 FALERT alertbuf; 620 621 int ret; 622 623 624 while ( 625 (ret = getform(form, &formbuf, &alertbuf, (FILE **)0)) == -1 626 && errno == EINTR 627 ) 628 ; 629 if (ret == -1) 630 return (0); 631 632 _form = calloc(1, sizeof (*_form)); 633 _form->plen = formbuf.plen; 634 _form->pwid = formbuf.pwid; 635 _form->lpi = formbuf.lpi; 636 _form->cpi = formbuf.cpi; 637 _form->np = formbuf.np; 638 _form->chset = formbuf.chset; 639 _form->mandatory = formbuf.mandatory; 640 _form->rcolor = formbuf.rcolor; 641 _form->comment = formbuf.comment; 642 _form->conttype = formbuf.conttype; 643 _form->name = formbuf.name; 644 _form->paper = formbuf.paper; 645 _form->isDefault = formbuf.isDefault; 646 647 if ((_form->alert.shcmd = alertbuf.shcmd) != NULL) { 648 _form->alert.Q = alertbuf.Q; 649 _form->alert.W = alertbuf.W; 650 } else { 651 _form->alert.Q = 0; 652 _form->alert.W = 0; 653 } 654 655 return (_form); 656 } 657 658 /** 659 ** Getprinter() 660 ** Getrequest() 661 ** Getuser() 662 ** Getclass() 663 ** Getpwheel() 664 ** Getsecure() 665 ** Loadfilters() 666 **/ 667 668 PRINTER * 669 Getprinter(char *name) 670 { 671 register PRINTER *ret; 672 673 while (!(ret = getprinter(name)) && errno == EINTR) 674 ; 675 return (ret); 676 } 677 678 REQUEST * 679 Getrequest(char *file) 680 { 681 register REQUEST *ret; 682 683 while (!(ret = getrequest(file)) && errno == EINTR) 684 ; 685 return (ret); 686 } 687 688 USER * 689 Getuser(char *name) 690 { 691 register USER *ret; 692 693 while (!(ret = getuser(name)) && errno == EINTR) 694 ; 695 return (ret); 696 } 697 698 CLASS * 699 Getclass(char *name) 700 { 701 register CLASS *ret; 702 703 while (!(ret = getclass(name)) && errno == EINTR) 704 ; 705 return (ret); 706 } 707 708 PWHEEL * 709 Getpwheel(char *name) 710 { 711 register PWHEEL *ret; 712 713 while (!(ret = getpwheel(name)) && errno == EINTR) 714 ; 715 return (ret); 716 } 717 718 SECURE * 719 Getsecure(char *file) 720 { 721 register SECURE *ret; 722 723 while (!(ret = getsecure(file)) && errno == EINTR) 724 ; 725 return ((SECURE *) ret); 726 } 727 728 729 int 730 Loadfilters(char *file) 731 { 732 register int ret; 733 734 while ((ret = loadfilters(file)) == -1 && errno == EINTR) 735 ; 736 return (ret); 737 } 738 739 /** 740 ** free_form() - FREE MEMORY ALLOCATED FOR _FORM STRUCTURE 741 **/ 742 743 void 744 free_form(register _FORM *pf) 745 { 746 if (!pf) 747 return; 748 if (pf->chset) 749 Free (pf->chset); 750 if (pf->rcolor) 751 Free (pf->rcolor); 752 if (pf->comment) 753 Free (pf->comment); 754 if (pf->conttype) 755 Free (pf->conttype); 756 if (pf->name) 757 Free (pf->name); 758 if (pf->paper) 759 Free (pf->paper); 760 pf->name = 0; 761 if (pf->alert.shcmd) 762 Free (pf->alert.shcmd); 763 return; 764 } 765 766 /** 767 ** getreqno() - GET NUMBER PART OF REQUEST ID 768 **/ 769 770 char * 771 getreqno(char *req_id) 772 { 773 register char *cp; 774 775 776 if (!(cp = strrchr(req_id, '-'))) 777 cp = req_id; 778 else 779 cp++; 780 return (cp); 781 } 782 783 /* Putsecure(): Insurance for writing out the secure request file. 784 * input: char ptr to name of the request file, 785 * ptr to the SECURE structure to be written. 786 * ouput: 0 if successful, -1 otherwise. 787 * 788 * Description: 789 * The normal call to putsecure() is woefully lacking. 790 * The bottom line here is that there 791 * is no way to make sure that the file has been written out 792 * as expected. This can cause rude behaviour later on. 793 * 794 * This routine calls putsecure(), and then does a getsecure(). 795 * The results are compared to the original structure. If the 796 * info obtained by getsecure() doesn't match, we retry a few 797 * times before giving up (presumably something is very seriously 798 * wrong at that point). 799 */ 800 801 802 int 803 Putsecure(char *file, SECURE *secbufp) 804 { 805 SECURE *pls; 806 int retries = 5; /* # of attempts */ 807 int status; /* 0 = success, nonzero otherwise */ 808 809 810 while (retries--) { 811 status = 1; /* assume the worst, hope for the best */ 812 if (putsecure(file, secbufp) == -1) { 813 rmsecure(file); 814 continue; 815 } 816 817 if ((pls = getsecure(file)) == (SECURE *) NULL) { 818 rmsecure(file); 819 status = 2; 820 continue; 821 } 822 823 /* now compare each field */ 824 825 /* 826 * A comparison is only valid if secbufp and pls point to 827 * different locations. In reality getsecure() will have 828 * already been called, allocating the same STATIC memory 829 * location to both structures making the following compare 830 * meaningless. 831 * Therefore test for this condition to prevent us from 832 * calling freesecure which will destroy uid and 833 * req_id fields in the strucure 834 */ 835 836 status = 0; 837 if (secbufp != pls) { 838 if (strcmp(pls->req_id, secbufp->req_id) != 0) { 839 rmsecure(file); 840 status = 3; 841 continue; 842 } 843 844 if (pls->uid != secbufp->uid) { 845 rmsecure(file); 846 status = 4; 847 continue; 848 } 849 850 if (strcmp(pls->user, secbufp->user) != 0) { 851 rmsecure(file); 852 status = 5; 853 continue; 854 } 855 856 if (pls->gid != secbufp->gid) { 857 rmsecure(file); 858 status = 6; 859 continue; 860 } 861 862 if (pls->size != secbufp->size) { 863 rmsecure(file); 864 status = 7; 865 continue; 866 } 867 868 if (pls->date != secbufp->date) { 869 rmsecure(file); 870 status = 8; 871 continue; 872 } 873 874 freesecure(pls); 875 } 876 break; 877 } 878 879 if (status != 0) { 880 note("Putsecure failed, status=%d\n", status); 881 return -1; 882 } 883 884 return 0; 885 } 886 887 void GetRequestFiles(REQUEST *req, char *buffer, int length) 888 { 889 char buf[BUFSIZ]; 890 891 memset(buf, 0, sizeof(buf)); 892 893 if (req->title) { 894 char *r = req->title; 895 char *ptr = buf; 896 897 while ( *r && strncmp(r,"\\n",2)) { 898 *ptr++ = *r++; 899 } 900 } else if (req->file_list) 901 strlcpy(buf, *req->file_list, sizeof (buf)); 902 903 if (*buf == NULL || !strncmp(buf, SPOOLDIR, sizeof(SPOOLDIR)-1)) 904 strcpy(buf, "<File name not available>"); 905 906 if (strlen(buf) > (size_t) 24) { 907 char *r; 908 909 if (r = strrchr(buf, '/')) 910 r++; 911 else 912 r = buf; 913 914 snprintf(buffer, length, "%-.24s", r); 915 } else 916 strlcpy(buffer, buf, length); 917 return; 918 } 919 920 921 /** 922 ** _Malloc() 923 ** _Realloc() 924 ** _Calloc() 925 ** _Strdup() 926 ** _Free() 927 **/ 928 929 void (*lp_alloc_fail_handler)( void ) = 0; 930 931 typedef void *alloc_type; 932 933 alloc_type 934 _Malloc(size_t size, const char *file, int line) 935 { 936 alloc_type ret; 937 938 ret = malloc(size); 939 if (!ret) { 940 if (lp_alloc_fail_handler) 941 (*lp_alloc_fail_handler)(); 942 errno = ENOMEM; 943 } 944 return (ret); 945 } 946 947 alloc_type 948 _Realloc(void *ptr, size_t size, const char *file, int line) 949 { 950 alloc_type ret = realloc(ptr, size); 951 952 if (!ret) { 953 if (lp_alloc_fail_handler) 954 (*lp_alloc_fail_handler)(); 955 errno = ENOMEM; 956 } 957 return (ret); 958 } 959 960 alloc_type 961 _Calloc(size_t nelem, size_t elsize, const char *file, int line) 962 { 963 alloc_type ret = calloc(nelem, elsize); 964 965 if (!ret) { 966 if (lp_alloc_fail_handler) 967 (*lp_alloc_fail_handler)(); 968 errno = ENOMEM; 969 } 970 return (ret); 971 } 972 973 char * 974 _Strdup(const char *s, const char *file, int line) 975 { 976 char * ret; 977 978 if (!s) 979 return( (char *) 0); 980 981 ret = strdup(s); 982 983 if (!ret) { 984 if (lp_alloc_fail_handler) 985 (*lp_alloc_fail_handler)(); 986 errno = ENOMEM; 987 } 988 return (ret); 989 } 990 991 void 992 _Free(void *ptr, const char *file, int line) 993 { 994 free (ptr); 995 return; 996 } 997