/* * * Copyright 2023 Oleg Borodin * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int log_fd = 0; static int mkdirall(const char* path, mode_t mode) { char buffer[1024]; size_t psize = strlen(path); if (psize == 0) return 0; if (psize == 1 && path[0] == '/') { return 0; } for (int i = 1; i < psize; i++) { if (path[i] == '/') { strncpy(buffer, path, i); buffer[i] = '\0'; if (mkdir(buffer, mode) < 0) { if (errno != EEXIST) { return -1; } } } } return 0; } char* last(const char* path) { char buffer[1024]; size_t psize = strlen(path); strcpy(buffer, path); buffer[psize] = '\0'; if (buffer[psize - 1] == '/') { buffer[--psize] = '\0'; } size_t pos = psize; for (size_t i = 1; i < psize; i++) { if (buffer[i] == '/') pos = i; } char* b = &buffer[++pos]; int bsize = strlen(b); char* res = malloc(bsize + 1); strcpy(res, b); //printf("\n%s\n", res); return res; } char* file(const char* path) { char buffer[1024]; size_t psize = strlen(path); strcpy(buffer, path); buffer[psize] = '\0'; //if (buffer[psize - 1] == '/') { // buffer[--psize] = '\0'; //} size_t pos = psize; for (size_t i = 1; i < psize; i++) { if (buffer[i] == '/') pos = i; } char* b = &buffer[++pos]; int bsize = strlen(b); char* res = malloc(bsize + 1); strcpy(res, b); //printf("\n%s\n", res); return res; } static int cworker_readconf(const cworker_t* worker) { log_debug("reading configiration"); int conf_fd = -1; if ((conf_fd = open(srv_configpath, O_RDONLY)) < 0) { log_error("cannot open config file %s", srv_configpath); return -1; } rcache_t cache; cflexer_t lexer; cfparser_t parser; rcache_init(&cache, conf_fd); cflexer_init(&lexer, &cache); cfparser_init(&parser, &lexer); if (cfparser_parse(&parser) < 0) { log_error("parse config error\n"); return -1; } cfparser_bind(&parser, CFVALTYPE_INT, "port", (void *)&(worker->port)); cfparser_destroy(&parser); cflexer_destroy(&lexer); rcache_destroy(&cache); return 0; } static int cworker_readopts(const cworker_t* worker, char** argv, int argc) { log_debug("reading options"); cllexer_t lexer; clparser_t parser; cllexer_init(&lexer); clparser_init(&parser, &lexer); clparser_bind(&parser, CLVALTYPE_INT, "port", (void *)&(worker->port)); if (clparser_parse(&parser, &argv[1], argc - 1) < 0) { log_error("parse args error"); return -1; } return 0; } static int cworker_openlog(const cworker_t* worker) { log_debug("redirect output"); if (mkdirall(srv_logpath, S_IRWXU|S_IRGRP|S_IXGRP) < 0) { log_error("creating log dir error: %s %s", strerror(errno), srv_logpath); } if ((log_fd = open(srv_logpath, O_WRONLY|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP)) < 0) { log_error("open log file error %s %s", strerror(errno), srv_logpath); return -1; } dup2(log_fd, STDOUT_FILENO); dup2(log_fd, STDERR_FILENO); return 0; } int cworker_writepid(const cworker_t* worker) { log_debug("write pid file"); if (mkdirall(srv_runpath, S_IRWXU|S_IRGRP|S_IXGRP) < 0) { log_error("createing run dir error: %s %s", strerror(errno), srv_runpath); } int pid_fd = -1; if ((pid_fd = open(srv_runpath, O_WRONLY|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP)) < 0) { log_error("open pid file error %s %s", strerror(errno), srv_runpath); return -1; } if (dprintf(pid_fd, "%d", getpid()) < 0) { log_error("cannon write pid, error %s %s", strerror(errno), srv_runpath); close(pid_fd); return -1; } close(pid_fd); return 0; } const int64_t default_port = 9701; int cworker_init(cworker_t* worker, char** argv, int argc) { if (cworker_openlog(worker) < 0) { log_error("openlog error"); return -1; } log_debug("init service"); worker->port = default_port; if (cworker_readconf(worker) < 0) { log_error("reading config error"); return -1; } if (cworker_readopts(worker, argv, argc) < 0) { log_error("reading config error"); return -1; } log_debug("port: %d", worker->port); return 0; } int cworker_detach(const cworker_t* worker) { log_debug("detach service"); int childpid = -1; if((childpid = fork()) < 0) { log_error("fork error: %s", strerror(errno)); return -1; } if (childpid == 0) { // child } else { // parent exit(0); } return 0; } int cworker_build(const cworker_t* worker) { log_debug("build service"); return 0; } int cworker_run(const cworker_t* worker) { log_debug("run service"); return 0; }