-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.cc
103 lines (81 loc) · 2.73 KB
/
main.cc
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
#include <civetweb.h>
#include <cstdlib>
#include <cstring>
#include <dlfcn.h>
#include <iostream>
#include <lace/haystack.h>
#include <lace/objectstack.h>
#include <lace/scoped.h>
#include <unistd.h>
#include <vector>
#include <string>
#include <map>
void mg_atexit() { mg_exit_library(); }
int
main(int argc, char ** argv) {
if (argc <= 1) {
for (const mg_option * opt = mg_get_valid_options() ; opt->name ; ++opt) {
std::cout << opt->name;
if (opt->default_value)
std::cout << "\t= " << opt->default_value;
std::cout << std::endl;
}
}
lace::haystack options;
for (int i = 1 ; i < argc ; ++i) {
char * arg = argv[i];
static const char prefix[] = "--";
if (0 != strncmp(arg, prefix, strlen(prefix)))
continue;
arg += strlen(prefix);
for (const mg_option * opt = mg_get_valid_options() ; opt->name ; ++opt) {
size_t l = strlen(opt->name);
if (0 == strncmp(arg, opt->name, l) && 0 == strcspn(arg+l, "=")) {
options.pointer(opt->name).pointer(arg+l+!!arg[l]);
arg = NULL;
break;
}
}
if (arg) std::cerr << "unknown argument: " << arg << std::endl;
}
if (!mg_init_library(MG_FEATURES_SSL))
return EXIT_FAILURE;
atexit(mg_atexit);
lace::objectstack dls;
lace::scoped<mg_context, void, mg_stop> mg(mg_start(NULL, 0, (const char **)options.pointer(NULL).finish()));
if (!mg)
return EXIT_FAILURE;
for (int i = 1 ; i < argc ; ++i) try {
if (argv[i][0] == '-')
continue;
std::string prefix = "/";
std::string config = "";
const char * c = argv[i];
size_t s = strcspn(c, "=#");
std::string object(c, s);
c += s;
if ('=' == *c) {
s = strcspn(c, "#");
prefix.assign(c+1, s-1);
c += s;
}
if ('#' == *c) {
s = strcspn(c, "");
config.assign(c+1, s-1);
c += s;
}
std::cerr << "loading " << object << "=" << prefix << "#" << config << std::endl;
void * h = dlopen(object.c_str(), RTLD_LOCAL | RTLD_LAZY);
if (!h) throw std::runtime_error(dlerror());
dls.make<lace::scoped<void, int, dlclose> >(h);
typedef void (*install_t)(mg_context *, const char *, const char *);
auto f = reinterpret_cast<install_t>(dlsym(h, "install"));
if (!f) throw std::runtime_error(dlerror());
f(mg, prefix.c_str(), config.c_str());
} catch(const std::exception &e) {
std::cerr << e.what() << std::endl;
continue;
}
while (true) { sleep (1); }
return EXIT_SUCCESS;
}