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 "stdio.h"
33 #include "string.h"
34 #include "errno.h"
35 #include "sys/types.h"
36 #include "stdlib.h"
37 
38 #include "lp.h"
39 #include "requests.h"
40 
41 extern struct {
42 	char			*v;
43 	short			len;
44 }			reqheadings[];
45 
46 /**
47  ** getrequest() - EXTRACT REQUEST STRUCTURE FROM DISK FILE
48  **/
49 
50 REQUEST *
51 #if	defined(__STDC__)
getrequest(char * file)52 getrequest (
53 	char *			file
54 )
55 #else
56 getrequest (file)
57 	char			*file;
58 #endif
59 {
60 	REQUEST		*reqp;
61 
62 	char			buf[BUFSIZ],
63 				*path,
64 				*p;
65 
66 	int fd;
67 
68 	int			fld;
69 
70 
71 	/*
72 	 * Full pathname? If so the file must lie in LP's
73 	 * regular temporary directory.
74 	 */
75 	if (*file == '/') {
76 		if (!STRNEQU(file, Lp_Tmp, strlen(Lp_Tmp))) {
77 			errno = EINVAL;
78 			return (0);
79 		}
80 		path = Strdup(file);
81 
82 	/*
83 	 * A relative pathname (such as system/name)?
84 	 * If so we'll locate it under LP's regular temporary
85 	 * directory.
86 	 */
87 	} else if (strchr(file, '/')) {
88 		if (!(path = makepath(Lp_Tmp, file, (char *)0)))
89 			return (0);
90 
91 	/*
92 	 * It must be a simple name. Locate this under the
93 	 * special temporary directory that is linked to the
94 	 * regular place for the local system.
95 	 */
96 	} else if (!(path = makepath(Lp_Temp, file, (char *)0)))
97 		return (0);
98 
99 
100 	if ((fd = open_locked(path, "r", 0)) < 0) {
101 		Free (path);
102 		return (0);
103 	}
104 	Free (path);
105 
106 	reqp = calloc(sizeof (*reqp), 1);
107 	reqp->copies		= 1;
108 	reqp->priority		= -1;
109 
110 	errno = 0;
111 	while (fdgets(buf, BUFSIZ, fd)) {
112 
113 		buf[strlen(buf) - 1] = 0;
114 
115 		for (fld = 0; fld < RQ_MAX; fld++)
116 			if (
117 				reqheadings[fld].v
118 			     && reqheadings[fld].len
119 			     && STRNEQU(
120 					buf,
121 					reqheadings[fld].v,
122 					reqheadings[fld].len
123 				)
124 			) {
125 				p = buf + reqheadings[fld].len;
126 				break;
127 			}
128 
129 		/*
130 		 * To allow future extensions to not impact applications
131 		 * using old versions of this routine, ignore strange
132 		 * fields.
133 		 */
134 		if (fld >= RQ_MAX)
135 			continue;
136 
137 		switch (fld) {
138 
139 		case RQ_COPIES:
140 			reqp->copies = atoi(p);
141 			break;
142 
143 		case RQ_DEST:
144 			reqp->destination = Strdup(p);
145 			break;
146 
147 		case RQ_FILE:
148 			appendlist (&reqp->file_list, p);
149 			break;
150 
151 		case RQ_FORM:
152 			if (!STREQU(p, NAME_ANY))
153 				reqp->form = Strdup(p);
154 			break;
155 
156 		case RQ_HANDL:
157 			if (STREQU(p, NAME_RESUME))
158 				reqp->actions |= ACT_RESUME;
159 			else if (STREQU(p, NAME_HOLD))
160 				reqp->actions |= ACT_HOLD;
161 			else if (STREQU(p, NAME_IMMEDIATE))
162 				reqp->actions |= ACT_IMMEDIATE;
163 			break;
164 
165 		case RQ_NOTIFY:
166 			if (STREQU(p, "M"))
167 				reqp->actions |= ACT_MAIL;
168 			else if (STREQU(p, "W"))
169 				reqp->actions |= ACT_WRITE;
170 			else if (STREQU(p, "N"))
171 				reqp->actions |= ACT_NOTIFY;
172 			else
173 				reqp->alert = Strdup(p);
174 			break;
175 
176 		case RQ_OPTS:
177 			reqp->options = Strdup(p);
178 			break;
179 
180 		case RQ_PRIOR:
181 			reqp->priority = atoi(p);
182 			break;
183 
184 		case RQ_PAGES:
185 			reqp->pages = Strdup(p);
186 			break;
187 
188 		case RQ_CHARS:
189 			if (!STREQU(p, NAME_ANY))
190 				reqp->charset = Strdup(p);
191 			break;
192 
193 		case RQ_TITLE:
194 			reqp->title = Strdup(p);
195 			break;
196 
197 		case RQ_MODES:
198 			reqp->modes = Strdup(p);
199 			break;
200 
201 		case RQ_TYPE:
202 			reqp->input_type = Strdup(p);
203 			break;
204 
205 		case RQ_USER:
206 			reqp->user = Strdup(p);
207 			break;
208 
209 		case RQ_RAW:
210 			reqp->actions |= ACT_RAW;
211 			break;
212 
213 		case RQ_FAST:
214 			reqp->actions |= ACT_FAST;
215 			break;
216 
217 		case RQ_STAT:
218 			reqp->outcome = (ushort)strtol(p, (char **)0, 16);
219 			break;
220 
221 		}
222 
223 	}
224 	if (errno != 0) {
225 		int			save_errno = errno;
226 
227 		close(fd);
228 		errno = save_errno;
229 		return (0);
230 	}
231 	close(fd);
232 
233 	/*
234 	 * Now go through the structure and see if we have
235 	 * anything strange.
236 	 */
237 	if (
238 		reqp->copies <= 0
239 	     || !reqp->file_list || !*(reqp->file_list)
240 	     || reqp->priority < -1 || 39 < reqp->priority
241 	     || STREQU(reqp->input_type, NAME_ANY)
242 	     || STREQU(reqp->input_type, NAME_TERMINFO)
243 	) {
244 		freerequest (reqp);
245 		errno = EBADF;
246 		return (0);
247 	}
248 
249 	/*
250 	 * Guarantee some return values won't be null or empty.
251 	 */
252 	if (!reqp->destination || !*reqp->destination) {
253 		if (reqp->destination)
254 			Free (reqp->destination);
255 		reqp->destination = Strdup(NAME_ANY);
256 	}
257 	if (!reqp->input_type || !*reqp->input_type) {
258 		if (reqp->input_type)
259 			Free (reqp->input_type);
260 		reqp->input_type = Strdup(NAME_SIMPLE);
261 	}
262 
263 	return (reqp);
264 }
265