10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*3125Sjacobs  * Common Development and Distribution License (the "License").
6*3125Sjacobs  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*3125Sjacobs 
220Sstevel@tonic-gate /*
23*3125Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate 
31*3125Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
320Sstevel@tonic-gate /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
330Sstevel@tonic-gate 
340Sstevel@tonic-gate #include "stdio.h"
350Sstevel@tonic-gate #include "string.h"
360Sstevel@tonic-gate #include "errno.h"
370Sstevel@tonic-gate #include "sys/types.h"
380Sstevel@tonic-gate #include "stdlib.h"
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #include "lp.h"
410Sstevel@tonic-gate #include "requests.h"
420Sstevel@tonic-gate 
430Sstevel@tonic-gate extern struct {
440Sstevel@tonic-gate 	char			*v;
450Sstevel@tonic-gate 	short			len;
460Sstevel@tonic-gate }			reqheadings[];
470Sstevel@tonic-gate 
480Sstevel@tonic-gate /**
490Sstevel@tonic-gate  ** getrequest() - EXTRACT REQUEST STRUCTURE FROM DISK FILE
500Sstevel@tonic-gate  **/
510Sstevel@tonic-gate 
520Sstevel@tonic-gate REQUEST *
530Sstevel@tonic-gate #if	defined(__STDC__)
540Sstevel@tonic-gate getrequest (
550Sstevel@tonic-gate 	char *			file
560Sstevel@tonic-gate )
570Sstevel@tonic-gate #else
580Sstevel@tonic-gate getrequest (file)
590Sstevel@tonic-gate 	char			*file;
600Sstevel@tonic-gate #endif
610Sstevel@tonic-gate {
62*3125Sjacobs 	REQUEST		*reqp;
630Sstevel@tonic-gate 
640Sstevel@tonic-gate 	char			buf[BUFSIZ],
650Sstevel@tonic-gate 				*path,
660Sstevel@tonic-gate 				*p;
670Sstevel@tonic-gate 
680Sstevel@tonic-gate 	int fd;
690Sstevel@tonic-gate 
700Sstevel@tonic-gate 	int			fld;
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 
730Sstevel@tonic-gate 	/*
740Sstevel@tonic-gate 	 * Full pathname? If so the file must lie in LP's
750Sstevel@tonic-gate 	 * regular temporary directory.
760Sstevel@tonic-gate 	 */
770Sstevel@tonic-gate 	if (*file == '/') {
780Sstevel@tonic-gate 		if (!STRNEQU(file, Lp_Tmp, strlen(Lp_Tmp))) {
790Sstevel@tonic-gate 			errno = EINVAL;
800Sstevel@tonic-gate 			return (0);
810Sstevel@tonic-gate 		}
820Sstevel@tonic-gate 		path = Strdup(file);
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	/*
850Sstevel@tonic-gate 	 * A relative pathname (such as system/name)?
860Sstevel@tonic-gate 	 * If so we'll locate it under LP's regular temporary
870Sstevel@tonic-gate 	 * directory.
880Sstevel@tonic-gate 	 */
890Sstevel@tonic-gate 	} else if (strchr(file, '/')) {
900Sstevel@tonic-gate 		if (!(path = makepath(Lp_Tmp, file, (char *)0)))
910Sstevel@tonic-gate 			return (0);
920Sstevel@tonic-gate 
930Sstevel@tonic-gate 	/*
940Sstevel@tonic-gate 	 * It must be a simple name. Locate this under the
950Sstevel@tonic-gate 	 * special temporary directory that is linked to the
960Sstevel@tonic-gate 	 * regular place for the local system.
970Sstevel@tonic-gate 	 */
980Sstevel@tonic-gate 	} else if (!(path = makepath(Lp_Temp, file, (char *)0)))
990Sstevel@tonic-gate 		return (0);
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	if ((fd = open_locked(path, "r", 0)) < 0) {
1030Sstevel@tonic-gate 		Free (path);
1040Sstevel@tonic-gate 		return (0);
1050Sstevel@tonic-gate 	}
1060Sstevel@tonic-gate 	Free (path);
1070Sstevel@tonic-gate 
108*3125Sjacobs 	reqp = calloc(sizeof (*reqp), 1);
109*3125Sjacobs 	reqp->copies		= 1;
110*3125Sjacobs 	reqp->priority		= -1;
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate 	errno = 0;
1130Sstevel@tonic-gate 	while (fdgets(buf, BUFSIZ, fd)) {
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 		buf[strlen(buf) - 1] = 0;
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 		for (fld = 0; fld < RQ_MAX; fld++)
1180Sstevel@tonic-gate 			if (
1190Sstevel@tonic-gate 				reqheadings[fld].v
1200Sstevel@tonic-gate 			     && reqheadings[fld].len
1210Sstevel@tonic-gate 			     && STRNEQU(
1220Sstevel@tonic-gate 					buf,
1230Sstevel@tonic-gate 					reqheadings[fld].v,
1240Sstevel@tonic-gate 					reqheadings[fld].len
1250Sstevel@tonic-gate 				)
1260Sstevel@tonic-gate 			) {
1270Sstevel@tonic-gate 				p = buf + reqheadings[fld].len;
1280Sstevel@tonic-gate 				break;
1290Sstevel@tonic-gate 			}
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 		/*
1320Sstevel@tonic-gate 		 * To allow future extensions to not impact applications
1330Sstevel@tonic-gate 		 * using old versions of this routine, ignore strange
1340Sstevel@tonic-gate 		 * fields.
1350Sstevel@tonic-gate 		 */
1360Sstevel@tonic-gate 		if (fld >= RQ_MAX)
1370Sstevel@tonic-gate 			continue;
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate 		switch (fld) {
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 		case RQ_COPIES:
142*3125Sjacobs 			reqp->copies = atoi(p);
1430Sstevel@tonic-gate 			break;
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 		case RQ_DEST:
146*3125Sjacobs 			reqp->destination = Strdup(p);
1470Sstevel@tonic-gate 			break;
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate 		case RQ_FILE:
150*3125Sjacobs 			appendlist (&reqp->file_list, p);
1510Sstevel@tonic-gate 			break;
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate 		case RQ_FORM:
1540Sstevel@tonic-gate 			if (!STREQU(p, NAME_ANY))
155*3125Sjacobs 				reqp->form = Strdup(p);
1560Sstevel@tonic-gate 			break;
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 		case RQ_HANDL:
1590Sstevel@tonic-gate 			if (STREQU(p, NAME_RESUME))
160*3125Sjacobs 				reqp->actions |= ACT_RESUME;
1610Sstevel@tonic-gate 			else if (STREQU(p, NAME_HOLD))
162*3125Sjacobs 				reqp->actions |= ACT_HOLD;
1630Sstevel@tonic-gate 			else if (STREQU(p, NAME_IMMEDIATE))
164*3125Sjacobs 				reqp->actions |= ACT_IMMEDIATE;
1650Sstevel@tonic-gate 			break;
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate 		case RQ_NOTIFY:
1680Sstevel@tonic-gate 			if (STREQU(p, "M"))
169*3125Sjacobs 				reqp->actions |= ACT_MAIL;
1700Sstevel@tonic-gate 			else if (STREQU(p, "W"))
171*3125Sjacobs 				reqp->actions |= ACT_WRITE;
1720Sstevel@tonic-gate 			else if (STREQU(p, "N"))
173*3125Sjacobs 				reqp->actions |= ACT_NOTIFY;
1740Sstevel@tonic-gate 			else
175*3125Sjacobs 				reqp->alert = Strdup(p);
1760Sstevel@tonic-gate 			break;
1770Sstevel@tonic-gate 
1780Sstevel@tonic-gate 		case RQ_OPTS:
179*3125Sjacobs 			reqp->options = Strdup(p);
1800Sstevel@tonic-gate 			break;
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate 		case RQ_PRIOR:
183*3125Sjacobs 			reqp->priority = atoi(p);
1840Sstevel@tonic-gate 			break;
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 		case RQ_PAGES:
187*3125Sjacobs 			reqp->pages = Strdup(p);
1880Sstevel@tonic-gate 			break;
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate 		case RQ_CHARS:
1910Sstevel@tonic-gate 			if (!STREQU(p, NAME_ANY))
192*3125Sjacobs 				reqp->charset = Strdup(p);
1930Sstevel@tonic-gate 			break;
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 		case RQ_TITLE:
196*3125Sjacobs 			reqp->title = Strdup(p);
1970Sstevel@tonic-gate 			break;
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate 		case RQ_MODES:
200*3125Sjacobs 			reqp->modes = Strdup(p);
2010Sstevel@tonic-gate 			break;
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 		case RQ_TYPE:
204*3125Sjacobs 			reqp->input_type = Strdup(p);
2050Sstevel@tonic-gate 			break;
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate 		case RQ_USER:
208*3125Sjacobs 			reqp->user = Strdup(p);
2090Sstevel@tonic-gate 			break;
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 		case RQ_RAW:
212*3125Sjacobs 			reqp->actions |= ACT_RAW;
2130Sstevel@tonic-gate 			break;
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 		case RQ_FAST:
216*3125Sjacobs 			reqp->actions |= ACT_FAST;
2170Sstevel@tonic-gate 			break;
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 		case RQ_STAT:
220*3125Sjacobs 			reqp->outcome = (ushort)strtol(p, (char **)0, 16);
2210Sstevel@tonic-gate 			break;
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 		}
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	}
2260Sstevel@tonic-gate 	if (errno != 0) {
2270Sstevel@tonic-gate 		int			save_errno = errno;
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 		close(fd);
2300Sstevel@tonic-gate 		errno = save_errno;
2310Sstevel@tonic-gate 		return (0);
2320Sstevel@tonic-gate 	}
2330Sstevel@tonic-gate 	close(fd);
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate 	/*
2360Sstevel@tonic-gate 	 * Now go through the structure and see if we have
2370Sstevel@tonic-gate 	 * anything strange.
2380Sstevel@tonic-gate 	 */
2390Sstevel@tonic-gate 	if (
240*3125Sjacobs 		reqp->copies <= 0
241*3125Sjacobs 	     || !reqp->file_list || !*(reqp->file_list)
242*3125Sjacobs 	     || reqp->priority < -1 || 39 < reqp->priority
243*3125Sjacobs 	     || STREQU(reqp->input_type, NAME_ANY)
244*3125Sjacobs 	     || STREQU(reqp->input_type, NAME_TERMINFO)
2450Sstevel@tonic-gate 	) {
246*3125Sjacobs 		freerequest (reqp);
2470Sstevel@tonic-gate 		errno = EBADF;
2480Sstevel@tonic-gate 		return (0);
2490Sstevel@tonic-gate 	}
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 	/*
2520Sstevel@tonic-gate 	 * Guarantee some return values won't be null or empty.
2530Sstevel@tonic-gate 	 */
254*3125Sjacobs 	if (!reqp->destination || !*reqp->destination) {
255*3125Sjacobs 		if (reqp->destination)
256*3125Sjacobs 			Free (reqp->destination);
257*3125Sjacobs 		reqp->destination = Strdup(NAME_ANY);
2580Sstevel@tonic-gate 	}
259*3125Sjacobs 	if (!reqp->input_type || !*reqp->input_type) {
260*3125Sjacobs 		if (reqp->input_type)
261*3125Sjacobs 			Free (reqp->input_type);
262*3125Sjacobs 		reqp->input_type = Strdup(NAME_SIMPLE);
2630Sstevel@tonic-gate 	}
2640Sstevel@tonic-gate 
265*3125Sjacobs 	return (reqp);
2660Sstevel@tonic-gate }
267