mirror of
https://github.com/sigmasternchen/CFloor
synced 2025-03-15 20:28:56 +00:00
logging config
This commit is contained in:
parent
a9f91af3da
commit
c67d7d6f78
7 changed files with 207 additions and 44 deletions
194
src/config.c
194
src/config.c
|
@ -3,6 +3,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
@ -33,6 +34,9 @@ void replaceOrAdd(void** array, int* length, void* old, void* new) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct config* config_parse(FILE* file) {
|
struct config* config_parse(FILE* file) {
|
||||||
|
// logger is not yet set but we need error messages
|
||||||
|
setLogging(stdout, ERROR, true);
|
||||||
|
|
||||||
void* toFree[LENGTH_OF_TOFREE_ARRAY];
|
void* toFree[LENGTH_OF_TOFREE_ARRAY];
|
||||||
int toFreeLength = 0;
|
int toFreeLength = 0;
|
||||||
|
|
||||||
|
@ -45,9 +49,12 @@ struct config* config_parse(FILE* file) {
|
||||||
replaceOrAdd(toFree, &toFreeLength, NULL, config);
|
replaceOrAdd(toFree, &toFreeLength, NULL, config);
|
||||||
config->nrBinds = 0;
|
config->nrBinds = 0;
|
||||||
config->binds = NULL;
|
config->binds = NULL;
|
||||||
|
config->logging.accessLogfile = NULL;
|
||||||
|
config->logging.serverLogfile = NULL;
|
||||||
|
config->logging.serverVerbosity = CONFIG_DEFAULT_LOGLEVEL;
|
||||||
|
|
||||||
|
|
||||||
#define BIND (0)
|
#define ROOT (0)
|
||||||
#define BIND_VALUE (10)
|
#define BIND_VALUE (10)
|
||||||
#define BIND_BRACKETS_OPEN (11)
|
#define BIND_BRACKETS_OPEN (11)
|
||||||
#define BIND_CONTENT (12)
|
#define BIND_CONTENT (12)
|
||||||
|
@ -70,7 +77,15 @@ struct config* config_parse(FILE* file) {
|
||||||
#define TYPE_VALUE (1464)
|
#define TYPE_VALUE (1464)
|
||||||
#define INDEX_EQUALS (1465)
|
#define INDEX_EQUALS (1465)
|
||||||
#define INDEX_VALUE (1466)
|
#define INDEX_VALUE (1466)
|
||||||
int state = BIND;
|
#define LOGGING_BRACKETS_OPEN (20)
|
||||||
|
#define LOGGING_CONTENT (21)
|
||||||
|
#define LOGGING_ACCESS_FILE_EQUALS (22)
|
||||||
|
#define LOGGING_ACCESS_FILE_VALUE (23)
|
||||||
|
#define LOGGING_SERVER_FILE_EQUALS (24)
|
||||||
|
#define LOGGING_SERVER_FILE_VALUE (25)
|
||||||
|
#define LOGGING_SERVER_VERBOSITY_EQUALS (26)
|
||||||
|
#define LOGGING_SERVER_VERBOSITY_VALUE (27)
|
||||||
|
int state = ROOT;
|
||||||
|
|
||||||
struct config_bind* currentBind = NULL;
|
struct config_bind* currentBind = NULL;
|
||||||
struct config_site* currentSite = NULL;
|
struct config_site* currentSite = NULL;
|
||||||
|
@ -97,44 +112,46 @@ struct config* config_parse(FILE* file) {
|
||||||
char** tmpArray;
|
char** tmpArray;
|
||||||
|
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case BIND:
|
case ROOT:
|
||||||
if (strcmp(currentToken, "bind") != 0) {
|
if (strcmp(currentToken, "bind") == 0) {
|
||||||
error("config: Unexpected token '%s' on line %d. 'bind' expected", currentToken, currentLine);
|
currentBind = malloc(sizeof(struct config_bind));
|
||||||
|
if (currentBind == NULL) {
|
||||||
|
error("config: couldn't allocate for bind struct: %s", strerror(errno));
|
||||||
|
freeEverything(toFree, toFreeLength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
replaceOrAdd(toFree, &toFreeLength, NULL, currentBind);
|
||||||
|
|
||||||
|
config->nrBinds++;
|
||||||
|
struct config_bind** tmpBind = realloc(config->binds, config->nrBinds * sizeof(struct config_bind*));
|
||||||
|
if (tmpBind == NULL) {
|
||||||
|
error("config: couldn't reallocate for bind array: %s", strerror(errno));
|
||||||
|
freeEverything(toFree, toFreeLength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceOrAdd(toFree, &toFreeLength, config->binds, tmpBind);
|
||||||
|
config->binds = tmpBind;
|
||||||
|
config->binds[config->nrBinds - 1] = currentBind;
|
||||||
|
|
||||||
|
currentBind->nrSites = 0;
|
||||||
|
currentBind->sites = NULL;
|
||||||
|
currentBind->addr = NULL;
|
||||||
|
currentBind->port = NULL;
|
||||||
|
|
||||||
|
#ifdef SSL_SUPPORT
|
||||||
|
currentBind->ssl = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
state = BIND_VALUE;
|
||||||
|
} else if (strcmp(currentToken, "logging") == 0) {
|
||||||
|
state = LOGGING_BRACKETS_OPEN;
|
||||||
|
} else {
|
||||||
|
error("config: Unexpected token '%s' on line %d.", currentToken, currentLine);
|
||||||
freeEverything(toFree, toFreeLength);
|
freeEverything(toFree, toFreeLength);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentBind = malloc(sizeof(struct config_bind));
|
|
||||||
if (currentBind == NULL) {
|
|
||||||
error("config: couldn't allocate for bind struct: %s", strerror(errno));
|
|
||||||
freeEverything(toFree, toFreeLength);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
replaceOrAdd(toFree, &toFreeLength, NULL, currentBind);
|
|
||||||
|
|
||||||
config->nrBinds++;
|
|
||||||
struct config_bind** tmpBind = realloc(config->binds, config->nrBinds * sizeof(struct config_bind*));
|
|
||||||
if (tmpBind == NULL) {
|
|
||||||
error("config: couldn't reallocate for bind array: %s", strerror(errno));
|
|
||||||
freeEverything(toFree, toFreeLength);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
replaceOrAdd(toFree, &toFreeLength, config->binds, tmpBind);
|
|
||||||
config->binds = tmpBind;
|
|
||||||
config->binds[config->nrBinds - 1] = currentBind;
|
|
||||||
|
|
||||||
currentBind->nrSites = 0;
|
|
||||||
currentBind->sites = NULL;
|
|
||||||
currentBind->addr = NULL;
|
|
||||||
currentBind->port = NULL;
|
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
|
||||||
currentBind->ssl = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
state = BIND_VALUE;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case BIND_VALUE: ;
|
case BIND_VALUE: ;
|
||||||
char* seperator = strstr(currentToken, ":");
|
char* seperator = strstr(currentToken, ":");
|
||||||
|
@ -212,7 +229,7 @@ struct config* config_parse(FILE* file) {
|
||||||
|
|
||||||
state = SITE_BRACKETS_OPEN;
|
state = SITE_BRACKETS_OPEN;
|
||||||
} else if (strcmp(currentToken, "}") == 0) {
|
} else if (strcmp(currentToken, "}") == 0) {
|
||||||
state = BIND;
|
state = ROOT;
|
||||||
} else if (strcmp(currentToken, "ssl") == 0) {
|
} else if (strcmp(currentToken, "ssl") == 0) {
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
if (currentBind->ssl != NULL) {
|
if (currentBind->ssl != NULL) {
|
||||||
|
@ -502,6 +519,84 @@ struct config* config_parse(FILE* file) {
|
||||||
|
|
||||||
state = HANDLER_CONTENT;
|
state = HANDLER_CONTENT;
|
||||||
break;
|
break;
|
||||||
|
case LOGGING_BRACKETS_OPEN:
|
||||||
|
if (strcmp(currentToken, "{") != 0) {
|
||||||
|
error("config: Unexpected token '%s' on line %d. '{' expected", currentToken, currentLine);
|
||||||
|
freeEverything(toFree, toFreeLength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = LOGGING_CONTENT;
|
||||||
|
break;
|
||||||
|
case LOGGING_CONTENT:
|
||||||
|
if (strcmp(currentToken, "access") == 0) {
|
||||||
|
state = LOGGING_ACCESS_FILE_EQUALS;
|
||||||
|
} else if (strcmp(currentToken, "server") == 0) {
|
||||||
|
state = LOGGING_SERVER_FILE_EQUALS;
|
||||||
|
} else if (strcmp(currentToken, "verbosity") == 0) {
|
||||||
|
state = LOGGING_SERVER_VERBOSITY_EQUALS;
|
||||||
|
} else if (strcmp(currentToken, "}") == 0) {
|
||||||
|
state = ROOT;
|
||||||
|
} else {
|
||||||
|
error("config: Unknown property '%s' on line %d.", currentToken, currentLine);
|
||||||
|
freeEverything(toFree, toFreeLength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LOGGING_ACCESS_FILE_EQUALS:
|
||||||
|
if (strcmp(currentToken, "=") != 0) {
|
||||||
|
error("config: Unexpected token '%s' on line %d. '=' expected", currentToken, currentLine);
|
||||||
|
freeEverything(toFree, toFreeLength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
state = LOGGING_ACCESS_FILE_VALUE;
|
||||||
|
break;
|
||||||
|
case LOGGING_ACCESS_FILE_VALUE:
|
||||||
|
config->logging.accessLogfile = strclone(currentToken);
|
||||||
|
if (config->logging.accessLogfile == NULL) {
|
||||||
|
error("config: error cloning access log file string");
|
||||||
|
freeEverything(toFree, toFreeLength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = LOGGING_CONTENT;
|
||||||
|
break;
|
||||||
|
case LOGGING_SERVER_FILE_EQUALS:
|
||||||
|
if (strcmp(currentToken, "=") != 0) {
|
||||||
|
error("config: Unexpected token '%s' on line %d. '=' expected", currentToken, currentLine);
|
||||||
|
freeEverything(toFree, toFreeLength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
state = LOGGING_SERVER_FILE_VALUE;
|
||||||
|
break;
|
||||||
|
case LOGGING_SERVER_FILE_VALUE:
|
||||||
|
config->logging.serverLogfile = strclone(currentToken);
|
||||||
|
if (config->logging.serverLogfile == NULL) {
|
||||||
|
error("config: error cloning server log file string");
|
||||||
|
freeEverything(toFree, toFreeLength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = LOGGING_CONTENT;
|
||||||
|
break;
|
||||||
|
case LOGGING_SERVER_VERBOSITY_EQUALS:
|
||||||
|
if (strcmp(currentToken, "=") != 0) {
|
||||||
|
error("config: Unexpected token '%s' on line %d. '=' expected", currentToken, currentLine);
|
||||||
|
freeEverything(toFree, toFreeLength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
state = LOGGING_SERVER_VERBOSITY_VALUE;
|
||||||
|
break;
|
||||||
|
case LOGGING_SERVER_VERBOSITY_VALUE:
|
||||||
|
config->logging.serverVerbosity = strtologlevel(currentToken);
|
||||||
|
|
||||||
|
if (config->logging.serverVerbosity == UNKNOWN) {
|
||||||
|
error("config: Unexpected token '%s' on line %d.", currentToken, currentLine);
|
||||||
|
freeEverything(toFree, toFreeLength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
state = LOGGING_CONTENT;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
@ -516,7 +611,7 @@ struct config* config_parse(FILE* file) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state != BIND) {
|
if (state != ROOT) {
|
||||||
error("config: unexpected EOF");
|
error("config: unexpected EOF");
|
||||||
freeEverything(toFree, toFreeLength);
|
freeEverything(toFree, toFreeLength);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -582,6 +677,29 @@ struct networkingConfig config_getNetworkingConfig(struct config* config) {
|
||||||
|
|
||||||
return networkingConfig;
|
return networkingConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void config_setLogging(struct config* config) {
|
||||||
|
setLogging(stdout, config->logging.serverVerbosity, true);
|
||||||
|
|
||||||
|
if (config->logging.serverLogfile != NULL) {
|
||||||
|
FILE* file = fopen(config->logging.serverLogfile, "a");
|
||||||
|
if (file == NULL) {
|
||||||
|
error("config: failed to open server log file %s: %s", config->logging.serverLogfile, strerror(errno));
|
||||||
|
} else {
|
||||||
|
setLogging(file, config->logging.serverVerbosity, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config->logging.accessLogfile != NULL) {
|
||||||
|
FILE* file = fopen(config->logging.accessLogfile, "a");
|
||||||
|
if (file == NULL) {
|
||||||
|
error("config: failed to open access log file %s: %s", config->logging.accessLogfile, strerror(errno));
|
||||||
|
} else {
|
||||||
|
setLogging(file, HTTP_ACCESS, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct handler config_getHandler(struct config* config, struct metaData metaData, const char* host, struct bind* bind) {
|
struct handler config_getHandler(struct config* config, struct metaData metaData, const char* host, struct bind* bind) {
|
||||||
struct handler handler = {};
|
struct handler handler = {};
|
||||||
|
|
||||||
|
|
14
src/config.h
14
src/config.h
|
@ -7,11 +7,14 @@
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "cgi.h"
|
#include "cgi.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CONFIG_DEFAULT_LOGLEVEL (DEFAULT_LOGLEVEL)
|
||||||
|
|
||||||
struct config {
|
struct config {
|
||||||
int nrBinds;
|
int nrBinds;
|
||||||
struct config_bind {
|
struct config_bind {
|
||||||
|
@ -39,6 +42,11 @@ struct config {
|
||||||
} **handlers;
|
} **handlers;
|
||||||
} **sites;
|
} **sites;
|
||||||
} **binds;
|
} **binds;
|
||||||
|
struct config_logging {
|
||||||
|
char* accessLogfile;
|
||||||
|
char* serverLogfile;
|
||||||
|
loglevel_t serverVerbosity;
|
||||||
|
} logging;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -59,6 +67,11 @@ bind [addr]:[port] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logging {
|
||||||
|
access = file
|
||||||
|
server = file
|
||||||
|
verboseity = debug|info|warn|error
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -66,6 +79,7 @@ bind [addr]:[port] {
|
||||||
struct config* config_parse(FILE* file);
|
struct config* config_parse(FILE* file);
|
||||||
|
|
||||||
struct networkingConfig config_getNetworkingConfig(struct config* config);
|
struct networkingConfig config_getNetworkingConfig(struct config* config);
|
||||||
|
void config_setLogging(struct config* config);
|
||||||
struct handler config_getHandler(struct config* config, struct metaData metaData, const char* host, struct bind* bind);
|
struct handler config_getHandler(struct config* config, struct metaData metaData, const char* host, struct bind* bind);
|
||||||
|
|
||||||
void config_destroy(struct config* config);
|
void config_destroy(struct config* config);
|
||||||
|
|
|
@ -290,3 +290,20 @@ void critical(const char* format, ...) {
|
||||||
vlogging(CRITICAL, format, argptr);
|
vlogging(CRITICAL, format, argptr);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
loglevel_t strtologlevel(const char* string) {
|
||||||
|
if (strcasecmp(string, "debug") == 0) {
|
||||||
|
return DEBUG;
|
||||||
|
} else if (strcasecmp(string, "info") == 0) {
|
||||||
|
return INFO;
|
||||||
|
} else if (strcasecmp(string, "warn") == 0) {
|
||||||
|
return WARN;
|
||||||
|
} else if (strcasecmp(string, "error") == 0) {
|
||||||
|
return ERROR;
|
||||||
|
} else if (strcasecmp(string, "critical") == 0) {
|
||||||
|
return CRITICAL;
|
||||||
|
} else {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
typedef int loglevel_t;
|
typedef int loglevel_t;
|
||||||
|
|
||||||
|
#define UNKNOWN (-1)
|
||||||
#define DEBUG (0)
|
#define DEBUG (0)
|
||||||
#define VERBOSE (1)
|
#define VERBOSE (1)
|
||||||
#define INFO (2)
|
#define INFO (2)
|
||||||
|
@ -35,4 +36,6 @@ void warn(const char* format, ...);
|
||||||
void error(const char* format, ...);
|
void error(const char* format, ...);
|
||||||
void critical(const char* format, ...);
|
void critical(const char* format, ...);
|
||||||
|
|
||||||
|
loglevel_t strtologlevel(const char* string);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
13
src/test.c
13
src/test.c
|
@ -269,6 +269,10 @@ void testConfig() {
|
||||||
checkString(config->binds[0]->sites[0]->handlers[0]->settings.fileSettings.documentRoot, "/var/www", "handler settings root check");
|
checkString(config->binds[0]->sites[0]->handlers[0]->settings.fileSettings.documentRoot, "/var/www", "handler settings root check");
|
||||||
checkInt(config->binds[0]->sites[0]->handlers[0]->settings.fileSettings.indexfiles.number, 1, "handler settings index no");
|
checkInt(config->binds[0]->sites[0]->handlers[0]->settings.fileSettings.indexfiles.number, 1, "handler settings index no");
|
||||||
checkString(config->binds[0]->sites[0]->handlers[0]->settings.fileSettings.indexfiles.files[0], "index.html", "handler settings index check");
|
checkString(config->binds[0]->sites[0]->handlers[0]->settings.fileSettings.indexfiles.files[0], "index.html", "handler settings index check");
|
||||||
|
checkString(config->logging.accessLogfile, "access.log", "access log file check");
|
||||||
|
checkString(config->logging.serverLogfile, "server.log", "server log file check");
|
||||||
|
printf("%s\n", config->logging.serverLogfile);
|
||||||
|
checkInt(config->logging.serverVerbosity, INFO, "server log verbosity check");
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
checkString(config->binds[1]->addr, "0.0.0.0", "bind addr check");
|
checkString(config->binds[1]->addr, "0.0.0.0", "bind addr check");
|
||||||
|
@ -306,15 +310,12 @@ void test(const char* name, void (*testFunction)()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
/**test("logging", &testLogging);
|
test("config", &testConfig);
|
||||||
test("util", &testUtil);
|
test("util", &testUtil);
|
||||||
test("linked lists", &testLinkedList);
|
test("linked lists", &testLinkedList);
|
||||||
test("signals", &testTimers);
|
test("signals", &testTimers);
|
||||||
test("headers", &testHeaders);*/
|
test("headers", &testHeaders);
|
||||||
|
test("logging", &testLogging);
|
||||||
setLogging(stderr, DEFAULT_LOGLEVEL, true);
|
|
||||||
|
|
||||||
test("config", &testConfig);
|
|
||||||
|
|
||||||
|
|
||||||
printf("\nOverall: %s\n", overall ? "OK" : "FAILED");
|
printf("\nOverall: %s\n", overall ? "OK" : "FAILED");
|
||||||
|
|
|
@ -22,3 +22,8 @@ bind 0.0.0.0:443 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logging {
|
||||||
|
access = access.log
|
||||||
|
server = server.log
|
||||||
|
verbosity = info
|
||||||
|
}
|
||||||
|
|
|
@ -8,3 +8,8 @@ bind 0.0.0.0:80 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logging {
|
||||||
|
access = access.log
|
||||||
|
server = server.log
|
||||||
|
verbosity = info
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue