xref: /kvm-unit-tests/lib/argv.c (revision 1b7dd7d312b93a5622b3df9886bd5017243d2deb)
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