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