diff --git a/src/lib/uri.c b/src/lib/uri.c index 4f620a5..6d240db 100644 --- a/src/lib/uri.c +++ b/src/lib/uri.c @@ -15,21 +15,26 @@ int path_is_directory(const char *path) { - struct stat statbuf; - return stat(path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode) != 0; + int e = errno; + struct stat stat_buf; + int ret = stat(path, &stat_buf); + errno = e; + return ret == 0 && S_ISDIR(stat_buf.st_mode) != 0; } int path_is_file(const char *path) { - struct stat statbuf; - int ret = stat(path, &statbuf); - errno = 0; - return ret == 0 && S_ISDIR(statbuf.st_mode) == 0; + int e = errno; + struct stat stat_buf; + int ret = stat(path, &stat_buf); + errno = e; + return ret == 0 && S_ISDIR(stat_buf.st_mode) == 0; } int path_exists(const char *path) { - struct stat statbuf; - int ret = stat(path, &statbuf); - errno = 0; + int e = errno; + struct stat stat_buf; + int ret = stat(path, &stat_buf); + errno = e; return ret == 0; } diff --git a/src/lib/utils.c b/src/lib/utils.c index 9faa07e..272e518 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -12,6 +12,10 @@ #include #include #include +#include +#include +#include +#include static const char base64_encode_table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -216,3 +220,45 @@ long clock_cpu(void) { clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time); return time.tv_sec * 1000000000 + time.tv_nsec; } + +int rm_rf(const char *path) { + struct stat stat_buf; + if (lstat(path, &stat_buf) != 0) + return (errno == ENOENT) ? 0 : -1; + + if (S_ISREG(stat_buf.st_mode)) { + // regular file + return unlink(path); + } else if (S_ISLNK(stat_buf.st_mode)) { + // link + return unlink(path); + } else if (S_ISDIR(stat_buf.st_mode)) { + // directory + char buf[FILENAME_MAX]; + DIR *dir; + + // open directory + if ((dir = opendir(path)) == NULL) + return -1; + + // read directory + for (struct dirent *ent; (ent = readdir(dir)) != NULL;) { + if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) + continue; + + snprintf(buf, sizeof(buf), "%s/%s", path, ent->d_name); + if (rm_rf(buf) != 0) { + closedir(dir); + return -1; + } + } + + // close and remove directory + closedir(dir); + return rmdir(path); + } else { + // other - not supported + errno = ENOTSUP; + return -1; + } +} diff --git a/src/lib/utils.h b/src/lib/utils.h index 56aeb05..ce54186 100644 --- a/src/lib/utils.h +++ b/src/lib/utils.h @@ -41,4 +41,6 @@ long clock_micros(void); long clock_cpu(void); +int rm_rf(const char *path); + #endif //SESIMOS_UTILS_H diff --git a/src/logger.c b/src/logger.c index 813ec79..e0725ea 100644 --- a/src/logger.c +++ b/src/logger.c @@ -278,4 +278,9 @@ int logger_init(void) { void logger_stop(void) { alive = 0; + pthread_kill(thread, SIGUSR1); +} + +int logger_join(void) { + return pthread_join(thread, NULL); } diff --git a/src/logger.h b/src/logger.h index efad784..58b8581 100644 --- a/src/logger.h +++ b/src/logger.h @@ -37,4 +37,6 @@ int logger_init(void); void logger_stop(void); +int logger_join(void); + #endif //SESIMOS_LOGGER_H diff --git a/src/server.c b/src/server.c index d48c06b..a3c4fb9 100644 --- a/src/server.c +++ b/src/server.c @@ -43,10 +43,35 @@ static client_ctx_t **clients; static const char *color_table[] = {"\x1B[31m", "\x1B[32m", "\x1B[33m", "\x1B[34m", "\x1B[35m", "\x1B[36m"}; -static int clean() { - remove("/var/sesimos/server/cache"); - rmdir("/var/sesimos/server/"); - return 0; +static void clean(void) { + notice("Cleaning sesimos cache and metadata files..."); + + // remove legacy files + // /.../server/, /.../server/cache + if (rm_rf("/var/sesimos/server") != 0) { + error("Unable to remove /var/sesimos/server/"); + } else if (!errno) { + notice("Successfully removed /var/sesimos/server/"); + } + errno = 0; + + // remove cache and metadata files + char buf[512]; + for (int i = 0; i < CONFIG_MAX_HOST_CONFIG; i++) { + host_config_t *hc = &config.hosts[i]; + if (hc->type == CONFIG_TYPE_UNSET) break; + if (hc->type != CONFIG_TYPE_LOCAL) continue; + + snprintf(buf, sizeof(buf), "%s/.sesimos", hc->local.webroot); + if (rm_rf(buf) != 0) { + error("Unable to remove %s/", buf); + } else if (!errno) { + notice("Successfully removed %s/", buf); + } + errno = 0; + } + + notice("Cleaned all sesimos cache and metadata files!"); } static int ssl_servername_cb(SSL *ssl, int *ad, void *arg) { @@ -154,6 +179,7 @@ static void nothing(int sig) {} int main(int argc, char *const argv[]) { const int YES = 1; int ret; + int mode = 0; memset(sockets, 0, sizeof(sockets)); clients = list_create(sizeof(void *), 64); @@ -167,8 +193,6 @@ int main(int argc, char *const argv[]) { {.sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_port = htons(443)} }; - logger_init(); - logger_set_name("server"); if (setvbuf(stdout, NULL, _IOLBF, 0) != 0 || setvbuf(stderr, NULL, _IOLBF, 0) != 0) { @@ -179,13 +203,13 @@ int main(int argc, char *const argv[]) { static const struct option long_opts[] = { {"help", no_argument, 0, 'h'}, + {"clean", no_argument, 0, 'C'}, {"config", required_argument, 0, 'c'}, { 0, 0, 0, 0 } }; config_file = NULL; - int c, opt_idx; - while ((c = getopt_long(argc, argv, "hc:", long_opts, &opt_idx)) != -1) { + for (int c, opt_idx; (c = getopt_long(argc, argv, "hCc:", long_opts, &opt_idx)) != -1;) { switch (c) { case 'h': fprintf(stderr, @@ -193,11 +217,15 @@ int main(int argc, char *const argv[]) { "\n" "Options:\n" " -c, --config path to the config file. If not provided, default will be used\n" + " -C, --clean clear cached files and other metadata\n" " -h, --help print this dialogue\n"); return 0; case 'c': config_file = optarg; break; + case 'C': + mode = 1; + break; case '?': default: critical("Unable to parse arguments"); @@ -213,6 +241,11 @@ int main(int argc, char *const argv[]) { if (config_load(config_file == NULL ? DEFAULT_CONFIG_FILE : config_file) != 0) return 1; + if (mode == 1) { + clean(); + return 0; + } + if ((sockets[0] = socket(AF_INET6, SOCK_STREAM, 0)) == -1 || (sockets[1] = socket(AF_INET6, SOCK_STREAM, 0)) == -1) { @@ -303,6 +336,9 @@ int main(int argc, char *const argv[]) { } } + logger_init(); + logger_set_name("server"); + workers_init(); for (int i = 0; i < NUM_SOCKETS; i++) { @@ -321,5 +357,7 @@ int main(int argc, char *const argv[]) { proxy_unload(); cache_join(); async_free(); + logger_stop(); + logger_join(); return 0; }