Browse Source

degesch: implement /save

Fuck yes. :)
tags/v0.9
Přemysl Janouch 5 years ago
parent
commit
72e5aeba58
1 changed files with 82 additions and 87 deletions
  1. +82
    -87
      degesch.c

+ 82
- 87
degesch.c View File

@@ -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…
Cancel
Save