1 #include "uwsgi.h"
2 
3 extern struct uwsgi_server uwsgi;
4 
5 /*
6    ini file must be read ALL into memory.
7    This memory must not be freed for all the server lifecycle
8    */
9 
10 static char *last_file = NULL;
11 
ini_rstrip(char * line)12 void ini_rstrip(char *line) {
13 
14 	off_t i;
15 
16 	for (i = strlen(line) - 1; i >= 0; i--) {
17 		if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r') {
18 			line[i] = 0;
19 			continue;
20 		}
21 		break;
22 	}
23 }
24 
ini_lstrip(char * line)25 char *ini_lstrip(char *line) {
26 
27 	off_t i;
28 	char *ptr = line;
29 
30 	for (i = 0; i < (int) strlen(line); i++) {
31 		if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r') {
32 			ptr++;
33 			continue;
34 		}
35 		break;
36 	}
37 
38 	return ptr;
39 }
40 
ini_get_key(char * key)41 char *ini_get_key(char *key) {
42 
43 	off_t i;
44 	char *ptr = key;
45 
46 	for (i = 0; i < (int) strlen(key); i++) {
47 		ptr++;
48 		if (key[i] == '=') {
49 			key[i] = 0;
50 			return ptr;
51 		}
52 	}
53 
54 	return ptr;
55 }
56 
ini_get_line(char * ini,size_t size)57 char *ini_get_line(char *ini, size_t size) {
58 
59 	size_t i;
60 	char *ptr = ini;
61 
62 	for (i = 0; i < size; i++) {
63 		ptr++;
64 		if (ini[i] == '\n') {
65 			ini[i] = 0;
66 			return ptr;
67 		}
68 	}
69 
70 	// check if it is a stupid file without \n at the end
71 	if (ptr > ini) {
72 		return ptr;
73 	}
74 
75 	return NULL;
76 
77 }
78 
uwsgi_ini_config(char * file,char * magic_table[])79 void uwsgi_ini_config(char *file, char *magic_table[]) {
80 
81 	size_t len = 0;
82 	char *ini;
83 
84 	char *ini_line;
85 
86 	char *section = "";
87 	char *key;
88 	char *val;
89 
90 	int lines = 1;
91 
92 	char *section_asked = "uwsgi";
93 	char *colon;
94 	int got_section = 0;
95 
96 
97 	if (uwsgi_check_scheme(file)) {
98 		colon = uwsgi_get_last_char(file, '/');
99 		colon = uwsgi_get_last_char(colon, ':');
100 	}
101 	else {
102 		colon = uwsgi_get_last_char(file, ':');
103 	}
104 
105 	if (colon) {
106 		colon[0] = 0;
107 		if (colon[1] != 0) {
108 			section_asked = colon + 1;
109 		}
110 
111 		if (colon == file) {
112 			file = last_file;
113 		}
114 	}
115 
116 	if (file[0] != 0 && file != last_file) {
117 		uwsgi_log_initial("[uWSGI] getting INI configuration from %s\n", file);
118 	}
119 
120 	ini = uwsgi_open_and_read(file, &len, 1, magic_table);
121 	if (file != last_file) {
122 		if (last_file) {
123 			free(last_file);
124 		}
125 		last_file = uwsgi_str(file);
126 	}
127 
128 	while (len) {
129 		ini_line = ini_get_line(ini, len);
130 		if (ini_line == NULL) {
131 			break;
132 		}
133 		lines++;
134 
135 		// skip empty line
136 		key = ini_lstrip(ini);
137 		ini_rstrip(key);
138 		if (key[0] != 0) {
139 			if (key[0] == '[') {
140 				section = key + 1;
141 				section[strlen(section) - 1] = 0;
142 			}
143 			else if (key[0] == ';' || key[0] == '#') {
144 				// this is a comment
145 			}
146 			else {
147 				// val is always valid, but (obviously) can be ignored
148 				val = ini_get_key(key);
149 
150 				if (!strcmp(section, section_asked)) {
151 					got_section = 1;
152 					ini_rstrip(key);
153 					val = ini_lstrip(val);
154 					ini_rstrip(val);
155 					add_exported_option((char *) key, val, 0);
156 				}
157 			}
158 		}
159 
160 
161 		len -= (ini_line - ini);
162 		ini += (ini_line - ini);
163 
164 	}
165 
166 	if (!got_section) {
167 		uwsgi_log("*** WARNING: Can't find section \"%s\" in INI configuration file %s ***\n", section_asked, file);
168 	}
169 
170 	if (colon) {
171 		colon[0] = ':';
172 	}
173 
174 
175 }
176