-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.c
More file actions
123 lines (99 loc) · 2.34 KB
/
Copy pathconfig.c
File metadata and controls
123 lines (99 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* redirect is a web server for subdomain redirects.
* Copyright (C) 2019 Esote
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <sys/mman.h>
#include <sys/stat.h>
#include <ctype.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "redirect.h"
struct route *
config(char *name)
{
char *f;
struct route *r;
struct stat st;
size_t f_l;
size_t n;
int fd;
char *t, *e1, *e2;
r = NULL;
n = 0;
if ((fd = open(name, O_RDONLY)) == -1) {
return NULL;
}
if (fstat(fd, &st) == -1) {
return NULL;
}
if (st.st_size == 0) {
errx(1, "empty config");
}
f_l = (size_t)st.st_size + 1;
if ((f = mmap(NULL, f_l, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
return NULL;
}
f[f_l - 1] = '\0';
if (close(fd) == -1) {
return NULL;
}
/* Tokenize line-separated routes between space-separated hosts. */
for (t = strtok_r(f, NL, &e1); t != NULL; t = strtok_r(NULL, NL, &e1)) {
if ((r = realloc(r, (n + 1) * sizeof(struct route))) == NULL) {
return NULL;
}
if ((t = strtok_r(t, SP, &e2)) == NULL) {
errx(1, "malformed config");
}
if ((r[n].from = strdup(t)) == NULL) {
return NULL;
}
if ((t = strtok_r(NULL, SP, &e2)) == NULL) {
errx(1, "malformed config");
}
if ((r[n].to = strdup(t)) == NULL) {
return NULL;
}
n++;
}
if (n == 0) {
errx(1, "no routes parsed");
}
if ((r = realloc(r, (n + 1) * sizeof(struct route))) == NULL) {
return NULL;
}
(void)memset(&r[n], 0, sizeof(struct route));
if (munmap(f, f_l) == -1) {
return NULL;
}
return r;
}
void
config_free(struct route *r)
{
struct route *rr = r;
while (rr->from != NULL)
{
free(rr->from);
free(rr->to);
rr++;
}
free(r);
}