Home | History | Annotate | Download | only in lpsched
      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