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 }