Files
cworker/cworker.c
2023-08-16 01:01:16 +02:00

233 lines
5.2 KiB
C

/*
*
* Copyright 2023 Oleg Borodin <borodin@unix7.org>
*
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <cllexer.h>
#include <clparser.h>
#include <cflexer.h>
#include <cfparser.h>
#include <massert.h>
#include <rcache.h>
#include <config.h>
#include <cworker.h>
#include <logger.h>
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;
}