#include #include #include static char g_cmdline[CMDLINE_MAX + 1] = {0}; static kern_status_t remove_quotes(char *s, size_t max) { size_t i = 0; while (i < max) { if (s[i] != '"') { i++; continue; } size_t start = i; size_t end = i + 1; while (s[end] != '"' && end < max) { end++; } if (s[end] != '"') { return KERN_INVALID_ARGUMENT; } /* length of quoted string (excluding quotes) */ size_t len = end - start - 1; /* remove trailing quote */ s[end] = 0; /* add 1 to len to include the null terminator */ memmove(s + start, s + start + 1, len + 1); i = end + 1; } return KERN_OK; } kern_status_t parse_cmdline(const char *cmdline) { strncpy(g_cmdline, cmdline, sizeof g_cmdline - 1); g_cmdline[sizeof g_cmdline - 1] = 0; bool in_string = false; for (size_t i = 0; g_cmdline[i]; i++) { char c = g_cmdline[i]; if (c == '"') { in_string = !in_string; continue; } if (isspace(c) && !in_string) { g_cmdline[i] = 0; } } if (in_string) { /* unterminated string on command line */ return KERN_INVALID_ARGUMENT; } remove_quotes(g_cmdline, sizeof g_cmdline); return KERN_OK; } static char *advance_to_next_arg(char *s, char *max) { while (*s && s < max) { s++; } while (!*s && s < max) { s++; } return s; } const char *arg_value(const char *arg_name) { char *s = g_cmdline; char *end = s + sizeof g_cmdline; while (s < end) { size_t len = strlen(s); size_t name_len = strcspn(s, "="); if (!strncmp(s, arg_name, name_len)) { if (len == name_len) { /* arg has no value */ return NULL; } return s + name_len + 1; } s = advance_to_next_arg(s, end); } return NULL; } bool arg_is_set(const char *arg_name) { char *s = g_cmdline; char *end = s + sizeof g_cmdline; while (s < end) { size_t name_len = strcspn(s, "="); if (!strncmp(s, arg_name, name_len)) { return true; } s = advance_to_next_arg(s, end); } return false; }