1 /* 2 * Set up arguments for main() and prepare environment variables 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU Library General Public License version 2. 6 */ 7 8 #include "libcflat.h" 9 #include "argv.h" 10 #include "auxinfo.h" 11 12 int __argc; 13 const char *__args; 14 char *__argv[100]; 15 char *__environ[200]; 16 17 char **environ = __environ; 18 19 static char args_copy[1000]; 20 static char *copy_ptr = args_copy; 21 22 #define isblank(c) ((c) == ' ' || (c) == '\t') 23 #define isalpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z') || (c) == '_') 24 #define isalnum(c) (isalpha(c) || ((c) >= '0' && (c) <= '9')) 25 26 static const char *skip_blanks(const char *p) 27 { 28 while (isblank(*p)) 29 ++p; 30 return p; 31 } 32 33 void __setup_args(void) 34 { 35 const char *args = __args; 36 char **argv = __argv + __argc; 37 38 while (*(args = skip_blanks(args)) != '\0') { 39 *argv++ = copy_ptr; 40 while (*args != '\0' && !isblank(*args)) 41 *copy_ptr++ = *args++; 42 *copy_ptr++ = '\0'; 43 } 44 __argc = argv - __argv; 45 } 46 47 static void setup_args(const char *args) 48 { 49 if (!args) 50 return; 51 52 __args = args; 53 __setup_args(); 54 } 55 56 void add_setup_arg(const char *arg) 57 { 58 __argv[__argc] = copy_ptr; 59 strcpy(__argv[__argc], arg); 60 copy_ptr += strlen(arg) + 1; 61 ++__argc; 62 } 63 64 void setup_args_progname(const char *args) 65 { 66 add_setup_arg(auxinfo.progname); 67 setup_args(args); 68 } 69 70 static char *env_eol(char *env) 71 { 72 while (*env && *env != '\n') 73 ++env; 74 return env; 75 } 76 77 static char *env_invalid_eol(char *env) 78 { 79 char *eol = env_eol(env); 80 char eol_old = *eol; 81 82 *eol = '\0'; 83 printf("Invalid environment variable: %s\n", env); 84 *eol = eol_old; 85 return eol; 86 } 87 88 static char *env_next(char *env) 89 { 90 char *p; 91 92 if (!*env) 93 return env; 94 95 if (isalpha(*env)) { 96 bool invalid = false; 97 98 p = env + 1; 99 while (*p && *p != '=' && *p != '\n') { 100 if (!isalnum(*p)) 101 invalid = true; 102 ++p; 103 } 104 105 if (*p != '=') 106 invalid = true; 107 108 if (invalid) { 109 env = env_invalid_eol(env); 110 return *env ? env_next(env + 1) : env; 111 } 112 return env; 113 } 114 115 p = env; 116 while (isblank(*p)) 117 ++p; 118 119 if (*p == '\n') 120 return env_next(p + 1); 121 122 if (*p == '#') 123 env = env_eol(env); 124 else 125 env = env_invalid_eol(env); 126 127 return *env ? env_next(env + 1) : env; 128 } 129 130 void setup_env(char *env, int size) 131 { 132 char *eof = env + size, *p = env; 133 bool newline = false; 134 int i = 0; 135 136 while (*p) 137 ++p; 138 if (p == eof) 139 newline = true; 140 141 while (env < eof) { 142 if (newline) 143 env = env_next(env); 144 if (!*env || env >= eof) 145 break; 146 __environ[i++] = env; 147 while (env < eof && *env && !(newline && *env == '\n')) 148 ++env; 149 *env++ = '\0'; 150 } 151 } 152