xref: /kvm-unit-tests/lib/argv.c (revision 8b13a5b5cfdb26920c8f631a1e56e7a5eac917fe)
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 setup_args_progname(const char *args)
57 {
58 	__argv[0] = copy_ptr;
59 	strcpy(__argv[0], auxinfo.progname);
60 	copy_ptr += strlen(auxinfo.progname) + 1;
61 	++__argc;
62 	setup_args(args);
63 }
64 
65 static char *env_eol(char *env)
66 {
67 	while (*env && *env != '\n')
68 		++env;
69 	return env;
70 }
71 
72 static char *env_invalid_eol(char *env)
73 {
74 	char *eol = env_eol(env);
75 	char eol_old = *eol;
76 
77 	*eol = '\0';
78 	printf("Invalid environment variable: %s\n", env);
79 	*eol = eol_old;
80 	return eol;
81 }
82 
83 static char *env_next(char *env)
84 {
85 	char *p;
86 
87 	if (!*env)
88 		return env;
89 
90 	if (isalpha(*env)) {
91 		bool invalid = false;
92 
93 		p = env + 1;
94 		while (*p && *p != '=' && *p != '\n') {
95 			if (!isalnum(*p))
96 				invalid = true;
97 			++p;
98 		}
99 
100 		if (*p != '=')
101 			invalid = true;
102 
103 		if (invalid) {
104 			env = env_invalid_eol(env);
105 			return *env ? env_next(env + 1) : env;
106 		}
107 		return env;
108 	}
109 
110 	p = env;
111 	while (isblank(*p))
112 		++p;
113 
114 	if (*p == '\n')
115 		return env_next(p + 1);
116 
117 	if (*p == '#')
118 		env = env_eol(env);
119 	else
120 		env = env_invalid_eol(env);
121 
122 	return *env ? env_next(env + 1) : env;
123 }
124 
125 void setup_env(char *env, int size)
126 {
127 	char *eof = env + size, *p = env;
128 	bool newline = false;
129 	int i = 0;
130 
131 	while (*p)
132 		++p;
133 	if (p == eof)
134 		newline = true;
135 
136 	while (env < eof) {
137 		if (newline)
138 			env = env_next(env);
139 		if (!*env || env >= eof)
140 			break;
141 		__environ[i++] = env;
142 		while (env < eof && *env && !(newline && *env == '\n'))
143 			++env;
144 		*env++ = '\0';
145 	}
146 }
147