Subversion Repositories Tewi

Rev

Rev 6 | Rev 12 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 nishi 1
/* $Id: config.c 7 2024-09-13 10:40:53Z nishi $ */
2
 
3
#include "tw_config.h"
4
 
5
#include <stdio.h>
7 nishi 6
#include <stdint.h>
4 nishi 7
#include <stdlib.h>
8
#include <string.h>
9
 
10
#include <cm_string.h>
11
#include <cm_log.h>
12
 
6 nishi 13
struct tw_config config;
14
 
7 nishi 15
void tw_config_init(void) {
16
	int i;
17
	for(i = 0; i < MAX_PORTS + 1; i++) {
18
		config.ports[i] = -1;
19
	}
20
}
6 nishi 21
 
22
int tw_config_read(const char* path) {
4 nishi 23
	cm_log("Config", "Reading %s", path);
24
	char cbuf[2];
25
	cbuf[1] = 0;
6 nishi 26
	int ln = 0;
4 nishi 27
	FILE* f = fopen(path, "r");
6 nishi 28
	if(f != NULL) {
4 nishi 29
		char* line = malloc(1);
30
		line[0] = 0;
6 nishi 31
		int stop = 0;
32
		char* vhost = NULL;
33
		while(stop == 0) {
4 nishi 34
			int c = fread(cbuf, 1, 1, f);
6 nishi 35
			if(cbuf[0] == '\n' || c <= 0) {
36
				ln++;
4 nishi 37
				char* l = cm_trim(line);
6 nishi 38
				if(strlen(l) > 0 && l[0] != '#') {
5 nishi 39
					char** r = cm_split(l, " \t");
40
					int i;
6 nishi 41
					if(cm_strcaseequ(r[0], "Include") || cm_strcaseequ(r[0], "IncludeOptional")) {
42
						for(i = 1; r[i] != NULL; i++) {
43
							if(tw_config_read(r[i]) != 0 && cm_strcaseequ(r[0], "Include")) {
44
								stop = 1;
45
								break;
5 nishi 46
							}
47
						}
6 nishi 48
					} else if(cm_strcaseequ(r[0], "BeginVirtualHost")) {
49
						if(vhost != NULL) {
50
							cm_log("Config", "Already in virtual host section");
51
							stop = 1;
52
						} else {
53
							if(r[1] == NULL) {
54
								cm_log("Config", "Missing virtual host");
55
								stop = 1;
56
							} else {
57
								vhost = cm_strdup(r[1]);
58
							}
59
						}
60
					} else if(cm_strcaseequ(r[0], "EndVirtualHost")) {
61
						if(vhost == NULL) {
62
							cm_log("Config", "Not in virtual host section");
63
							stop = 1;
64
						} else {
65
							free(vhost);
66
							vhost = NULL;
67
						}
7 nishi 68
					} else if(cm_strcaseequ(r[0], "Listen") || cm_strcaseequ(r[0], "ListenSSL")) {
69
						for(i = 1; r[i] != NULL; i++) {
70
							uint64_t port = atoi(r[i]);
71
							cm_log("Config", "Going to listen at port %d%s", (int)port, cm_strcaseequ(r[0], "ListenSSL") ? " with SSL" : "");
72
							if(cm_strcaseequ(r[0], "ListenSSL")) port |= (1ULL << 32);
73
							int j;
74
							for(j = 0; config.ports[j] != -1; j++)
75
								;
76
							config.ports[j] = port;
77
						}
6 nishi 78
					} else {
79
						if(r[0] != NULL) {
80
							cm_log("Config", "Unknown directive `%s' at line %d", r[0], ln);
81
						}
82
						stop = 1;
5 nishi 83
					}
84
					for(i = 0; r[i] != NULL; i++) free(r[i]);
85
					free(r);
4 nishi 86
				}
87
				free(l);
88
				free(line);
89
				line = malloc(1);
90
				line[0] = 0;
91
				if(c <= 0) break;
6 nishi 92
			} else if(cbuf[0] != '\r') {
4 nishi 93
				char* tmp = line;
94
				line = cm_strcat(tmp, cbuf);
95
				free(tmp);
96
			}
97
		}
98
		free(line);
99
		fclose(f);
6 nishi 100
		return stop;
101
	} else {
5 nishi 102
		cm_log("Config", "Could not open the file");
4 nishi 103
		return 1;
104
	}
105
}