|
@@ -104,7 +104,112 @@ __cmdline_find_option_bool(const char *cmdline, int max_cmdline_size,
|
|
return 0; /* Buffer overrun */
|
|
return 0; /* Buffer overrun */
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Find a non-boolean option (i.e. option=argument). In accordance with
|
|
|
|
+ * standard Linux practice, if this option is repeated, this returns the
|
|
|
|
+ * last instance on the command line.
|
|
|
|
+ *
|
|
|
|
+ * @cmdline: the cmdline string
|
|
|
|
+ * @max_cmdline_size: the maximum size of cmdline
|
|
|
|
+ * @option: option string to look for
|
|
|
|
+ * @buffer: memory buffer to return the option argument
|
|
|
|
+ * @bufsize: size of the supplied memory buffer
|
|
|
|
+ *
|
|
|
|
+ * Returns the length of the argument (regardless of if it was
|
|
|
|
+ * truncated to fit in the buffer), or -1 on not found.
|
|
|
|
+ */
|
|
|
|
+static int
|
|
|
|
+__cmdline_find_option(const char *cmdline, int max_cmdline_size,
|
|
|
|
+ const char *option, char *buffer, int bufsize)
|
|
|
|
+{
|
|
|
|
+ char c;
|
|
|
|
+ int pos = 0, len = -1;
|
|
|
|
+ const char *opptr = NULL;
|
|
|
|
+ char *bufptr = buffer;
|
|
|
|
+ enum {
|
|
|
|
+ st_wordstart = 0, /* Start of word/after whitespace */
|
|
|
|
+ st_wordcmp, /* Comparing this word */
|
|
|
|
+ st_wordskip, /* Miscompare, skip */
|
|
|
|
+ st_bufcpy, /* Copying this to buffer */
|
|
|
|
+ } state = st_wordstart;
|
|
|
|
+
|
|
|
|
+ if (!cmdline)
|
|
|
|
+ return -1; /* No command line */
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * This 'pos' check ensures we do not overrun
|
|
|
|
+ * a non-NULL-terminated 'cmdline'
|
|
|
|
+ */
|
|
|
|
+ while (pos++ < max_cmdline_size) {
|
|
|
|
+ c = *(char *)cmdline++;
|
|
|
|
+ if (!c)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ switch (state) {
|
|
|
|
+ case st_wordstart:
|
|
|
|
+ if (myisspace(c))
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ state = st_wordcmp;
|
|
|
|
+ opptr = option;
|
|
|
|
+ /* fall through */
|
|
|
|
+
|
|
|
|
+ case st_wordcmp:
|
|
|
|
+ if ((c == '=') && !*opptr) {
|
|
|
|
+ /*
|
|
|
|
+ * We matched all the way to the end of the
|
|
|
|
+ * option we were looking for, prepare to
|
|
|
|
+ * copy the argument.
|
|
|
|
+ */
|
|
|
|
+ len = 0;
|
|
|
|
+ bufptr = buffer;
|
|
|
|
+ state = st_bufcpy;
|
|
|
|
+ break;
|
|
|
|
+ } else if (c == *opptr++) {
|
|
|
|
+ /*
|
|
|
|
+ * We are currently matching, so continue
|
|
|
|
+ * to the next character on the cmdline.
|
|
|
|
+ */
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ state = st_wordskip;
|
|
|
|
+ /* fall through */
|
|
|
|
+
|
|
|
|
+ case st_wordskip:
|
|
|
|
+ if (myisspace(c))
|
|
|
|
+ state = st_wordstart;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case st_bufcpy:
|
|
|
|
+ if (myisspace(c)) {
|
|
|
|
+ state = st_wordstart;
|
|
|
|
+ } else {
|
|
|
|
+ /*
|
|
|
|
+ * Increment len, but don't overrun the
|
|
|
|
+ * supplied buffer and leave room for the
|
|
|
|
+ * NULL terminator.
|
|
|
|
+ */
|
|
|
|
+ if (++len < bufsize)
|
|
|
|
+ *bufptr++ = c;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (bufsize)
|
|
|
|
+ *bufptr = '\0';
|
|
|
|
+
|
|
|
|
+ return len;
|
|
|
|
+}
|
|
|
|
+
|
|
int cmdline_find_option_bool(const char *cmdline, const char *option)
|
|
int cmdline_find_option_bool(const char *cmdline, const char *option)
|
|
{
|
|
{
|
|
return __cmdline_find_option_bool(cmdline, COMMAND_LINE_SIZE, option);
|
|
return __cmdline_find_option_bool(cmdline, COMMAND_LINE_SIZE, option);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+int cmdline_find_option(const char *cmdline, const char *option, char *buffer,
|
|
|
|
+ int bufsize)
|
|
|
|
+{
|
|
|
|
+ return __cmdline_find_option(cmdline, COMMAND_LINE_SIZE, option,
|
|
|
|
+ buffer, bufsize);
|
|
|
|
+}
|