degesch: implement /save
Fuck yes. :)
This commit is contained in:
parent
bdad4dce42
commit
72e5aeba58
169
degesch.c
169
degesch.c
@ -785,6 +785,59 @@ get_config_boolean (struct app_context *ctx, const char *key)
|
||||
return item->value.boolean;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
static char *
|
||||
write_configuration_file (const struct str *data, struct error **e)
|
||||
{
|
||||
struct str path;
|
||||
str_init (&path);
|
||||
get_xdg_home_dir (&path, "XDG_CONFIG_HOME", ".config");
|
||||
str_append (&path, "/" PROGRAM_NAME);
|
||||
|
||||
if (!mkdir_with_parents (path.str, e))
|
||||
goto error;
|
||||
|
||||
str_append (&path, "/" PROGRAM_NAME ".conf");
|
||||
FILE *fp = fopen (path.str, "w");
|
||||
if (!fp)
|
||||
{
|
||||
error_set (e, "could not open `%s' for writing: %s",
|
||||
path.str, strerror (errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
fwrite (data->str, data->len, 1, fp);
|
||||
fclose (fp);
|
||||
|
||||
if (errno)
|
||||
{
|
||||
error_set (e, "writing to `%s' failed: %s", path.str, strerror (errno));
|
||||
goto error;
|
||||
}
|
||||
return str_steal (&path);
|
||||
|
||||
error:
|
||||
str_free (&path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
serialize_configuration (struct app_context *ctx, struct str *output)
|
||||
{
|
||||
str_append (output,
|
||||
"# " PROGRAM_NAME " " PROGRAM_VERSION " configuration file\n"
|
||||
"#\n"
|
||||
"# Relative paths are searched for in ${XDG_CONFIG_HOME:-~/.config}\n"
|
||||
"# /" PROGRAM_NAME " as well as in $XDG_CONFIG_DIRS/" PROGRAM_NAME "\n"
|
||||
"#\n"
|
||||
"# Everything is in UTF-8. Any custom comments will be overwritten.\n"
|
||||
"\n");
|
||||
|
||||
config_item_write (ctx->config.root, true, output);
|
||||
}
|
||||
|
||||
// --- Attributed output -------------------------------------------------------
|
||||
|
||||
static struct
|
||||
@ -3981,6 +4034,33 @@ handle_command_set (struct app_context *ctx, char *arguments)
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool
|
||||
handle_command_save (struct app_context *ctx, char *arguments)
|
||||
{
|
||||
if (*arguments)
|
||||
return false;
|
||||
|
||||
struct str data;
|
||||
str_init (&data);
|
||||
serialize_configuration (ctx, &data);
|
||||
|
||||
struct error *e = NULL;
|
||||
char *filename = write_configuration_file (&data, &e);
|
||||
str_free (&data);
|
||||
|
||||
if (!filename)
|
||||
{
|
||||
buffer_send_error (ctx, ctx->global_buffer,
|
||||
"%s: %s", "Saving configuration failed", e->message);
|
||||
error_free (e);
|
||||
}
|
||||
else
|
||||
buffer_send_status (ctx, ctx->global_buffer,
|
||||
"Configuration written to `%s'", filename);
|
||||
free (filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
handle_command_msg (struct app_context *ctx, char *arguments)
|
||||
{
|
||||
@ -4211,6 +4291,8 @@ g_command_handlers[] =
|
||||
"list | clear | move | { close [<number> | <name>] } | <number>" },
|
||||
{ "set", handle_command_set, "Manage configuration",
|
||||
"[<option>]" },
|
||||
{ "save", handle_command_save, "Save configuration",
|
||||
"" },
|
||||
|
||||
{ "msg", handle_command_msg, "Send message to a nick or channel",
|
||||
"<target> <message>" },
|
||||
@ -4940,88 +5022,6 @@ load_configuration (struct app_context *ctx)
|
||||
get_config_integer (ctx, "server.reconnect_delay");
|
||||
}
|
||||
|
||||
static char *
|
||||
write_configuration_file (const struct str *data, struct error **e)
|
||||
{
|
||||
struct str path;
|
||||
str_init (&path);
|
||||
get_xdg_home_dir (&path, "XDG_CONFIG_HOME", ".config");
|
||||
str_append (&path, "/" PROGRAM_NAME);
|
||||
|
||||
if (!mkdir_with_parents (path.str, e))
|
||||
goto error;
|
||||
|
||||
str_append (&path, "/" PROGRAM_NAME ".conf");
|
||||
FILE *fp = fopen (path.str, "w");
|
||||
if (!fp)
|
||||
{
|
||||
error_set (e, "could not open `%s' for writing: %s",
|
||||
path.str, strerror (errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
fwrite (data->str, data->len, 1, fp);
|
||||
fclose (fp);
|
||||
|
||||
if (errno)
|
||||
{
|
||||
error_set (e, "writing to `%s' failed: %s", path.str, strerror (errno));
|
||||
goto error;
|
||||
}
|
||||
return str_steal (&path);
|
||||
|
||||
error:
|
||||
str_free (&path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
serialize_configuration (struct app_context *ctx, struct str *output)
|
||||
{
|
||||
str_append (output,
|
||||
"# " PROGRAM_NAME " " PROGRAM_VERSION " configuration file\n"
|
||||
"#\n"
|
||||
"# Relative paths are searched for in ${XDG_CONFIG_HOME:-~/.config}\n"
|
||||
"# /" PROGRAM_NAME " as well as in $XDG_CONFIG_DIRS/" PROGRAM_NAME "\n"
|
||||
"#\n"
|
||||
"# Everything is in UTF-8. Any custom comments will be overwritten.\n"
|
||||
"\n");
|
||||
|
||||
config_item_write (ctx->config.root, true, output);
|
||||
}
|
||||
|
||||
static void
|
||||
write_default_configuration ()
|
||||
{
|
||||
// XXX: this is a hack before we remove this awkward functionality
|
||||
// altogether; the user will want to do this from the user interface
|
||||
|
||||
struct app_context ctx = {};
|
||||
config_init (&ctx.config);
|
||||
register_config_modules (&ctx);
|
||||
config_load (&ctx.config, config_item_object ());
|
||||
|
||||
struct str data;
|
||||
str_init (&data);
|
||||
serialize_configuration (&ctx, &data);
|
||||
|
||||
struct error *e = NULL;
|
||||
char *filename = write_configuration_file (&data, &e);
|
||||
str_free (&data);
|
||||
config_free (&ctx.config);
|
||||
|
||||
if (!filename)
|
||||
{
|
||||
print_error ("%s", e->message);
|
||||
error_free (e);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
print_status ("configuration written to `%s'", filename);
|
||||
free (filename);
|
||||
}
|
||||
|
||||
|
||||
// --- Main program ------------------------------------------------------------
|
||||
|
||||
static void
|
||||
@ -5050,8 +5050,6 @@ main (int argc, char *argv[])
|
||||
{ 'd', "debug", NULL, 0, "run in debug mode" },
|
||||
{ 'h', "help", NULL, 0, "display this help and exit" },
|
||||
{ 'V', "version", NULL, 0, "output version information and exit" },
|
||||
{ 'w', "write-default-cfg", NULL, OPT_LONG_ONLY,
|
||||
"write a default configuration file and exit" },
|
||||
{ 0, NULL, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
@ -5071,9 +5069,6 @@ main (int argc, char *argv[])
|
||||
case 'V':
|
||||
printf (PROGRAM_NAME " " PROGRAM_VERSION "\n");
|
||||
exit (EXIT_SUCCESS);
|
||||
case 'w':
|
||||
write_default_configuration ();
|
||||
exit (EXIT_SUCCESS);
|
||||
default:
|
||||
print_error ("wrong options");
|
||||
opt_handler_usage (&oh, stderr);
|
||||
|
Loading…
Reference in New Issue
Block a user