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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.14 */ 32 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */ 33 34 #include "stdio.h" 35 #include "string.h" 36 #include "errno.h" 37 #include "sys/types.h" 38 #include "stdlib.h" 39 40 #include "lp.h" 41 #include "requests.h" 42 43 extern struct { 44 char *v; 45 short len; 46 } reqheadings[]; 47 48 /** 49 ** getrequest() - EXTRACT REQUEST STRUCTURE FROM DISK FILE 50 **/ 51 52 REQUEST * 53 #if defined(__STDC__) 54 getrequest ( 55 char * file 56 ) 57 #else 58 getrequest (file) 59 char *file; 60 #endif 61 { 62 static REQUEST reqbuf; 63 64 char buf[BUFSIZ], 65 *path, 66 *p; 67 68 int fd; 69 70 int fld; 71 72 73 /* 74 * Full pathname? If so the file must lie in LP's 75 * regular temporary directory. 76 */ 77 if (*file == '/') { 78 if (!STRNEQU(file, Lp_Tmp, strlen(Lp_Tmp))) { 79 errno = EINVAL; 80 return (0); 81 } 82 path = Strdup(file); 83 84 /* 85 * A relative pathname (such as system/name)? 86 * If so we'll locate it under LP's regular temporary 87 * directory. 88 */ 89 } else if (strchr(file, '/')) { 90 if (!(path = makepath(Lp_Tmp, file, (char *)0))) 91 return (0); 92 93 /* 94 * It must be a simple name. Locate this under the 95 * special temporary directory that is linked to the 96 * regular place for the local system. 97 */ 98 } else if (!(path = makepath(Lp_Temp, file, (char *)0))) 99 return (0); 100 101 102 if ((fd = open_locked(path, "r", 0)) < 0) { 103 Free (path); 104 return (0); 105 } 106 Free (path); 107 108 reqbuf.copies = 1; 109 reqbuf.destination = 0; 110 reqbuf.file_list = 0; 111 reqbuf.form = 0; 112 reqbuf.actions = 0; 113 reqbuf.alert = 0; 114 reqbuf.options = 0; 115 reqbuf.priority = -1; 116 reqbuf.pages = 0; 117 reqbuf.charset = 0; 118 reqbuf.modes = 0; 119 reqbuf.title = 0; 120 reqbuf.input_type = 0; 121 reqbuf.user = 0; 122 reqbuf.outcome = 0; 123 reqbuf.version = VERSION_OLD_LP; 124 125 errno = 0; 126 while (fdgets(buf, BUFSIZ, fd)) { 127 128 buf[strlen(buf) - 1] = 0; 129 130 for (fld = 0; fld < RQ_MAX; fld++) 131 if ( 132 reqheadings[fld].v 133 && reqheadings[fld].len 134 && STRNEQU( 135 buf, 136 reqheadings[fld].v, 137 reqheadings[fld].len 138 ) 139 ) { 140 p = buf + reqheadings[fld].len; 141 break; 142 } 143 144 /* 145 * To allow future extensions to not impact applications 146 * using old versions of this routine, ignore strange 147 * fields. 148 */ 149 if (fld >= RQ_MAX) 150 continue; 151 152 switch (fld) { 153 154 case RQ_COPIES: 155 reqbuf.copies = atoi(p); 156 break; 157 158 case RQ_DEST: 159 reqbuf.destination = Strdup(p); 160 break; 161 162 case RQ_FILE: 163 appendlist (&reqbuf.file_list, p); 164 break; 165 166 case RQ_FORM: 167 if (!STREQU(p, NAME_ANY)) 168 reqbuf.form = Strdup(p); 169 break; 170 171 case RQ_HANDL: 172 if (STREQU(p, NAME_RESUME)) 173 reqbuf.actions |= ACT_RESUME; 174 else if (STREQU(p, NAME_HOLD)) 175 reqbuf.actions |= ACT_HOLD; 176 else if (STREQU(p, NAME_IMMEDIATE)) 177 reqbuf.actions |= ACT_IMMEDIATE; 178 break; 179 180 case RQ_NOTIFY: 181 if (STREQU(p, "M")) 182 reqbuf.actions |= ACT_MAIL; 183 else if (STREQU(p, "W")) 184 reqbuf.actions |= ACT_WRITE; 185 else if (STREQU(p, "N")) 186 reqbuf.actions |= ACT_NOTIFY; 187 else 188 reqbuf.alert = Strdup(p); 189 break; 190 191 case RQ_OPTS: 192 reqbuf.options = Strdup(p); 193 break; 194 195 case RQ_PRIOR: 196 reqbuf.priority = atoi(p); 197 break; 198 199 case RQ_PAGES: 200 reqbuf.pages = Strdup(p); 201 break; 202 203 case RQ_CHARS: 204 if (!STREQU(p, NAME_ANY)) 205 reqbuf.charset = Strdup(p); 206 break; 207 208 case RQ_TITLE: 209 reqbuf.title = Strdup(p); 210 break; 211 212 case RQ_MODES: 213 reqbuf.modes = Strdup(p); 214 break; 215 216 case RQ_TYPE: 217 reqbuf.input_type = Strdup(p); 218 break; 219 220 case RQ_USER: 221 reqbuf.user = Strdup(p); 222 break; 223 224 case RQ_RAW: 225 reqbuf.actions |= ACT_RAW; 226 break; 227 228 case RQ_FAST: 229 reqbuf.actions |= ACT_FAST; 230 break; 231 232 case RQ_STAT: 233 reqbuf.outcome = (ushort)strtol(p, (char **)0, 16); 234 break; 235 236 case RQ_VERSION: 237 reqbuf.version = atoi(p); 238 break; 239 240 } 241 242 } 243 if (errno != 0) { 244 int save_errno = errno; 245 246 close(fd); 247 errno = save_errno; 248 return (0); 249 } 250 close(fd); 251 252 /* 253 * Now go through the structure and see if we have 254 * anything strange. 255 */ 256 if ( 257 reqbuf.copies <= 0 258 || !reqbuf.file_list || !*(reqbuf.file_list) 259 || reqbuf.priority < -1 || 39 < reqbuf.priority 260 || STREQU(reqbuf.input_type, NAME_ANY) 261 || STREQU(reqbuf.input_type, NAME_TERMINFO) 262 ) { 263 freerequest (&reqbuf); 264 errno = EBADF; 265 return (0); 266 } 267 268 /* 269 * Guarantee some return values won't be null or empty. 270 */ 271 if (!reqbuf.destination || !*reqbuf.destination) { 272 if (reqbuf.destination) 273 Free (reqbuf.destination); 274 reqbuf.destination = Strdup(NAME_ANY); 275 } 276 if (!reqbuf.input_type || !*reqbuf.input_type) { 277 if (reqbuf.input_type) 278 Free (reqbuf.input_type); 279 reqbuf.input_type = Strdup(NAME_SIMPLE); 280 } 281 282 return (&reqbuf); 283 } 284