1 /**
2 * xrdp: A Remote Desktop Protocol server.
3 *
4 * Copyright (C) Jay Sorg 2004-2014
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * read a config file
19 */
20
21 #if defined(HAVE_CONFIG_H)
22 #include <config_ac.h>
23 #endif
24
25 #include "arch.h"
26 #include "os_calls.h"
27 #include "string_calls.h"
28 #include "list.h"
29 #include "file.h"
30 #include "parse.h"
31
32 #define FILE_MAX_LINE_BYTES 2048
33
34 static int
35 file_read_ini_line(struct stream *s, char *text, int text_bytes);
36
37 /*****************************************************************************/
38 /* look up for a section name within str (i.e. pattern [section_name])
39 * if a section name is found, this function return 1 and copy the section
40 * inplace of str. */
41 static int
line_lookup_for_section_name(char * str,int str_bytes)42 line_lookup_for_section_name(char *str, int str_bytes)
43 {
44 int name_index_start;
45 int index;
46 char c;
47
48 name_index_start = -1;
49 index = 0;
50 while ((c = str[index]) != 0)
51 {
52 if (c == '[')
53 {
54 name_index_start = index + 1;
55 }
56 else if (c == ']' && name_index_start > 0)
57 {
58 if (name_index_start + index >= str_bytes)
59 {
60 return 0;
61 }
62 for (index = index - name_index_start; index > 0; index--)
63 {
64 str[0] = str[name_index_start];
65 str++;
66 }
67 str[0] = 0;
68 return 1;
69 }
70 ++index;
71 }
72 return 0;
73 }
74
75
76 /*****************************************************************************/
77 /* returns error
78 returns 0 if everything is ok
79 returns 1 if problem reading file */
80 static int
l_file_read_sections(int fd,int max_file_size,struct list * names)81 l_file_read_sections(int fd, int max_file_size, struct list *names)
82 {
83 struct stream *s;
84 char text[FILE_MAX_LINE_BYTES];
85 int len;
86 int rv;
87
88 rv = 0;
89 g_file_seek(fd, 0);
90 g_memset(text, 0, FILE_MAX_LINE_BYTES);
91 list_clear(names);
92 make_stream(s);
93 init_stream(s, max_file_size);
94 len = g_file_read(fd, s->data, max_file_size);
95
96 if (len > 0)
97 {
98 s->end = s->p + len;
99 while (file_read_ini_line(s, text, FILE_MAX_LINE_BYTES) == 0)
100 {
101 if (line_lookup_for_section_name(text, FILE_MAX_LINE_BYTES) != 0)
102 {
103 list_add_item(names, (tbus)g_strdup(text));
104 }
105 }
106 }
107 else if (len < 0)
108 {
109 rv = 1;
110 }
111
112 free_stream(s);
113 return rv;
114 }
115
116 /*****************************************************************************/
117 /* Read a line in the stream 's', removing comments.
118 * returns error
119 * returns 0 if everything is ok
120 * returns 1 if problem reading file */
121 static int
file_read_ini_line(struct stream * s,char * text,int text_bytes)122 file_read_ini_line(struct stream *s, char *text, int text_bytes)
123 {
124 int i;
125 int skip_to_end;
126 int at_end;
127 char c;
128
129 skip_to_end = 0;
130
131 if (!s_check_rem(s, 1))
132 {
133 return 1;
134 }
135
136 i = 0;
137 in_uint8(s, c);
138
139 while (c != 10 && c != 13)
140 {
141 /* these mean skip the rest of the line */
142 if (c == '#' || c == ';')
143 {
144 skip_to_end = 1;
145 }
146
147 if (!skip_to_end)
148 {
149 text[i] = c;
150 i++;
151 if (i >= text_bytes)
152 {
153 return 1;
154 }
155 }
156
157 if (s_check_rem(s, 1))
158 {
159 in_uint8(s, c);
160 }
161 else
162 {
163 c = 0;
164 break;
165 }
166 }
167
168 if (c == 10 || c == 13)
169 {
170 at_end = 0;
171
172 while (c == 10 || c == 13)
173 {
174 if (s_check_rem(s, 1))
175 {
176 in_uint8(s, c);
177 }
178 else
179 {
180 at_end = 1;
181 break;
182 }
183 }
184
185 if (!at_end)
186 {
187 s->p--;
188 }
189 }
190
191 text[i] = 0;
192
193 return 0;
194 }
195
196
197 /*****************************************************************************/
198 /* returns error */
199 static int
file_split_name_value(char * text,char * name,char * value)200 file_split_name_value(char *text, char *name, char *value)
201 {
202 int len;
203 int i;
204 int value_index;
205 int name_index;
206 int on_to;
207
208 value_index = 0;
209 name_index = 0;
210 on_to = 0;
211 name[0] = 0;
212 value[0] = 0;
213 len = g_strlen(text);
214
215 for (i = 0; i < len; i++)
216 {
217 if (text[i] == '=' && !on_to)
218 {
219 on_to = 1;
220 }
221 else if (on_to)
222 {
223 value[value_index] = text[i];
224 value_index++;
225 value[value_index] = 0;
226 }
227 else
228 {
229 name[name_index] = text[i];
230 name_index++;
231 name[name_index] = 0;
232 }
233 }
234
235 g_strtrim(name, 3); /* trim both right and left */
236 g_strtrim(value, 3); /* trim both right and left */
237 return 0;
238 }
239
240 /*****************************************************************************/
241 /* return error */
242 static int
l_file_read_section(int fd,int max_file_size,const char * section,struct list * names,struct list * values)243 l_file_read_section(int fd, int max_file_size, const char *section,
244 struct list *names, struct list *values)
245 {
246 struct stream *s;
247 char *data;
248 char *text;
249 char *name;
250 char *value;
251 char *lvalue;
252 int len;
253 int file_size;
254
255 data = (char *) g_malloc(FILE_MAX_LINE_BYTES * 3, 0);
256 text = data;
257 name = text + FILE_MAX_LINE_BYTES;
258 value = name + FILE_MAX_LINE_BYTES;
259
260 file_size = 32 * 1024; /* 32 K file size limit */
261 g_file_seek(fd, 0);
262 g_memset(text, 0, FILE_MAX_LINE_BYTES);
263 list_clear(names);
264 list_clear(values);
265 make_stream(s);
266 init_stream(s, file_size);
267 len = g_file_read(fd, s->data, file_size);
268
269 if (len > 0)
270 {
271 s->end = s->p + len;
272 while (file_read_ini_line(s, text, FILE_MAX_LINE_BYTES) == 0)
273 {
274 if (line_lookup_for_section_name(text, FILE_MAX_LINE_BYTES) != 0)
275 {
276 if (g_strcasecmp(section, text) == 0)
277 {
278 while (file_read_ini_line(s, text,
279 FILE_MAX_LINE_BYTES) == 0)
280 {
281 if (line_lookup_for_section_name(text, FILE_MAX_LINE_BYTES) != 0)
282 {
283 break;
284 }
285
286 if (g_strlen(text) > 0)
287 {
288 file_split_name_value(text, name, value);
289 list_add_item(names, (tbus)g_strdup(name));
290
291 if (value[0] == '$')
292 {
293 lvalue = g_getenv(value + 1);
294
295 if (lvalue != 0)
296 {
297 list_add_item(values, (tbus)g_strdup(lvalue));
298 }
299 else
300 {
301 list_add_item(values, (tbus)g_strdup(""));
302 }
303 }
304 else
305 {
306 list_add_item(values, (tbus)g_strdup(value));
307 }
308 }
309 }
310 free_stream(s);
311 g_free(data);
312 return 0;
313 }
314 }
315 }
316 }
317
318 free_stream(s);
319 g_free(data);
320 return 1;
321 }
322
323 /*****************************************************************************/
324 /* returns error
325 returns 0 if everything is ok
326 returns 1 if problem reading file */
327 /* 32 K file size limit */
328 int
file_read_sections(int fd,struct list * names)329 file_read_sections(int fd, struct list *names)
330 {
331 return l_file_read_sections(fd, 32 * 1024, names);
332 }
333
334 /*****************************************************************************/
335 /* return error */
336 /* this function should be preferred over file_read_sections because it can
337 read any file size */
338 int
file_by_name_read_sections(const char * file_name,struct list * names)339 file_by_name_read_sections(const char *file_name, struct list *names)
340 {
341 int fd;
342 int file_size;
343 int rv;
344
345 file_size = g_file_get_size(file_name);
346
347 if (file_size < 1)
348 {
349 return 1;
350 }
351
352 fd = g_file_open_ex(file_name, 1, 0, 0, 0);
353
354 if (fd < 0)
355 {
356 return 1;
357 }
358
359 rv = l_file_read_sections(fd, file_size, names);
360 g_file_close(fd);
361 return rv;
362 }
363
364 /*****************************************************************************/
365 /* return error */
366 /* 32 K file size limit */
367 int
file_read_section(int fd,const char * section,struct list * names,struct list * values)368 file_read_section(int fd, const char *section,
369 struct list *names, struct list *values)
370 {
371 return l_file_read_section(fd, 32 * 1024, section, names, values);
372 }
373
374 /*****************************************************************************/
375 /* return error */
376 /* this function should be preferred over file_read_section because it can
377 read any file size */
378 int
file_by_name_read_section(const char * file_name,const char * section,struct list * names,struct list * values)379 file_by_name_read_section(const char *file_name, const char *section,
380 struct list *names, struct list *values)
381 {
382 int fd;
383 int file_size;
384 int rv;
385
386 file_size = g_file_get_size(file_name);
387
388 if (file_size < 1)
389 {
390 return 1;
391 }
392
393 fd = g_file_open_ex(file_name, 1, 0, 0, 0);
394
395 if (fd < 0)
396 {
397 return 1;
398 }
399
400 rv = l_file_read_section(fd, file_size, section, names, values);
401 g_file_close(fd);
402 return rv;
403 }
404