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