This commit is contained in:
2023-08-18 22:38:43 +02:00
parent db3bbf21c8
commit bdfed6f56b
20 changed files with 609 additions and 291 deletions

View File

@@ -219,19 +219,19 @@ distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = ${SHELL} /home/ziggi/Projects/jcomp/missing aclocal
ACLOCAL = ${SHELL} /home/ziggi/Projects/cworker/missing aclocal
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1
APP_CACHEDIR = /home/ziggi/Projects/jcomp/cache
APP_CONFIGDIR = /home/ziggi/Projects/jcomp/
APP_DATABASEDIR = /home/ziggi/Projects/jcomp/data
APP_LIBDIR = /home/ziggi/Projects/jcomp/lib
APP_LOGDIR = /home/ziggi/Projects/jcomp/log
APP_RUNDIR = /home/ziggi/Projects/jcomp/run
APP_CACHEDIR = /home/ziggi/Projects/cworker/cache
APP_CONFIGDIR = /home/ziggi/Projects/cworker/
APP_DATABASEDIR = /home/ziggi/Projects/cworker/data
APP_LIBDIR = /home/ziggi/Projects/cworker/lib
APP_LOGDIR = /home/ziggi/Projects/cworker/log
APP_RUNDIR = /home/ziggi/Projects/cworker/run
APP_USER = ziggi
AUTOCONF = ${SHELL} /home/ziggi/Projects/jcomp/missing autoconf
AUTOHEADER = ${SHELL} /home/ziggi/Projects/jcomp/missing autoheader
AUTOMAKE = ${SHELL} /home/ziggi/Projects/jcomp/missing automake
AUTOCONF = ${SHELL} /home/ziggi/Projects/cworker/missing autoconf
AUTOHEADER = ${SHELL} /home/ziggi/Projects/cworker/missing autoheader
AUTOMAKE = ${SHELL} /home/ziggi/Projects/cworker/missing automake
AWK = gawk
CC = clang
CCDEPMODE = depmode=none
@@ -255,7 +255,7 @@ LDFLAGS =
LIBOBJS =
LIBS =
LTLIBOBJS =
MAKEINFO = ${SHELL} /home/ziggi/Projects/jcomp/missing makeinfo
MAKEINFO = ${SHELL} /home/ziggi/Projects/cworker/missing makeinfo
MKDIR_P = /usr/local/bin/gmkdir -p
OBJEXT = o
PACKAGE = cworker
@@ -271,23 +271,23 @@ SHELL = /bin/sh
STRIP =
VALGRIND = /usr/local/bin/valgrind
VERSION = 0.0.1
abs_builddir = /home/ziggi/Projects/jcomp
abs_srcdir = /home/ziggi/Projects/jcomp
abs_top_builddir = /home/ziggi/Projects/jcomp
abs_top_srcdir = /home/ziggi/Projects/jcomp
abs_builddir = /home/ziggi/Projects/cworker
abs_srcdir = /home/ziggi/Projects/cworker
abs_top_builddir = /home/ziggi/Projects/cworker
abs_top_srcdir = /home/ziggi/Projects/cworker
ac_ct_CC = clang
am__include = include
am__leading_dot = .
am__quote =
am__tar = $${TAR-tar} chof - "$$tardir"
am__untar = $${TAR-tar} xf -
app_cachedir = /home/ziggi/Projects/jcomp/cache
app_configdir = /home/ziggi/Projects/jcomp/
app_databasedir = /home/ziggi/Projects/jcomp/data
app_libdir = /home/ziggi/Projects/jcomp/lib
app_logdir = /home/ziggi/Projects/jcomp/log
app_cachedir = /home/ziggi/Projects/cworker/cache
app_configdir = /home/ziggi/Projects/cworker/
app_databasedir = /home/ziggi/Projects/cworker/data
app_libdir = /home/ziggi/Projects/cworker/lib
app_logdir = /home/ziggi/Projects/cworker/log
app_name = cworker
app_rundir = /home/ziggi/Projects/jcomp/run
app_rundir = /home/ziggi/Projects/cworker/run
app_user = ziggi
bindir = ${exec_prefix}/bin
build = amd64-unknown-freebsd12.4
@@ -309,7 +309,7 @@ host_vendor = unknown
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /home/ziggi/Projects/jcomp/install-sh
install_sh = ${SHELL} /home/ziggi/Projects/cworker/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
@@ -895,6 +895,7 @@ valgrind: $(bin_TESTS)
clean-local:
rm -rf autom4te.cache
rm -rf *~
rm -rf run log
#install-data-local:
# test -z $(DESTDIR)$(APP_LIBDIR) || $(MKDIR_P) $(DESTDIR)$(APP_LIBDIR)

View File

@@ -895,6 +895,7 @@ valgrind: $(bin_TESTS)
clean-local:
rm -rf autom4te.cache
rm -rf *~
rm -rf run log
#install-data-local:
# test -z $(DESTDIR)$(APP_LIBDIR) || $(MKDIR_P) $(DESTDIR)$(APP_LIBDIR)

View File

@@ -11,6 +11,16 @@
#include <cflexer.h>
#define CFLEXCONT_COMM 1
#define CFLEXCONT_END 2
#define CFLEXCONT_LWORD 3
#define CFLEXCONT_SEPAR 4
#define CFLEXCONT_SPACE 5
#define CFLEXCONT_UNDEF 6
#define CFLEXCONT_UNKNOW 7
#define CFLEXCONT_WORD 8
#define CFLEXCONT_NEWLN 9
#define CFLEXTYPE_CHAR 1
#define CFLEXTYPE_COMM 2
#define CFLEXTYPE_EOF 3

View File

@@ -16,17 +16,6 @@ typedef struct {
} cflexer_t;
#define CFLEXCONT_COMM 1
#define CFLEXCONT_END 2
#define CFLEXCONT_LWORD 3
#define CFLEXCONT_SEPAR 4
#define CFLEXCONT_SPACE 5
#define CFLEXCONT_UNDEF 6
#define CFLEXCONT_UNKNOW 7
#define CFLEXCONT_WORD 8
#define CFLEXCONT_NEWLN 9
#define CFLEXTOK_BLOCKB 1
#define CFLEXTOK_COMM 2
#define CFLEXTOK_END 3

View File

@@ -9,6 +9,14 @@
#include <cllexer.h>
#define CLLEXCONT_UNDEF 0
#define CLLEXCONT_KEY 1
#define CLLEXCONT_WORD 2
#define CLLEXCONT_SPACE 3
#define CLLEXCONT_SEP 4
#define CLLEXCONT_END 5
#define CLLEXCONT_LWORD 6
#define CLLEXTYPE_UNDEF 0
#define CLLEXTYPE_KEY 1
#define CLLEXTYPE_CHAR 2

View File

@@ -15,13 +15,6 @@ typedef struct {
bool screen;
} cllexer_t;
#define CLLEXCONT_UNDEF 0
#define CLLEXCONT_KEY 1
#define CLLEXCONT_WORD 2
#define CLLEXCONT_SPACE 3
#define CLLEXCONT_SEP 4
#define CLLEXCONT_END 5
#define CLLEXCONT_LWORD 6
#define CLLEXTOK_UNDEF 0
#define CLLEXTOK_KEY 1

View File

@@ -2,8 +2,8 @@
#ifndef CONFIG_H_QWER
#define CONFIG_H_QWER
static const char *srv_runpath = "/home/ziggi/Projects/jcomp/run/cworker.pid";
static const char *srv_logpath = "/home/ziggi/Projects/jcomp/log/cworker.log";
static const char *srv_configpath = "/home/ziggi/Projects/jcomp//cworker.conf";
static const char *srv_runpath = "/home/ziggi/Projects/cworker/run/cworker.pid";
static const char *srv_logpath = "/home/ziggi/Projects/cworker/log/cworker.log";
static const char *srv_configpath = "/home/ziggi/Projects/cworker//cworker.conf";
#endif

View File

@@ -430,7 +430,7 @@ Copyright (C) 2021 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
ac_pwd='/home/ziggi/Projects/jcomp'
ac_pwd='/home/ziggi/Projects/cworker'
srcdir='.'
INSTALL='/usr/bin/install -c'
MKDIR_P='/usr/local/bin/gmkdir -p'
@@ -612,20 +612,20 @@ S["am__EXEEXT_FALSE"]=""
S["am__EXEEXT_TRUE"]="#"
S["LTLIBOBJS"]=""
S["app_name"]="cworker"
S["app_cachedir"]="/home/ziggi/Projects/jcomp/cache"
S["APP_CACHEDIR"]="/home/ziggi/Projects/jcomp/cache"
S["app_databasedir"]="/home/ziggi/Projects/jcomp/data"
S["APP_DATABASEDIR"]="/home/ziggi/Projects/jcomp/data"
S["app_cachedir"]="/home/ziggi/Projects/cworker/cache"
S["APP_CACHEDIR"]="/home/ziggi/Projects/cworker/cache"
S["app_databasedir"]="/home/ziggi/Projects/cworker/data"
S["APP_DATABASEDIR"]="/home/ziggi/Projects/cworker/data"
S["app_user"]="ziggi"
S["APP_USER"]="ziggi"
S["app_libdir"]="/home/ziggi/Projects/jcomp/lib"
S["APP_LIBDIR"]="/home/ziggi/Projects/jcomp/lib"
S["app_rundir"]="/home/ziggi/Projects/jcomp/run"
S["APP_RUNDIR"]="/home/ziggi/Projects/jcomp/run"
S["app_logdir"]="/home/ziggi/Projects/jcomp/log"
S["APP_LOGDIR"]="/home/ziggi/Projects/jcomp/log"
S["app_configdir"]="/home/ziggi/Projects/jcomp/"
S["APP_CONFIGDIR"]="/home/ziggi/Projects/jcomp/"
S["app_libdir"]="/home/ziggi/Projects/cworker/lib"
S["APP_LIBDIR"]="/home/ziggi/Projects/cworker/lib"
S["app_rundir"]="/home/ziggi/Projects/cworker/run"
S["APP_RUNDIR"]="/home/ziggi/Projects/cworker/run"
S["app_logdir"]="/home/ziggi/Projects/cworker/log"
S["APP_LOGDIR"]="/home/ziggi/Projects/cworker/log"
S["app_configdir"]="/home/ziggi/Projects/cworker/"
S["APP_CONFIGDIR"]="/home/ziggi/Projects/cworker/"
S["SYSTEMD_FALSE"]=""
S["SYSTEMD_TRUE"]="#"
S["LINUX_OS_FALSE"]=""
@@ -676,12 +676,12 @@ S["mkdir_p"]="$(MKDIR_P)"
S["MKDIR_P"]="/usr/local/bin/gmkdir -p"
S["INSTALL_STRIP_PROGRAM"]="$(install_sh) -c -s"
S["STRIP"]=""
S["install_sh"]="${SHELL} /home/ziggi/Projects/jcomp/install-sh"
S["MAKEINFO"]="${SHELL} /home/ziggi/Projects/jcomp/missing makeinfo"
S["AUTOHEADER"]="${SHELL} /home/ziggi/Projects/jcomp/missing autoheader"
S["AUTOMAKE"]="${SHELL} /home/ziggi/Projects/jcomp/missing automake"
S["AUTOCONF"]="${SHELL} /home/ziggi/Projects/jcomp/missing autoconf"
S["ACLOCAL"]="${SHELL} /home/ziggi/Projects/jcomp/missing aclocal"
S["install_sh"]="${SHELL} /home/ziggi/Projects/cworker/install-sh"
S["MAKEINFO"]="${SHELL} /home/ziggi/Projects/cworker/missing makeinfo"
S["AUTOHEADER"]="${SHELL} /home/ziggi/Projects/cworker/missing autoheader"
S["AUTOMAKE"]="${SHELL} /home/ziggi/Projects/cworker/missing automake"
S["AUTOCONF"]="${SHELL} /home/ziggi/Projects/cworker/missing autoconf"
S["ACLOCAL"]="${SHELL} /home/ziggi/Projects/cworker/missing aclocal"
S["VERSION"]="0.0.1"
S["PACKAGE"]="cworker"
S["CYGPATH_W"]="echo"
@@ -813,13 +813,13 @@ D["HAVE_MEMSET"]=" 1"
D["HAVE_MKDIR"]=" 1"
D["HAVE_SETLOCALE"]=" 1"
D["HAVE_SOCKET"]=" 1"
D["APP_CONFIGDIR"]=" \"/home/ziggi/Projects/jcomp/\""
D["APP_LOGDIR"]=" \"/home/ziggi/Projects/jcomp/log\""
D["APP_RUNDIR"]=" \"/home/ziggi/Projects/jcomp/run\""
D["APP_LIBDIR"]=" \"/home/ziggi/Projects/jcomp/lib\""
D["APP_CONFIGDIR"]=" \"/home/ziggi/Projects/cworker/\""
D["APP_LOGDIR"]=" \"/home/ziggi/Projects/cworker/log\""
D["APP_RUNDIR"]=" \"/home/ziggi/Projects/cworker/run\""
D["APP_LIBDIR"]=" \"/home/ziggi/Projects/cworker/lib\""
D["APP_USER"]=" \"ziggi\""
D["APP_DATABASEDIR"]=" \"/home/ziggi/Projects/jcomp/data\""
D["APP_CACHEDIR"]=" \"/home/ziggi/Projects/jcomp/cache\""
D["APP_DATABASEDIR"]=" \"/home/ziggi/Projects/cworker/data\""
D["APP_CACHEDIR"]=" \"/home/ziggi/Projects/cworker/cache\""
for (key in D) D_is_set[key] = 1
FS = ""
}

501
cworker.c
View File

@@ -4,15 +4,26 @@
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <limits.h>
#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 <pthread.h>
#include <poll.h>
#include <signal.h>
#include <cllexer.h>
#include <clparser.h>
@@ -20,16 +31,312 @@
#include <cfparser.h>
#include <massert.h>
#include <rcache.h>
#include <jlexer.h>
#include <jparser.h>
#include <config.h>
#include <cworker.h>
#include <logger.h>
int log_fd = 0;
static const int64_t default_port = 9701;
static cworker_t* pworker = NULL;
static int mkdirall(const char* path, mode_t mode);
void sighandler(int signum);
static int cworker_readconf(const cworker_t* worker) {
log_debug("Configuration reading");
int conffd = -1;
if ((conffd = open(srv_configpath, O_RDONLY)) < 0) {
log_error("Configuration file opening error: %s %s", strerror(errno), srv_configpath);
return -1;
}
rcache_t cache;
cflexer_t lexer;
cfparser_t parser;
rcache_init(&cache, conffd);
cflexer_init(&lexer, &cache);
cfparser_init(&parser, &lexer);
if (cfparser_parse(&parser) < 0) {
log_error("Configuration parsing error");
return -1;
}
cfparser_bind(&parser, CFVALTYPE_INT, "port", (void *)&(worker->port));
cfparser_bind(&parser, CFVALTYPE_BOOL, "nofork", (void *)&(worker->nofork));
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));
clparser_bind(&parser, CLVALTYPE_BOOL, "nofork", (void *)&(worker->nofork));
if (clparser_parse(&parser, &argv[1], argc - 1) < 0) {
log_error("Args parsing error");
return -1;
}
return 0;
}
static int cworker_openlog(cworker_t* worker) {
if (!worker->nofork) {
log_debug("Redirect output");
if (mkdirall(srv_logpath, S_IRWXU|S_IRGRP|S_IXGRP) < 0) {
log_error("Log dir creating error: %s %s", strerror(errno), srv_logpath);
}
if ((worker->logfd = open(srv_logpath, O_WRONLY|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP)) < 0) {
log_error("Log file opening error: %s %s", strerror(errno), srv_logpath);
return -1;
}
dup2(worker->logfd, STDOUT_FILENO);
dup2(worker->logfd, STDERR_FILENO);
}
return 0;
}
int cworker_writepid(const cworker_t* worker) {
if (!worker->nofork) {
log_debug("Write pid file");
if (mkdirall(srv_runpath, S_IRWXU|S_IRGRP|S_IXGRP) < 0) {
log_error("Run directory creating 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("Process ID file opening error: %s %s", strerror(errno), srv_runpath);
return -1;
}
if (dprintf(pid_fd, "%d", getpid()) < 0) {
log_error("Process ID file writing error: %s %s", strerror(errno), srv_runpath);
close(pid_fd);
return -1;
}
close(pid_fd);
}
return 0;
}
int cworker_init(cworker_t* worker, char** argv, int argc) {
log_init();
log_debug("Init service");
worker->port = default_port;
worker->nofork = true;
worker->socket = 0;
worker->logfd = 0;
pworker = worker;
if (cworker_readconf(worker) < 0) {
log_error("Config reading error");
return -1;
}
if (cworker_readopts(worker, argv, argc) < 0) {
log_error("Options reading error");
return -1;
}
if (!worker->nofork) {
if (cworker_openlog(worker) < 0) {
log_error("Log opening error");
return -1;
}
}
log_debug("Listening port: %d", worker->port);
return 0;
}
int cworker_detach(const cworker_t* worker) {
if (!worker->nofork) {
log_debug("Service detaching");
int childpid = -1;
if((childpid = fork()) < 0) {
log_error("Fork error %d: %s ", errno, strerror(errno));
return -1;
}
if (childpid == 0) {
log_debug("Service forked");
return 0;
// child
} else {
// parent
exit(0);
}
}
return 0;
}
int cworker_build(cworker_t* worker) {
log_debug("Service building");
signal(SIGCHLD, SIG_IGN);
signal(SIGHUP, sighandler);
signal(SIGTERM, sighandler);
if((worker->socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
log_debug("Socket creating error %d: %s", errno, strerror(errno));
return -1;
}
int optval = 1;
if (setsockopt(worker->socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
log_debug("Socket option setting error %d: %s", errno, strerror(errno));
return -1;
}
struct sockaddr addr;
struct sockaddr_in* paddr = (struct sockaddr_in*)&addr;
paddr->sin_family = AF_INET;
paddr->sin_addr.s_addr = INADDR_ANY;
paddr->sin_port = htons(worker->port);
paddr->sin_len = sizeof(struct sockaddr_in);
if (bind(worker->socket, (struct sockaddr*)paddr, paddr->sin_len) < 0) {
log_debug("Socket binding error %d: %s ", errno, strerror(errno));
return -1;
}
int backlog = 100;
if (listen(worker->socket, backlog) < 0) {
log_debug("Socket listening error %d: %s ", errno, strerror(errno));
return -1;
}
return 0;
}
int cworker_handler(const cworker_t* worker, int socket);
int cworker_run(const cworker_t* worker) {
log_debug("Service running");
while (1) {
int newsocket = 0;
if ((newsocket = accept(worker->socket, NULL, 0)) > 3) {
int childpid = -1;
if((childpid = fork()) < 0) {
log_error("Fork error %d: %s ", errno, strerror(errno));
continue;
}
if (childpid == 0) {
// child
log_debug("Service %d forked", getpid());
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, SIG_IGN);
struct timeval tv = { .tv_sec = 5, .tv_usec = 0 };
if (setsockopt(newsocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) < 0) {
log_debug("Socket option setting error %d: %s ", errno, strerror(errno));
return -1;
}
cworker_handler(worker, newsocket);
log_debug("Handler %d done", getpid());
close(newsocket);
return 0;
} else {
// parent
close(newsocket);
}
}
}
close(worker->socket);
return 0;
}
int cworker_handler(const cworker_t* worker, int socket) {
int err = 0;
rcache_t cache;
jlexer_t lexer;
jparser_t parser;
rcache_init(&cache, socket);
jlexer_init(&lexer, &cache);
jparser_init(&parser, &lexer);
if (jparser_parse(&parser) < 0) {
log_error("Cannot parse json");
err = -1;
goto exit;
}
int64_t id = 0;
char* name = "none";
if (jparser_bind(&parser, JVALTYPE_NUM, "id", (void *)&id) < 0) {
log_error("Cannot bind id");
}
if (jparser_bind(&parser, JVALTYPE_STR, "name", (void *)&name) < 0) {
log_error("Cannot bind name");
}
dprintf(socket, "{}");
free(name);
exit:
jparser_destroy(&parser);
jlexer_destroy(&lexer);
rcache_destroy(&cache);
return err;
}
void cworker_shutdown(cworker_t* worker) {
log_warning("Shutdown service %d", getpid());
if (worker->socket != 0) {
close(worker->socket);
worker->logfd = 0;
}
if (worker->logfd != 0) {
close(worker->logfd);
worker->logfd = 0;
}
wait(NULL);
log_destroy();
}
void sighandler(int signum) {
log_warning("Handle signal %d", signum);
if (signum == SIGHUP) {
log_warning("Handle HUP signal");
} else if (signum == SIGTERM) {
log_warning("Handle TERM signal");
if (pworker != NULL) {
cworker_shutdown(pworker);
sleep(1);
exit(0);
}
}
}
static int mkdirall(const char* path, mode_t mode) {
char buffer[1024];
char buffer[PATH_MAX];
size_t psize = strlen(path);
if (psize > PATH_MAX) {
return -1;
}
if (psize == 0) return 0;
if (psize == 1 && path[0] == '/') {
return 0;
@@ -47,187 +354,3 @@ static int mkdirall(const char* path, mode_t mode) {
}
return 0;
}
char* path_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* path_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) {
log_debug("service forkerd");
return 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;
}

View File

@@ -6,6 +6,9 @@
typedef struct {
int64_t port;
int socket;
int nofork;
int logfd;
} cworker_t;
int cworker_init(cworker_t* worker, char** argv, int argc);
@@ -13,7 +16,7 @@ int cworker_init(cworker_t* worker, char** argv, int argc);
int cworker_detach(const cworker_t* worker);
int cworker_writepid(const cworker_t* worker);
int cworker_configure(const cworker_t* worker);
int cworker_build(const cworker_t* worker);
int cworker_build(cworker_t* worker);
int cworker_run(const cworker_t* worker);

View File

@@ -2,22 +2,22 @@
/* defines.h.in. Generated from configure.ac by autoheader. */
/* location of cache dir */
#define APP_CACHEDIR "/home/ziggi/Projects/jcomp/cache"
#define APP_CACHEDIR "/home/ziggi/Projects/cworker/cache"
/* location of configuration files for ${PACKAGE} */
#define APP_CONFIGDIR "/home/ziggi/Projects/jcomp/"
#define APP_CONFIGDIR "/home/ziggi/Projects/cworker/"
/* location of database dir */
#define APP_DATABASEDIR "/home/ziggi/Projects/jcomp/data"
#define APP_DATABASEDIR "/home/ziggi/Projects/cworker/data"
/* location of libs */
#define APP_LIBDIR "/home/ziggi/Projects/jcomp/lib"
#define APP_LIBDIR "/home/ziggi/Projects/cworker/lib"
/* location of ${PACKAGE} logdir */
#define APP_LOGDIR "/home/ziggi/Projects/jcomp/log"
#define APP_LOGDIR "/home/ziggi/Projects/cworker/log"
/* location of pid file */
#define APP_RUNDIR "/home/ziggi/Projects/jcomp/run"
#define APP_RUNDIR "/home/ziggi/Projects/cworker/run"
/* effective user */
#define APP_USER "ziggi"

View File

@@ -10,6 +10,15 @@
#include <rcache.h>
#include <jlexer.h>
#define JLEXCONT_UNDEF 0
#define JLEXCONT_WORD 1
#define JLEXCONT_BLOCKB 2
#define JLEXCONT_BLOCKE 3
#define JLEXCONT_SEPAR 4
#define JLEXCONT_NUM 5
#define JLEXCONT_UNKNOW 6
#define JLEXCONT_END 9
#define JLEXTYPE_UNDEF 0
#define JLEXTYPE_BLOCKB 1
#define JLEXTYPE_BLOCKE 2
@@ -83,8 +92,8 @@ int jlexer_gettoken(jlexer_t * lexer, char* token) {
case JLEXCONT_END:{
lexer->context = JLEXCONT_END;
lexer->tokpos = 0;
lexer->rewind = true;
strcpy(token, "END");
//lexer->rewind = true;
strcpy(token, "EOF");
return JLEXTOK_END;
}
case JLEXCONT_UNDEF:{
@@ -95,12 +104,12 @@ int jlexer_gettoken(jlexer_t * lexer, char* token) {
break;
}
case JLEXTYPE_BLOCKB:{
strcpy(token, "BEGIN");
strcpy(token, "BLOCK BEGIN");
lexer->context = JLEXCONT_UNDEF;
return JLEXTOK_BLOCKB;
}
case JLEXTYPE_BLOCKE:{
strcpy(token, "END");
strcpy(token, "BLOCK END");
lexer->context = JLEXCONT_UNDEF;
return JLEXTOK_BLOCKE;
}

View File

@@ -14,14 +14,6 @@ typedef struct {
bool rewind;
} jlexer_t;
#define JLEXCONT_UNDEF 0
#define JLEXCONT_WORD 1
#define JLEXCONT_BLOCKB 2
#define JLEXCONT_BLOCKE 3
#define JLEXCONT_SEPAR 4
#define JLEXCONT_NUM 5
#define JLEXCONT_UNKNOW 6
#define JLEXCONT_END 9
#define JLEXTOK_BLOCKB 1

View File

@@ -40,11 +40,16 @@ int jparser_parse(jparser_t * parser) {
char* key = "";
while ((type = jlexer_gettoken(lex, token)) != JLEXTOK_END) {
//printf("pos %d %d: %s\n", pos, type, token);
switch (pos) {
// POS 0
case 0:{
if (type == JLEXTOK_END) {
log_error("End token received in position %d", pos);
return -1;
}
if (type != JLEXTOK_BLOCKB) {
log_error("wrong block token: %s", token);
log_error("Wrong block token: %s", token);
return -1;
}
pos++;
@@ -52,6 +57,10 @@ int jparser_parse(jparser_t * parser) {
}
// POS 1
case 1:{
if (type == JLEXTOK_END) {
log_error("End token received in position %d", pos);
//return -1;
}
if (type == JLEXTOK_SPACE)
continue;
if (type == JLEXTOK_NEXT)
@@ -59,7 +68,7 @@ int jparser_parse(jparser_t * parser) {
if (type == JLEXTOK_BLOCKE)
return 0;
if (type != JLEXTOK_WORD) {
log_error("wrong word token: %s", token);
log_error("Wrong word token: %s", token);
return -1;
}
key = strcopy(token);
@@ -68,10 +77,14 @@ int jparser_parse(jparser_t * parser) {
}
// POS 2
case 2:{
if (type == JLEXTOK_END) {
log_error("End token received in position %d", pos);
return -1;
}
if (type == JLEXTOK_SPACE)
continue;
if (type != JLEXTOK_SEPAR) {
log_error("wrong delimeter token: %s", token);
log_error("Wrong delimeter token: %s", token);
return -1;
}
pos++;
@@ -79,10 +92,18 @@ int jparser_parse(jparser_t * parser) {
}
// POS 3
case 3:{
if (type == JLEXTOK_END) {
log_error("End token received in position %d", pos);
return -1;
}
if (type == JLEXTOK_SPACE)
continue;
if (type == JLEXTOK_BLOCKB) {
pos = 1;
continue;
}
if (type != JLEXTOK_WORD && type != JLEXTOK_NUMB) {
log_error("wrong delimeter token: %s", token);
log_error("Wrong value token: %s", token);
return -1;
}
char* val = strcopy(token);
@@ -106,17 +127,28 @@ int jparser_parse(jparser_t * parser) {
}
// POS 4
case 4:{
if (type == JLEXTOK_SPACE)
if (type == JLEXTOK_END) {
log_error("End token received in position %d", pos);
return -1;
}
if (type == JLEXTOK_SPACE) {
continue;
if (type != JLEXTOK_NEXT && type != JLEXTOK_BLOCKE) {
log_error("wrong next token: %s", token);
} else if (type == JLEXTOK_BLOCKE) {
//log_debug("Block ended: %s", token);
return 0;
} else if (type != JLEXTOK_NEXT && type != JLEXTOK_BLOCKE) {
log_error("Wrong next token: %s", token);
return -1;
}
pos = 1;
break;
}
default:{
log_error("wrong parser stage: %s", token);
log_error("Wrong parser stage: %s", token);
if (type == JLEXTOK_END) {
log_error("End token received in position %d", pos);
return -1;
}
return -1;
}
}

View File

@@ -1,6 +1,6 @@
#ifndef CLPARSER_H_QWERTY
#define CLPARSER_H_QWERTY
#ifndef JPARSER_H_QWERTY
#define JPARSER_H_QWERTY
#include <stdbool.h>
#include <jlexer.h>

View File

@@ -8,12 +8,27 @@
#include <string.h>
#include <time.h>
#include <stdarg.h>
#include <pthread.h>
#define _CLOCK_SOURCE CLOCK_MONOTONIC
//#define CLOCK_SOURCE CLOCK_REALTIME_PRECISE
#define CLOCK_SOURCE CLOCK_MONOTONIC
#define MAX_TS_LEN 256
static pthread_mutex_t logmutex = NULL;
static pthread_mutexattr_t logmutex_attrs;
void log_init(void) {
pthread_mutexattr_init(&logmutex_attrs);
pthread_mutexattr_setpshared(&logmutex_attrs, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&logmutex, &logmutex_attrs);
}
void log_destroy(void) {
pthread_mutex_destroy(&logmutex);
pthread_mutexattr_destroy(&logmutex_attrs);
}
void static set_timestamp(char* buffer) {
time_t now = time(NULL);
if (now < 0) {
@@ -25,7 +40,7 @@ void static set_timestamp(char* buffer) {
}
struct timespec tv;
clock_gettime(_CLOCK_SOURCE, &tv);
clock_gettime(CLOCK_SOURCE, &tv);
memset(buffer, '\0', MAX_TS_LEN);
sprintf(buffer, "%04d-%02d-%02dT%02d:%02d:%02d.%ld+%s",
ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour,
@@ -37,23 +52,43 @@ void log_error(const char* format, ...) {
char timestamp[MAX_TS_LEN];
set_timestamp(timestamp);
pthread_mutex_lock(&logmutex);
va_list args;
fprintf(stderr, "%s error: ", timestamp);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\n");
pthread_mutex_unlock(&logmutex);
}
void log_warning(const char* format, ...) {
char timestamp[MAX_TS_LEN];
set_timestamp(timestamp);
pthread_mutex_lock(&logmutex);
va_list args;
fprintf(stderr, "%s warning: ", timestamp);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\n");
pthread_mutex_unlock(&logmutex);
}
void log_debug(const char* format, ...) {
char timestamp[MAX_TS_LEN];
set_timestamp(timestamp);
pthread_mutex_lock(&logmutex);
va_list args;
fprintf(stderr, "%s debug: ", timestamp);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\n");
pthread_mutex_unlock(&logmutex);
}

View File

@@ -1,6 +1,11 @@
#ifndef LOGGER_H_QWERTY
#define LOGGER_H_QWERTY
void log_init(void);
void log_destroy(void);
void log_error(const char* format, ... );
void log_debug(const char* format, ... );
void log_warning(const char* format, ... );
#endif

View File

@@ -33,8 +33,10 @@ char rcache_getc(rcache_t * cache) {
if (unread == 0) {
char* buffer[BUFFER_SIZE];
size_t rsize = read(cache->fd, buffer, sizeof(buffer));
ssize_t rsize = read(cache->fd, buffer, sizeof(buffer));
if (rsize < 0) {
return EOF;
}
if (rsize == 0) {
return EOF;
}
@@ -51,6 +53,7 @@ char rcache_getc(rcache_t * cache) {
memcpy(&(cache->data[cache->wpos]), buffer, (size_t)rsize);
cache->wpos += rsize;
}
//printf("[%c]", (char)cache->data[cache->rpos]);
return (char)cache->data[cache->rpos++];
}

40
works/fileoper.c Normal file
View File

@@ -0,0 +1,40 @@
char* path_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* path_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;
}

74
works/handlers.c Normal file
View File

@@ -0,0 +1,74 @@
int handler4(int socket) {
int err = 0;
rcache_t cache;
jlexer_t lexer;
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
rcache_init(&cache, socket);
jlexer_init(&lexer, &cache);
char token[1024];
int type = 0;
while ((type = jlexer_gettoken(&lexer, token)) != JLEXTOK_END) {
printf("%d: %s\n", type, token);
}
printf("= %d: %s\n", type, token);
//rcache_destroy(&cache);
return 0;
}
int handler5(int socket) {
int err = 0;
rcache_t cache;
rcache_init(&cache, socket);
char c = '\0';
while ((c = rcache_getc(&cache)) != EOF) {
printf("%c", c);
if (c == '}') {
dprintf(socket, "good bay!\n");
close(socket);
}
}
rcache_destroy(&cache);
return 0;
}
int handler3(int socket) {
//struct timeval tv;
//tv.tv_sec = 1;
//tv.tv_usec = 0;
//setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
const int bsize = 1024;
char buffer[bsize];
ssize_t rsize = 0;
ssize_t tsize = 0;
while(true) {
memset(buffer, '\0', bsize);
rsize = read(socket, buffer, bsize);
if (rsize < 0) {
log_debug("Socket error: %s", strerror(errno));
if (errno != EAGAIN) {
return -1;
}
} else if (rsize == 0) {
log_debug("Socket rsize is zero");
return 0;
} else {
tsize += rsize;
printf("%ld:%s\n", rsize, buffer);
}
}
return 0;
}