]> git.saurik.com Git - apple/xnu.git/blob - pexpert/gen/bootargs.c
4c5b5f07d0a4e9684ba471ba5890dc62783cf9f5
[apple/xnu.git] / pexpert / gen / bootargs.c
1 /*
2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 #include <pexpert/pexpert.h>
29
30 extern boolean_t isargsep( char c);
31 extern int argstrcpy(char *from, char *to);
32 extern int getval(char *s, int *val);
33
34 static int argstrcpy2(char *from,char *to, unsigned maxlen);
35
36 #define NUM 0
37 #define STR 1
38
39 #if !defined(__LP64__) && !defined(__arm__)
40 boolean_t
41 PE_parse_boot_arg(
42 const char *arg_string,
43 void *arg_ptr)
44 {
45 int max_len = -1;
46
47 #if CONFIG_EMBEDDED
48 /* Limit arg size to 4 byte when no size is given */
49 max_len = 4;
50 #endif
51
52 return PE_parse_boot_argn(arg_string, arg_ptr, max_len);
53 }
54 #endif
55
56 boolean_t
57 PE_parse_boot_argn(
58 const char *arg_string,
59 void *arg_ptr,
60 int max_len)
61 {
62 char *args;
63 char *cp, c;
64 unsigned int i;
65 int val;
66 boolean_t arg_boolean;
67 boolean_t arg_found;
68
69 args = PE_boot_args();
70 if (*args == '\0') return FALSE;
71
72 arg_found = FALSE;
73
74 while(*args && isargsep(*args)) args++;
75
76 while (*args)
77 {
78 if (*args == '-')
79 arg_boolean = TRUE;
80 else
81 arg_boolean = FALSE;
82
83 cp = args;
84 while (!isargsep (*cp) && *cp != '=')
85 cp++;
86 if (*cp != '=' && !arg_boolean)
87 goto gotit;
88
89 c = *cp;
90
91 i = cp-args;
92 if (strncmp(args, arg_string, i) ||
93 (i!=strlen(arg_string)))
94 goto gotit;
95 if (arg_boolean) {
96 *(unsigned int *)arg_ptr = TRUE;
97 arg_found = TRUE;
98 break;
99 } else {
100 while (*cp && isargsep (*cp))
101 cp++;
102 if (*cp == '=' && c != '=') {
103 args = cp+1;
104 goto gotit;
105 }
106 if ('_' == *arg_string) /* Force a string copy if the argument name begins with an underscore */
107 {
108 int hacklen = 17 > max_len ? 17 : max_len;
109 argstrcpy2 (++cp, (char *)arg_ptr, hacklen - 1); /* Hack - terminate after 16 characters */
110 arg_found = TRUE;
111 break;
112 }
113 switch (getval(cp, &val))
114 {
115 case NUM:
116 *(unsigned int *)arg_ptr = val;
117 arg_found = TRUE;
118 break;
119 case STR:
120 if(max_len > 0) //max_len of 0 performs no copy at all
121 argstrcpy2(++cp, (char *)arg_ptr, max_len - 1);
122 else if(max_len == -1)
123 argstrcpy(++cp, (char *)arg_ptr);
124 arg_found = TRUE;
125 break;
126 }
127 goto gotit;
128 }
129 gotit:
130 /* Skip over current arg */
131 while(!isargsep(*args)) args++;
132
133 /* Skip leading white space (catch end of args) */
134 while(*args && isargsep(*args)) args++;
135 }
136
137 return(arg_found);
138 }
139
140 boolean_t isargsep(
141 char c)
142 {
143 if (c == ' ' || c == '\0' || c == '\t')
144 return(TRUE);
145 else
146 return(FALSE);
147 }
148
149 int
150 argstrcpy(
151 char *from,
152 char *to)
153 {
154 int i = 0;
155
156 while (!isargsep(*from)) {
157 i++;
158 *to++ = *from++;
159 }
160 *to = 0;
161 return(i);
162 }
163
164 static int
165 argstrcpy2(
166 char *from,
167 char *to,
168 unsigned maxlen)
169 {
170 unsigned int i = 0;
171
172 while (!isargsep(*from) && i < maxlen) {
173 i++;
174 *to++ = *from++;
175 }
176 *to = 0;
177 return(i);
178 }
179
180 int
181 getval(
182 char *s,
183 int *val)
184 {
185 unsigned int radix, intval;
186 unsigned char c;
187 int sign = 1;
188
189 if (*s == '=') {
190 s++;
191 if (*s == '-')
192 sign = -1, s++;
193 intval = *s++-'0';
194 radix = 10;
195 if (intval == 0) {
196 switch(*s) {
197
198 case 'x':
199 radix = 16;
200 s++;
201 break;
202
203 case 'b':
204 radix = 2;
205 s++;
206 break;
207
208 case '0': case '1': case '2': case '3':
209 case '4': case '5': case '6': case '7':
210 intval = *s-'0';
211 s++;
212 radix = 8;
213 break;
214
215 default:
216 if (!isargsep(*s))
217 return (STR);
218 }
219 } else if (intval >= radix) {
220 return (STR);
221 }
222 for(;;) {
223 c = *s++;
224 if (isargsep(c))
225 break;
226 if ((radix <= 10) &&
227 ((c >= '0') && (c <= ('9' - (10 - radix))))) {
228 c -= '0';
229 } else if ((radix == 16) &&
230 ((c >= '0') && (c <= '9'))) {
231 c -= '0';
232 } else if ((radix == 16) &&
233 ((c >= 'a') && (c <= 'f'))) {
234 c -= 'a' - 10;
235 } else if ((radix == 16) &&
236 ((c >= 'A') && (c <= 'F'))) {
237 c -= 'A' - 10;
238 } else if (c == 'k' || c == 'K') {
239 sign *= 1024;
240 break;
241 } else if (c == 'm' || c == 'M') {
242 sign *= 1024 * 1024;
243 break;
244 } else if (c == 'g' || c == 'G') {
245 sign *= 1024 * 1024 * 1024;
246 break;
247 } else {
248 return (STR);
249 }
250 if (c >= radix)
251 return (STR);
252 intval *= radix;
253 intval += c;
254 }
255 if (!isargsep(c) && !isargsep(*s))
256 return STR;
257 *val = intval * sign;
258 return (NUM);
259 }
260 *val = 1;
261 return (NUM);
262 }