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