source: Main/trunk/Server/config.c@ 20

Last change on this file since 20 was 20, checked in by Nishi, on Sep 14, 2024 at 6:59:15 PM

can show index

  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1/* $Id: config.c 20 2024-09-14 09:59:15Z nishi $ */
2
3#define SOURCE
4
5#include "tw_config.h"
6#include "tw_module.h"
7
8#include <stdio.h>
9#include <stdint.h>
10#include <stdlib.h>
11#include <string.h>
12#include <unistd.h>
13
14#ifdef __MINGW32__
15#include <winsock2.h>
16#endif
17
18#include <cm_string.h>
19#include <cm_log.h>
20
21struct tw_config config;
22
23struct tw_config_entry* tw_vhost_match(const char* name, int port) {
24 int i;
25 for(i = 0; i < config.vhost_count; i++) {
26 if(strcmp(config.vhosts[i].name, name) == 0 && (config.vhosts[i].port == -1 ? 1 : config.vhosts[i].port == port)) {
27 return &config.vhosts[i];
28 }
29 }
30 return &config.root;
31}
32
33void tw_config_init(void) {
34 int i;
35 for(i = 0; i < MAX_PORTS + 1; i++) {
36 config.ports[i] = -1;
37 }
38 for(i = 0; i < MAX_VHOSTS; i++) {
39 config.vhosts[i].sslkey = NULL;
40 config.vhosts[i].sslcert = NULL;
41 config.vhosts[i].root = NULL;
42 }
43 config.root.sslkey = NULL;
44 config.root.sslcert = NULL;
45 config.root.root = NULL;
46 config.vhost_count = 0;
47 config.module_count = 0;
48 config.extension = NULL;
49 config.server_root = cm_strdup(PREFIX);
50 gethostname(config.hostname, 1024);
51}
52
53int tw_config_read(const char* path) {
54 cm_log("Config", "Reading %s", path);
55 char cbuf[2];
56 cbuf[1] = 0;
57 int ln = 0;
58 FILE* f = fopen(path, "r");
59 if(f != NULL) {
60 char* line = malloc(1);
61 line[0] = 0;
62 int stop = 0;
63 struct tw_config_entry* current = &config.root;
64 char* vhost = NULL;
65 while(stop == 0) {
66 int c = fread(cbuf, 1, 1, f);
67 if(cbuf[0] == '\n' || c <= 0) {
68 ln++;
69 char* l = cm_trim(line);
70 if(strlen(l) > 0 && l[0] != '#') {
71 char** r = cm_split(l, " \t");
72 int i;
73 if(cm_strcaseequ(r[0], "Include") || cm_strcaseequ(r[0], "IncludeOptional")) {
74 for(i = 1; r[i] != NULL; i++) {
75 if(tw_config_read(r[i]) != 0 && cm_strcaseequ(r[0], "Include")) {
76 stop = 1;
77 break;
78 }
79 }
80 } else if(cm_strcaseequ(r[0], "BeginVirtualHost")) {
81 if(vhost != NULL) {
82 cm_log("Config", "Already in virtual host section at line %d", ln);
83 stop = 1;
84 } else {
85 if(r[1] == NULL) {
86 cm_log("Config", "Missing virtual host at line %d", ln);
87 stop = 1;
88 } else {
89 vhost = cm_strdup(r[1]);
90 current = &config.vhosts[config.vhost_count++];
91 int i;
92 current->name = cm_strdup(vhost);
93 current->port = -1;
94 for(i = 0; vhost[i] != 0; i++) {
95 if(vhost[i] == ':') {
96 current->name[i] = 0;
97 current->port = atoi(current->name + i + 1);
98 break;
99 }
100 }
101 }
102 }
103 } else if(cm_strcaseequ(r[0], "EndVirtualHost")) {
104 if(vhost == NULL) {
105 cm_log("Config", "Not in virtual host section at line %d", ln);
106 stop = 1;
107 } else {
108 free(vhost);
109 vhost = NULL;
110 current = &config.root;
111 }
112 } else if(cm_strcaseequ(r[0], "Listen") || cm_strcaseequ(r[0], "ListenSSL")) {
113 for(i = 1; r[i] != NULL; i++) {
114 uint64_t port = atoi(r[i]);
115 cm_log("Config", "Going to listen at port %d%s", (int)port, cm_strcaseequ(r[0], "ListenSSL") ? " with SSL" : "");
116 if(cm_strcaseequ(r[0], "ListenSSL")) port |= (1ULL << 32);
117 int j;
118 for(j = 0; config.ports[j] != -1; j++)
119 ;
120 config.ports[j] = port;
121 }
122 } else if(cm_strcaseequ(r[0], "SSLKey")) {
123 if(r[1] == NULL) {
124 cm_log("Config", "Missing path at line %d", ln);
125 stop = 1;
126 } else {
127 if(current->sslkey != NULL) free(current->sslkey);
128 current->sslkey = cm_strdup(r[1]);
129 }
130 } else if(cm_strcaseequ(r[0], "SSLCertificate")) {
131 if(r[1] == NULL) {
132 cm_log("Config", "Missing path at line %d", ln);
133 stop = 1;
134 } else {
135 if(current->sslcert != NULL) free(current->sslcert);
136 current->sslcert = cm_strdup(r[1]);
137 }
138 } else if(cm_strcaseequ(r[0], "DocumentRoot")) {
139 if(r[1] == NULL) {
140 cm_log("Config", "Missing path at line %d", ln);
141 stop = 1;
142 } else {
143 if(current->root != NULL) free(current->root);
144 current->root = cm_strdup(r[1]);
145 }
146 } else if(cm_strcaseequ(r[0], "ServerRoot")) {
147 if(r[1] == NULL) {
148 cm_log("Config", "Missing path at line %d", ln);
149 stop = 1;
150 } else {
151 if(config.server_root != NULL) free(config.server_root);
152 config.server_root = cm_strdup(r[1]);
153 }
154 } else if(cm_strcaseequ(r[0], "LoadModule")) {
155 for(i = 1; r[i] != NULL; i++) {
156 void* mod = tw_module_load(r[i]);
157 if(mod != NULL) {
158 config.modules[config.module_count++] = mod;
159 if(tw_module_init(mod) != 0) {
160 stop = 1;
161 break;
162 }
163 } else {
164 stop = 1;
165 break;
166 }
167 }
168 } else {
169 if(r[0] != NULL) {
170 cm_log("Config", "Unknown directive `%s' at line %d", r[0], ln);
171 }
172 stop = 1;
173 }
174 for(i = 0; r[i] != NULL; i++) free(r[i]);
175 free(r);
176 }
177 free(l);
178 free(line);
179 line = malloc(1);
180 line[0] = 0;
181 if(c <= 0) break;
182 } else if(cbuf[0] != '\r') {
183 char* tmp = line;
184 line = cm_strcat(tmp, cbuf);
185 free(tmp);
186 }
187 }
188 free(line);
189 fclose(f);
190 return stop;
191 } else {
192 cm_log("Config", "Could not open the file");
193 return 1;
194 }
195}
Note: See TracBrowser for help on using the repository browser.