xref: /illumos-gate/usr/src/cmd/lp/cmd/lpsched/fncs.c (revision 7c478bd9)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 
26 /*
27  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
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 /**
45  ** walk_ptable() - WALK PRINTER TABLE, RETURNING ACTIVE ENTRIES
46  ** walk_ftable() - WALK FORMS TABLE, RETURNING ACTIVE ENTRIES
47  ** walk_ctable() - WALK CLASS TABLE, RETURNING ACTIVE ENTRIES
48  ** walk_pwtable() - WALK PRINT WHEEL TABLE, RETURNING ACTIVE ENTRIES
49  **/
50 
51 
52 PSTATUS *
53 walk_ptable(int start)
54 {
55 	static PSTATUS		*psend,
56 				*ps = 0;
57 
58 	if (start || !ps) {
59 		ps = PStatus;
60 		psend = PStatus + PT_Size;
61 	}
62 
63 	while (ps < psend && !ps->printer->name)
64 		ps++;
65 
66 	if (ps >= psend)
67 		return (ps = 0);
68 	else
69 		return (ps++);
70 }
71 
72 FSTATUS *
73 walk_ftable(int start)
74 {
75 	static FSTATUS		*psend,
76 				*ps = 0;
77 
78 	if (start || !ps) {
79 		ps = FStatus;
80 		psend = FStatus + FT_Size;
81 	}
82 
83 	while (ps < psend && !ps->form->name)
84 		ps++;
85 
86 	if (ps >= psend)
87 		return (ps = 0);
88 	else
89 		return (ps++);
90 }
91 
92 CSTATUS *
93 walk_ctable (int start)
94 {
95 	static CSTATUS		*psend,
96 				*ps = 0;
97 
98 	if (start || !ps) {
99 		ps = CStatus;
100 		psend = CStatus + CT_Size;
101 	}
102 
103 	while (ps < psend && !ps->class->name)
104 		ps++;
105 
106 	if (ps >= psend)
107 		return (ps = 0);
108 	else
109 		return (ps++);
110 }
111 
112 PWSTATUS *
113 walk_pwtable(int start)
114 {
115 	static PWSTATUS		*psend,
116 				*ps = 0;
117 
118 	if (start || !ps) {
119 		ps = PWStatus;
120 		psend = PWStatus + PWT_Size;
121 	}
122 
123 	while (ps < psend && !ps->pwheel->name)
124 		ps++;
125 
126 	if (ps >= psend)
127 		return (ps = 0);
128 	else
129 		return (ps++);
130 }
131 
132 
133 /**
134  ** search_ptable() - SEARCH PRINTER TABLE
135  ** search_ftable() - SEARCH FORMS TABLE
136  ** search_ctable() - SEARCH CLASS TABLE
137  ** search_pwtable() - SEARCH PRINT WHEEL TABLE
138  **/
139 
140 PSTATUS *
141 search_ptable(register char *name)
142 {
143 	register PSTATUS	*ps,
144 				*psend;
145 
146 	for (
147 		ps = & PStatus[0], psend = & PStatus[PT_Size];
148 		ps < psend && !SAME(ps->printer->name, name);
149 		ps++
150 	)
151 		;
152 
153 	if (ps >= psend)
154 		ps = 0;
155 
156 	return (ps);
157 }
158 
159 
160 FSTATUS *
161 search_ftable(register char *name)
162 {
163 	register FSTATUS	*ps, *psend;
164 
165 	for (ps = & FStatus[0], psend = & FStatus[FT_Size];
166 	    ps < psend && !SAME(ps->form->name, name); ps++);
167 
168 	if (ps >= psend)
169 		ps = 0;
170 
171 	return (ps);
172 }
173 
174 FSTATUS *
175 search_fptable(register char *paper)
176 {
177 	register FSTATUS	*ps,*cand, *psend;
178 
179 	cand = NULL;
180 	for (ps = & FStatus[0], psend = & FStatus[FT_Size]; ps < psend; ps++)
181 		if (SAME(ps->form->paper, paper)) {
182 			if (ps->form->isDefault) {
183 				cand = ps;
184 				break;
185 			} else if (!cand)
186 				cand = ps;
187 		}
188 
189 	return (cand);
190 }
191 
192 CSTATUS *
193 search_ctable(register char *name)
194 {
195 	register CSTATUS	*ps,
196 				*psend;
197 
198 	for (
199 		ps = & CStatus[0], psend = & CStatus[CT_Size];
200 		ps < psend && !SAME(ps->class->name, name);
201 		ps++
202 	)
203 		;
204 
205 	if (ps >= psend)
206 		ps = 0;
207 
208 	return (ps);
209 }
210 
211 PWSTATUS *
212 search_pwtable(register char *name)
213 {
214 	register PWSTATUS	*ps,
215 				*psend;
216 
217 	for (
218 		ps = & PWStatus[0], psend = & PWStatus[PWT_Size];
219 		ps < psend && !SAME(ps->pwheel->name, name);
220 		ps++
221 	)
222 		;
223 
224 	if (ps >= psend)
225 		ps = 0;
226 
227 	return (ps);
228 }
229 
230 
231 /**
232  ** load_str() - LOAD STRING WHERE ALLOC'D STRING MAY BE
233  ** unload_str() - REMOVE POSSIBLE ALLOC'D STRING
234  **/
235 
236 void
237 load_str(char **pdst, char *src)
238 {
239 	if (*pdst)
240 		Free (*pdst);
241 	*pdst = Strdup(src);
242 	return;
243 }
244 
245 void
246 unload_str(char **pdst)
247 {
248 	if (*pdst)
249 		Free (*pdst);
250 	*pdst = 0;
251 	return;
252 }
253 
254 /**
255  ** unload_list() - REMOVE POSSIBLE ALLOC'D LIST
256  **/
257 
258 void
259 unload_list(char ***plist)
260 {
261 	if (*plist)
262 		freelist (*plist);
263 	*plist = 0;
264 	return;
265 }
266 
267 /**
268  ** load_sdn() - LOAD STRING WITH ASCII VERSION OF SCALED DECIMAL NUMBER
269  **/
270 
271 void
272 load_sdn(char **p, SCALED sdn)
273 {
274 	if (!p)
275 		return;
276 
277 	if (*p)
278 		Free (*p);
279 	*p = 0;
280 
281 	if (sdn.val <= 0 || 999999 < sdn.val)
282 		return;
283 
284 	*p = Malloc(sizeof("999999.999x"));
285 	sprintf (
286 		*p,
287 		"%.3f%s",
288 		sdn.val,
289 		(sdn.sc == 'c'? "c" : (sdn.sc == 'i'? "i" : ""))
290 	);
291 
292 	return;
293 }
294 
295 /**
296  ** Getform() - EASIER INTERFACE TO "getform()"
297  **/
298 
299 _FORM *
300 Getform(char *form)
301 {
302 	static _FORM		_formbuf;
303 
304 	FORM			formbuf;
305 
306 	FALERT			alertbuf;
307 
308 	int			ret;
309 
310 
311 	while (
312 		(ret = getform(form, &formbuf, &alertbuf, (FILE **)0)) == -1
313 	     && errno == EINTR
314 	)
315 		;
316 	if (ret == -1)
317 		return (0);
318 
319 	_formbuf.plen = formbuf.plen;
320 	_formbuf.pwid = formbuf.pwid;
321 	_formbuf.lpi = formbuf.lpi;
322 	_formbuf.cpi = formbuf.cpi;
323 	_formbuf.np = formbuf.np;
324 	_formbuf.chset = formbuf.chset;
325 	_formbuf.mandatory = formbuf.mandatory;
326 	_formbuf.rcolor = formbuf.rcolor;
327 	_formbuf.comment = formbuf.comment;
328 	_formbuf.conttype = formbuf.conttype;
329 	_formbuf.name = formbuf.name;
330 	_formbuf.paper = formbuf.paper;
331 	_formbuf.isDefault = formbuf.isDefault;
332 
333 	if ((_formbuf.alert.shcmd = alertbuf.shcmd) != NULL) {
334 		_formbuf.alert.Q = alertbuf.Q;
335 		_formbuf.alert.W = alertbuf.W;
336 	} else {
337 		_formbuf.alert.Q = 0;
338 		_formbuf.alert.W = 0;
339 	}
340 
341 	return (&_formbuf);
342 }
343 
344 /**
345  ** Getprinter()
346  ** Getrequest()
347  ** Getuser()
348  ** Getclass()
349  ** Getpwheel()
350  ** Getsecure()
351  ** Getsystem()
352  ** Loadfilters()
353  **/
354 
355 PRINTER *
356 Getprinter(char *name)
357 {
358 	register PRINTER	*ret;
359 
360 	while (!(ret = getprinter(name)) && errno == EINTR)
361 		;
362 	return (ret);
363 }
364 
365 REQUEST *
366 Getrequest(char *file)
367 {
368 	register REQUEST	*ret;
369 
370 	while (!(ret = getrequest(file)) && errno == EINTR)
371 		;
372 	return (ret);
373 }
374 
375 USER *
376 Getuser(char *name)
377 {
378 	register USER		*ret;
379 
380 	while (!(ret = getuser(name)) && errno == EINTR)
381 		;
382 	return (ret);
383 }
384 
385 CLASS *
386 Getclass(char *name)
387 {
388 	register CLASS		*ret;
389 
390 	while (!(ret = getclass(name)) && errno == EINTR)
391 		;
392 	return (ret);
393 }
394 
395 PWHEEL *
396 Getpwheel(char *name)
397 {
398 	register PWHEEL		*ret;
399 
400 	while (!(ret = getpwheel(name)) && errno == EINTR)
401 		;
402 	return (ret);
403 }
404 
405 SECURE *
406 Getsecure(char *file)
407 {
408 	register SECURE		*ret;
409 
410 	while (!(ret = getsecure(file)) && errno == EINTR)
411 		;
412         return ((SECURE *) ret);
413 }
414 
415 
416 int
417 Loadfilters(char *file)
418 {
419 	register int		ret;
420 
421 	while ((ret = loadfilters(file)) == -1 && errno == EINTR)
422 		;
423 	return (ret);
424 }
425 
426 /**
427  ** free_form() - FREE MEMORY ALLOCATED FOR _FORM STRUCTURE
428  **/
429 
430 void
431 free_form(register _FORM *pf)
432 {
433 	if (!pf)
434 		return;
435 	if (pf->chset)
436 		Free (pf->chset);
437 	if (pf->rcolor)
438 		Free (pf->rcolor);
439 	if (pf->comment)
440 		Free (pf->comment);
441 	if (pf->conttype)
442 		Free (pf->conttype);
443 	if (pf->name)
444 		Free (pf->name);
445 	if (pf->paper)
446 		Free (pf->paper);
447 	pf->name = 0;
448 	if (pf->alert.shcmd)
449 		Free (pf->alert.shcmd);
450 	return;
451 }
452 
453 /**
454  ** getreqno() - GET NUMBER PART OF REQUEST ID
455  **/
456 
457 char *
458 getreqno(char *req_id)
459 {
460 	register char		*cp;
461 
462 
463 	if (!(cp = strrchr(req_id, '-')))
464 		cp = req_id;
465 	else
466 		cp++;
467 	return (cp);
468 }
469 
470 /* Putsecure():	Insurance for writing out the secure request file.
471  *	input:	char ptr to name of the request file,
472  *		ptr to the SECURE structure to be written.
473  *	ouput:	0 if successful, -1 otherwise.
474  *
475  *	Description:
476  *		The normal call to putsecure() is woefully lacking.
477  *		The bottom line here is that there
478  *		is no way to make sure that the file has been written out
479  *		as expected. This can cause rude behaviour later on.
480  *
481  *		This routine calls putsecure(), and then does a getsecure().
482  *		The results are compared to the original structure. If the
483  *		info obtained by getsecure() doesn't match, we retry a few
484  *		times before giving up (presumably something is very seriously
485  *		wrong at that point).
486  */
487 
488 
489 int
490 Putsecure(char *file, SECURE *secbufp)
491 {
492 	SECURE	*pls;
493 	int	retries = 5;	/* # of attempts			*/
494 	int	status;		/*  0 = success, nonzero otherwise	*/
495 
496 
497 	while (retries--) {
498 		status = 1;	/* assume the worst, hope for the best	*/
499 		if (putsecure(file, secbufp) == -1) {
500 			rmsecure(file);
501 			continue;
502 		}
503 
504 		if ((pls = getsecure(file)) == (SECURE *) NULL) {
505 			rmsecure(file);
506 			status = 2;
507 			continue;
508 		}
509 
510 		/* now compare each field	*/
511 
512 		/*
513 		 * A comparison is only valid if secbufp and pls point to
514 		 * different locations.  In reality getsecure() will have
515 		 * already been called, allocating the same STATIC memory
516 		 * location to both structures making the following compare
517 		 * meaningless.
518 		 * Therefore test for this condition to prevent us from
519 		 * calling freesecure which will destroy uid, system and
520 		 * req_id fields in the strucure
521 		 */
522 
523 		status = 0;
524 		if (secbufp != pls) {
525 			if (strcmp(pls->req_id, secbufp->req_id) != 0) {
526 				rmsecure(file);
527 				status = 3;
528 				continue;
529 			}
530 
531 			if (pls->uid != secbufp->uid) {
532 				rmsecure(file);
533 				status = 4;
534 				continue;
535 			}
536 
537 			if (strcmp(pls->user, secbufp->user) != 0) {
538 				rmsecure(file);
539 				status = 5;
540 				continue;
541 			}
542 
543 			if (pls->gid != secbufp->gid) {
544 				rmsecure(file);
545 				status = 6;
546 				continue;
547 			}
548 
549 			if (pls->size != secbufp->size) {
550 				rmsecure(file);
551 				status = 7;
552 				continue;
553 			}
554 
555 			if (pls->date != secbufp->date) {
556 				rmsecure(file);
557 				status = 8;
558 				continue;
559 			}
560 
561 			if (strcmp(pls->system, secbufp->system) != 0) {
562 				rmsecure(file);
563 				status = 9;
564 				continue;
565 			}
566 			freesecure(pls);
567 		}
568 		break;
569 	}
570 
571 	if (status != 0) {
572 		note("Putsecure failed, status=%d\n", status);
573 		return -1;
574 	}
575 
576 	return 0;
577 }
578 
579 void GetRequestFiles(REQUEST *req, char *buffer, int length)
580 {
581 	char buf[BUFSIZ];
582 
583 	memset(buf, 0, sizeof(buf));
584 
585 	if (req->title) {
586 		char *r = req->title;
587 		char *ptr = buf;
588 
589 		while ( *r && strncmp(r,"\\n",2)) {
590 		  	*ptr++ = *r++;
591 		}
592 	} else if (req->file_list)
593 		strlcpy(buf, *req->file_list, sizeof (buf));
594 
595 	if (*buf == NULL || !strncmp(buf, SPOOLDIR, sizeof(SPOOLDIR)-1))
596 		strcpy(buf, "<File name not available>");
597 
598 	if (strlen(buf) > (size_t) 24) {
599 		char *r;
600 
601 		if (r = strrchr(buf, '/'))
602 			r++;
603 		else
604 			r = buf;
605 
606 		snprintf(buffer, length, "%-.24s", r);
607 	} else
608 		strlcpy(buffer, buf, length);
609 	return;
610 }
611 
612 
613 /**
614  ** _Malloc()
615  ** _Realloc()
616  ** _Calloc()
617  ** _Strdup()
618  ** _Free()
619  **/
620 
621 void			(*lp_alloc_fail_handler)( void ) = 0;
622 
623 typedef void *alloc_type;
624 extern etext;
625 
626 alloc_type
627 _Malloc(size_t size, const char *file, int line)
628 {
629 	alloc_type		ret;
630 
631 	ret = malloc(size);
632 	if (!ret) {
633 		if (lp_alloc_fail_handler)
634 			(*lp_alloc_fail_handler)();
635 		errno = ENOMEM;
636 	}
637 	return (ret);
638 }
639 
640 alloc_type
641 _Realloc(void *ptr, size_t size, const char *file, int line)
642 {
643 	alloc_type		ret	= realloc(ptr, size);
644 
645 	if (!ret) {
646 		if (lp_alloc_fail_handler)
647 			(*lp_alloc_fail_handler)();
648 		errno = ENOMEM;
649 	}
650 	return (ret);
651 }
652 
653 alloc_type
654 _Calloc(size_t nelem, size_t elsize, const char *file, int line)
655 {
656 	alloc_type		ret	= calloc(nelem, elsize);
657 
658 	if (!ret) {
659 		if (lp_alloc_fail_handler)
660 			(*lp_alloc_fail_handler)();
661 		errno = ENOMEM;
662 	}
663 	return (ret);
664 }
665 
666 char *
667 _Strdup(const char *s, const char *file, int line)
668 {
669 	char *			ret;
670 
671 	if (!s)
672 		return( (char *) 0);
673 
674 	ret = strdup(s);
675 
676 	if (!ret) {
677 		if (lp_alloc_fail_handler)
678 			(*lp_alloc_fail_handler)();
679 		errno = ENOMEM;
680 	}
681 	return (ret);
682 }
683 
684 void
685 _Free(void *ptr, const char *file, int line)
686 {
687 	free (ptr);
688 	return;
689 }
690