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/*
23 * Copyright 1997 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
31#pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.14	*/
32/* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
33
34#include "stdio.h"
35#include "string.h"
36#include "errno.h"
37#include "sys/types.h"
38#include "stdlib.h"
39
40#include "lp.h"
41#include "form.h"
42
43/*
44 * getform() - EXTRACT FORM STRUCTURE FROM DISK FILE
45 *
46 * The FILE **align_fp doesn't need to be changed for scalability, because
47 * it is always NULL when getform is called by lpsched.
48 */
49int
50getform(char *name, FORM *formp, FALERT *alertp, FILE **align_fp)
51{
52	static long		lastdir		= -1;
53
54	int fd;
55
56	register char *		path;
57
58
59	if (!name || !*name) {
60		errno = EINVAL;
61		return (-1);
62	}
63
64	/*
65	 * Getting ``all''? If so, jump into the directory
66	 * wherever we left off.
67	 */
68	if (STREQU(NAME_ALL, name)) {
69		if (!(name = next_dir(Lp_A_Forms, &lastdir)))
70			return (-1);
71	} else
72		lastdir = -1;
73
74
75	/*
76	 * Get the form configuration information (?)
77	 */
78	if (formp) {
79		path = getformfile(name, DESCRIBE);
80		if (!path)
81			return (-1);
82		if ((fd = open_locked(path, "r", 0)) < 0) {
83			Free (path);
84			return (-1);
85		}
86		Free (path);
87
88		if (rdform(name, formp, fd, 0, (int *)0) == -1) {
89			close(fd);
90			return (-1);
91		}
92		close(fd);
93	}
94
95	/*
96	 * Get the alert information (?)
97	 */
98	if (alertp) {
99
100		FALERT *		pa = getalert(Lp_A_Forms, name);
101
102
103		/*
104		 * Don't fail if we can't read it because of access
105		 * permission UNLESS we're "root" or "lp"
106		 */
107		if (!pa) {
108
109			if (errno == ENOENT) {
110				alertp->shcmd = 0;
111				alertp->Q = alertp->W = -1;
112
113			} else if (errno == ENOTDIR) {
114				freeform (formp);
115				errno = ENOENT;	/* form doesn't exist */
116				return (-1);
117
118			} else if (
119				errno != EACCES
120			     || !getpid()		  /* we be root */
121			     || STREQU(getname(), LPUSER) /* we be lp   */
122			) {
123				freeform (formp);
124				return (-1);
125			}
126
127		} else
128			*alertp = *pa;
129	}
130
131	/*
132	 * Get the alignment pattern (?)
133	 */
134	if (align_fp) {
135		path = getformfile(name, ALIGN_PTRN);
136		if (!path) {
137			freeform (formp);
138			errno = ENOMEM;
139			return (-1);
140		}
141		if (
142			!(*align_fp = open_lpfile(path, "r", 0))
143		     && errno != ENOENT
144		) {
145			Free (path);
146			freeform (formp);
147			return (-1);
148		}
149		Free (path);
150	}
151
152	return (0);
153}
154