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 31 #pragma ident "%Z%%M% %I% %E% SMI" 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 REQUEST *reqp; 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 reqp = calloc(sizeof (*reqp), 1); 109 reqp->copies = 1; 110 reqp->priority = -1; 111 112 errno = 0; 113 while (fdgets(buf, BUFSIZ, fd)) { 114 115 buf[strlen(buf) - 1] = 0; 116 117 for (fld = 0; fld < RQ_MAX; fld++) 118 if ( 119 reqheadings[fld].v 120 && reqheadings[fld].len 121 && STRNEQU( 122 buf, 123 reqheadings[fld].v, 124 reqheadings[fld].len 125 ) 126 ) { 127 p = buf + reqheadings[fld].len; 128 break; 129 } 130 131 /* 132 * To allow future extensions to not impact applications 133 * using old versions of this routine, ignore strange 134 * fields. 135 */ 136 if (fld >= RQ_MAX) 137 continue; 138 139 switch (fld) { 140 141 case RQ_COPIES: 142 reqp->copies = atoi(p); 143 break; 144 145 case RQ_DEST: 146 reqp->destination = Strdup(p); 147 break; 148 149 case RQ_FILE: 150 appendlist (&reqp->file_list, p); 151 break; 152 153 case RQ_FORM: 154 if (!STREQU(p, NAME_ANY)) 155 reqp->form = Strdup(p); 156 break; 157 158 case RQ_HANDL: 159 if (STREQU(p, NAME_RESUME)) 160 reqp->actions |= ACT_RESUME; 161 else if (STREQU(p, NAME_HOLD)) 162 reqp->actions |= ACT_HOLD; 163 else if (STREQU(p, NAME_IMMEDIATE)) 164 reqp->actions |= ACT_IMMEDIATE; 165 break; 166 167 case RQ_NOTIFY: 168 if (STREQU(p, "M")) 169 reqp->actions |= ACT_MAIL; 170 else if (STREQU(p, "W")) 171 reqp->actions |= ACT_WRITE; 172 else if (STREQU(p, "N")) 173 reqp->actions |= ACT_NOTIFY; 174 else 175 reqp->alert = Strdup(p); 176 break; 177 178 case RQ_OPTS: 179 reqp->options = Strdup(p); 180 break; 181 182 case RQ_PRIOR: 183 reqp->priority = atoi(p); 184 break; 185 186 case RQ_PAGES: 187 reqp->pages = Strdup(p); 188 break; 189 190 case RQ_CHARS: 191 if (!STREQU(p, NAME_ANY)) 192 reqp->charset = Strdup(p); 193 break; 194 195 case RQ_TITLE: 196 reqp->title = Strdup(p); 197 break; 198 199 case RQ_MODES: 200 reqp->modes = Strdup(p); 201 break; 202 203 case RQ_TYPE: 204 reqp->input_type = Strdup(p); 205 break; 206 207 case RQ_USER: 208 reqp->user = Strdup(p); 209 break; 210 211 case RQ_RAW: 212 reqp->actions |= ACT_RAW; 213 break; 214 215 case RQ_FAST: 216 reqp->actions |= ACT_FAST; 217 break; 218 219 case RQ_STAT: 220 reqp->outcome = (ushort)strtol(p, (char **)0, 16); 221 break; 222 223 } 224 225 } 226 if (errno != 0) { 227 int save_errno = errno; 228 229 close(fd); 230 errno = save_errno; 231 return (0); 232 } 233 close(fd); 234 235 /* 236 * Now go through the structure and see if we have 237 * anything strange. 238 */ 239 if ( 240 reqp->copies <= 0 241 || !reqp->file_list || !*(reqp->file_list) 242 || reqp->priority < -1 || 39 < reqp->priority 243 || STREQU(reqp->input_type, NAME_ANY) 244 || STREQU(reqp->input_type, NAME_TERMINFO) 245 ) { 246 freerequest (reqp); 247 errno = EBADF; 248 return (0); 249 } 250 251 /* 252 * Guarantee some return values won't be null or empty. 253 */ 254 if (!reqp->destination || !*reqp->destination) { 255 if (reqp->destination) 256 Free (reqp->destination); 257 reqp->destination = Strdup(NAME_ANY); 258 } 259 if (!reqp->input_type || !*reqp->input_type) { 260 if (reqp->input_type) 261 Free (reqp->input_type); 262 reqp->input_type = Strdup(NAME_SIMPLE); 263 } 264 265 return (reqp); 266 } 267