1 // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 3 * 4 * Misc librarized functions for cmdline pokin 5 */ 6 #include <linux/kernel.h> 7 #include <linux/string.h> 8 #include <linux/ctype.h> 9 10 #include <asm/setup.h> 11 #include <asm/cmdline.h> 12 #include <asm/bug.h> 13 14 static inline int myisspace(u8 c) 15 { 16 return c <= ' '; /* Close enoug 17 } 18 19 /* 20 * Find a boolean option (like quiet,noapic,no 21 * 22 * @cmdline: the cmdline string 23 * @max_cmdline_size: the maximum size of cmdl 24 * @option: option string to look for 25 * 26 * Returns the position of that @option (start 27 * or 0 on not found. @option will only be fo 28 * as an entire word in @cmdline. For instanc 29 * then a cmdline which contains "cart" will n 30 */ 31 static int 32 __cmdline_find_option_bool(const char *cmdline 33 const char *option) 34 { 35 char c; 36 int pos = 0, wstart = 0; 37 const char *opptr = NULL; 38 enum { 39 st_wordstart = 0, /* Sta 40 st_wordcmp, /* Comparing t 41 st_wordskip, /* Miscompare, 42 } state = st_wordstart; 43 44 if (!cmdline) 45 return -1; /* No command 46 47 /* 48 * This 'pos' check ensures we do not 49 * a non-NULL-terminated 'cmdline' 50 */ 51 while (pos < max_cmdline_size) { 52 c = *(char *)cmdline++; 53 pos++; 54 55 switch (state) { 56 case st_wordstart: 57 if (!c) 58 return 0; 59 else if (myisspace(c)) 60 break; 61 62 state = st_wordcmp; 63 opptr = option; 64 wstart = pos; 65 fallthrough; 66 67 case st_wordcmp: 68 if (!*opptr) { 69 /* 70 * We matched 71 * option we w 72 * command-lin 73 * we matched! 74 */ 75 if (!c || myis 76 return 77 /* 78 * We hit the 79 * the end of 80 * a match. 81 */ 82 } else if (!c) { 83 /* 84 * Hit the NUL 85 * cmdline. 86 */ 87 return 0; 88 } else if (c == *opptr 89 /* 90 * We are curr 91 * to the next 92 */ 93 break; 94 } 95 state = st_wordskip; 96 fallthrough; 97 98 case st_wordskip: 99 if (!c) 100 return 0; 101 else if (myisspace(c)) 102 state = st_wor 103 break; 104 } 105 } 106 107 return 0; /* Buffer overrun */ 108 } 109 110 /* 111 * Find a non-boolean option (i.e. option=argu 112 * standard Linux practice, if this option is 113 * last instance on the command line. 114 * 115 * @cmdline: the cmdline string 116 * @max_cmdline_size: the maximum size of cmdl 117 * @option: option string to look for 118 * @buffer: memory buffer to return the option 119 * @bufsize: size of the supplied memory buffe 120 * 121 * Returns the length of the argument (regardl 122 * truncated to fit in the buffer), or -1 on n 123 */ 124 static int 125 __cmdline_find_option(const char *cmdline, int 126 const char *option, char 127 { 128 char c; 129 int pos = 0, len = -1; 130 const char *opptr = NULL; 131 char *bufptr = buffer; 132 enum { 133 st_wordstart = 0, /* Sta 134 st_wordcmp, /* Comparing t 135 st_wordskip, /* Miscompare, 136 st_bufcpy, /* Copying thi 137 } state = st_wordstart; 138 139 if (!cmdline) 140 return -1; /* No command 141 142 /* 143 * This 'pos' check ensures we do not 144 * a non-NULL-terminated 'cmdline' 145 */ 146 while (pos++ < max_cmdline_size) { 147 c = *(char *)cmdline++; 148 if (!c) 149 break; 150 151 switch (state) { 152 case st_wordstart: 153 if (myisspace(c)) 154 break; 155 156 state = st_wordcmp; 157 opptr = option; 158 fallthrough; 159 160 case st_wordcmp: 161 if ((c == '=') && !*op 162 /* 163 * We matched 164 * option we w 165 * copy the ar 166 */ 167 len = 0; 168 bufptr = buffe 169 state = st_buf 170 break; 171 } else if (c == *opptr 172 /* 173 * We are curr 174 * to the next 175 */ 176 break; 177 } 178 state = st_wordskip; 179 fallthrough; 180 181 case st_wordskip: 182 if (myisspace(c)) 183 state = st_wor 184 break; 185 186 case st_bufcpy: 187 if (myisspace(c)) { 188 state = st_wor 189 } else { 190 /* 191 * Increment l 192 * supplied bu 193 * NULL termin 194 */ 195 if (++len < bu 196 *bufpt 197 } 198 break; 199 } 200 } 201 202 if (bufsize) 203 *bufptr = '\0'; 204 205 return len; 206 } 207 208 int cmdline_find_option_bool(const char *cmdli 209 { 210 int ret; 211 212 ret = __cmdline_find_option_bool(cmdli 213 if (ret > 0) 214 return ret; 215 216 if (IS_ENABLED(CONFIG_CMDLINE_BOOL) && 217 return __cmdline_find_option_b 218 219 return ret; 220 } 221 222 int cmdline_find_option(const char *cmdline, c 223 int bufsize) 224 { 225 int ret; 226 227 ret = __cmdline_find_option(cmdline, C 228 if (ret > 0) 229 return ret; 230 231 if (IS_ENABLED(CONFIG_CMDLINE_BOOL) && 232 return __cmdline_find_option(b 233 234 return ret; 235 } 236
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.