xref: /illumos-gate/usr/src/cmd/lp/cmd/lpsched/fncs.c (revision 03100a6332bd4edc7a53091fcf7c9a7131bcdaa7)
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