kike: resolve the path to PID files better
This commit is contained in:
parent
51bf132c6b
commit
b486965277
43
common.c
43
common.c
|
@ -90,6 +90,49 @@ strncasecmp_ascii (const char *a, const char *b, size_t n)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
resolve_relative_runtime_filename (const char *filename)
|
||||
{
|
||||
struct str path;
|
||||
str_init (&path);
|
||||
|
||||
const char *runtime_dir = getenv ("XDG_RUNTIME_DIR");
|
||||
if (runtime_dir && *runtime_dir == '/')
|
||||
str_append (&path, runtime_dir);
|
||||
else
|
||||
get_xdg_home_dir (&path, "XDG_DATA_HOME", ".local/share");
|
||||
str_append_printf (&path, "/%s/%s", PROGRAM_NAME, filename);
|
||||
|
||||
// Try to create the file's ancestors
|
||||
const char *last_slash = strrchr (path.str, '/');
|
||||
if (last_slash && last_slash != path.str)
|
||||
{
|
||||
char *copy = xstrndup (path.str, last_slash - path.str);
|
||||
(void) mkdir_with_parents (copy, NULL);
|
||||
free (copy);
|
||||
}
|
||||
return str_steal (&path);
|
||||
}
|
||||
|
||||
static char *
|
||||
resolve_filename (const char *filename, char *(*relative_cb) (const char *))
|
||||
{
|
||||
// Absolute path is absolute
|
||||
if (*filename == '/')
|
||||
return xstrdup (filename);
|
||||
|
||||
// We don't want to use wordexp() for this as it may execute /bin/sh
|
||||
if (*filename == '~')
|
||||
{
|
||||
// Paths to home directories ought to be absolute
|
||||
char *expanded = try_expand_tilde (filename + 1);
|
||||
if (expanded)
|
||||
return expanded;
|
||||
print_debug ("failed to expand the home directory in `%s'", filename);
|
||||
}
|
||||
return relative_cb (filename);
|
||||
}
|
||||
|
||||
// --- Logging -----------------------------------------------------------------
|
||||
|
||||
static void
|
||||
|
|
35
kike.c
35
kike.c
|
@ -31,15 +31,7 @@
|
|||
|
||||
static struct config_item g_config_table[] =
|
||||
{
|
||||
// TODO: use XDG_RUNTIME_DIR if relative. The last fallback is:
|
||||
//
|
||||
// "$XDG_DATA_HOME defines the base directory relative to which user
|
||||
// specific data files should be stored. If $XDG_DATA_HOME is either not
|
||||
// set or empty, a default equal to $HOME/.local/share should be used."
|
||||
//
|
||||
// Note that when using XDG_RUNTIME_DIR, it either needs to have access
|
||||
// time bumped every 6 hours, or have the sticky bit set.
|
||||
{ "pid_file", NULL, "Full path for the PID file" },
|
||||
{ "pid_file", NULL, "Path or name of the PID file" },
|
||||
{ "server_name", NULL, "Server name" },
|
||||
{ "server_info", "My server", "Brief server description" },
|
||||
{ "motd", NULL, "MOTD filename" },
|
||||
|
@ -3671,14 +3663,12 @@ irc_initialize_server_name (struct server_context *ctx, struct error **e)
|
|||
}
|
||||
|
||||
static bool
|
||||
irc_lock_pid_file (struct server_context *ctx, struct error **e)
|
||||
lock_pid_file (const char *path, struct error **e)
|
||||
{
|
||||
const char *path = str_map_find (&ctx->config, "pid_file");
|
||||
if (!path)
|
||||
return true;
|
||||
|
||||
// When using XDG_RUNTIME_DIR, the file needs to either have its
|
||||
// access time bumped every 6 hours, or have the sticky bit set
|
||||
int fd = open (path, O_RDWR | O_CREAT,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH /* 644 */);
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH /* 644 */ | S_ISVTX /* sticky */);
|
||||
if (fd < 0)
|
||||
{
|
||||
error_set (e, "can't open `%s': %s", path, strerror (errno));
|
||||
|
@ -3695,6 +3685,7 @@ irc_lock_pid_file (struct server_context *ctx, struct error **e)
|
|||
if (fcntl (fd, F_SETLK, &lock))
|
||||
{
|
||||
error_set (e, "can't lock `%s': %s", path, strerror (errno));
|
||||
xclose (fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3706,6 +3697,7 @@ irc_lock_pid_file (struct server_context *ctx, struct error **e)
|
|||
|| write (fd, pid.str, pid.len) != (ssize_t) pid.len)
|
||||
{
|
||||
error_set (e, "can't write to `%s': %s", path, strerror (errno));
|
||||
xclose (fd);
|
||||
return false;
|
||||
}
|
||||
str_free (&pid);
|
||||
|
@ -3715,6 +3707,19 @@ irc_lock_pid_file (struct server_context *ctx, struct error **e)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
irc_lock_pid_file (struct server_context *ctx, struct error **e)
|
||||
{
|
||||
const char *path = str_map_find (&ctx->config, "pid_file");
|
||||
if (!path)
|
||||
return true;
|
||||
|
||||
char *resolved = resolve_filename (path, resolve_relative_runtime_filename);
|
||||
bool result = lock_pid_file (resolved, e);
|
||||
free (resolved);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
irc_listen (struct addrinfo *gai_iter)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue