/* Initialize from ini file */
int sbase_initialize(SBASE *sbase, char *conf)
{
char line[HTTP_HEAD_MAX], *s = NULL, *p = NULL,
*cacert_file = NULL, *privkey_file = NULL;
int n = 0, i = 0;
void *dp = NULL;
if((dict = iniparser_new(conf)) == NULL)
{
fprintf(stderr, "Initializing conf:%s failed, %s\n", conf, strerror(errno));
_exit(-1);
}
/* SBASE */
sbase->nchilds = iniparser_getint(dict, "SBASE:nchilds", 0);
sbase->connections_limit = iniparser_getint(dict, "SBASE:connections_limit", SB_CONN_MAX);
sbase->usec_sleep = iniparser_getint(dict, "SBASE:usec_sleep", SB_USEC_SLEEP);
sbase->set_log(sbase, iniparser_getstr(dict, "SBASE:logfile"));
sbase->set_evlog(sbase, iniparser_getstr(dict, "SBASE:evlogfile"));
/* XHTTPD */
if((service = service_init()) == NULL)
{
fprintf(stderr, "Initialize service failed, %s", strerror(errno));
_exit(-1);
}
service->family = iniparser_getint(dict, "XHTTPD:inet_family", AF_INET);
service->sock_type = iniparser_getint(dict, "XHTTPD:socket_type", SOCK_STREAM);
service->ip = iniparser_getstr(dict, "XHTTPD:service_ip");
service->port = iniparser_getint(dict, "XHTTPD:service_port", 80);
service->working_mode = iniparser_getint(dict, "XHTTPD:working_mode", WORKING_PROC);
service->service_type = iniparser_getint(dict, "XHTTPD:service_type", C_SERVICE);
service->service_name = iniparser_getstr(dict, "XHTTPD:service_name");
service->nprocthreads = iniparser_getint(dict, "XHTTPD:nprocthreads", 1);
service->ndaemons = iniparser_getint(dict, "XHTTPD:ndaemons", 0);
service->use_iodaemon = iniparser_getint(dict, "XHTTPD:use_iodaemon", 0);
service->session.packet_type=iniparser_getint(dict, "XHTTPD:packet_type",PACKET_DELIMITER);
if((service->session.packet_delimiter = iniparser_getstr(dict, "XHTTPD:packet_delimiter")))
{
p = s = service->session.packet_delimiter;
while(*p != 0 )
{
if(*p == '\\' && *(p+1) == 'n')
{
*s++ = '\n';
p += 2;
}
else if (*p == '\\' && *(p+1) == 'r')
{
*s++ = '\r';
p += 2;
}
else
*s++ = *p++;
}
*s++ = 0;
service->session.packet_delimiter_length = strlen(service->session.packet_delimiter);
}
service->session.buffer_size = iniparser_getint(dict, "XHTTPD:buffer_size", SB_BUF_SIZE);
service->session.packet_reader = &xhttpd_packet_reader;
service->session.packet_handler = &xhttpd_packet_handler;
service->session.data_handler = &xhttpd_data_handler;
service->session.oob_handler = &xhttpd_oob_handler;
cacert_file = iniparser_getstr(dict, "XHTTPD:cacert_file");
privkey_file = iniparser_getstr(dict, "XHTTPD:privkey_file");
if(cacert_file && privkey_file && iniparser_getint(dict, "XHTTPD:is_use_SSL", 0))
{
service->is_use_SSL = 1;
service->cacert_file = cacert_file;
service->privkey_file = privkey_file;
}
//httpd home
TRIETAB_INIT(http_headers_map);
if(http_headers_map)
{
for(i = 0; i < HTTP_HEADER_NUM; i++)
{
p = http_headers[i].e;
s = line;
while(*p != '\0')
{
if(*p >= 'A' && *p <= 'Z')
{
*s++ = *p++ - ('A' - 'a');
}
else *s++ = *p++;
}
*s = '\0';
dp = (void *)((long)(i + 1));
TRIETAB_ADD(http_headers_map, line, http_headers[i].elen, dp);
}
}
if((p = iniparser_getstr(dict, "XHTTPD:httpd_home")))
httpd_home = p;
http_indexes_view = iniparser_getint(dict, "XHTTPD:http_indexes_view", 1);
if((p = iniparser_getstr(dict, "XHTTPD:httpd_index")))
{
memset(http_indexes, 0, sizeof(char *) * HTTP_INDEX_MAX);
nindexes = 0;
while(nindexes < HTTP_INDEX_MAX && *p != '\0')
{
while(*p == 0x20 || *p == '\t' || *p == ',' || *p == ';')++p;
if(*p != '\0')
{
http_indexes[nindexes] = p;
while(*p != '\0' && *p != 0x20 && *p != '\t'
&& *p != ',' && *p != ';')++p;
*p++ = '\0';
//fprintf(stdout, "%s::%d %d[%s]\n", __FILE__, __LINE__, nindexes, http_indexes[nindexes]);
++nindexes;
}else break;
}
}
if((httpd_compress = iniparser_getint(dict, "XHTTPD:httpd_compress", 0)))
{
if((p = iniparser_getstr(dict, "XHTTPD:httpd_compress_cachedir")))
httpd_compress_cachedir = p;
if(access(httpd_compress_cachedir, F_OK) && xhttpd_mkdir(httpd_compress_cachedir, 0755))
{
fprintf(stderr, "create compress cache dir %s failed, %s\n",
httpd_compress_cachedir, strerror(errno));
return -1;
}
}
//name map
TRIETAB_INIT(namemap);
if(namemap)
{
for(i = 0; i < HTTP_MIME_NUM; i++)
{
dp = (void *)((long)(i + 1));
p = http_mime_types[i].e;
n = http_mime_types[i].elen;
TRIETAB_ADD(namemap, p, n, dp);
}
if((p = iniparser_getstr(dict, "XHTTPD:httpd_vhosts")))
{
memset(httpd_vhosts, 0, sizeof(HTTP_VHOST) * HTTP_VHOST_MAX);
nvhosts = 0;
while(nvhosts < HTTP_VHOST_MAX && *p != '\0')
{
while(*p != '[') ++p;
++p;
while(*p == 0x20 || *p == '\t' || *p == ',' || *p == ';')++p;
httpd_vhosts[nvhosts].name = p;
while(*p != ':' && *p != 0x20 && *p != '\t') ++p;
*p = '\0';
if((n = (p - httpd_vhosts[nvhosts].name)) > 0)
{
dp = (void *)((long)(nvhosts + 1));
TRIETAB_ADD(namemap, httpd_vhosts[nvhosts].name, n, dp);
}
++p;
while(*p == 0x20 || *p == '\t' || *p == ',' || *p == ';')++p;
httpd_vhosts[nvhosts].home = p;
while(*p != ']' && *p != 0x20 && *p != '\t') ++p;
*p++ = '\0';
++nvhosts;
}
}
}
//host map
TRIETAB_INIT(hostmap);
TRIETAB_INIT(urlmap);
if((p = iniparser_getstr(dict, "XHTTPD:logfile")))
{
service->set_log(service, p);
}
if((p = iniparser_getstr(dict, "XHTTPD:access_log")))
{
LOGGER_INIT(logger, p);
}
/* server */
//fprintf(stdout, "Parsing for server...\n");
return sbase->add_service(sbase, service);
/*
if(service->sock_type == SOCK_DGRAM
&& (p = iniparser_getstr(dict, "XHTTPD:multicast")) && ret == 0)
{
ret = service->add_multicast(service, p);
}
return ret;
*/
}
int main(int argc, char **argv)
{
pid_t pid;
char *conf = NULL, *p = NULL, ch = 0;
int is_daemon = 0;
/* get configure file */
while((ch = getopt(argc, argv, "c:d")) != -1)
{
if(ch == 'c') conf = optarg;
else if(ch == 'd') is_daemon = 1;
}
if(conf == NULL)
{
fprintf(stderr, "Usage:%s -d -c config_file\n", argv[0]);
_exit(-1);
}
/* locale */
setlocale(LC_ALL, "C");
/* signal */
signal(SIGTERM, &xhttpd_stop);
signal(SIGINT, &xhttpd_stop);
signal(SIGHUP, &xhttpd_stop);
signal(SIGPIPE, SIG_IGN);
//daemon
if(is_daemon)
{
pid = fork();
switch (pid) {
case -1:
perror("fork()");
exit(EXIT_FAILURE);
break;
case 0: //child
if(setsid() == -1)
exit(EXIT_FAILURE);
break;
default://parent
_exit(EXIT_SUCCESS);
break;
}
}
setrlimiter("RLIMIT_NOFILE", RLIMIT_NOFILE, 10240);
if((sbase = sbase_init()) == NULL)
{
exit(EXIT_FAILURE);
return -1;
}
fprintf(stdout, "Initializing from configure file:%s\n", conf);
/* Initialize sbase */
if(sbase_initialize(sbase, conf) != 0 )
{
fprintf(stderr, "Initialize from configure file failed\n");
exit(EXIT_FAILURE);
return -1;
}
fprintf(stdout, "Initialized successed\n");
if(service->sock_type == SOCK_DGRAM
&& (p = iniparser_getstr(dict, "XHTTPD:multicast")))
{
if(service->add_multicast(service, p) != 0)
{
fprintf(stderr, "add multicast:%s failed, %s", p, strerror(errno));
exit(EXIT_FAILURE);
return -1;
}
p = "224.1.1.168";
if(service->add_multicast(service, p) != 0)
{
fprintf(stderr, "add multicast:%s failed, %s", p, strerror(errno));
exit(EXIT_FAILURE);
return -1;
}
}
sbase->running(sbase, 0);
//sbase->running(sbase, 3600);
//sbase->running(sbase, 90000000);sbase->stop(sbase);
sbase->clean(&sbase);
if(namemap) TRIETAB_CLEAN(namemap);
if(hostmap) TRIETAB_CLEAN(hostmap);
if(urlmap) TRIETAB_CLEAN(urlmap);
if(http_headers_map) TRIETAB_CLEAN(http_headers_map);
LOGGER_CLEAN(logger);
if(dict)iniparser_free(dict);
return 0;
}