218 lines
3.8 KiB
C
218 lines
3.8 KiB
C
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#ifndef NDEBUG
|
|
#include <wlr/util/log.h>
|
|
#endif
|
|
|
|
#include <hikari/server.h>
|
|
|
|
#include "version.h"
|
|
|
|
static char *
|
|
get_default_path(char *path)
|
|
{
|
|
char *prefix = getenv("XDG_CONFIG_HOME");
|
|
char *subdirectory;
|
|
|
|
if (prefix == NULL) {
|
|
prefix = getenv("HOME");
|
|
subdirectory = "/.config/hikari/";
|
|
} else {
|
|
subdirectory = "/hikari/";
|
|
}
|
|
|
|
size_t len = strlen(prefix) + strlen(subdirectory) + strlen(path);
|
|
|
|
char *ret = malloc(len + 1);
|
|
|
|
strcpy(ret, prefix);
|
|
strcat(ret, subdirectory);
|
|
strcat(ret, path);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static char *
|
|
get_user_autostart(void)
|
|
{
|
|
return get_default_path("autostart");
|
|
}
|
|
|
|
static char *
|
|
get_user_config_path(void)
|
|
{
|
|
return get_default_path("hikari.conf");
|
|
}
|
|
|
|
#define STR(s) #s
|
|
#define DEFAULT_CONFIG(s) STR(s) "/etc/hikari/hikari.conf"
|
|
#define DEFAULT_CONFIG_FILE DEFAULT_CONFIG(HIKARI_ETC_PREFIX)
|
|
|
|
static char *
|
|
get_default_config_path(void)
|
|
{
|
|
return strdup(DEFAULT_CONFIG_FILE);
|
|
}
|
|
|
|
#undef STR
|
|
#undef DEFAULT_CONFIG
|
|
#undef DEFAULT_CONFIG_FILE
|
|
|
|
static bool
|
|
check_perms(char *path, int mode)
|
|
{
|
|
struct stat s;
|
|
return stat(path, &s) == 0 && S_ISREG(s.st_mode) && !access(path, mode);
|
|
}
|
|
|
|
static char *
|
|
check_path(char *path, int mode)
|
|
{
|
|
char *check = path;
|
|
|
|
if (!check_perms(check, mode)) {
|
|
free(path);
|
|
check = NULL;
|
|
}
|
|
|
|
return check;
|
|
}
|
|
|
|
static char *
|
|
get_config_path(char *path)
|
|
{
|
|
char *config;
|
|
|
|
if (path != NULL) {
|
|
char *option_config = check_path(path, R_OK);
|
|
|
|
config = option_config;
|
|
} else {
|
|
char *user_config = check_path(get_user_config_path(), R_OK);
|
|
|
|
if (user_config == NULL) {
|
|
char *default_config = check_path(get_default_config_path(), R_OK);
|
|
|
|
config = default_config;
|
|
} else {
|
|
config = user_config;
|
|
}
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
static char *
|
|
get_autostart(char *path)
|
|
{
|
|
char *autostart;
|
|
int mode = R_OK | X_OK;
|
|
|
|
if (path != NULL) {
|
|
char *option_autostart = check_path(path, mode);
|
|
|
|
autostart = option_autostart;
|
|
} else {
|
|
char *user_autostart = check_path(get_user_autostart(), mode);
|
|
|
|
autostart = user_autostart;
|
|
}
|
|
|
|
return autostart;
|
|
}
|
|
|
|
const char *usage = "Usage: hikari [options]\n"
|
|
"\n"
|
|
"Options: \n"
|
|
" -a <executable> Specify an autostart executable.\n"
|
|
" -c <config> Specify a configuration file.\n"
|
|
" -h Show this message and quit.\n"
|
|
" -v Show version and quit.\n"
|
|
"\n";
|
|
|
|
struct options {
|
|
char *config_path;
|
|
char *autostart;
|
|
};
|
|
|
|
static void
|
|
parse_options(int argc, char **argv, struct options *options)
|
|
{
|
|
char *config_path = NULL;
|
|
char *autostart = NULL;
|
|
|
|
char flag;
|
|
while ((flag = getopt(argc, argv, "vhc:a:")) != -1) {
|
|
switch (flag) {
|
|
case 'a':
|
|
free(autostart);
|
|
autostart = strdup(optarg);
|
|
break;
|
|
|
|
case 'c':
|
|
free(config_path);
|
|
config_path = strdup(optarg);
|
|
break;
|
|
|
|
case 'v':
|
|
free(config_path);
|
|
free(autostart);
|
|
|
|
printf("%s\n", HIKARI_VERSION);
|
|
exit(EXIT_SUCCESS);
|
|
break;
|
|
|
|
case 'h':
|
|
free(config_path);
|
|
free(autostart);
|
|
|
|
printf("%s", usage);
|
|
exit(EXIT_SUCCESS);
|
|
break;
|
|
|
|
case '?':
|
|
default:
|
|
free(config_path);
|
|
free(autostart);
|
|
|
|
printf("%s", usage);
|
|
exit(EXIT_FAILURE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
options->config_path = get_config_path(config_path);
|
|
options->autostart = get_autostart(autostart);
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
#ifndef NDEBUG
|
|
wlr_log_init(WLR_DEBUG, NULL);
|
|
#endif
|
|
struct options options;
|
|
parse_options(argc, argv, &options);
|
|
|
|
if (options.config_path == NULL) {
|
|
free(options.autostart);
|
|
|
|
fprintf(stderr, "could not load configuration\n");
|
|
|
|
return EXIT_FAILURE;
|
|
} else {
|
|
hikari_server_prepare_privileged();
|
|
|
|
assert(geteuid() != 0 && geteuid() == getuid());
|
|
assert(getegid() != 0 && getegid() == getgid());
|
|
|
|
hikari_server_start(options.config_path, options.autostart);
|
|
hikari_server_stop();
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
}
|