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