Removing gotos in config.c

This commit is contained in:
2023-01-26 17:31:20 +01:00
parent 9ee0e11c86
commit bd73061462

View File

@ -16,27 +16,10 @@
config_t config; config_t config;
int config_load(const char *filename) { static int config_parse_line(char *line, char *section, int *i, int *j) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
critical("Unable to open config file");
return -1;
}
memset(&config, 0, sizeof(config));
int i = 0;
int j = 0;
int line_num = 0;
int mode = 0; int mode = 0;
char section = 0;
char *source, *target; char *source, *target;
char *line = NULL;
ssize_t read;
size_t line_len = 0;
while ((read = getline(&line, &line_len, file)) != -1) {
line_num++;
char *ptr = line; char *ptr = line;
char *comment = strpbrk(ptr, "#\r\n"); char *comment = strpbrk(ptr, "#\r\n");
if (comment != NULL) comment[0] = 0; if (comment != NULL) comment[0] = 0;
@ -48,33 +31,33 @@ int config_load(const char *filename) {
end_ptr--; end_ptr--;
} }
len = strlen(ptr); len = strlen(ptr);
if (len == 0) continue; if (len == 0) return 0;
if (ptr[0] == '[') { if (ptr[0] == '[') {
if (ptr[len - 1] != ']') goto err; if (ptr[len - 1] != ']') return -1;
ptr++; ptr++;
int l = 0; int l = 0;
if (strncmp(ptr, "host", 4) == 0 && (ptr[4] == ' ' || ptr[4] == '\t')) { if (strncmp(ptr, "host", 4) == 0 && (ptr[4] == ' ' || ptr[4] == '\t')) {
ptr += 4; ptr += 4;
while (ptr[0] == ' ' || ptr[0] == '\t' || ptr[0] == ']') ptr++; while (ptr[0] == ' ' || ptr[0] == '\t' || ptr[0] == ']') ptr++;
while (ptr[l] != ' ' && ptr[l] != '\t' && ptr[l] != ']') l++; while (ptr[l] != ' ' && ptr[l] != '\t' && ptr[l] != ']') l++;
if (l == 0) goto err; if (l == 0) return -1;
snprintf(config.hosts[i].name, sizeof(config.hosts[i].name), "%.*s", l, ptr); snprintf(config.hosts[*i].name, sizeof(config.hosts[*i].name), "%.*s", l, ptr);
i++; ++(*i);
section = 'h'; *section = 'h';
} else if (strncmp(ptr, "cert", 4) == 0 && (ptr[4] == ' ' || ptr[4] == '\t')) { } else if (strncmp(ptr, "cert", 4) == 0 && (ptr[4] == ' ' || ptr[4] == '\t')) {
ptr += 4; ptr += 4;
while (ptr[0] == ' ' || ptr[0] == '\t' || ptr[0] == ']') ptr++; while (ptr[0] == ' ' || ptr[0] == '\t' || ptr[0] == ']') ptr++;
while (ptr[l] != ' ' && ptr[l] != '\t' && ptr[l] != ']') l++; while (ptr[l] != ' ' && ptr[l] != '\t' && ptr[l] != ']') l++;
if (l == 0) goto err; if (l == 0) return -1;
snprintf(config.certs[j].name, sizeof(config.certs[j].name), "%.*s", l, ptr); snprintf(config.certs[*j].name, sizeof(config.certs[*j].name), "%.*s", l, ptr);
j++; ++(*j);
section = 'c'; *section = 'c';
} else { } else {
goto err; return -1;
} }
continue; return 0;
} else if (section == 0) { } else if (*section == 0) {
if (len > 10 && strncmp(ptr, "geoip_dir", 9) == 0 && (ptr[9] == ' ' || ptr[9] == '\t')) { if (len > 10 && strncmp(ptr, "geoip_dir", 9) == 0 && (ptr[9] == ' ' || ptr[9] == '\t')) {
source = ptr + 9; source = ptr + 9;
target = config.geoip_dir; target = config.geoip_dir;
@ -82,10 +65,10 @@ int config_load(const char *filename) {
source = ptr + 10; source = ptr + 10;
target = config.dns_server; target = config.dns_server;
} else { } else {
goto err; return -1;
} }
} else if (section == 'c') { } else if (*section == 'c') {
cert_config_t *cc = &config.certs[j - 1]; cert_config_t *cc = &config.certs[*j - 1];
if (len > 12 && strncmp(ptr, "certificate", 11) == 0 && (ptr[11] == ' ' || ptr[11] == '\t')) { if (len > 12 && strncmp(ptr, "certificate", 11) == 0 && (ptr[11] == ' ' || ptr[11] == '\t')) {
source = ptr + 11; source = ptr + 11;
target = cc->full_chain; target = cc->full_chain;
@ -93,15 +76,15 @@ int config_load(const char *filename) {
source = ptr + 11; source = ptr + 11;
target = cc->priv_key; target = cc->priv_key;
} else { } else {
goto err; return -1;
} }
} else if (section == 'h') { } else if (*section == 'h') {
host_config_t *hc = &config.hosts[i - 1]; host_config_t *hc = &config.hosts[*i - 1];
if (len > 8 && strncmp(ptr, "webroot", 7) == 0 && (ptr[7] == ' ' || ptr[7] == '\t')) { if (len > 8 && strncmp(ptr, "webroot", 7) == 0 && (ptr[7] == ' ' || ptr[7] == '\t')) {
source = ptr + 7; source = ptr + 7;
target = hc->local.webroot; target = hc->local.webroot;
if (hc->type != 0 && hc->type != CONFIG_TYPE_LOCAL) { if (hc->type != 0 && hc->type != CONFIG_TYPE_LOCAL) {
goto err; return -1;
} else { } else {
hc->type = CONFIG_TYPE_LOCAL; hc->type = CONFIG_TYPE_LOCAL;
} }
@ -113,7 +96,7 @@ int config_load(const char *filename) {
target = NULL; target = NULL;
mode = 1; mode = 1;
if (hc->type != 0 && hc->type != CONFIG_TYPE_LOCAL) { if (hc->type != 0 && hc->type != CONFIG_TYPE_LOCAL) {
goto err; return -1;
} else { } else {
hc->type = CONFIG_TYPE_LOCAL; hc->type = CONFIG_TYPE_LOCAL;
} }
@ -121,7 +104,7 @@ int config_load(const char *filename) {
source = ptr + 8; source = ptr + 8;
target = hc->proxy.hostname; target = hc->proxy.hostname;
if (hc->type != 0 && hc->type != CONFIG_TYPE_REVERSE_PROXY) { if (hc->type != 0 && hc->type != CONFIG_TYPE_REVERSE_PROXY) {
goto err; return -1;
} else { } else {
hc->type = CONFIG_TYPE_REVERSE_PROXY; hc->type = CONFIG_TYPE_REVERSE_PROXY;
} }
@ -130,56 +113,75 @@ int config_load(const char *filename) {
target = NULL; target = NULL;
mode = 2; mode = 2;
if (hc->type != 0 && hc->type != CONFIG_TYPE_REVERSE_PROXY) { if (hc->type != 0 && hc->type != CONFIG_TYPE_REVERSE_PROXY) {
goto err; return -1;
} else { } else {
hc->type = CONFIG_TYPE_REVERSE_PROXY; hc->type = CONFIG_TYPE_REVERSE_PROXY;
} }
} else if (streq(ptr, "http")) { } else if (streq(ptr, "http")) {
if (hc->type != 0 && hc->type != CONFIG_TYPE_REVERSE_PROXY) { if (hc->type != 0 && hc->type != CONFIG_TYPE_REVERSE_PROXY) {
goto err; return -1;
} else { } else {
hc->type = CONFIG_TYPE_REVERSE_PROXY; hc->type = CONFIG_TYPE_REVERSE_PROXY;
hc->proxy.enc = 0; hc->proxy.enc = 0;
} }
continue; return 0;
} else if (streq(ptr, "https")) { } else if (streq(ptr, "https")) {
if (hc->type != 0 && hc->type != CONFIG_TYPE_REVERSE_PROXY) { if (hc->type != 0 && hc->type != CONFIG_TYPE_REVERSE_PROXY) {
goto err; return -1;
} else { } else {
hc->type = CONFIG_TYPE_REVERSE_PROXY; hc->type = CONFIG_TYPE_REVERSE_PROXY;
hc->proxy.enc = 1; hc->proxy.enc = 1;
} }
continue; return 0;
} else { } else {
goto err; return -1;
} }
} else { } else {
goto err; return -1;
} }
while (source[0] == ' ' || source[0] == '\t') source++; while (source[0] == ' ' || source[0] == '\t') source++;
if (strlen(source) == 0) { if (strlen(source) == 0) return -1;
err:
critical("Unable to parse config file (line %i)", line);
free(line);
fclose(file);
return -2;
}
if (target != NULL) { if (target != NULL) {
strcpy(target, source); strcpy(target, source);
} else if (mode == 1) { } else if (mode == 1) {
if (streq(source, "forbidden")) { if (streq(source, "forbidden")) {
config.hosts[i - 1].local.dir_mode = URI_DIR_MODE_FORBIDDEN; config.hosts[*i - 1].local.dir_mode = URI_DIR_MODE_FORBIDDEN;
} else if (streq(source, "info")) { } else if (streq(source, "info")) {
config.hosts[i - 1].local.dir_mode = URI_DIR_MODE_INFO; config.hosts[*i - 1].local.dir_mode = URI_DIR_MODE_INFO;
} else if (streq(source, "list")) { } else if (streq(source, "list")) {
config.hosts[i - 1].local.dir_mode = URI_DIR_MODE_LIST; config.hosts[*i - 1].local.dir_mode = URI_DIR_MODE_LIST;
} else { } else {
goto err; return -1;
} }
} else if (mode == 2) { } else if (mode == 2) {
config.hosts[i - 1].proxy.port = (unsigned short) strtoul(source, NULL, 10); config.hosts[*i - 1].proxy.port = (unsigned short) strtoul(source, NULL, 10);
}
return 0;
}
int config_load(const char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
critical("Unable to open config file");
return -1;
}
memset(&config, 0, sizeof(config));
int i = 0, j = 0;
char section = 0;
char *line = NULL;
size_t line_len = 0;
for (int line_num = 1; getline(&line, &line_len, file) != -1; line_num++) {
if (config_parse_line(line, &section, &i, &j) != 0) {
critical("Unable to parse config file (line %i)", line_num);
free(line);
fclose(file);
return -2;
} }
} }
@ -190,11 +192,14 @@ int config_load(const char *filename) {
host_config_t *hc = &config.hosts[k]; host_config_t *hc = &config.hosts[k];
if (hc->type == CONFIG_TYPE_LOCAL) { if (hc->type == CONFIG_TYPE_LOCAL) {
char *webroot = config.hosts[k].local.webroot; char *webroot = config.hosts[k].local.webroot;
if (webroot[strlen(webroot) - 1] == '/') { while (webroot[strlen(webroot) - 1] == '/') webroot[strlen(webroot) - 1] = 0;
webroot[strlen(webroot) - 1] = 0;
} }
if (hc->cert_name[0] == 0) {
critical("Unable to parse config file: host config (%s) does not contain a certificate", hc->name);
return -2;
} }
if (hc->cert_name[0] == 0) goto err2;
int found = 0; int found = 0;
for (int m = 0; m < j; m++) { for (int m = 0; m < j; m++) {
if (streq(config.certs[m].name, hc->cert_name)) { if (streq(config.certs[m].name, hc->cert_name)) {
@ -204,8 +209,7 @@ int config_load(const char *filename) {
} }
} }
if (!found) { if (!found) {
err2: critical("Unable to parse config file: certificate (%s) for host config (%s) not found", hc->cert_name, hc->name);
critical("Unable to parse config file");
return -2; return -2;
} }
} }