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  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27 /*	  All Rights Reserved  	*/
28 
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
32 
33 #include "stdio.h"
34 #include "string.h"
35 #include "errno.h"
36 #include "sys/types.h"
37 #include "sys/utsname.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  ** putrequest() - WRITE REQUEST STRUCTURE TO DISK FILE
50  **/
51 
52 int
53 #if	defined(__STDC__)
putrequest(char * file,REQUEST * reqbufp)54 putrequest (
55 	char *			file,
56 	REQUEST *		reqbufp
57 )
58 #else
59 putrequest (file, reqbufp)
60 	char			*file;
61 	REQUEST			*reqbufp;
62 #endif
63 {
64 	char			**pp,
65 				*path;
66 
67 	int fd;
68 
69 	int			fld;
70 
71 	/*
72 	 * First go through the structure and see if we have
73 	 * anything strange.
74 	 */
75 	if (
76 		reqbufp->copies <= 0
77 	     || !(reqbufp->destination)
78 	     || !reqbufp->file_list || !*(reqbufp->file_list)
79 	     || (reqbufp->actions & (ACT_MAIL|ACT_WRITE))
80 			&& (reqbufp->alert && *(reqbufp->alert))
81 	     || reqbufp->priority < -1 || 39 < reqbufp->priority
82 	) {
83 		errno = EINVAL;
84 		return (-1);
85 	}
86 
87 	/*
88 	 * Now open the file and write out the request.
89 	 */
90 
91 	/*
92 	 * Full pathname? If so the file must lie in LP's
93 	 * regular temporary directory.
94 	 */
95 	if (*file == '/') {
96 		if (!STRNEQU(file, Lp_Tmp, strlen(Lp_Tmp))) {
97 			errno = EINVAL;
98 			return (-1);
99 		}
100 		path = Strdup(file);
101 
102 	/*
103 	 * A relative pathname (such as system/name)?
104 	 * If so we'll locate it under LP's regular temporary
105 	 * directory.
106 	 */
107 	} else if (strchr(file, '/')) {
108 		if (!(path = makepath(Lp_Tmp, file, (char *)0)))
109 			return (-1);
110 
111 	/*
112 	 * If must be a simple name. Locate this under the
113 	 * special temporary directory that is linked to the
114 	 * regular place for the local system.
115 	 */
116 	} else if (!(path = makepath(Lp_Temp, file, (char *)0)))
117 		return (-1);
118 
119 	if ((fd = open_locked(path, "w", MODE_NOREAD)) < 0) {
120 		Free (path);
121 		return (-1);
122 	}
123 	Free (path);
124 
125 	for (fld = 0; fld < RQ_MAX; fld++)  switch (fld) {
126 
127 #define HEAD	reqheadings[fld].v
128 
129 	case RQ_COPIES:
130 		(void)fdprintf(fd, "%s%d\n", HEAD, reqbufp->copies);
131 		break;
132 
133 	case RQ_DEST:
134 		(void)fdprintf(fd, "%s%s\n", HEAD, reqbufp->destination);
135 		break;
136 
137 	case RQ_FILE:
138 		for (pp = reqbufp->file_list; *pp; pp++)
139 			(void)fdprintf(fd, "%s%s\n", HEAD, *pp);
140 		break;
141 
142 	case RQ_FORM:
143 		if (reqbufp->form)
144 			(void)fdprintf(fd, "%s%s\n", HEAD, reqbufp->form);
145 		break;
146 
147 	case RQ_HANDL:
148 		if ((reqbufp->actions & ACT_SPECIAL) == ACT_IMMEDIATE)
149 			(void)fdprintf(fd, "%s%s\n", HEAD, NAME_IMMEDIATE);
150 		else if ((reqbufp->actions & ACT_SPECIAL) == ACT_RESUME)
151 			(void)fdprintf(fd, "%s%s\n", HEAD, NAME_RESUME);
152 		else if ((reqbufp->actions & ACT_SPECIAL) == ACT_HOLD)
153 			(void)fdprintf(fd, "%s%s\n", HEAD, NAME_HOLD);
154 		break;
155 
156 	case RQ_NOTIFY:
157 		if (reqbufp->actions & ACT_MAIL)
158 			(void)fdprintf(fd, "%sM\n", HEAD);
159 		else if (reqbufp->actions & ACT_WRITE)
160 			(void)fdprintf(fd, "%sW\n", HEAD);
161 		else if (reqbufp->actions & ACT_NOTIFY)
162 			(void)fdprintf(fd, "%sN\n", HEAD);
163 		else if (reqbufp->alert && *(reqbufp->alert))
164 			(void)fdprintf(fd, "%s%s\n", HEAD, reqbufp->alert);
165 		break;
166 
167 	case RQ_OPTS:
168 		if (reqbufp->options)
169 			(void)fdprintf(fd, "%s%s\n", HEAD, reqbufp->options);
170 		break;
171 
172 	case RQ_PRIOR:
173 		if (reqbufp->priority != -1)
174 			(void)fdprintf(fd, "%s%d\n", HEAD, reqbufp->priority);
175 		break;
176 
177 	case RQ_PAGES:
178 		if (reqbufp->pages)
179 			(void)fdprintf(fd, "%s%s\n", HEAD, reqbufp->pages);
180 		break;
181 
182 	case RQ_CHARS:
183 		if (reqbufp->charset)
184 			(void)fdprintf(fd, "%s%s\n", HEAD, reqbufp->charset);
185 		break;
186 
187 	case RQ_TITLE:
188 		if (reqbufp->title)
189 			(void)fdprintf(fd, "%s%s\n", HEAD, reqbufp->title);
190 		break;
191 
192 	case RQ_MODES:
193 		if (reqbufp->modes)
194 			(void)fdprintf(fd, "%s%s\n", HEAD, reqbufp->modes);
195 		break;
196 
197 	case RQ_TYPE:
198 		if (reqbufp->input_type)
199 			(void)fdprintf(fd, "%s%s\n", HEAD, reqbufp->input_type);
200 		break;
201 
202 	case RQ_USER:
203 		if (reqbufp->user)
204 			(void)fdprintf(fd, "%s%s\n", HEAD, reqbufp->user);
205 		break;
206 
207 	case RQ_RAW:
208 		if (reqbufp->actions & ACT_RAW)
209 			(void)fdprintf(fd, "%s\n", HEAD);
210 		break;
211 
212 	case RQ_FAST:
213 		if (reqbufp->actions & ACT_FAST)
214 			(void)fdprintf(fd, "%s\n", HEAD);
215 		break;
216 
217 	case RQ_STAT:
218 		(void)fdprintf(fd, "%s%#6.4x\n", HEAD, reqbufp->outcome);
219 		break;
220 
221 	}
222 
223 	close(fd);
224 	return (0);
225 }
226