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