hikari/main.c

218 lines
3.8 KiB
C
Raw Normal View History

#include <assert.h>
2020-02-05 04:02:33 -06:00
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#ifndef NDEBUG
2020-02-05 04:02:33 -06:00
#include <wlr/util/log.h>
#endif
2020-02-05 04:02:33 -06:00
#include <hikari/server.h>
#include "version.h"
static char *
get_default_path(char *path)
{
2024-02-24 01:00:11 -06:00
char *prefix = getenv("XDG_CONFIG_HOME");
char *subdirectory;
2024-02-24 01:00:11 -06:00
if (prefix == NULL) {
prefix = getenv("HOME");
subdirectory = "/.config/hikari/";
} else {
subdirectory = "/hikari/";
}
2024-02-24 01:00:11 -06:00
size_t len = strlen(prefix) + strlen(subdirectory) + strlen(path);
2020-05-14 08:09:57 -05:00
2024-02-24 01:00:11 -06:00
char *ret = malloc(len + 1);
2024-02-24 01:00:11 -06:00
strcpy(ret, prefix);
strcat(ret, subdirectory);
strcat(ret, path);
2024-02-24 01:00:11 -06:00
return ret;
}
static char *
get_user_autostart(void)
{
2024-02-24 01:00:11 -06:00
return get_default_path("autostart");
}
static char *
get_user_config_path(void)
{
2024-02-24 01:00:11 -06:00
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)
{
2024-02-24 01:00:11 -06:00
return strdup(DEFAULT_CONFIG_FILE);
}
#undef STR
#undef DEFAULT_CONFIG
#undef DEFAULT_CONFIG_FILE
static bool
check_perms(char *path, int mode)
{
2024-02-24 01:00:11 -06:00
struct stat s;
return stat(path, &s) == 0 && S_ISREG(s.st_mode) && !access(path, mode);
}
static char *
check_path(char *path, int mode)
{
2024-02-24 01:00:11 -06:00
char *check = path;
2024-02-24 01:00:11 -06:00
if (!check_perms(check, mode)) {
free(path);
check = NULL;
}
2024-02-24 01:00:11 -06:00
return check;
}
static char *
get_config_path(char *path)
{
2024-02-24 01:00:11 -06:00
char *config;
2024-02-24 01:00:11 -06:00
if (path != NULL) {
char *option_config = check_path(path, R_OK);
2024-02-24 01:00:11 -06:00
config = option_config;
} else {
char *user_config = check_path(get_user_config_path(), R_OK);
2024-02-24 01:00:11 -06:00
if (user_config == NULL) {
char *default_config = check_path(get_default_config_path(), R_OK);
2024-02-24 01:00:11 -06:00
config = default_config;
} else {
config = user_config;
}
}
2024-02-24 01:00:11 -06:00
return config;
}
static char *
get_autostart(char *path)
{
2024-02-24 01:00:11 -06:00
char *autostart;
int mode = R_OK | X_OK;
2024-02-24 01:00:11 -06:00
if (path != NULL) {
char *option_autostart = check_path(path, mode);
2024-02-24 01:00:11 -06:00
autostart = option_autostart;
} else {
char *user_autostart = check_path(get_user_autostart(), mode);
2024-02-24 01:00:11 -06:00
autostart = user_autostart;
}
2024-02-24 01:00:11 -06:00
return autostart;
}
const char *usage = "Usage: hikari [options]\n"
2024-02-24 01:00:11 -06:00
"\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 {
2024-02-24 01:00:11 -06:00
char *config_path;
char *autostart;
};
static void
parse_options(int argc, char **argv, struct options *options)
2020-02-05 04:02:33 -06:00
{
2024-02-24 01:00:11 -06:00
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
2024-02-24 01:00:11 -06:00
wlr_log_init(WLR_DEBUG, NULL);
#endif
2024-02-24 01:00:11 -06:00
struct options options;
parse_options(argc, argv, &options);
2024-02-24 01:00:11 -06:00
if (options.config_path == NULL) {
free(options.autostart);
2024-02-24 01:00:11 -06:00
fprintf(stderr, "could not load configuration\n");
2024-02-24 01:00:11 -06:00
return EXIT_FAILURE;
} else {
hikari_server_prepare_privileged();
2024-02-24 01:00:11 -06:00
assert(geteuid() != 0 && geteuid() == getuid());
assert(getegid() != 0 && getegid() == getgid());
2024-02-24 01:00:11 -06:00
hikari_server_start(options.config_path, options.autostart);
hikari_server_stop();
2020-02-05 04:02:33 -06:00
2024-02-24 01:00:11 -06:00
return EXIT_SUCCESS;
}
2020-02-05 04:02:33 -06:00
}