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
43extern struct {
44	char			*v;
45	short			len;
46}			reqheadings[];
47
48/**
49 ** putrequest() - WRITE REQUEST STRUCTURE TO DISK FILE
50 **/
51
52int
53#if	defined(__STDC__)
54putrequest (
55	char *			file,
56	REQUEST *		reqbufp
57)
58#else
59putrequest (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