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__)
getrequest(char * file)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