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