2 * Copyright (c) 2021 Matthias Schmidt <xhr@giessen.ccc.de>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include <sys/types.h>
29 #include <readline/readline.h>
30 #include <readline/history.h>
32 #include "isscrolls.h"
34 static char prompt[MAX_PROMPT_LEN];
35 char isscrolls_dir[_POSIX_PATH_MAX];
41 signal_handler(int signal)
49 log_errx(1, "Unknown signal");
54 show_banner(__attribute__((unused)) char *unused)
56 pm(GREEN, "\n██▓ ██████ ██████ ▄████▄ ██▀███ ▒█████ ██▓ ██▓ ██████\n");
57 pm(GREEN, "▓██▒▒██ ▒ ▒██ ▒ ▒██▀ ▀█ ▓██ ▒ ██▒▒██▒ ██▒▓██▒ ▓██▒ ▒██ ▒\n");
58 pm(GREEN, "▒██▒░ ▓██▄ ░ ▓██▄ ▒▓█ ▄ ▓██ ░▄█ ▒▒██░ ██▒▒██░ ▒██░ ░ ▓██▄\n");
59 pm(GREEN, "░██░ ▒ ██▒ ▒ ██▒▒▓▓▄ ▄██▒▒██▀▀█▄ ▒██ ██░▒██░ ▒██░ ▒ ██▒\n");
60 pm(GREEN, "░██░▒██████▒▒▒██████▒▒▒ ▓███▀ ░░██▓ ▒██▒░ ████▓▒░░██████▒░██████▒▒██████▒▒\n");
61 pm(GREEN, "░▓ ▒ ▒▓▒ ▒ ░▒ ▒▓▒ ▒ ░░ ░▒ ▒ ░░ ▒▓ ░▒▓░░ ▒░▒░▒░ ░ ▒░▓ ░░ ▒░▓ ░▒ ▒▓▒ ▒ ░\n");
62 pm(GREEN, " ▒ ░░ ░▒ ░ ░░ ░▒ ░ ░ ░ ▒ ░▒ ░ ▒░ ░ ▒ ▒░ ░ ░ ▒ ░░ ░ ▒ ░░ ░▒ ░ ░\n");
63 pm(GREEN, " ▒ ░░ ░ ░ ░ ░ ░ ░ ░░ ░ ░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░\n");
64 pm(GREEN, " ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░\n");
66 printf(" Version %s\n\n", VERSION);
67 printf("\tSimple player toolkit for the Ironsworn tabletop RPG\n");
68 printf("\tBy Matthias Schmidt - https://mastodon.social/@_xhr_\n\n");
69 printf("Enter 'help' for available commands\n\n");
73 main(int argc, char **argv)
79 * Seed the PRNG with the current time of the day. This is not fine
80 * for a security critical application, for rolling dice it is
84 while ((ch = getopt(argc, argv, "cd")) != -1) {
100 initialize_readline(isscrolls_dir);
104 if (signal(SIGINT, signal_handler) == SIG_ERR)
105 log_errx(1, "signal");
106 if (signal(SIGTERM, signal_handler) == SIG_ERR)
107 log_errx(1, "signal");
109 sandbox(isscrolls_dir);
111 load_characters_list();
115 line = readline(prompt);
118 res = stripwhite(line);
122 execute_command(res);
134 set_prompt(const char *p)
136 if (p == NULL || strlen(p) == 0)
139 snprintf(prompt, sizeof(prompt), "%s", p);
143 sandbox(const char *dir)
146 if (unveil(_PATH_SHARE_DIR, "r") == -1)
147 log_errx(1, "unveil");
148 if (unveil(dir, "rwc") == -1)
149 log_errx(1, "unveil");
150 if (unveil(NULL, NULL) == -1)
151 log_errx(1, "unveil");
153 if (pledge("stdio rpath wpath cpath tty", NULL) == -1)
154 log_errx(1, "pledge");
155 #endif /* __OpenBSD__ */
159 cmd_quit(__attribute__((unused)) char *unused)
167 char hist_path[_POSIX_PATH_MAX];
169 save_current_character();
171 snprintf(hist_path, _POSIX_PATH_MAX, "%s/history", isscrolls_dir);
173 log_debug("Writing history to %s\n", hist_path);
174 write_history(hist_path);
183 char *home, *xdg_home;
185 if ((xdg_home = getenv("XDG_CONFIG_HOME")) != NULL) {
186 snprintf(isscrolls_dir, _POSIX_PATH_MAX, "%s/isscrolls", xdg_home);
187 } else if ((home = getenv("HOME")) != NULL) {
188 snprintf(isscrolls_dir, _POSIX_PATH_MAX, "%s/.isscrolls", home);
190 log_errx(1, "Neither $XDG_CONFIG_HOME nor $HOME is set!");
193 if (stat(isscrolls_dir, &sb) == 0 && S_ISDIR(sb.st_mode)) {
194 log_debug("%s already exists\n", isscrolls_dir);
196 log_debug("%s does not exists. Attempt to create it\n", isscrolls_dir);
197 if (mkdir(isscrolls_dir, 0755) == -1) {
198 log_errx(1, "Cannot create %s directory\n", isscrolls_dir);
204 log_debug(const char *fmt, ...)
212 fprintf(stdout, "[*] ");
213 vfprintf(stdout, fmt, ap);
218 log_errx(int prio, const char *fmt, ...)
223 vfprintf(stderr, fmt, ap);
230 pm(int what, const char *fmt, ...)
238 fprintf(stdout, ANSI_COLOR_RED);
241 fprintf(stdout, ANSI_COLOR_YELLOW);
244 fprintf(stdout, ANSI_COLOR_GREEN);
251 vfprintf(stdout, fmt, ap);
253 fprintf(stdout, ANSI_COLOR_RESET);
260 return isscrolls_dir;