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 /* 23 * Copyright 2006 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 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */ 31 32 #include "stdio.h" 33 #include "string.h" 34 #include "errno.h" 35 #include "sys/types.h" 36 #include "stdlib.h" 37 38 #include "lp.h" 39 #include "requests.h" 40 41 extern struct { 42 char *v; 43 short len; 44 } reqheadings[]; 45 46 /** 47 ** getrequest() - EXTRACT REQUEST STRUCTURE FROM DISK FILE 48 **/ 49 50 REQUEST * 51 #if defined(__STDC__) 52 getrequest ( 53 char * file 54 ) 55 #else 56 getrequest (file) 57 char *file; 58 #endif 59 { 60 REQUEST *reqp; 61 62 char buf[BUFSIZ], 63 *path, 64 *p; 65 66 int fd; 67 68 int fld; 69 70 71 /* 72 * Full pathname? If so the file must lie in LP's 73 * regular temporary directory. 74 */ 75 if (*file == '/') { 76 if (!STRNEQU(file, Lp_Tmp, strlen(Lp_Tmp))) { 77 errno = EINVAL; 78 return (0); 79 } 80 path = Strdup(file); 81 82 /* 83 * A relative pathname (such as system/name)? 84 * If so we'll locate it under LP's regular temporary 85 * directory. 86 */ 87 } else if (strchr(file, '/')) { 88 if (!(path = makepath(Lp_Tmp, file, (char *)0))) 89 return (0); 90 91 /* 92 * It must be a simple name. Locate this under the 93 * special temporary directory that is linked to the 94 * regular place for the local system. 95 */ 96 } else if (!(path = makepath(Lp_Temp, file, (char *)0))) 97 return (0); 98 99 100 if ((fd = open_locked(path, "r", 0)) < 0) { 101 Free (path); 102 return (0); 103 } 104 Free (path); 105 106 reqp = calloc(sizeof (*reqp), 1); 107 reqp->copies = 1; 108 reqp->priority = -1; 109 110 errno = 0; 111 while (fdgets(buf, BUFSIZ, fd)) { 112 113 buf[strlen(buf) - 1] = 0; 114 115 for (fld = 0; fld < RQ_MAX; fld++) 116 if ( 117 reqheadings[fld].v 118 && reqheadings[fld].len 119 && STRNEQU( 120 buf, 121 reqheadings[fld].v, 122 reqheadings[fld].len 123 ) 124 ) { 125 p = buf + reqheadings[fld].len; 126 break; 127 } 128 129 /* 130 * To allow future extensions to not impact applications 131 * using old versions of this routine, ignore strange 132 * fields. 133 */ 134 if (fld >= RQ_MAX) 135 continue; 136 137 switch (fld) { 138 139 case RQ_COPIES: 140 reqp->copies = atoi(p); 141 break; 142 143 case RQ_DEST: 144 reqp->destination = Strdup(p); 145 break; 146 147 case RQ_FILE: 148 appendlist (&reqp->file_list, p); 149 break; 150 151 case RQ_FORM: 152 if (!STREQU(p, NAME_ANY)) 153 reqp->form = Strdup(p); 154 break; 155 156 case RQ_HANDL: 157 if (STREQU(p, NAME_RESUME)) 158 reqp->actions |= ACT_RESUME; 159 else if (STREQU(p, NAME_HOLD)) 160 reqp->actions |= ACT_HOLD; 161 else if (STREQU(p, NAME_IMMEDIATE)) 162 reqp->actions |= ACT_IMMEDIATE; 163 break; 164 165 case RQ_NOTIFY: 166 if (STREQU(p, "M")) 167 reqp->actions |= ACT_MAIL; 168 else if (STREQU(p, "W")) 169 reqp->actions |= ACT_WRITE; 170 else if (STREQU(p, "N")) 171 reqp->actions |= ACT_NOTIFY; 172 else 173 reqp->alert = Strdup(p); 174 break; 175 176 case RQ_OPTS: 177 reqp->options = Strdup(p); 178 break; 179 180 case RQ_PRIOR: 181 reqp->priority = atoi(p); 182 break; 183 184 case RQ_PAGES: 185 reqp->pages = Strdup(p); 186 break; 187 188 case RQ_CHARS: 189 if (!STREQU(p, NAME_ANY)) 190 reqp->charset = Strdup(p); 191 break; 192 193 case RQ_TITLE: 194 reqp->title = Strdup(p); 195 break; 196 197 case RQ_MODES: 198 reqp->modes = Strdup(p); 199 break; 200 201 case RQ_TYPE: 202 reqp->input_type = Strdup(p); 203 break; 204 205 case RQ_USER: 206 reqp->user = Strdup(p); 207 break; 208 209 case RQ_RAW: 210 reqp->actions |= ACT_RAW; 211 break; 212 213 case RQ_FAST: 214 reqp->actions |= ACT_FAST; 215 break; 216 217 case RQ_STAT: 218 reqp->outcome = (ushort)strtol(p, (char **)0, 16); 219 break; 220 221 } 222 223 } 224 if (errno != 0) { 225 int save_errno = errno; 226 227 close(fd); 228 errno = save_errno; 229 return (0); 230 } 231 close(fd); 232 233 /* 234 * Now go through the structure and see if we have 235 * anything strange. 236 */ 237 if ( 238 reqp->copies <= 0 239 || !reqp->file_list || !*(reqp->file_list) 240 || reqp->priority < -1 || 39 < reqp->priority 241 || STREQU(reqp->input_type, NAME_ANY) 242 || STREQU(reqp->input_type, NAME_TERMINFO) 243 ) { 244 freerequest (reqp); 245 errno = EBADF; 246 return (0); 247 } 248 249 /* 250 * Guarantee some return values won't be null or empty. 251 */ 252 if (!reqp->destination || !*reqp->destination) { 253 if (reqp->destination) 254 Free (reqp->destination); 255 reqp->destination = Strdup(NAME_ANY); 256 } 257 if (!reqp->input_type || !*reqp->input_type) { 258 if (reqp->input_type) 259 Free (reqp->input_type); 260 reqp->input_type = Strdup(NAME_SIMPLE); 261 } 262 263 return (reqp); 264 } 265