diff --git a/include/utils/logger.h b/include/utils/logger.h index 59ca40f..eb2fffd 100644 --- a/include/utils/logger.h +++ b/include/utils/logger.h @@ -18,7 +18,8 @@ enum { #define log_fatal(...) log_printf(LOG_FATAL, __VA_ARGS__) extern int LOG_LEVEL; -void log_perror(char *prefix); +//void log_perror(char *prefix); +void log_perror(const char *fmt, ...); void log_printf(int level, const char *fmt, ...); #endif diff --git a/include/utils/process.h b/include/utils/process.h index b979ead..db2a08c 100644 --- a/include/utils/process.h +++ b/include/utils/process.h @@ -6,6 +6,7 @@ typedef struct { char **cmd; char **env; char *cwd; + int8_t is_group; // bool value } process; void process_list_run(); @@ -14,4 +15,7 @@ void process_list_append(process *proc); void process_add_arg(process *proc, const char *arg); process* process_init(const char *caption, const char *bin); +#include +pid_t process_exec(process *proc); + #endif diff --git a/src/cleardns.c b/src/cleardns.c index 45034b7..d65a561 100644 --- a/src/cleardns.c +++ b/src/cleardns.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "loader.h" #include "logger.h" #include "constant.h" @@ -51,20 +52,37 @@ int main(int argc, char *argv[]) { // ClearDNS server char *config_file = init(argc, argv); + LOG_LEVEL = LOG_DEBUG; log_info("ClearDNS server start (%s)", VERSION); - create_folder(WORK_DIR); +// process *test = process_init("TEST", "lls"); + process *test = process_init("TEST", "ls"); - load_config(config_file); - free(config_file); + process_add_arg(test, "-al"); - process_list_init(); - process_list_append(dnsproxy_load("Domestic", loader.domestic, "domestic.json")); - process_list_append(dnsproxy_load("Foreign", loader.foreign, "foreign.json")); - process_list_append(overture_load(loader.diverter, "overture.json")); - if (loader.filter != NULL) { - process_list_append(adguard_load(loader.filter, ADGUARD_DIR)); - } +// test->cwd = "/etc/cleardns/fuck"; + + int pid = process_exec(test); + + log_info("PID = %d", pid); + + int status; + wait(&status); + + return 0; + + create_folder(WORK_DIR); + +// load_config(config_file); +// free(config_file); +// +// process_list_init(); +// process_list_append(dnsproxy_load("Domestic", loader.domestic, "domestic.json")); +// process_list_append(dnsproxy_load("Foreign", loader.foreign, "foreign.json")); +// process_list_append(overture_load(loader.diverter, "overture.json")); +// if (loader.filter != NULL) { +// process_list_append(adguard_load(loader.filter, ADGUARD_DIR)); +// } // TODO: running custom script diff --git a/src/utils/logger.c b/src/utils/logger.c index 121132f..944153f 100644 --- a/src/utils/logger.c +++ b/src/utils/logger.c @@ -51,9 +51,21 @@ void log_printf(int level, const char *fmt, ...) { } } -void log_perror(char *prefix) { +//void log_perror(char *prefix) { +// fprint_prefix(); +// fprintf(stderr, " %s%s\x1b[0m ", log_color[LOG_ERROR], log_string[LOG_ERROR]); +// fflush(stderr); +// perror(prefix); +//} + +// TODO: update perror logger + +void log_perror(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); fprint_prefix(); fprintf(stderr, " %s%s\x1b[0m ", log_color[LOG_ERROR], log_string[LOG_ERROR]); + vfprintf(stderr, fmt, ap); // output log content fflush(stderr); - perror(prefix); + perror(""); } diff --git a/src/utils/process.c b/src/utils/process.c index 31bc46e..e1496a2 100644 --- a/src/utils/process.c +++ b/src/utils/process.c @@ -1,4 +1,9 @@ #include +#include +#include +#include +#include +#include #include "sundry.h" #include "process.h" #include "constant.h" @@ -13,6 +18,7 @@ process* process_init(const char *caption, const char *bin) { // init process st proc->cmd = string_list_append(string_list_init(), bin); // argv[0] normally be process file name proc->env = string_list_init(); // empty environment variable proc->cwd = WORK_DIR; // current working directory + proc->is_group = FALSE; // create new process group return proc; } @@ -39,3 +45,51 @@ void process_list_run() { log_warn("proc -> %s", (*p)->name); } } + +void server_exit() { + // TODO: kill subprocess and exit cleardns +} + + +void process_dump(process *proc) { + char *process_cmd = string_list_dump(proc->cmd); + char *process_env = string_list_dump(proc->env); + log_debug("%s cwd -> %s", proc->name, proc->cwd); + log_debug("%s command -> %s", proc->name, process_cmd); + log_debug("%s env variable -> %s", proc->name, process_env); + log_debug("%s new group -> %s", proc->name, show_bool(proc->is_group)); + free(process_env); + free(process_cmd); +} + +pid_t process_exec(process *proc) { + pid_t pid; + + process_dump(proc); + + if ((pid = fork()) < 0) { // fork error + log_perror("Fork error"); + server_exit(); + } else if (pid == 0) { // child process + // TODO: new process group + + if (proc->is_group) { + setpgrp(); // new process group + } + + if (chdir(proc->cwd)) { // change working directory + log_perror("%s with invalid cwd `%s` -> ", proc->name, proc->cwd); + exit(2); + } + + prctl(PR_SET_PDEATHSIG, SIGKILL); // child process die with father process + if (execvpe(*(proc->cmd), proc->cmd, proc->env) < 0) { + log_perror("%s exec error -> ", proc->name); + exit(1); + } + } + + return pid; + +} +