Allow "kore build" to produce single binaries.

Producing single binaries can now be done with building with
"kore build". To get started edit your build.conf and add the
following directives:

single_binary = yes
kore_source = /path/to/kore

optionally you can add kore_flavor to instruct how kore should
be built:

kore_flavor = NOTLS=1

When doing this your build.conf must also include the correct
linking options as the linking is now done fully by kore build.

The binary produced will include your configuration and takes
over a few of kore its command line flags (such as -f, -n or -r).
This commit is contained in:
Joris Vink 2016-07-06 16:16:15 +02:00
parent 7ac1ea379d
commit 39a5f21986
9 changed files with 431 additions and 80 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ kore
*.module
*.DSYM
cert
obj

View File

@ -2,6 +2,7 @@
CC?=gcc
PREFIX?=/usr/local
OBJDIR?=obj
KORE=kore
INSTALL_DIR=$(PREFIX)/bin
INCLUDE_DIR=$(PREFIX)/include/kore
@ -9,7 +10,6 @@ INCLUDE_DIR=$(PREFIX)/include/kore
S_SRC= src/kore.c src/buf.c src/cli.c src/config.c src/connection.c \
src/domain.c src/mem.c src/msg.c src/module.c src/net.c \
src/pool.c src/timer.c src/utils.c src/worker.c src/keymgr.c
S_OBJS= $(S_SRC:.c=.o)
CFLAGS+=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
CFLAGS+=-Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual
@ -70,11 +70,18 @@ else
S_SRC+=src/bsd.c
endif
$(KORE): $(S_OBJS)
S_OBJS= $(S_SRC:src/%.c=$(OBJDIR)/%.o)
$(KORE): $(OBJDIR) $(S_OBJS)
$(CC) $(S_OBJS) $(LDFLAGS) -o $(KORE)
objects: $(OBJDIR) $(S_OBJS)
all: $(KORE)
$(OBJDIR):
@mkdir -p $(OBJDIR)
install:
mkdir -p $(INCLUDE_DIR)
mkdir -p $(INSTALL_DIR)
@ -85,11 +92,11 @@ uninstall:
rm -f $(INSTALL_DIR)/$(KORE)
rm -rf $(INCLUDE_DIR)
.c.o:
$(OBJDIR)/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
find . -type f -name \*.o -exec rm {} \;
rm -f $(KORE)
rm -rf $(KORE) $(OBJDIR)
.PHONY: all clean

View File

@ -399,6 +399,10 @@ struct kore_keyreq {
};
#endif
#if !defined(KORE_SINGLE_BINARY)
extern char *config_file;
#endif
extern pid_t kore_pid;
extern int foreground;
extern int kore_debug;
@ -407,7 +411,6 @@ extern char *chroot_path;
extern int skip_runas;
extern char *runas_user;
extern char *kore_pidfile;
extern char *config_file;
extern char *kore_tls_cipher_list;
extern int tls_version;
@ -631,6 +634,10 @@ void kore_buf_replace_string(struct kore_buf *, char *, void *, size_t);
void kore_keymgr_run(void);
void kore_keymgr_cleanup(void);
#if defined(KORE_SINGLE_BINARY)
void kore_main(void);
#endif
#if defined(__cplusplus)
}
#endif

329
src/cli.c
View File

@ -68,6 +68,9 @@
struct buildopt {
char *name;
char *kore_source;
char *kore_flavor;
int single_binary;
struct kore_buf *cflags;
struct kore_buf *cxxflags;
struct kore_buf *ldflags;
@ -99,9 +102,10 @@ TAILQ_HEAD(cfile_list, cfile);
static void cli_fatal(const char *, ...) __attribute__((noreturn));
static void cli_file_close(int);
static void cli_run_kore(void *);
static void cli_run_kore(void);
static void cli_generate_certs(void);
static void cli_link_library(void *);
static void cli_compile_kore(void *);
static void cli_compile_source_file(void *);
static void cli_mkdir(const char *, int);
static int cli_dir_exists(const char *);
@ -118,6 +122,7 @@ static void cli_file_write(int, const void *, size_t);
static int cli_vasprintf(char **, const char *, ...);
static void cli_spawn_proc(void (*cb)(void *), void *);
static void cli_write_asset(const char *, const char *);
static void cli_register_kore_file(char *, struct dirent *);
static void cli_register_source_file(char *, struct dirent *);
static void cli_file_create(const char *, const char *, size_t);
static int cli_file_requires_build(struct stat *, const char *);
@ -126,6 +131,7 @@ static void cli_find_files(const char *,
static void cli_add_source_file(char *, char *, char *,
struct stat *, int);
static struct buildopt *cli_buildopt_default(void);
static struct buildopt *cli_buildopt_new(const char *);
static struct buildopt *cli_buildopt_find(const char *);
static void cli_buildopt_cleanup(void);
@ -133,6 +139,12 @@ static void cli_buildopt_parse(const char *);
static void cli_buildopt_cflags(struct buildopt *, const char *);
static void cli_buildopt_cxxflags(struct buildopt *, const char *);
static void cli_buildopt_ldflags(struct buildopt *, const char *);
static void cli_buildopt_single_binary(struct buildopt *,
const char *);
static void cli_buildopt_kore_source(struct buildopt *,
const char *);
static void cli_buildopt_kore_flavor(struct buildopt *,
const char *);
static void cli_flavor_load(void);
static void cli_flavor_change(const char *);
@ -209,6 +221,14 @@ static const char *build_data =
"# %s build config\n"
"# You can switch flavors using: kore flavor [newflavor]\n"
"\n"
"# Set to yes if you wish to produce a single binary instead\n"
"# of a dynamic library. If you set this to yes you must also\n"
"# set kore_source together with kore_flavor and update ldflags\n"
"# to include the appropriate libraries you will be linking with.\n"
"#single_binary=no\n"
"#kore_source=/home/joris/src/kore\n"
"#kore_flavor=\n"
"\n"
"# The flags below are shared between flavors\n"
"cflags=-Wall -Wmissing-declarations -Wshadow\n"
"cflags=-Wstrict-prototypes -Wmissing-prototypes\n"
@ -245,6 +265,7 @@ static const char *gitignore = "*.o\n.flavor\n.objs\n%s.so\nassets.h\ncert\n";
static int s_fd = -1;
static char *appl = NULL;
static int run_after = 0;
static char *rootdir = NULL;
static char *compiler_c = "gcc";
static char *compiler_cpp = "g++";
@ -393,6 +414,7 @@ cli_flavor(int argc, char **argv)
static void
cli_build(int argc, char **argv)
{
struct dirent dp;
struct cfile *cf;
struct buildopt *bopt;
struct timeval times[2];
@ -427,7 +449,6 @@ cli_build(int argc, char **argv)
if (!cli_dir_exists(src_path) || !cli_file_exists(config))
cli_fatal("%s doesn't appear to be a kore app", appl);
free(config);
cli_flavor_load();
bopt = cli_buildopt_new("_default");
@ -437,38 +458,62 @@ cli_build(int argc, char **argv)
free(data);
}
cli_buildopt_parse(build_path);
free(build_path);
/* Build all source files. */
cli_find_files(src_path, cli_register_source_file);
free(src_path);
printf("building %s (%s)\n", appl, flavor);
cli_build_cflags(bopt);
cli_build_cxxflags(bopt);
cli_build_ldflags(bopt);
cli_buildopt_parse(build_path);
free(build_path);
(void)cli_vasprintf(&obj_path, "%s/.objs", rootdir);
if (!cli_dir_exists(obj_path))
cli_mkdir(obj_path, 0755);
free(obj_path);
if (bopt->single_binary) {
if (bopt->kore_source == NULL)
cli_fatal("single_binary set but not kore_source");
printf("building kore (%s)\n", bopt->kore_source);
cli_spawn_proc(cli_compile_kore, bopt);
(void)cli_vasprintf(&src_path, "%s/src", bopt->kore_source);
cli_find_files(src_path, cli_register_kore_file);
free(src_path);
}
printf("building %s (%s)\n", appl, flavor);
cli_build_cflags(bopt);
cli_build_cxxflags(bopt);
cli_build_ldflags(bopt);
(void)unlink(assets_header);
/* Generate the assets. */
if (cli_dir_exists(assets_path)) {
cli_file_open(assets_header,
O_CREAT | O_TRUNC | O_WRONLY, &s_fd);
cli_file_open(assets_header, O_CREAT | O_TRUNC | O_WRONLY, &s_fd);
cli_file_writef(s_fd, "#ifndef __H_KORE_ASSETS_H\n");
cli_file_writef(s_fd, "#define __H_KORE_ASSETS_H\n");
cli_file_writef(s_fd, "#ifndef __H_KORE_ASSETS_H\n");
cli_file_writef(s_fd, "#define __H_KORE_ASSETS_H\n");
if (cli_dir_exists(assets_path))
cli_find_files(assets_path, cli_build_asset);
cli_file_writef(s_fd, "\n#endif\n");
cli_file_close(s_fd);
if (bopt->single_binary) {
memset(&dp, 0, sizeof(dp));
dp.d_type = DT_REG;
printf("adding config %s\n", config);
(void)snprintf(dp.d_name,
sizeof(dp.d_name), "builtin_kore.conf");
cli_build_asset(config, &dp);
}
cli_file_writef(s_fd, "\n#endif\n");
cli_file_close(s_fd);
free(assets_path);
free(config);
if (cxx_files_count > 0)
compiler_ld = compiler_cpp;
requires_relink = 0;
TAILQ_FOREACH(cf, &source_files, list) {
@ -485,10 +530,6 @@ cli_build(int argc, char **argv)
if (utimes(cf->opath, times) == -1)
printf("utime(%s): %s\n", cf->opath, errno_s);
if (cf->build == BUILD_CXX) {
compiler_ld = compiler_cpp;
}
requires_relink++;
}
@ -502,18 +543,26 @@ cli_build(int argc, char **argv)
}
free(cpath);
(void)cli_vasprintf(&sofile, "%s.so", appl);
if (bopt->single_binary) {
requires_relink++;
(void)cli_vasprintf(&sofile, "%s", appl);
} else {
(void)cli_vasprintf(&sofile, "%s.so", appl);
}
if (!cli_file_exists(sofile))
requires_relink++;
free(sofile);
if (requires_relink) {
cli_spawn_proc(cli_link_library, NULL);
cli_spawn_proc(cli_link_library, bopt);
printf("%s built successfully!\n", appl);
} else {
printf("nothing to be done!\n");
}
cli_buildopt_cleanup();
if (run_after == 0)
cli_buildopt_cleanup();
}
static void
@ -538,6 +587,7 @@ cli_clean(int argc, char **argv)
static void
cli_run(int argc, char **argv)
{
run_after = 1;
cli_build(argc, argv);
if (chdir(rootdir) == -1)
@ -547,7 +597,7 @@ cli_run(int argc, char **argv)
* We are exec()'ing kore again, while we could technically set
* the right cli options manually and just continue running.
*/
cli_run_kore(NULL);
cli_run_kore();
}
static void
@ -850,12 +900,14 @@ cli_register_source_file(char *fpath, struct dirent *dp)
if (stat(fpath, &st) == -1)
cli_fatal("stat(%s): %s", fpath, errno_s);
if (!strcmp(ext, ".cpp"))
cxx_files_count++;
(void)cli_vasprintf(&opath, "%s/.objs/%s.o", rootdir, dp->d_name);
if (!cli_file_requires_build(&st, opath)) {
build = BUILD_NOBUILD;
} else if (!strcmp(ext, ".cpp")) {
build = BUILD_CXX;
cxx_files_count++;
} else {
build = BUILD_C;
}
@ -863,6 +915,33 @@ cli_register_source_file(char *fpath, struct dirent *dp)
cli_add_source_file(dp->d_name, fpath, opath, &st, build);
}
static void
cli_register_kore_file(char *fpath, struct dirent *dp)
{
struct stat st, ost;
char *opath, *ext, *fname;
if ((ext = strrchr(fpath, '.')) == NULL || strcmp(ext, ".c"))
return;
if (stat(fpath, &st) == -1)
cli_fatal("stat(%s): %s", fpath, errno_s);
*ext = '\0';
if ((fname = basename(fpath)) == NULL)
cli_fatal("basename failed");
(void)cli_vasprintf(&opath, "%s/.objs/%s.o", rootdir, fname);
/* Silently ignore non existing object files for kore source files. */
if (stat(opath, &ost) == -1) {
free(opath);
return;
}
cli_add_source_file(dp->d_name, fpath, opath, &st, BUILD_NOBUILD);
}
static void
cli_file_remove(char *fpath, struct dirent *dp)
{
@ -1049,17 +1128,24 @@ cli_compile_source_file(void *arg)
args[idx] = NULL;
execvp(compiler, args);
cli_fatal("failed to start '%s': %s", compiler, errno_s);
}
static void
cli_link_library(void *arg)
{
struct cfile *cf;
struct buildopt *bopt;
int idx, i;
char *libname;
char *output;
char *args[source_files_count + 11 + LD_FLAGS_MAX];
(void)cli_vasprintf(&libname, "%s/%s.so", rootdir, appl);
bopt = arg;
if (bopt->single_binary)
(void)cli_vasprintf(&output, "%s/%s", rootdir, appl);
else
(void)cli_vasprintf(&output, "%s/%s.so", rootdir, appl);
idx = 0;
args[idx++] = compiler_ld;
@ -1070,26 +1156,95 @@ cli_link_library(void *arg)
for (i = 0; i < ldflags_count; i++)
args[idx++] = ldflags[i];
if (bopt->single_binary) {
args[idx++] = "-rdynamic";
#if defined(__linux__)
args[idx++] = "-ldl";
#endif
}
args[idx++] = "-o";
args[idx++] = libname;
args[idx++] = output;
args[idx] = NULL;
execvp(compiler_ld, args);
cli_fatal("failed to start '%s': %s", compiler_ld, errno_s);
}
static void
cli_run_kore(void *arg)
cli_compile_kore(void *arg)
{
char *args[4], *cpath;
struct buildopt *bopt = arg;
int idx, i, fcnt;
char *obj, *args[16], pwd[MAXPATHLEN], *flavors[7];
(void)cli_vasprintf(&cpath, "conf/%s.conf", appl);
if (getcwd(pwd, sizeof(pwd)) == NULL)
cli_fatal("could not get cwd: %s", errno_s);
args[0] = "kore";
args[1] = "-fnrc";
args[2] = cpath;
args[3] = NULL;
(void)cli_vasprintf(&obj, "OBJDIR=%s/.objs", pwd);
execvp("kore", args);
if (putenv(obj) != 0)
cli_fatal("cannot set OBJDIR for building kore");
if (putenv("CFLAGS=-DKORE_SINGLE_BINARY") != 0)
cli_fatal("cannot set CFLAGS for building kore");
fcnt = kore_split_string(bopt->kore_flavor, " ", flavors, 7);
#if defined(OpenBSD) || defined(__FreeBSD_version) || \
defined(NetBSD) || defined(__DragonFly_version)
args[0] = "gmake";
#else
args[0] = "make";
#endif
args[1] = "-s";
args[2] = "-C";
args[3] = bopt->kore_source;
args[4] = "objects";
idx = 5;
for (i = 0; i < fcnt; i++) {
printf("using flavor %s\n", flavors[i]);
args[idx++] = flavors[i];
}
args[idx] = NULL;
execvp(args[0], args);
cli_fatal("failed to start '%s': %s", args[0], errno_s);
}
static void
cli_run_kore(void)
{
struct buildopt *bopt;
char *args[4], *cpath, *cmd, *flags;
bopt = cli_buildopt_default();
if (bopt->single_binary) {
cpath = NULL;
flags = "-fnr";
(void)cli_vasprintf(&cmd, "./%s", appl);
} else {
cmd = "kore";
flags = "-fnrc";
(void)cli_vasprintf(&cpath, "conf/%s.conf", appl);
}
args[0] = cmd;
args[1] = flags;
if (cpath != NULL) {
args[2] = cpath;
args[3] = NULL;
} else {
args[2] = NULL;
}
execvp(args[0], args);
cli_fatal("failed to start '%s': %s", args[0], errno_s);
}
static void
@ -1142,8 +1297,14 @@ parse_option:
cli_buildopt_cxxflags(bopt, t);
} else if (!strcasecmp(p, "ldflags")) {
cli_buildopt_ldflags(bopt, t);
} else if (!strcasecmp(p, "single_binary")) {
cli_buildopt_single_binary(bopt, t);
} else if (!strcasecmp(p, "kore_source")) {
cli_buildopt_kore_source(bopt, t);
} else if (!strcasecmp(p, "kore_flavor")) {
cli_buildopt_kore_flavor(bopt, t);
} else {
printf("ignoring unknown option %s\n", p);
printf("ignoring unknown option '%s'\n", p);
}
}
}
@ -1157,6 +1318,9 @@ cli_buildopt_new(const char *name)
bopt->cflags = NULL;
bopt->cxxflags = NULL;
bopt->ldflags = NULL;
bopt->single_binary = 0;
bopt->kore_source = NULL;
bopt->kore_flavor = NULL;
bopt->name = kore_strdup(name);
TAILQ_INSERT_TAIL(&build_options, bopt, list);
@ -1176,6 +1340,17 @@ cli_buildopt_find(const char *name)
return (NULL);
}
static struct buildopt *
cli_buildopt_default(void)
{
struct buildopt *bopt;
if ((bopt = cli_buildopt_find("_default")) == NULL)
fatal("no _default buildopt options");
return (bopt);
}
static void
cli_buildopt_cleanup(void)
{
@ -1191,6 +1366,10 @@ cli_buildopt_cleanup(void)
kore_buf_free(bopt->cxxflags);
if (bopt->ldflags != NULL)
kore_buf_free(bopt->ldflags);
if (bopt->kore_source != NULL)
kore_mem_free(bopt->kore_source);
if (bopt->kore_flavor != NULL)
kore_mem_free(bopt->kore_flavor);
kore_mem_free(bopt);
}
}
@ -1198,10 +1377,8 @@ cli_buildopt_cleanup(void)
static void
cli_buildopt_cflags(struct buildopt *bopt, const char *string)
{
if (bopt == NULL) {
if ((bopt = cli_buildopt_find("_default")) == NULL)
cli_fatal("no _default build options");
}
if (bopt == NULL)
bopt = cli_buildopt_default();
if (bopt->cflags == NULL)
bopt->cflags = kore_buf_create(128);
@ -1212,10 +1389,8 @@ cli_buildopt_cflags(struct buildopt *bopt, const char *string)
static void
cli_buildopt_cxxflags(struct buildopt *bopt, const char *string)
{
if (bopt == NULL) {
if ((bopt = cli_buildopt_find("_default")) == NULL)
cli_fatal("no _default build options");
}
if (bopt == NULL)
bopt = cli_buildopt_default();
if (bopt->cxxflags == NULL)
bopt->cxxflags = kore_buf_create(128);
@ -1226,10 +1401,8 @@ cli_buildopt_cxxflags(struct buildopt *bopt, const char *string)
static void
cli_buildopt_ldflags(struct buildopt *bopt, const char *string)
{
if (bopt == NULL) {
if ((bopt = cli_buildopt_find("_default")) == NULL)
cli_fatal("no _default build options");
}
if (bopt == NULL)
bopt = cli_buildopt_default();
if (bopt->ldflags == NULL)
bopt->ldflags = kore_buf_create(128);
@ -1237,6 +1410,48 @@ cli_buildopt_ldflags(struct buildopt *bopt, const char *string)
kore_buf_appendf(bopt->ldflags, "%s ", string);
}
static void
cli_buildopt_single_binary(struct buildopt *bopt, const char *string)
{
if (bopt == NULL)
bopt = cli_buildopt_default();
else
cli_fatal("single_binary only supported in global context");
if (!strcmp(string, "yes"))
bopt->single_binary = 1;
else
bopt->single_binary = 0;
}
static void
cli_buildopt_kore_source(struct buildopt *bopt, const char *string)
{
if (bopt == NULL)
bopt = cli_buildopt_default();
else
cli_fatal("kore_source only supported in global context");
if (bopt->kore_source != NULL)
kore_mem_free(bopt->kore_source);
bopt->kore_source = kore_strdup(string);
}
static void
cli_buildopt_kore_flavor(struct buildopt *bopt, const char *string)
{
if (bopt == NULL)
bopt = cli_buildopt_default();
else
cli_fatal("kore_flavor only supported in global context");
if (bopt->kore_flavor != NULL)
kore_mem_free(bopt->kore_flavor);
bopt->kore_flavor = kore_strdup(string);
}
static void
cli_build_flags_common(struct kore_buf* buf)
{
@ -1282,6 +1497,9 @@ cli_build_cflags(struct buildopt *bopt)
obopt->cflags->offset);
}
if (bopt->single_binary)
kore_buf_appendf(bopt->cflags, "-DKORE_SINGLE_BINARY");
string = kore_buf_stringify(bopt->cflags, NULL);
printf("CFLAGS=%s\n", string);
cflags_count = kore_split_string(string, " ", cflags, CFLAGS_MAX);
@ -1324,12 +1542,14 @@ cli_build_ldflags(struct buildopt *bopt)
if (bopt->ldflags == NULL)
bopt->ldflags = kore_buf_create(128);
if (bopt->single_binary == 0) {
#if defined(__MACH__)
kore_buf_appendf(bopt->ldflags,
"-dynamiclib -undefined suppress -flat_namespace ");
kore_buf_appendf(bopt->ldflags,
"-dynamiclib -undefined suppress -flat_namespace ");
#else
kore_buf_appendf(bopt->ldflags, "-shared ");
kore_buf_appendf(bopt->ldflags, "-shared ");
#endif
}
if (obopt != NULL && obopt->ldflags != NULL) {
kore_buf_append(bopt->ldflags, obopt->ldflags->data,
@ -1351,6 +1571,9 @@ cli_flavor_load(void)
cli_fatal("could not get cwd: %s", errno_s);
appl = basename(pwd);
if (appl == NULL)
cli_fatal("basename: %s", errno_s);
appl = kore_strdup(appl);
(void)cli_vasprintf(&conf, "conf/%s.conf", appl);
if (!cli_dir_exists("conf") || !cli_file_exists(conf))

View File

@ -14,6 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <stdio.h>
@ -36,9 +37,16 @@
/* XXX - This is becoming a clusterfuck. Fix it. */
#if !defined(KORE_SINGLE_BINARY)
static int configure_load(char *);
#else
static FILE *config_file_write(void);
extern u_int8_t asset_builtin_kore_conf[];
extern u_int32_t asset_len_builtin_kore_conf;
#endif
static int configure_include(char *);
static int configure_bind(char *);
static int configure_load(char *);
static int configure_domain(char *);
static int configure_chroot(char *);
static int configure_runas(char *);
@ -100,7 +108,9 @@ static struct {
} config_names[] = {
{ "include", configure_include },
{ "bind", configure_bind },
#if !defined(KORE_SINGLE_BINARY)
{ "load", configure_load },
#endif
{ "domain", configure_domain },
{ "chroot", configure_chroot },
{ "runas", configure_runas },
@ -150,7 +160,9 @@ static struct {
{ NULL, NULL },
};
#if !defined(KORE_SINGLE_BINARY)
char *config_file = NULL;
#endif
#if !defined(KORE_NO_HTTP)
static u_int8_t current_method = 0;
@ -158,15 +170,20 @@ static struct kore_auth *current_auth = NULL;
static struct kore_module_handle *current_handler = NULL;
#endif
extern const char *__progname;
static struct kore_domain *current_domain = NULL;
void
kore_parse_config(void)
{
#if !defined(KORE_SINGLE_BINARY)
kore_parse_config_file(config_file);
#else
kore_parse_config_file(NULL);
#endif
if (!kore_module_loaded())
fatal("no site module was loaded");
fatal("no application module was loaded");
if (skip_chroot != 1 && chroot_path == NULL) {
fatal("missing a chroot path");
@ -192,8 +209,12 @@ kore_parse_config_file(const char *fpath)
int i, lineno;
char buf[BUFSIZ], *p, *t;
#if !defined(KORE_SINGLE_BINARY)
if ((fp = fopen(fpath, "r")) == NULL)
fatal("configuration given cannot be opened: %s", fpath);
#else
fp = config_file_write();
#endif
kore_debug("parsing configuration file '%s'", fpath);
@ -282,6 +303,7 @@ configure_bind(char *options)
return (kore_server_bind(argv[0], argv[1], argv[2]));
}
#if !defined(KORE_SINGLE_BINARY)
static int
configure_load(char *options)
{
@ -294,6 +316,46 @@ configure_load(char *options)
kore_module_load(argv[0], argv[1]);
return (KORE_RESULT_OK);
}
#else
static FILE *
config_file_write(void)
{
FILE *fp;
ssize_t ret;
int fd, len;
char fpath[MAXPATHLEN];
len = snprintf(fpath, sizeof(fpath), "/tmp/%s.XXXXXX", __progname);
if (len == -1 || (size_t)len >= sizeof(fpath))
fatal("failed to create temporary path");
if ((fd = mkstemp(fpath)) == -1)
fatal("mkstemp(%s): %s", fpath, errno_s);
(void)unlink(fpath);
for (;;) {
ret = write(fd, asset_builtin_kore_conf,
asset_len_builtin_kore_conf);
if (ret == -1) {
if (errno == EINTR)
continue;
fatal("failed to write temporary config: %s", errno_s);
}
if ((size_t)ret != asset_len_builtin_kore_conf)
fatal("failed to write temporary config");
break;
}
if ((fp = fdopen(fd, "w+")) == NULL)
fatal("fdopen(): %s", errno_s);
rewind(fp);
return (fp);
}
#endif
#if !defined(KORE_NO_TLS)
static int

View File

@ -47,6 +47,8 @@ u_int32_t kore_socket_backlog = 5000;
char *kore_pidfile = KORE_PIDFILE_DEFAULT;
char *kore_tls_cipher_list = KORE_DEFAULT_CIPHER_LIST;
extern char *__progname;
static void usage(void);
static void version(void);
static void kore_server_start(void);
@ -56,24 +58,37 @@ static void kore_server_sslstart(void);
static void
usage(void)
{
#if !defined(KORE_SINGLE_BINARY)
fprintf(stderr, "Usage: kore [options | command]\n");
#else
fprintf(stderr, "Usage: %s [options]\n", __progname);
#endif
fprintf(stderr, "\n");
fprintf(stderr, "Available options:\n");
fprintf(stderr, "\t-c\tspecify the configuration file to use\n");
fprintf(stderr, "\t-d\trun with debug on (if compiled in)\n");
fprintf(stderr, "\t-f\tstart kore in foreground mode\n");
#if !defined(KORE_SINGLE_BINARY)
fprintf(stderr, "\t-c\tconfiguration to use\n");
#endif
#if defined(KORE_DEBUG)
fprintf(stderr, "\t-d\trun with debug on)\n");
#endif
fprintf(stderr, "\t-f\tstart in foreground\n");
fprintf(stderr, "\t-h\tthis help text\n");
fprintf(stderr, "\t-n\tdo not chroot\n");
fprintf(stderr, "\t-r\tdo not drop privs\n");
fprintf(stderr, "\t-v\tdisplay kore's version information\n");
fprintf(stderr, "\t-r\tdo not drop privileges\n");
fprintf(stderr, "\t-v\tdisplay kore build information\n");
#if !defined(KORE_SINGLE_BINARY)
kore_cli_usage(0);
#else
fprintf(stderr, "\nbuilt with https://kore.io\n");
exit(1);
#endif
}
static void
version(void)
{
printf("kore %d.%d.%d-%s ", KORE_VERSION_MAJOR, KORE_VERSION_MINOR,
printf("%d.%d.%d-%s ", KORE_VERSION_MAJOR, KORE_VERSION_MINOR,
KORE_VERSION_PATCH, KORE_VERSION_STATE);
#if defined(KORE_NO_TLS)
printf("no-tls ");
@ -89,6 +104,9 @@ version(void)
#endif
#if defined(KORE_DEBUG)
printf("debug ");
#endif
#if defined(KORE_SINGLE_BINARY)
printf("single ");
#endif
printf("\n");
@ -99,22 +117,29 @@ int
main(int argc, char *argv[])
{
int ch, flags;
#if defined(KORE_SINGLE_BINARY)
void (*kmain)(void);
#endif
flags = 0;
#if !defined(KORE_SINGLE_BINARY)
while ((ch = getopt(argc, argv, "c:dfhnrv")) != -1) {
#else
while ((ch = getopt(argc, argv, "dfhnrv")) != -1) {
#endif
flags++;
switch (ch) {
#if !defined(KORE_SINGLE_BINARY)
case 'c':
config_file = optarg;
break;
case 'd':
#if defined(KORE_DEBUG)
kore_debug = 1;
#else
printf("kore not compiled with debug support\n");
#endif
#if defined(KORE_DEBUG)
case 'd':
kore_debug = 1;
break;
#endif
case 'f':
foreground = 1;
break;
@ -140,11 +165,13 @@ main(int argc, char *argv[])
kore_mem_init();
#if !defined(KORE_SINGLE_BINARY)
if (argc > 0) {
if (flags)
fatal("You cannot specify kore flags and a command");
return (kore_cli_main(argc, argv));
}
#endif
kore_pid = getpid();
nlisteners = 0;
@ -159,8 +186,15 @@ main(int argc, char *argv[])
kore_module_init();
kore_server_sslstart();
#if !defined(KORE_SINGLE_BINARY)
if (config_file == NULL)
usage();
#else
kore_module_load(NULL, NULL);
*(void **)&(kmain) = kore_module_getsym("kore_main");
if (kmain != NULL)
kmain();
#endif
kore_parse_config();
kore_platform_init();
@ -380,7 +414,7 @@ kore_server_start(void)
if (!foreground)
kore_write_kore_pid();
kore_log(LOG_NOTICE, "kore is starting up");
kore_log(LOG_NOTICE, "%s is starting up", __progname);
#if defined(KORE_USE_PGSQL)
kore_log(LOG_NOTICE, "pgsql built-in enabled");
#endif
@ -407,8 +441,10 @@ kore_server_start(void)
if (sig_recv != 0) {
switch (sig_recv) {
case SIGHUP:
#if !defined(KORE_SINGLE_BINARY)
kore_worker_dispatch_signal(sig_recv);
kore_module_reload(0);
#endif
break;
case SIGINT:
case SIGQUIT:

View File

@ -46,19 +46,27 @@ kore_module_cleanup(void)
void
kore_module_load(const char *path, const char *onload)
{
#if !defined(KORE_SINGLE_BINARY)
struct stat st;
#endif
struct kore_module *module;
kore_debug("kore_module_load(%s, %s)", path, onload);
module = kore_malloc(sizeof(struct kore_module));
module->onload = NULL;
module->ocb = NULL;
#if !defined(KORE_SINGLE_BINARY)
if (stat(path, &st) == -1)
fatal("stat(%s): %s", path, errno_s);
module = kore_malloc(sizeof(struct kore_module));
module->path = kore_strdup(path);
module->mtime = st.st_mtime;
module->onload = NULL;
module->ocb = NULL;
#else
module->path = NULL;
module->mtime = 0;
#endif
module->handle = dlopen(module->path, RTLD_NOW | RTLD_GLOBAL);
if (module->handle == NULL)
@ -77,6 +85,7 @@ kore_module_load(const char *path, const char *onload)
void
kore_module_onload(void)
{
#if !defined(KORE_SINGLE_BINARY)
struct kore_module *module;
TAILQ_FOREACH(module, &modules, list) {
@ -85,11 +94,13 @@ kore_module_onload(void)
(void)module->ocb(KORE_MODULE_LOAD);
}
#endif
}
void
kore_module_reload(int cbs)
{
#if !defined(KORE_SINGLE_BINARY)
struct stat st;
struct kore_domain *dom;
struct kore_module_handle *hdlr;
@ -148,6 +159,7 @@ kore_module_reload(int cbs)
#if !defined(KORE_NO_HTTP)
kore_validator_reload();
#endif
#endif
}
int

View File

@ -521,8 +521,8 @@ kore_text_trim(char *string, size_t len)
if (len == 0)
return (string);
end = string + len;
while (isspace(*string))
end = (string + len) - 1;
while (isspace(*string) && string < end)
string++;
while (isspace(*end) && end > string)
@ -561,8 +561,9 @@ kore_read_line(FILE *fp, char *in, size_t len)
void
fatal(const char *fmt, ...)
{
va_list args;
char buf[2048];
va_list args;
char buf[2048];
extern const char *__progname;
va_start(args, fmt);
(void)vsnprintf(buf, sizeof(buf), fmt, args);
@ -576,6 +577,6 @@ fatal(const char *fmt, ...)
kore_keymgr_cleanup();
#endif
printf("kore: %s\n", buf);
printf("%s: %s\n", __progname, buf);
exit(1);
}

View File

@ -333,7 +333,9 @@ kore_worker_entry(struct kore_worker *kw)
if (sig_recv != 0) {
switch (sig_recv) {
case SIGHUP:
#if !defined(KORE_SINGLE_BINARY)
kore_module_reload(1);
#endif
break;
case SIGQUIT:
case SIGINT: