| /* |
| * Set up arguments for main() and prepare environment variables |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU Library General Public License version 2. |
| */ |
| |
| #include "libcflat.h" |
| #include "ctype.h" |
| #include "argv.h" |
| #include "auxinfo.h" |
| |
| int __argc; |
| const char *__args; |
| char *__argv[100]; |
| char *__environ[200]; |
| |
| char **environ = __environ; |
| |
| static char args_copy[1000]; |
| static char *copy_ptr = args_copy; |
| |
| static const char *skip_blanks(const char *p) |
| { |
| while (isblank(*p)) |
| ++p; |
| return p; |
| } |
| |
| void __setup_args(void) |
| { |
| const char *args = __args; |
| char **argv = __argv + __argc; |
| |
| while (*(args = skip_blanks(args)) != '\0') { |
| *argv++ = copy_ptr; |
| while (*args != '\0' && !isblank(*args)) |
| *copy_ptr++ = *args++; |
| *copy_ptr++ = '\0'; |
| } |
| __argc = argv - __argv; |
| } |
| |
| static void setup_args(const char *args) |
| { |
| if (!args) |
| return; |
| |
| __args = args; |
| __setup_args(); |
| } |
| |
| void add_setup_arg(const char *arg) |
| { |
| __argv[__argc] = copy_ptr; |
| strcpy(__argv[__argc], arg); |
| copy_ptr += strlen(arg) + 1; |
| ++__argc; |
| } |
| |
| void setup_args_progname(const char *args) |
| { |
| add_setup_arg(auxinfo.progname); |
| setup_args(args); |
| } |
| |
| static char *env_eol(char *env) |
| { |
| while (*env && *env != '\n') |
| ++env; |
| return env; |
| } |
| |
| static char *env_invalid_eol(char *env) |
| { |
| char *eol = env_eol(env); |
| char eol_old = *eol; |
| |
| *eol = '\0'; |
| printf("Invalid environment variable: %s\n", env); |
| *eol = eol_old; |
| return eol; |
| } |
| |
| static char *env_next(char *env) |
| { |
| char *p; |
| |
| if (!*env) |
| return env; |
| |
| if (isalpha(*env) || *env == '_') { |
| bool invalid = false; |
| |
| p = env + 1; |
| while (*p && *p != '=' && *p != '\n') { |
| if (!(isalnum(*p) || *p == '_')) |
| invalid = true; |
| ++p; |
| } |
| |
| if (*p != '=') |
| invalid = true; |
| |
| if (invalid) { |
| env = env_invalid_eol(env); |
| return *env ? env_next(env + 1) : env; |
| } |
| return env; |
| } |
| |
| p = env; |
| while (isblank(*p)) |
| ++p; |
| |
| if (*p == '\n') |
| return env_next(p + 1); |
| |
| if (*p == '#') |
| env = env_eol(env); |
| else |
| env = env_invalid_eol(env); |
| |
| return *env ? env_next(env + 1) : env; |
| } |
| |
| void setup_env(char *env, int size) |
| { |
| char *eof = env + size, *p = env; |
| bool newline = false; |
| int i = 0; |
| |
| while (*p) |
| ++p; |
| if (p == eof) |
| newline = true; |
| |
| while (env < eof) { |
| if (newline) |
| env = env_next(env); |
| if (!*env || env >= eof) |
| break; |
| __environ[i++] = env; |
| while (env < eof && *env && !(newline && *env == '\n')) |
| ++env; |
| *env++ = '\0'; |
| } |
| } |