summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2008-08-19 23:22:52 +0200
committerSebastien Helleu <flashcode@flashtux.org>2008-08-19 23:22:52 +0200
commitb76d7e4a5cac659b08ae992b74af5f26b67dc205 (patch)
tree0edd58880852c7f70cc4ff4f8faf79473c09c164 /src/core
parentff1983533b9288f4d310e7eac6fb976bd119a48d (diff)
downloadweechat-b76d7e4a5cac659b08ae992b74af5f26b67dc205.zip
Reintroduce /upgrade command, working only with core and IRC plugin today
Command will be improved in near future and other plugins like xfer will be modified to manage upgrade process.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/Makefile.am4
-rw-r--r--src/core/wee-command.c75
-rw-r--r--src/core/wee-config-file.c201
-rw-r--r--src/core/wee-config-file.h3
-rw-r--r--src/core/wee-debug.c3
-rw-r--r--src/core/wee-infolist.c708
-rw-r--r--src/core/wee-infolist.h105
-rw-r--r--src/core/wee-upgrade-file.c715
-rw-r--r--src/core/wee-upgrade-file.h59
-rw-r--r--src/core/wee-upgrade.c1975
-rw-r--r--src/core/wee-upgrade.h185
-rw-r--r--src/core/weechat.c26
13 files changed, 2112 insertions, 1949 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index a1a87b495..68edf3ec6 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -22,12 +22,14 @@ wee-config.c wee-config.h
wee-config-file.c wee-config-file.h
wee-debug.c wee-debug.h
wee-hook.c wee-hook.h
+wee-infolist.c wee-infolist.h
wee-input.c wee-input.h
wee-list.c wee-list.h
wee-log.c wee-log.h
wee-network.c wee-network.h
wee-string.c wee-string.h
wee-upgrade.c wee-upgrade.h
+wee-upgrade-file.c wee-upgrade-file.h
wee-utf8.c wee-utf8.h
wee-util.c wee-util.h)
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 32d24c438..c2c57442f 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -32,6 +32,8 @@ lib_weechat_core_a_SOURCES = weechat.c \
wee-debug.h \
wee-hook.c \
wee-hook.h \
+ wee-infolist.c \
+ wee-infolist.h \
wee-input.c \
wee-input.h \
wee-list.c \
@@ -42,6 +44,8 @@ lib_weechat_core_a_SOURCES = weechat.c \
wee-network.h \
wee-upgrade.c \
wee-upgrade.h \
+ wee-upgrade-file.c \
+ wee-upgrade-file.h \
wee-string.c \
wee-string.h \
wee-utf8.c \
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index 32e4bf72c..9cc11c373 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -51,6 +51,7 @@
#include "../gui/gui-hotlist.h"
#include "../gui/gui-input.h"
#include "../gui/gui-keyboard.h"
+#include "../gui/gui-main.h"
#include "../gui/gui-status.h"
#include "../gui/gui-window.h"
#include "../plugins/plugin.h"
@@ -2283,9 +2284,8 @@ int
command_upgrade (void *data, struct t_gui_buffer *buffer,
int argc, char **argv, char **argv_eol)
{
- /*int filename_length;
- char *filename, *ptr_binary;
- char *exec_args[7] = { NULL, "-a", "--dir", NULL, "--session", NULL, NULL };*/
+ char *ptr_binary;
+ char *exec_args[7] = { NULL, "-a", "--dir", NULL, "--upgrade", NULL };
/* make C compiler happy */
(void) data;
@@ -2293,85 +2293,46 @@ command_upgrade (void *data, struct t_gui_buffer *buffer,
(void) argc;
(void) argv;
(void) argv_eol;
-
- /* TODO: enable again /upgrade command */
- gui_chat_printf (NULL, "/upgrade command is temporarirly disabled.");
- return WEECHAT_RC_OK;
- /*ptr_binary = (argc > 1) ? argv_eol[1] : weechat_argv0;
-
- for (ptr_server = irc_servers; ptr_server;
- ptr_server = ptr_server->next_server)
- {
- if (ptr_server->child_pid != 0)
- {
- gui_chat_printf_error (NULL,
- _("Error: can't upgrade: connection to at least "
- "one server is pending"));
- return WEECHAT_RC_ERROR;
- }*/
- /* TODO: remove this test, and fix gnutls save/load in session */
- /*if (ptr_server->is_connected && ptr_server->ssl_connected)
- {
- gui_chat_printf_error_nolog (NULL,
- _("Error: can't upgrade: connection to at least "
- "one SSL server is active "
- "(should be fixed in a future version)"));
- return WEECHAT_RC_ERROR;
- }
- if (ptr_server->outqueue)
- {
- gui_chat_printf_error_nolog (NULL,
- _("Error: can't upgrade: anti-flood is active on "
- "at least one server (sending many lines)"));
- return WEECHAT_RC_ERROR;
- }
- }
+ ptr_binary = (argc > 1) ? argv_eol[1] : weechat_argv0;
- filename_length = strlen (weechat_home) + strlen (WEECHAT_SESSION_NAME) + 2;
- filename = malloc (filename_length);
- if (!filename)
- return -2;
- snprintf (filename, filename_length, "%s%s" WEECHAT_SESSION_NAME,
- weechat_home, DIR_SEPARATOR);
+ gui_chat_printf (NULL,
+ _("Upgrading WeeChat..."));
- gui_chat_printf_info_nolog (NULL,
- _("Upgrading WeeChat..."));
+ /* send "upgrade" signal to plugins */
+ hook_signal_send ("upgrade", WEECHAT_HOOK_SIGNAL_STRING, NULL);
- if (!session_save (filename))
+ if (!upgrade_weechat_save ())
{
- free (filename);
- gui_chat_printf_error_nolog (NULL,
- _("Error: unable to save session in file"));
+ gui_chat_printf (NULL,
+ _("%sError: unable to save session in file"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]);
return WEECHAT_RC_ERROR;
}
exec_args[0] = strdup (ptr_binary);
exec_args[3] = strdup (weechat_home);
- exec_args[5] = strdup (filename);*/
/* unload plugins, save config, then upgrade */
plugin_end ();
- /*if (CONFIG_BOOLEAN(config_look_save_on_exit))
- (void) config_write (NULL);
+ if (CONFIG_BOOLEAN(config_look_save_on_exit))
+ (void) config_weechat_write ();
gui_main_end (1);
- fifo_remove ();
- weechat_log_close ();
+ log_close ();
- execvp (exec_args[0], exec_args);*/
+ execvp (exec_args[0], exec_args);
/* this code should not be reached if execvp is ok */
plugin_init (1, 0, NULL);
- /*string_iconv_fprintf (stderr,
+ string_iconv_fprintf (stderr,
_("Error: exec failed (program: \"%s\"), exiting WeeChat"),
exec_args[0]);
free (exec_args[0]);
free (exec_args[3]);
- free (filename);
- exit (EXIT_FAILURE);*/
+ exit (EXIT_FAILURE);
/* never executed */
return WEECHAT_RC_ERROR;
diff --git a/src/core/wee-config-file.c b/src/core/wee-config-file.c
index ae8680e8c..ac703e13a 100644
--- a/src/core/wee-config-file.c
+++ b/src/core/wee-config-file.c
@@ -33,6 +33,7 @@
#include "weechat.h"
#include "wee-config-file.h"
#include "wee-hook.h"
+#include "wee-infolist.h"
#include "wee-log.h"
#include "wee-string.h"
#include "../gui/gui-color.h"
@@ -2105,6 +2106,206 @@ config_file_free_all_plugin (struct t_weechat_plugin *plugin)
}
/*
+ * config_file_add_to_infolist: add config options in an infolist
+ * return 1 if ok, 0 if error
+ */
+
+int
+config_file_add_to_infolist (struct t_infolist *infolist,
+ const char *option_name)
+{
+ struct t_config_file *ptr_config;
+ struct t_config_section *ptr_section;
+ struct t_config_option *ptr_option;
+ struct t_infolist_item *ptr_item;
+ int length;
+ char *option_full_name, value[128];
+
+ if (!infolist)
+ return 0;
+
+ for (ptr_config = config_files; ptr_config;
+ ptr_config = ptr_config->next_config)
+ {
+ for (ptr_section = ptr_config->sections; ptr_section;
+ ptr_section = ptr_section->next_section)
+ {
+ for (ptr_option = ptr_section->options; ptr_option;
+ ptr_option = ptr_option->next_option)
+ {
+ length = strlen (ptr_config->name) + 1 +
+ strlen (ptr_section->name) + 1 +
+ strlen (ptr_option->name) + 1;
+ option_full_name = malloc (length);
+ if (option_full_name)
+ {
+ snprintf (option_full_name, length, "%s.%s.%s",
+ ptr_config->name,
+ ptr_section->name,
+ ptr_option->name);
+ if (!option_name || !option_name[0]
+ || string_match (option_full_name, option_name, 0))
+ {
+ ptr_item = infolist_new_item (infolist);
+ if (!ptr_item)
+ {
+ free (option_full_name);
+ return 0;
+ }
+ if (!infolist_new_var_string (ptr_item,
+ "full_name",
+ option_full_name))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ if (!infolist_new_var_string (ptr_item,
+ "name",
+ ptr_option->name))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ switch (ptr_option->type)
+ {
+ case CONFIG_OPTION_TYPE_BOOLEAN:
+ if (!infolist_new_var_string (ptr_item,
+ "type",
+ "boolean"))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ if (CONFIG_BOOLEAN(ptr_option) == CONFIG_BOOLEAN_TRUE)
+ snprintf (value, sizeof (value), "on");
+ else
+ snprintf (value, sizeof (value), "off");
+ if (!infolist_new_var_string (ptr_item,
+ "value",
+ value))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ if (CONFIG_BOOLEAN_DEFAULT(ptr_option) == CONFIG_BOOLEAN_TRUE)
+ snprintf (value, sizeof (value), "on");
+ else
+ snprintf (value, sizeof (value), "off");
+ if (!infolist_new_var_string (ptr_item,
+ "default_value",
+ value))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ break;
+ case CONFIG_OPTION_TYPE_INTEGER:
+ if (!infolist_new_var_string (ptr_item,
+ "type",
+ "integer"))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ if (ptr_option->string_values)
+ {
+ if (!infolist_new_var_string (ptr_item,
+ "value",
+ ptr_option->string_values[CONFIG_INTEGER(ptr_option)]))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ if (!infolist_new_var_string (ptr_item,
+ "default_value",
+ ptr_option->string_values[CONFIG_INTEGER_DEFAULT(ptr_option)]))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ }
+ else
+ {
+ snprintf (value, sizeof (value), "%d",
+ CONFIG_INTEGER(ptr_option));
+ if (!infolist_new_var_string (ptr_item,
+ "value",
+ value))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ snprintf (value, sizeof (value), "%d",
+ CONFIG_INTEGER_DEFAULT(ptr_option));
+ if (!infolist_new_var_string (ptr_item,
+ "default_value",
+ value))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ }
+ break;
+ case CONFIG_OPTION_TYPE_STRING:
+ if (!infolist_new_var_string (ptr_item,
+ "type",
+ "string"))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ if (!infolist_new_var_string (ptr_item,
+ "value",
+ CONFIG_STRING(ptr_option)))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ if (!infolist_new_var_string (ptr_item,
+ "default_value",
+ CONFIG_STRING_DEFAULT(ptr_option)))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ break;
+ case CONFIG_OPTION_TYPE_COLOR:
+ if (!infolist_new_var_string (ptr_item,
+ "type",
+ "color"))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ if (!infolist_new_var_string (ptr_item,
+ "value",
+ gui_color_get_name (CONFIG_COLOR(ptr_option))))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ if (!infolist_new_var_string (ptr_item,
+ "default_value",
+ gui_color_get_name (CONFIG_COLOR_DEFAULT(ptr_option))))
+ {
+ free (option_full_name);
+ return 0;
+ }
+ break;
+ case CONFIG_NUM_OPTION_TYPES:
+ break;
+ }
+ }
+ free (option_full_name);
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+/*
* config_file_print_stdout: print options on standard output
*/
diff --git a/src/core/wee-config-file.h b/src/core/wee-config-file.h
index 1b2315287..25ab005ba 100644
--- a/src/core/wee-config-file.h
+++ b/src/core/wee-config-file.h
@@ -36,6 +36,7 @@
#define CONFIG_BOOLEAN_TRUE 1
struct t_weelist;
+struct t_infolist;
struct t_config_file
{
@@ -228,6 +229,8 @@ extern void config_file_section_free (struct t_config_file *config_file,
extern void config_file_free (struct t_config_file *config_file);
extern void config_file_free_all ();
extern void config_file_free_all_plugin (struct t_weechat_plugin *plugin);
+extern int config_file_add_to_infolist (struct t_infolist *infolist,
+ const char *option_name);
extern void config_file_print_stdout (struct t_config_file *config_file);
extern void config_file_print_log ();
diff --git a/src/core/wee-debug.c b/src/core/wee-debug.c
index 53477f215..7bf5ef791 100644
--- a/src/core/wee-debug.c
+++ b/src/core/wee-debug.c
@@ -28,6 +28,7 @@
#include "weechat.h"
#include "wee-backtrace.h"
#include "wee-config-file.h"
+#include "wee-infolist.h"
#include "wee-log.h"
#include "wee-hook.h"
#include "wee-string.h"
@@ -83,6 +84,8 @@ debug_dump (int crash)
gui_bar_item_print_log ();
gui_hotlist_print_log ();
+ infolist_print_log ();
+
hook_print_log ();
config_file_print_log ();
diff --git a/src/core/wee-infolist.c b/src/core/wee-infolist.c
new file mode 100644
index 000000000..64d4cb8a7
--- /dev/null
+++ b/src/core/wee-infolist.c
@@ -0,0 +1,708 @@
+/*
+ * Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
+ * See README for License detail, AUTHORS for developers list.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* wee-infolist.c: manages info lists */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "weechat.h"
+#include "wee-log.h"
+#include "wee-string.h"
+#include "wee-infolist.h"
+
+
+struct t_infolist *weechat_infolists = NULL;
+struct t_infolist *last_weechat_infolist = NULL;
+
+
+/*
+ * infolist_new: create a new weechat infolist
+ */
+
+struct t_infolist *
+infolist_new ()
+{
+ struct t_infolist *new_infolist;
+
+ new_infolist = malloc (sizeof (*new_infolist));
+ if (new_infolist)
+ {
+ new_infolist->items = NULL;
+ new_infolist->last_item = NULL;
+ new_infolist->ptr_item = NULL;
+
+ new_infolist->prev_infolist = last_weechat_infolist;
+ new_infolist->next_infolist = NULL;
+ if (weechat_infolists)
+ last_weechat_infolist->next_infolist = new_infolist;
+ else
+ weechat_infolists = new_infolist;
+ last_weechat_infolist = new_infolist;
+ }
+
+ return new_infolist;
+}
+
+/*
+ * infolist_new_item: create a new item in an infolist
+ */
+
+struct t_infolist_item *
+infolist_new_item (struct t_infolist *infolist)
+{
+ struct t_infolist_item *new_item;
+
+ new_item = malloc (sizeof (*new_item));
+ if (new_item)
+ {
+ new_item->vars = NULL;
+ new_item->last_var = NULL;
+ new_item->fields = NULL;
+
+ new_item->prev_item = infolist->last_item;
+ new_item->next_item = NULL;
+ if (infolist->items)
+ infolist->last_item->next_item = new_item;
+ else
+ infolist->items = new_item;
+ infolist->last_item = new_item;
+ }
+
+ return new_item;
+}
+
+/*
+ * infolist_new_var_integer: create a new integer variable in an item
+ */
+
+struct t_infolist_var *
+infolist_new_var_integer (struct t_infolist_item *item,
+ const char *name, int value)
+{
+ struct t_infolist_var *new_var;
+
+ if (!item || !name || !name[0])
+ return NULL;
+
+ new_var = malloc (sizeof (*new_var));
+ if (new_var)
+ {
+ new_var->name = strdup (name);
+ new_var->type = INFOLIST_INTEGER;
+ new_var->value = malloc (sizeof (int));
+ if (new_var->value)
+ *((int *)new_var->value) = value;
+
+ new_var->prev_var = item->last_var;
+ new_var->next_var = NULL;
+ if (item->vars)
+ item->last_var->next_var = new_var;
+ else
+ item->vars = new_var;
+ item->last_var = new_var;
+ }
+
+ return new_var;
+}
+
+/*
+ * infolist_new_var_string: create a new string variable in an item
+ */
+
+struct t_infolist_var *
+infolist_new_var_string (struct t_infolist_item *item,
+ const char *name, const char *value)
+{
+ struct t_infolist_var *new_var;
+
+ if (!item || !name || !name[0])
+ return NULL;
+
+ new_var = malloc (sizeof (*new_var));
+ if (new_var)
+ {
+ new_var->name = strdup (name);
+ new_var->type = INFOLIST_STRING;
+ new_var->value = (value) ? strdup (value) : NULL;
+
+ new_var->prev_var = item->last_var;
+ new_var->next_var = NULL;
+ if (item->vars)
+ item->last_var->next_var = new_var;
+ else
+ item->vars = new_var;
+ item->last_var = new_var;
+ }
+
+ return new_var;
+}
+
+/*
+ * infolist_new_var_pointer: create a new pointer variable in an item
+ */
+
+struct t_infolist_var *
+infolist_new_var_pointer (struct t_infolist_item *item,
+ const char *name, void *pointer)
+{
+ struct t_infolist_var *new_var;
+
+ if (!item || !name || !name[0])
+ return NULL;
+
+ new_var = malloc (sizeof (*new_var));
+ if (new_var)
+ {
+ new_var->name = strdup (name);
+ new_var->type = INFOLIST_POINTER;
+ new_var->value = pointer;
+
+ new_var->prev_var = item->last_var;
+ new_var->next_var = NULL;
+ if (item->vars)
+ item->last_var->next_var = new_var;
+ else
+ item->vars = new_var;
+ item->last_var = new_var;
+ }
+
+ return new_var;
+}
+
+/*
+ * infolist_new_var_buffer: create a new buffer variable in an item
+ */
+
+struct t_infolist_var *
+infolist_new_var_buffer (struct t_infolist_item *item,
+ const char *name, void *pointer, int size)
+{
+ struct t_infolist_var *new_var;
+
+ if (!item || !name || !name[0] || (size <= 0))
+ return NULL;
+
+ new_var = malloc (sizeof (*new_var));
+ if (new_var)
+ {
+ new_var->name = strdup (name);
+ new_var->type = INFOLIST_BUFFER;
+ new_var->value = malloc (size);
+ if (new_var->value)
+ memcpy (new_var->value, pointer, size);
+ new_var->size = size;
+
+ new_var->prev_var = item->last_var;
+ new_var->next_var = NULL;
+ if (item->vars)
+ item->last_var->next_var = new_var;
+ else
+ item->vars = new_var;
+ item->last_var = new_var;
+ }
+
+ return new_var;
+}
+
+/*
+ * infolist_new_var_time: create a new time variable in an item
+ */
+
+struct t_infolist_var *
+infolist_new_var_time (struct t_infolist_item *item,
+ const char *name, time_t time)
+{
+ struct t_infolist_var *new_var;
+
+ if (!item || !name || !name[0])
+ return NULL;
+
+ new_var = malloc (sizeof (*new_var));
+ if (new_var)
+ {
+ new_var->name = strdup (name);
+ new_var->type = INFOLIST_TIME;
+ new_var->value = malloc (sizeof (time_t));
+ if (new_var->value)
+ *((time_t *)new_var->value) = time;
+
+ new_var->prev_var = item->last_var;
+ new_var->next_var = NULL;
+ if (item->vars)
+ item->last_var->next_var = new_var;
+ else
+ item->vars = new_var;
+ item->last_var = new_var;
+ }
+
+ return new_var;
+}
+
+/*
+ * infolist_valid: check if an infolist pointer exists
+ * return 1 if list exists
+ * 0 if list is not found
+ */
+
+int
+infolist_valid (struct t_infolist *infolist)
+{
+ struct t_infolist *ptr_infolist;
+
+ for (ptr_infolist = weechat_infolists; ptr_infolist;
+ ptr_infolist = ptr_infolist->next_infolist)
+ {
+ if (ptr_infolist == infolist)
+ return 1;
+ }
+
+ /* list not found */
+ return 0;
+}
+
+/*
+ * infolist_next: return next item for an infolist
+ * if current item pointer is NULL,
+ * then return first item of infolist
+ */
+
+struct t_infolist_item *
+infolist_next (struct t_infolist *infolist)
+{
+ if (!infolist->ptr_item)
+ {
+ infolist->ptr_item = infolist->items;
+ return infolist->ptr_item;
+ }
+ infolist->ptr_item = infolist->ptr_item->next_item;
+ return infolist->ptr_item;
+}
+
+/*
+ * infolist_prev: return previous item for an infolist
+ * if current item pointer is NULL,
+ * then return last item of infolist
+ */
+
+struct t_infolist_item *
+infolist_prev (struct t_infolist *infolist)
+{
+ if (!infolist->ptr_item)
+ {
+ infolist->ptr_item = infolist->last_item;
+ return infolist->ptr_item;
+ }
+ infolist->ptr_item = infolist->ptr_item->prev_item;
+ return infolist->ptr_item;
+}
+
+/*
+ * infolist_reset_item_cursor: reset pointer to current item in infolist
+ */
+
+void
+infolist_reset_item_cursor (struct t_infolist *infolist)
+{
+ infolist->ptr_item = NULL;
+}
+
+/*
+ * infolist_fields: get list of fields for current infolist item
+ */
+
+char *
+infolist_fields (struct t_infolist *infolist)
+{
+ struct t_infolist_var *ptr_var;
+ int length;
+
+ if (!infolist || !infolist->ptr_item)
+ return NULL;
+
+ /* list of fields already asked ? if yes, just return string */
+ if (infolist->ptr_item->fields)
+ return infolist->ptr_item->fields;
+
+ length = 0;
+ for (ptr_var = infolist->ptr_item->vars;
+ ptr_var; ptr_var = ptr_var->next_var)
+ {
+ length += strlen (ptr_var->name) + 3;
+ }
+
+ infolist->ptr_item->fields = malloc (length + 1);
+ if (!infolist->ptr_item->fields)
+ return NULL;
+
+ infolist->ptr_item->fields[0] = '\0';
+ for (ptr_var = infolist->ptr_item->vars; ptr_var;
+ ptr_var = ptr_var->next_var)
+ {
+ switch (ptr_var->type)
+ {
+ case INFOLIST_INTEGER:
+ strcat (infolist->ptr_item->fields, "i:");
+ break;
+ case INFOLIST_STRING:
+ strcat (infolist->ptr_item->fields, "s:");
+ break;
+ case INFOLIST_POINTER:
+ strcat (infolist->ptr_item->fields, "p:");
+ break;
+ case INFOLIST_BUFFER:
+ strcat (infolist->ptr_item->fields, "b:");
+ break;
+ case INFOLIST_TIME:
+ strcat (infolist->ptr_item->fields, "t:");
+ break;
+ }
+ strcat (infolist->ptr_item->fields, ptr_var->name);
+ if (ptr_var->next_var)
+ strcat (infolist->ptr_item->fields, ",");
+ }
+
+ return infolist->ptr_item->fields;
+}
+
+/*
+ * infolist_integer: get an integer variable value in current infolist item
+ */
+
+int
+infolist_integer (struct t_infolist *infolist, const char *var)
+{
+ struct t_infolist_var *ptr_var;
+
+ if (!infolist || !infolist->ptr_item || !var || !var[0])
+ return 0;
+
+ for (ptr_var = infolist->ptr_item->vars; ptr_var;
+ ptr_var = ptr_var->next_var)
+ {
+ if (string_strcasecmp (ptr_var->name, var) == 0)
+ {
+ if (ptr_var->type == INFOLIST_INTEGER)
+ return *((int *)ptr_var->value);
+ else
+ return 0;
+ }
+ }
+
+ /* variable not found */
+ return 0;
+}
+
+/*
+ * infolist_string: get a string variable value in current list item
+ */
+
+char *
+infolist_string (struct t_infolist *infolist, const char *var)
+{
+ struct t_infolist_var *ptr_var;
+
+ if (!infolist || !infolist->ptr_item || !var || !var[0])
+ return NULL;
+
+ for (ptr_var = infolist->ptr_item->vars; ptr_var;
+ ptr_var = ptr_var->next_var)
+ {
+ if (string_strcasecmp (ptr_var->name, var) == 0)
+ {
+ if (ptr_var->type == INFOLIST_STRING)
+ return (char *)ptr_var->value;
+ else
+ return NULL;
+ }
+ }
+
+ /* variable not found */
+ return NULL;
+}
+
+/*
+ * infolist_pointer: get a pointer variable value in current infolist item
+ */
+
+void *
+infolist_pointer (struct t_infolist *infolist, const char *var)
+{
+ struct t_infolist_var *ptr_var;
+
+ if (!infolist || !infolist->ptr_item || !var || !var[0])
+ return NULL;
+
+ for (ptr_var = infolist->ptr_item->vars; ptr_var;
+ ptr_var = ptr_var->next_var)
+ {
+ if (string_strcasecmp (ptr_var->name, var) == 0)
+ {
+ if (ptr_var->type == INFOLIST_POINTER)
+ return ptr_var->value;
+ else
+ return NULL;
+ }
+ }
+
+ /* variable not found */
+ return NULL;
+}
+
+/*
+ * infolist_buffer: get a buffer variable value in current infolist item
+ * size is used to return size of buffer
+ */
+
+void *
+infolist_buffer (struct t_infolist *infolist, const char *var,
+ int *size)
+{
+ struct t_infolist_var *ptr_var;
+
+ if (!infolist || !infolist->ptr_item || !var || !var[0])
+ return NULL;
+
+ for (ptr_var = infolist->ptr_item->vars; ptr_var;
+ ptr_var = ptr_var->next_var)
+ {
+ if (string_strcasecmp (ptr_var->name, var) == 0)
+ {
+ if (ptr_var->type == INFOLIST_BUFFER)
+ {
+ *size = ptr_var->size;
+ return ptr_var->value;
+ }
+ else
+ return NULL;
+ }
+ }
+
+ /* variable not found */
+ return NULL;
+}
+
+/*
+ * infolist_time: get a time variable value in current infolist item
+ */
+
+time_t
+infolist_time (struct t_infolist *infolist, const char *var)
+{
+ struct t_infolist_var *ptr_var;
+
+ if (!infolist || !infolist->ptr_item || !var || !var[0])
+ return 0;
+
+ for (ptr_var = infolist->ptr_item->vars; ptr_var;
+ ptr_var = ptr_var->next_var)
+ {
+ if (string_strcasecmp (ptr_var->name, var) == 0)
+ {
+ if (ptr_var->type == INFOLIST_TIME)
+ return *((time_t *)ptr_var->value);
+ else
+ return 0;
+ }
+ }
+
+ /* variable not found */
+ return 0;
+}
+
+/*
+ * infolist_var_free: free an infolist variable
+ */
+
+void
+infolist_var_free (struct t_infolist_item *item,
+ struct t_infolist_var *var)
+{
+ struct t_infolist_var *new_vars;
+
+ /* remove var */
+ if (item->last_var == var)
+ item->last_var = var->prev_var;
+ if (var->prev_var)
+ {
+ (var->prev_var)->next_var = var->next_var;
+ new_vars = item->vars;
+ }
+ else
+ new_vars = var->next_var;
+
+ if (var->next_var)
+ (var->next_var)->prev_var = var->prev_var;
+
+ /* free data */
+ if (var->name)
+ free (var->name);
+ if (((var->type == INFOLIST_INTEGER)
+ || (var->type == INFOLIST_STRING)
+ || (var->type == INFOLIST_BUFFER)
+ || (var->type == INFOLIST_TIME))
+ && var->value)
+ {
+ free (var->value);
+ }
+
+ free (var);
+
+ item->vars = new_vars;
+}
+
+/*
+ * infolist_item_free: free an infolist item
+ */
+
+void
+infolist_item_free (struct t_infolist *infolist,
+ struct t_infolist_item *item)
+{
+ struct t_infolist_item *new_items;
+
+ /* remove var */
+ if (infolist->last_item == item)
+ infolist->last_item = item->prev_item;
+ if (item->prev_item)
+ {
+ (item->prev_item)->next_item = item->next_item;
+ new_items = infolist->items;
+ }
+ else
+ new_items = item->next_item;
+
+ if (item->next_item)
+ (item->next_item)->prev_item = item->prev_item;
+
+ /* free data */
+ while (item->vars)
+ {
+ infolist_var_free (item, item->vars);
+ }
+ if (item->fields)
+ free (item->fields);
+
+ free (item);
+
+ infolist->items = new_items;
+}
+
+/*
+ * infolist_free: free an infolist
+ */
+
+void
+infolist_free (struct t_infolist *infolist)
+{
+ struct t_infolist *new_weechat_infolists;
+
+ /* remove list */
+ if (last_weechat_infolist == infolist)
+ last_weechat_infolist = infolist->prev_infolist;
+ if (infolist->prev_infolist)
+ {
+ (infolist->prev_infolist)->next_infolist = infolist->next_infolist;
+ new_weechat_infolists = weechat_infolists;
+ }
+ else
+ new_weechat_infolists = infolist->next_infolist;
+
+ if (infolist->next_infolist)
+ (infolist->next_infolist)->prev_infolist = infolist->prev_infolist;
+
+ /* free data */
+ while (infolist->items)
+ {
+ infolist_item_free (infolist, infolist->items);
+ }
+
+ free (infolist);
+
+ weechat_infolists = new_weechat_infolists;
+}
+
+/*
+ * infolist_print_log: print infolists infos in log (usually for crash dump)
+ */
+
+void
+infolist_print_log ()
+{
+ struct t_infolist *ptr_infolist;
+ struct t_infolist_item *ptr_item;
+ struct t_infolist_var *ptr_var;
+
+ for (ptr_infolist = weechat_infolists; ptr_infolist;
+ ptr_infolist = ptr_infolist->next_infolist)
+ {
+ log_printf ("");
+ log_printf ("[infolist (addr:0x%x)]", ptr_infolist);
+ log_printf (" items. . . . . . . . . : 0x%x", ptr_infolist->items);
+ log_printf (" last_item. . . . . . . : 0x%x", ptr_infolist->last_item);
+ log_printf (" ptr_item . . . . . . . : 0x%x", ptr_infolist->ptr_item);
+ log_printf (" prev_infolist. . . . . : 0x%x", ptr_infolist->prev_infolist);
+ log_printf (" next_infolist. . . . . : 0x%x", ptr_infolist->next_infolist);
+
+ for (ptr_item = ptr_infolist->items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ log_printf ("");
+ log_printf (" [item (addr:0x%x)]", ptr_item);
+ log_printf (" vars . . . . . . . . . : 0x%x", ptr_item->vars);
+ log_printf (" last_var . . . . . . . : 0x%x", ptr_item->last_var);
+ log_printf (" prev_item. . . . . . . : 0x%x", ptr_item->prev_item);
+ log_printf (" next_item. . . . . . . : 0x%x", ptr_item->next_item);
+
+ for (ptr_var = ptr_item->vars; ptr_var;
+ ptr_var = ptr_var->next_var)
+ {
+ log_printf ("");
+ log_printf (" [var (addr:0x%x)]", ptr_var);
+ log_printf (" name . . . . . . . . : '%s'", ptr_var->name);
+ log_printf (" type . . . . . . . . : %d", ptr_var->type);
+ switch (ptr_var->type)
+ {
+ case INFOLIST_INTEGER:
+ log_printf (" value (integer). . . : %d", *((int *)ptr_var->value));
+ break;
+ case INFOLIST_STRING:
+ log_printf (" value (string) . . . : '%s'", (char *)ptr_var->value);
+ break;
+ case INFOLIST_POINTER:
+ log_printf (" value (pointer). . . : 0x%x", ptr_var->value);
+ break;
+ case INFOLIST_BUFFER:
+ log_printf (" value (buffer) . . . : 0x%x", ptr_var->value);
+ log_printf (" size of buffer . . . : %d", ptr_var->size);
+ break;
+ case INFOLIST_TIME:
+ log_printf (" value (time) . . . . : %ld", *((time_t *)ptr_var->value));
+ break;
+ }
+ log_printf (" prev_var . . . . . . : 0x%x", ptr_var->prev_var);
+ log_printf (" next_var . . . . . . : 0x%x", ptr_var->next_var);
+ }
+ }
+ }
+}
diff --git a/src/core/wee-infolist.h b/src/core/wee-infolist.h
new file mode 100644
index 000000000..681d5e4f8
--- /dev/null
+++ b/src/core/wee-infolist.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
+ * See README for License detail, AUTHORS for developers list.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __WEECHAT_INFOLIST_H
+#define __WEECHAT_INFOLIST_H 1
+
+/* list structures */
+
+enum t_infolist_type
+{
+ INFOLIST_INTEGER = 0,
+ INFOLIST_STRING,
+ INFOLIST_POINTER,
+ INFOLIST_BUFFER,
+ INFOLIST_TIME,
+};
+
+struct t_infolist_var
+{
+ char *name; /* variable name */
+ enum t_infolist_type type; /* type: int, string, ... */
+ void *value; /* pointer to value */
+ int size; /* for type buffer */
+ struct t_infolist_var *prev_var; /* link to previous variable */
+ struct t_infolist_var *next_var; /* link to next variable */
+};
+
+struct t_infolist_item
+{
+ struct t_infolist_var *vars; /* item variables */
+ struct t_infolist_var *last_var; /* last variable */
+ char *fields; /* fields list (NULL if never asked) */
+ struct t_infolist_item *prev_item; /* link to previous item */
+ struct t_infolist_item *next_item; /* link to next item */
+};
+
+struct t_infolist
+{
+ struct t_infolist_item *items; /* link to items */
+ struct t_infolist_item *last_item; /* last variable */
+ struct t_infolist_item *ptr_item; /* pointer to current item */
+ struct t_infolist *prev_infolist; /* link to previous list */
+ struct t_infolist *next_infolist; /* link to next list */
+};
+
+/* list variables */
+
+extern struct t_infolist *weechat_infolists;
+extern struct t_infolist *last_weechat_infolist;
+
+/* list functions */
+
+extern struct t_infolist *infolist_new ();
+extern struct t_infolist_item *infolist_new_item (struct t_infolist *infolist);
+extern struct t_infolist_var *infolist_new_var_integer (struct t_infolist_item *item,
+ const char *name,
+ int value);
+extern struct t_infolist_var *infolist_new_var_string (struct t_infolist_item *item,
+ const char *name,
+ const char *value);
+extern struct t_infolist_var *infolist_new_var_pointer (struct t_infolist_item *item,
+ const char *name,
+ void *pointer);
+extern struct t_infolist_var *infolist_new_var_buffer (struct t_infolist_item *item,
+ const char *name,
+ void *pointer,
+ int size);
+extern struct t_infolist_var *infolist_new_var_time (struct t_infolist_item *item,
+ const char *name,
+ time_t time);
+extern int infolist_valid (struct t_infolist *infolist);
+extern struct t_infolist_item *infolist_next (struct t_infolist *infolist);
+extern struct t_infolist_item *infolist_prev (struct t_infolist *infolist);
+extern void infolist_reset_item_cursor (struct t_infolist *infolist);
+extern char *infolist_fields (struct t_infolist *infolist);
+extern int infolist_integer (struct t_infolist *infolist,
+ const char *var);
+extern char *infolist_string (struct t_infolist *infolist,
+ const char *var);
+extern void *infolist_pointer (struct t_infolist *infolist,
+ const char *var);
+extern void *infolist_buffer (struct t_infolist *infolist,
+ const char *var, int *size);
+extern time_t infolist_time (struct t_infolist *infolist,
+ const char *var);
+extern void infolist_free (struct t_infolist *infolist);
+extern void infolist_print_log ();
+
+#endif /* wee-infolist.h */
diff --git a/src/core/wee-upgrade-file.c b/src/core/wee-upgrade-file.c
new file mode 100644
index 000000000..68c9e9e9a
--- /dev/null
+++ b/src/core/wee-upgrade-file.c
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
+ * See README for License detail, AUTHORS for developers list.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* wee-upgrade-file.c: save/restore data for upgrading WeeChat */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "weechat.h"
+#include "wee-upgrade-file.h"
+#include "wee-infolist.h"
+#include "wee-string.h"
+#include "wee-utf8.h"
+#include "../gui/gui-chat.h"
+#include "../gui/gui-main.h"
+#include "../plugins/plugin.h"
+
+
+struct t_upgrade_file *upgrade_files = NULL;
+struct t_upgrade_file *last_upgrade_file = NULL;
+
+
+/*
+ * upgrade_file_error: display error
+ */
+
+void
+upgrade_file_error (struct t_upgrade_file *upgrade_file, char *message,
+ char *file, int line)
+{
+ gui_chat_printf (NULL,
+ _("%sError upgrading WeeChat:"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ message, file, line);
+ gui_chat_printf (NULL,
+ _("%s error: %s"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ message);
+ if ((upgrade_file->last_read_pos > 0)
+ || (upgrade_file->last_read_length > 0))
+ {
+ gui_chat_printf (NULL,
+ _("%s last read: position: %ld, length: %d"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ upgrade_file->last_read_pos,
+ upgrade_file->last_read_length);
+ }
+ gui_chat_printf (NULL,
+ _("%s source: %s, line: %d"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ file, line);
+ gui_chat_printf (NULL,
+ _("%s*** Please report above info to developers ***"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]);
+}
+
+/*
+ * upgrade_file_write_integer: write int value in upgrade file
+ * return 1 if ok, 0 if error
+ */
+
+int
+upgrade_file_write_integer (struct t_upgrade_file *upgrade_file, int value)
+{
+ if (fwrite ((void *)(&value), sizeof (value), 1, upgrade_file->file) <= 0)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * upgrade_file_write_time: write int value in upgrade file
+ * return 1 if ok, 0 if error
+ */
+
+int
+upgrade_file_write_time (struct t_upgrade_file *upgrade_file, time_t date)
+{
+ if (fwrite ((void *)(&date), sizeof (date), 1, upgrade_file->file) <= 0)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * upgrade_file_write_string: write string in upgrade file
+ * return 1 if ok, 0 if error
+ */
+
+int
+upgrade_file_write_string (struct t_upgrade_file *upgrade_file, char *string)
+{
+ int length;
+
+ if (string && string[0])
+ {
+ length = strlen (string);
+ if (!upgrade_file_write_integer (upgrade_file, length))
+ return 0;
+ if (fwrite ((void *)string, length, 1, upgrade_file->file) <= 0)
+ return 0;
+ }
+ else
+ {
+ if (!upgrade_file_write_integer (upgrade_file, 0))
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * upgrade_file_write_buffer: write buffer in upgrade file
+ * return 1 if ok, 0 if error
+ */
+
+int
+upgrade_file_write_buffer (struct t_upgrade_file *upgrade_file, void *pointer,
+ int size)
+{
+ if (pointer)
+ {
+ if (!upgrade_file_write_integer (upgrade_file, size))
+ return 0;
+ if (fwrite (pointer, size, 1, upgrade_file->file) <= 0)
+ return 0;
+ }
+ else
+ {
+ if (!upgrade_file_write_integer (upgrade_file, 0))
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * upgrade_file_create: create an upgrade file
+ * if write == 1 then it's open in write mode, otherwise
+ * read mode
+ */
+
+struct t_upgrade_file *
+upgrade_file_create (const char *filename, int write)
+{
+ int length;
+ struct t_upgrade_file *new_upgrade_file;
+
+ if (!filename)
+ return NULL;
+
+ new_upgrade_file = malloc (sizeof (*new_upgrade_file));
+ if (new_upgrade_file)
+ {
+ /* build name of file */
+ length = strlen (weechat_home) + 1 + strlen (filename) + 16 + 1;
+ new_upgrade_file->filename = malloc (length + 1);
+ if (!new_upgrade_file->filename)
+ {
+ free (new_upgrade_file);
+ return NULL;
+ }
+ snprintf (new_upgrade_file->filename, length, "%s/%s.upgrade",
+ weechat_home, filename);
+
+ /* open file in read or write mode */
+ if (write)
+ new_upgrade_file->file = fopen (new_upgrade_file->filename, "wb");
+ else
+ new_upgrade_file->file = fopen (new_upgrade_file->filename, "rb");
+
+ if (!new_upgrade_file->file)
+ {
+ free (new_upgrade_file->filename);
+ free (new_upgrade_file);
+ return NULL;
+ }
+
+ /* change permissions if write mode */
+ if (write)
+ {
+ chmod (new_upgrade_file->filename, 0600);
+
+ /* write signature */
+ upgrade_file_write_string (new_upgrade_file, UPGRADE_SIGNATURE);
+ }
+
+ /* init positions */
+ new_upgrade_file->last_read_pos = 0;
+ new_upgrade_file->last_read_length = 0;
+
+ /* add upgrade file to list of upgrade files */
+ new_upgrade_file->prev_upgrade = last_upgrade_file;
+ new_upgrade_file->next_upgrade = NULL;
+ if (upgrade_files)
+ last_upgrade_file->next_upgrade = new_upgrade_file;
+ else
+ upgrade_files = new_upgrade_file;
+ last_upgrade_file = new_upgrade_file;
+ }
+ return new_upgrade_file;
+}
+
+/*
+ * upgrade_file_write_object: write object to file
+ * return 1 if ok, 0 if error
+ */
+
+int
+upgrade_file_write_object (struct t_upgrade_file *upgrade_file, int object_id,
+ struct t_infolist *infolist)
+{
+ int i, argc, length;
+ char *fields, **argv;
+ void *buf;
+
+ /* write all infolist variables */
+ infolist_reset_item_cursor (infolist);
+ while (infolist_next (infolist))
+ {
+ /* write object start with id */
+ if (!upgrade_file_write_integer (upgrade_file, UPGRADE_TYPE_OBJECT_START))
+ {
+ UPGRADE_ERROR("write - object type - 'object start'");
+ return 0;
+ }
+ if (!upgrade_file_write_integer (upgrade_file, object_id))
+ {
+ UPGRADE_ERROR("write - object id");
+ return 0;
+ }
+
+ fields = infolist_fields (infolist);
+ if (fields)
+ {
+ argv = string_explode (fields, ",", 0, 0, &argc);
+ if (argv && (argc > 0))
+ {
+ for (i = 0; i < argc; i++)
+ {
+ switch (argv[i][0])
+ {
+ case 'i': /* integer */
+ if (!upgrade_file_write_integer (upgrade_file, UPGRADE_TYPE_OBJECT_VAR))
+ {
+ UPGRADE_ERROR("write - object type - 'object var'");
+ return 0;
+ }
+ if (!upgrade_file_write_string (upgrade_file, argv[i] + 2))
+ {
+ UPGRADE_ERROR("write - variable name");
+ return 0;
+ }
+ if (!upgrade_file_write_integer (upgrade_file, INFOLIST_INTEGER))
+ {
+ UPGRADE_ERROR("write - infolist type - 'integer'");
+ return 0;
+ }
+ if (!upgrade_file_write_integer (upgrade_file,
+ infolist_integer (infolist, argv[i] + 2)))
+ {
+ UPGRADE_ERROR("write - integer variable");
+ return 0;
+ }
+ break;
+ case 's': /* string */
+ if (!upgrade_file_write_integer (upgrade_file, UPGRADE_TYPE_OBJECT_VAR))
+ {
+ UPGRADE_ERROR("write - object type - 'object var'");
+ return 0;
+ }
+ if (!upgrade_file_write_string (upgrade_file, argv[i] + 2))
+ {
+ UPGRADE_ERROR("write - variable name");
+ return 0;
+ }
+ if (!upgrade_file_write_integer (upgrade_file, INFOLIST_STRING))
+ {
+ UPGRADE_ERROR("write - infolist type - 'string'");
+ return 0;
+ }
+ if (!upgrade_file_write_string (upgrade_file,
+ infolist_string (infolist, argv[i] + 2)))
+ {
+ UPGRADE_ERROR("write - string variable");
+ return 0;
+ }
+ break;
+ case 'p': /* pointer */
+ /* pointer in not used in upgrade files, only buffer is */
+ break;
+ case 'b': /* buffer */
+ buf = infolist_buffer (infolist, argv[i] + 2, &length);
+ if (buf && (length > 0))
+ {
+ if (!upgrade_file_write_integer (upgrade_file, UPGRADE_TYPE_OBJECT_VAR))
+ {
+ UPGRADE_ERROR("write - object type - 'object var'");
+ return 0;
+ }
+ if (!upgrade_file_write_string (upgrade_file, argv[i] + 2))
+ {
+ UPGRADE_ERROR("write - variable name");
+ return 0;
+ }
+ if (!upgrade_file_write_integer (upgrade_file, INFOLIST_BUFFER))
+ {
+ UPGRADE_ERROR("write - infolist type - 'buffer'");
+ return 0;
+ }
+ if (!upgrade_file_write_buffer (upgrade_file, buf, length))
+ {
+ UPGRADE_ERROR("write - buffer variable");
+ return 0;
+ }
+ }
+ break;
+ case 't': /* time */
+ if (!upgrade_file_write_integer (upgrade_file, UPGRADE_TYPE_OBJECT_VAR))
+ {
+ UPGRADE_ERROR("write - object type - 'object var'");
+ return 0;
+ }
+ if (!upgrade_file_write_string (upgrade_file, argv[i] + 2))
+ {
+ UPGRADE_ERROR("write - variable name");
+ return 0;
+ }
+ if (!upgrade_file_write_integer (upgrade_file, INFOLIST_TIME))
+ {
+ UPGRADE_ERROR("write - infolist type - 'time'");
+ return 0;
+ }
+ if (!upgrade_file_write_time (upgrade_file,
+ infolist_time (infolist, argv[i] + 2)))
+ {
+ UPGRADE_ERROR("write - time variable");
+ return 0;
+ }
+ break;
+ }
+ }
+ }
+ if (argv)
+ string_free_exploded (argv);
+ }
+
+ /* write object end */
+ if (!upgrade_file_write_integer (upgrade_file, UPGRADE_TYPE_OBJECT_END))
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * upgrade_file_read_integer: read integer from upgrade file
+ */
+
+int
+upgrade_file_read_integer (struct t_upgrade_file *upgrade_file, int *value)
+{
+ upgrade_file->last_read_pos = ftell (upgrade_file->file);
+ upgrade_file->last_read_length = sizeof (*value);
+
+ if (value)
+ {
+ if (fread ((void *)value, sizeof (*value), 1, upgrade_file->file) <= 0)
+ return 0;
+ }
+ else
+ {
+ if (fseek (upgrade_file->file, sizeof (*value), SEEK_CUR) < 0)
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * upgrade_file_read_string: read string from upgrade file
+ */
+
+int
+upgrade_file_read_string (struct t_upgrade_file *upgrade_file, char **string)
+{
+ int length;
+
+ if (string && *string)
+ {
+ free (*string);
+ *string = NULL;
+ }
+
+ if (!upgrade_file_read_integer (upgrade_file, &length))
+ return 0;
+
+ upgrade_file->last_read_pos = ftell (upgrade_file->file);
+ upgrade_file->last_read_length = length;
+
+ if (string)
+ {
+ if (length == 0)
+ return 1;
+
+ (*string) = malloc (length + 1);
+ if (!(*string))
+ return 0;
+
+ if (fread ((void *)(*string), length, 1, upgrade_file->file) <= 0)
+ {
+ free (*string);
+ *string = NULL;
+ return 0;
+ }
+ (*string)[length] = '\0';
+ }
+ else
+ {
+ if (fseek (upgrade_file->file, length, SEEK_CUR) < 0)
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * upgrade_file_read_string_utf8: read string from file, then normalize UTF-8
+ */
+
+int
+upgrade_file_read_string_utf8 (struct t_upgrade_file *upgrade_file,
+ char **string)
+{
+ if (!upgrade_file_read_string (upgrade_file, string))
+ return 0;
+
+ if (string && *string)
+ utf8_normalize (*string, '?');
+
+ return 1;
+}
+
+/*
+ * upgrade_file_read_buffer: read buffer from upgrade file
+ */
+
+int
+upgrade_file_read_buffer (struct t_upgrade_file *upgrade_file,
+ void **buffer, int *size)
+{
+ if (buffer && *buffer)
+ {
+ free (*buffer);
+ *buffer = NULL;
+ }
+
+ if (!upgrade_file_read_integer (upgrade_file, size))
+ return 0;
+
+ if (*size > 0)
+ {
+ upgrade_file->last_read_pos = ftell (upgrade_file->file);
+ upgrade_file->last_read_length = *size;
+
+ *buffer = malloc (*size);
+
+ if (buffer && *buffer)
+ {
+ if (fread (*buffer, *size, 1, upgrade_file->file) <= 0)
+ return 0;
+ }
+ else
+ {
+ if (fseek (upgrade_file->file, *size, SEEK_CUR) < 0)
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * upgrade_file_read_time: read time from upgrade file
+ */
+
+int
+upgrade_file_read_time (struct t_upgrade_file *upgrade_file, time_t *time)
+{
+ upgrade_file->last_read_pos = ftell (upgrade_file->file);
+ upgrade_file->last_read_length = sizeof (*time);
+
+ if (time)
+ {
+ if (fread ((void *)time, sizeof (*time), 1, upgrade_file->file) <= 0)
+ return 0;
+ }
+ else
+ {
+ if (fseek (upgrade_file->file, sizeof (*time), SEEK_CUR) < 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * upgrade_file_read_object: read object from file, then call read callback
+ * return 1 if ok, 0 if error
+ */
+
+int
+upgrade_file_read_object (struct t_upgrade_file *upgrade_file)
+{
+ struct t_infolist *infolist;
+ struct t_infolist_item *item;
+ int rc, object_id, type, type_var, value, size;
+ char *name, *value_str;
+ void *buffer;
+ time_t time;
+
+ rc = 0;
+
+ infolist = NULL;
+ name = NULL;
+ value_str = NULL;
+ buffer = NULL;
+
+ if (!upgrade_file_read_integer (upgrade_file, &type))
+ {
+ if (feof (upgrade_file->file))
+ rc = 1;
+ else
+ UPGRADE_ERROR("read - object type");
+ goto end;
+ }
+
+ if (type != UPGRADE_TYPE_OBJECT_START)
+ {
+ UPGRADE_ERROR("read - bad object type (not 'object start')");
+ goto end;
+ }
+
+ if (!upgrade_file_read_integer (upgrade_file, &object_id))
+ {
+ UPGRADE_ERROR("read - object id");
+ goto end;
+ }
+
+ infolist = infolist_new ();
+ if (!infolist)
+ {
+ UPGRADE_ERROR("read - infolist creation");
+ goto end;
+ }
+ item = infolist_new_item (infolist);
+ if (!item)
+ {
+ UPGRADE_ERROR("read - infolist item creation");
+ goto end;
+ }
+
+ while (1)
+ {
+ if (!upgrade_file_read_integer (upgrade_file, &type))
+ {
+ UPGRADE_ERROR("read - object type");
+ goto end;
+ }
+
+ if (type == UPGRADE_TYPE_OBJECT_END)
+ break;
+
+ if (type == UPGRADE_TYPE_OBJECT_VAR)
+ {
+ if (!upgrade_file_read_string (upgrade_file, &name))
+ {
+ UPGRADE_ERROR("read - variable name");
+ goto end;
+ }
+ if (!name)
+ {
+ UPGRADE_ERROR("read - variable name");
+ goto end;
+ }
+ if (!upgrade_file_read_integer (upgrade_file, &type_var))
+ {
+ UPGRADE_ERROR("read - variable type");
+ goto end;
+ }
+
+ switch (type_var)
+ {
+ case INFOLIST_INTEGER:
+ if (!upgrade_file_read_integer (upgrade_file, &value))
+ {
+ UPGRADE_ERROR("read - integer value");
+ goto end;
+ }
+ infolist_new_var_integer (item, name, value);
+ break;
+ case INFOLIST_STRING:
+ if (!upgrade_file_read_string (upgrade_file, &value_str))
+ {
+ UPGRADE_ERROR("read - string value");
+ goto end;
+ }
+ infolist_new_var_string (item, name, value_str);
+ break;
+ case INFOLIST_POINTER:
+ break;
+ case INFOLIST_BUFFER:
+ if (!upgrade_file_read_buffer (upgrade_file, &buffer, &size))
+ {
+ UPGRADE_ERROR("read - buffer value");
+ goto end;
+ }
+ infolist_new_var_buffer (item, name, buffer, size);
+ break;
+ case INFOLIST_TIME:
+ if (!upgrade_file_read_time (upgrade_file, &time))
+ {
+ UPGRADE_ERROR("read - time value");
+ goto end;
+ }
+ infolist_new_var_time (item, name, time);
+ break;
+ }
+ }
+ }
+
+ rc = 1;
+
+ if (upgrade_file->callback_read)
+ {
+ if ((int)(upgrade_file->callback_read) (object_id, infolist) == WEECHAT_RC_ERROR)
+ rc = 0;
+ }
+
+ end:
+ if (infolist)
+ infolist_free (infolist);
+ if (name)
+ free (name);
+ if (value_str)
+ free (value_str);
+ if (buffer)
+ free (buffer);
+
+ return rc;
+}
+
+/*
+ * upgrade_file_read: read an upgrade file
+ */
+
+int
+upgrade_file_read (struct t_upgrade_file *upgrade_file,
+ int (*callback_read)(int object_id,
+ struct t_infolist *infolist))
+{
+ char *signature;
+
+ upgrade_file->callback_read = callback_read;
+
+ signature = NULL;
+ if (!upgrade_file_read_string (upgrade_file, &signature))
+ return 0;
+
+ if (!signature || (strcmp (signature, UPGRADE_SIGNATURE) != 0))
+ return 0;
+
+ free (signature);
+
+ while (!feof (upgrade_file->file))
+ {
+ if (!upgrade_file_read_object (upgrade_file))
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * upgrade_file_close: close an upgrade file
+ */
+
+void
+upgrade_file_close (struct t_upgrade_file *upgrade_file)
+{
+ fclose (upgrade_file->file);
+}
diff --git a/src/core/wee-upgrade-file.h b/src/core/wee-upgrade-file.h
new file mode 100644
index 000000000..45b3c73bf
--- /dev/null
+++ b/src/core/wee-upgrade-file.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
+ * See README for License detail, AUTHORS for developers list.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __WEECHAT_UPGRADE_FILE_H
+#define __WEECHAT_UPGRADE_FILE_H 1
+
+#define UPGRADE_SIGNATURE "===== WeeChat Upgrade file v2.0 - binary, do not edit! ====="
+
+#define UPGRADE_ERROR(msg) upgrade_file_error(upgrade_file, msg, __FILE__, __LINE__)
+
+struct t_infolist;
+
+enum t_upgrade_type
+{
+ UPGRADE_TYPE_OBJECT_START = 0,
+ UPGRADE_TYPE_OBJECT_END,
+ UPGRADE_TYPE_OBJECT_VAR,
+};
+
+struct t_upgrade_file
+{
+ char *filename; /* filename with path */
+ FILE *file; /* file pointer */
+ long last_read_pos; /* last read position */
+ int last_read_length; /* last read length */
+ int (*callback_read) /* callback called when reading */
+ (int object_id, /* file */
+ struct t_infolist *infolist);
+ struct t_upgrade_file *prev_upgrade; /* link to previous upgrade file */
+ struct t_upgrade_file *next_upgrade; /* link to next upgrade file */
+};
+
+extern struct t_upgrade_file *upgrade_file_create (const char *filename,
+ int write);
+extern int upgrade_file_write_object (struct t_upgrade_file *upgrade_file,
+ int object_id,
+ struct t_infolist *infolist);
+extern int upgrade_file_read (struct t_upgrade_file *upgrade_file,
+ int (*callback_read)(int object_id,
+ struct t_infolist *infolist));
+extern void upgrade_file_close (struct t_upgrade_file *upgrade_file);
+
+#endif /* wee-upgrade-file.h */
diff --git a/src/core/wee-upgrade.c b/src/core/wee-upgrade.c
index 2213fb6ed..3cfd14cfe 100644
--- a/src/core/wee-upgrade.c
+++ b/src/core/wee-upgrade.c
@@ -23,1842 +23,415 @@
#include "config.h"
#endif
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
#include <string.h>
-/*#ifdef HAVE_GNUTLS
-#include <gnutls/gnutls.h>
-#endif*/
-
#include "weechat.h"
#include "wee-upgrade.h"
-#include "wee-log.h"
+#include "wee-infolist.h"
#include "wee-string.h"
-#include "wee-utf8.h"
+#include "../gui/gui-buffer.h"
#include "../gui/gui-chat.h"
-#include "../gui/gui-main.h"
-
-
-/* current server/channel (used when loading session) */
-/*t_irc_server *session_current_server = NULL;
-t_irc_channel *session_current_channel = NULL;
-t_gui_buffer *session_current_buffer = NULL;*/
+#include "../gui/gui-history.h"
+#include "../gui/gui-hotlist.h"
+#include "../gui/gui-nicklist.h"
+#include "../gui/gui-window.h"
+#include "../plugins/plugin.h"
-long session_last_read_pos = 0;
-int session_last_read_length = 0;
+struct t_gui_buffer *upgrade_current_buffer = NULL;
+struct t_gui_buffer *upgrade_set_current_buffer = NULL;
+int hotlist_reset = 0;
-/*
- * session_write_id: write object ID to file
- */
-
-int
-session_write_id (FILE *file, int id)
-{
- return (fwrite ((void *)(&id), sizeof (int), 1, file) > 0);
-}
/*
- * session_write_int: write an integer to file
+ * upgrade_weechat_save_history: save history info to upgrade file
+ * (from last to first, to restore it in good order)
*/
int
-session_write_int (FILE *file, int id, int value)
+upgrade_weechat_save_history (struct t_upgrade_file *upgrade_file,
+ struct t_gui_history *last_history)
{
- char type;
+ struct t_infolist *ptr_infolist;
+ struct t_infolist_item *ptr_item;
+ struct t_gui_history *ptr_history;
+ int rc;
- if (id >= 0)
- {
- if (!session_write_id (file, id))
- return 0;
- }
- type = SESSION_TYPE_INT;
- if (fwrite ((void *)(&type), sizeof (char), 1, file) == 0)
- return 0;
- return (fwrite ((void *)(&value), sizeof (int), 1, file) > 0);
-}
-
-/*
- * session_write_str: write a string to file
- */
-
-int
-session_write_str (FILE *file, int id, const char *string)
-{
- char type;
- int length;
+ if (!last_history)
+ return 1;
- if (id >= 0)
- {
- if (!session_write_id (file, id))
- return 0;
- }
- type = SESSION_TYPE_STR;
- if (fwrite ((void *)(&type), sizeof (char), 1, file) == 0)
+ ptr_infolist = infolist_new ();
+ if (!ptr_infolist)
return 0;
- if (string && string[0])
- {
- length = strlen (string);
- if (fwrite ((void *)(&length), sizeof (int), 1, file) == 0)
- return 0;
- return (fwrite ((void *)string, length, 1, file) > 0);
- }
- else
- {
- length = 0;
- return (fwrite ((void *)(&length), sizeof (int), 1, file) > 0);
- }
-}
-
-/*
- * session_write_buf: write a buffer to file
- */
-
-int
-session_write_buf (FILE *file, int id, void *buffer, int size)
-{
- char type;
- if (id >= 0)
+ ptr_history = last_history;
+ while (ptr_history)
{
- if (!session_write_id (file, id))
+ ptr_item = infolist_new_item (ptr_infolist);
+ if (!ptr_item)
+ {
+ infolist_free (ptr_infolist);
return 0;
+ }
+
+ if (!infolist_new_var_string (ptr_item, "text", ptr_history->text))
+ {
+ infolist_free (ptr_infolist);
+ return 0;
+ }
+
+ ptr_history = ptr_history->prev_history;
}
- type = SESSION_TYPE_BUF;
- if (fwrite ((void *)(&type), sizeof (char), 1, file) == 0)
- return 0;
- if (fwrite ((void *)(&size), sizeof (int), 1, file) == 0)
- return 0;
- return (fwrite (buffer, size, 1, file) > 0);
-}
-
-/*
- * session_save_nick: save a nick into session file
- */
-
-/*int
-session_save_nick (FILE *file, t_irc_nick *nick)
-{
- int rc;
-
- rc = 1;
- rc = rc && (session_write_id (file, SESSION_OBJ_NICK));
- rc = rc && (session_write_str (file, SESSION_NICK_NICK, nick->nick));
- rc = rc && (session_write_int (file, SESSION_NICK_FLAGS, nick->flags));
- rc = rc && (session_write_int (file, SESSION_NICK_COLOR, nick->color));
- rc = rc && (session_write_str (file, SESSION_NICK_HOST, nick->host));
- rc = rc && (session_write_id (file, SESSION_NICK_END));
- return rc;
-}*/
-
-/*
- * session_save_channel: save a channel into session file
- */
-
-/*int
-session_save_channel (FILE *file, t_irc_channel *channel)
-{
- int rc;
- t_irc_nick *ptr_nick;
-
- rc = 1;
- rc = rc && (session_write_id (file, SESSION_OBJ_CHANNEL));
- rc = rc && (session_write_int (file, SESSION_CHAN_TYPE, channel->type));
- rc = rc && (session_write_str (file, SESSION_CHAN_NAME, channel->name));
- rc = rc && (session_write_str (file, SESSION_CHAN_TOPIC, channel->topic));
- rc = rc && (session_write_str (file, SESSION_CHAN_MODES, channel->modes));
- rc = rc && (session_write_int (file, SESSION_CHAN_LIMIT, channel->limit));
- rc = rc && (session_write_str (file, SESSION_CHAN_KEY, channel->key));
- rc = rc && (session_write_int (file, SESSION_CHAN_NICKS_COUNT, channel->nicks_count));
- rc = rc && (session_write_int (file, SESSION_CHAN_CHECKING_AWAY, channel->checking_away));
- rc = rc && (session_write_str (file, SESSION_CHAN_AWAY_MESSAGE, channel->away_message));
- rc = rc && (session_write_int (file, SESSION_CHAN_CYCLE, channel->cycle));
- rc = rc && (session_write_int (file, SESSION_CHAN_CLOSE, channel->close));
- rc = rc && (session_write_int (file, SESSION_CHAN_DISPLAY_CREATION_DATE, channel->display_creation_date));
- rc = rc && (session_write_id (file, SESSION_CHAN_END));
+ rc = upgrade_file_write_object (upgrade_file,
+ UPGRADE_WEECHAT_TYPE_HISTORY,
+ ptr_infolist);
+ infolist_free (ptr_infolist);
if (!rc)
return 0;
- for (ptr_nick = channel->nicks; ptr_nick;
- ptr_nick = ptr_nick->next_nick)
- {
- if (!session_save_nick (file, ptr_nick))
- return 0;
- }
-
return 1;
-}*/
+}
/*
- * session_save_servers: save all servers into session file
+ * upgrade_weechat_save_buffers: save buffers info to upgrade file
*/
-/*int
-session_save_servers (FILE *file)
+int
+upgrade_weechat_save_buffers (struct t_upgrade_file *upgrade_file)
{
+ struct t_infolist *ptr_infolist;
+ struct t_gui_buffer *ptr_buffer;
+ struct t_gui_line *ptr_line;
int rc;
-#ifdef HAVE_GNUTLS
- void *session_data;
- size_t session_size;
-#endif
- t_irc_server *ptr_server;
- t_irc_channel *ptr_channel;
- rc = 1;
-
- for (ptr_server = irc_servers; ptr_server;
- ptr_server = ptr_server->next_server)
+ for (ptr_buffer = gui_buffers; ptr_buffer;
+ ptr_buffer = ptr_buffer->next_buffer)
{
- rc = rc && (session_write_id (file, SESSION_OBJ_SERVER));
- rc = rc && (session_write_str (file, SESSION_SERV_NAME, ptr_server->name));
- rc = rc && (session_write_int (file, SESSION_SERV_AUTOCONNECT, ptr_server->autoconnect));
- rc = rc && (session_write_int (file, SESSION_SERV_AUTORECONNECT, ptr_server->autoreconnect));
- rc = rc && (session_write_int (file, SESSION_SERV_AUTORECONNECT_DELAY, ptr_server->autoreconnect_delay));
- rc = rc && (session_write_int (file, SESSION_SERV_TEMP_SERVER, ptr_server->temp_server));
- rc = rc && (session_write_str (file, SESSION_SERV_ADDRESS, ptr_server->address));
- rc = rc && (session_write_int (file, SESSION_SERV_PORT, ptr_server->port));
- rc = rc && (session_write_int (file, SESSION_SERV_IPV6, ptr_server->ipv6));
- rc = rc && (session_write_int (file, SESSION_SERV_SSL, ptr_server->ssl));
- rc = rc && (session_write_str (file, SESSION_SERV_PASSWORD, ptr_server->password));
- rc = rc && (session_write_str (file, SESSION_SERV_NICK1, ptr_server->nick1));
- rc = rc && (session_write_str (file, SESSION_SERV_NICK2, ptr_server->nick2));
- rc = rc && (session_write_str (file, SESSION_SERV_NICK3, ptr_server->nick3));
- rc = rc && (session_write_str (file, SESSION_SERV_USERNAME, ptr_server->username));
- rc = rc && (session_write_str (file, SESSION_SERV_REALNAME, ptr_server->realname));
- rc = rc && (session_write_str (file, SESSION_SERV_HOSTNAME, ptr_server->hostname));
- rc = rc && (session_write_str (file, SESSION_SERV_COMMAND, ptr_server->command));
- rc = rc && (session_write_int (file, SESSION_SERV_COMMAND_DELAY, ptr_server->command_delay));
- rc = rc && (session_write_str (file, SESSION_SERV_AUTOJOIN, ptr_server->autojoin));
- rc = rc && (session_write_int (file, SESSION_SERV_AUTOREJOIN, ptr_server->autorejoin));
- rc = rc && (session_write_str (file, SESSION_SERV_NOTIFY_LEVELS, ptr_server->notify_levels));
- rc = rc && (session_write_int (file, SESSION_SERV_CHILD_PID, ptr_server->child_pid));
- rc = rc && (session_write_int (file, SESSION_SERV_CHILD_READ, ptr_server->child_read));
- rc = rc && (session_write_int (file, SESSION_SERV_CHILD_WRITE, ptr_server->child_write));
- rc = rc && (session_write_int (file, SESSION_SERV_SOCK, ptr_server->sock));
- rc = rc && (session_write_int (file, SESSION_SERV_IS_CONNECTED, ptr_server->is_connected));
- rc = rc && (session_write_int (file, SESSION_SERV_SSL_CONNECTED, ptr_server->ssl_connected));
-#ifdef HAVE_GNUTLS
- if (ptr_server->is_connected && ptr_server->ssl_connected)
+ /* save buffer */
+ ptr_infolist = infolist_new ();
+ if (!ptr_infolist)
+ return 0;
+ if (!gui_buffer_add_to_infolist (ptr_infolist, ptr_buffer))
{
- gnutls_session_get_data (ptr_server->gnutls_sess, NULL, &session_size);
- if (session_size > 0)
- {
- session_data = malloc (session_size);
- gnutls_session_get_data (ptr_server->gnutls_sess, session_data, &session_size);
- rc = rc && (session_write_buf (file, SESSION_SERV_GNUTLS_SESS, &(session_data), session_size));
- free (session_data);
- }
+ infolist_free (ptr_infolist);
+ return 0;
}
-#endif
- rc = rc && (session_write_str (file, SESSION_SERV_UNTERMINATED_MESSAGE, ptr_server->unterminated_message));
- rc = rc && (session_write_str (file, SESSION_SERV_NICK, ptr_server->nick));
- rc = rc && (session_write_str (file, SESSION_SERV_NICK_MODES, ptr_server->nick_modes));
- rc = rc && (session_write_str (file, SESSION_SERV_PREFIX, ptr_server->prefix));
- rc = rc && (session_write_buf (file, SESSION_SERV_RECONNECT_START, &(ptr_server->reconnect_start), sizeof (time_t)));
- rc = rc && (session_write_buf (file, SESSION_SERV_COMMAND_TIME, &(ptr_server->command_time), sizeof (time_t)));
- rc = rc && (session_write_int (file, SESSION_SERV_RECONNECT_JOIN, ptr_server->reconnect_join));
- rc = rc && (session_write_int (file, SESSION_SERV_IS_AWAY, ptr_server->is_away));
- rc = rc && (session_write_str (file, SESSION_SERV_AWAY_MESSAGE, ptr_server->away_message));
- rc = rc && (session_write_buf (file, SESSION_SERV_AWAY_TIME, &(ptr_server->away_time), sizeof (time_t)));
- rc = rc && (session_write_int (file, SESSION_SERV_LAG, ptr_server->lag));
- rc = rc && (session_write_buf (file, SESSION_SERV_LAG_CHECK_TIME, &(ptr_server->lag_check_time), sizeof (struct timeval)));
- rc = rc && (session_write_buf (file, SESSION_SERV_LAG_NEXT_CHECK, &(ptr_server->lag_next_check), sizeof (time_t)));
- rc = rc && (session_write_id (file, SESSION_SERV_END));
-
+ rc = upgrade_file_write_object (upgrade_file,
+ UPGRADE_WEECHAT_TYPE_BUFFER,
+ ptr_infolist);
+ infolist_free (ptr_infolist);
if (!rc)
return 0;
- for (ptr_channel = ptr_server->channels; ptr_channel;
- ptr_channel = ptr_channel->next_channel)
+ /* save nicklist */
+ if (ptr_buffer->nicklist)
{
- if (!session_save_channel (file, ptr_channel))
+ ptr_infolist = infolist_new ();
+ if (!ptr_infolist)
+ return 0;
+ if (!gui_nicklist_add_to_infolist (ptr_infolist, ptr_buffer))
+ {
+ infolist_free (ptr_infolist);
+ return 0;
+ }
+ rc = upgrade_file_write_object (upgrade_file,
+ UPGRADE_WEECHAT_TYPE_NICKLIST,
+ ptr_infolist);
+ infolist_free (ptr_infolist);
+ if (!rc)
return 0;
}
- }
- return 1;
-}*/
-
-/*
- * session_save_dcc: save all DCC into session file
- */
-
-/*int
-session_save_dcc (FILE *file)
-{
- int rc;
- t_irc_dcc *ptr_dcc;
-
- rc = 1;
-
- for (ptr_dcc = irc_last_dcc; ptr_dcc;
- ptr_dcc = ptr_dcc->prev_dcc)
- {
- rc = rc && (session_write_id (file, SESSION_OBJ_DCC));
- rc = rc && (session_write_str (file, SESSION_DCC_SERVER, (ptr_dcc->server) ? ptr_dcc->server->name : NULL));
- rc = rc && (session_write_str (file, SESSION_DCC_CHANNEL, (ptr_dcc->channel) ? ptr_dcc->channel->name : NULL));
- rc = rc && (session_write_int (file, SESSION_DCC_TYPE, ptr_dcc->type));
- rc = rc && (session_write_int (file, SESSION_DCC_STATUS, ptr_dcc->status));
- rc = rc && (session_write_buf (file, SESSION_DCC_START_TIME, &(ptr_dcc->start_time), sizeof (time_t)));
- rc = rc && (session_write_buf (file, SESSION_DCC_START_TRANSFER, &(ptr_dcc->start_transfer), sizeof (time_t)));
- rc = rc && (session_write_buf (file, SESSION_DCC_ADDR, &(ptr_dcc->addr), sizeof (unsigned long)));
- rc = rc && (session_write_int (file, SESSION_DCC_PORT, ptr_dcc->port));
- rc = rc && (session_write_str (file, SESSION_DCC_NICK, ptr_dcc->nick));
- rc = rc && (session_write_int (file, SESSION_DCC_SOCK, ptr_dcc->sock));
- rc = rc && (session_write_str (file, SESSION_DCC_UNTERMINATED_MESSAGE, ptr_dcc->unterminated_message));
- rc = rc && (session_write_int (file, SESSION_DCC_FILE, ptr_dcc->file));
- rc = rc && (session_write_str (file, SESSION_DCC_FILENAME, ptr_dcc->filename));
- rc = rc && (session_write_str (file, SESSION_DCC_LOCAL_FILENAME, ptr_dcc->local_filename));
- rc = rc && (session_write_int (file, SESSION_DCC_FILENAME_SUFFIX, ptr_dcc->filename_suffix));
- rc = rc && (session_write_buf (file, SESSION_DCC_SIZE, &(ptr_dcc->size), sizeof (unsigned long)));
- rc = rc && (session_write_buf (file, SESSION_DCC_POS, &(ptr_dcc->pos), sizeof (unsigned long)));
- rc = rc && (session_write_buf (file, SESSION_DCC_ACK, &(ptr_dcc->ack), sizeof (unsigned long)));
- rc = rc && (session_write_buf (file, SESSION_DCC_START_RESUME, &(ptr_dcc->start_resume), sizeof (unsigned long)));
- rc = rc && (session_write_buf (file, SESSION_DCC_LAST_CHECK_TIME, &(ptr_dcc->last_check_time), sizeof (time_t)));
- rc = rc && (session_write_buf (file, SESSION_DCC_LAST_CHECK_POS, &(ptr_dcc->last_check_pos), sizeof (unsigned long)));
- rc = rc && (session_write_buf (file, SESSION_DCC_LAST_ACTIVITY, &(ptr_dcc->last_activity), sizeof (time_t)));
- rc = rc && (session_write_buf (file, SESSION_DCC_BYTES_PER_SEC, &(ptr_dcc->bytes_per_sec), sizeof (unsigned long)));
- rc = rc && (session_write_buf (file, SESSION_DCC_ETA, &(ptr_dcc->eta), sizeof (unsigned long)));
- rc = rc && (session_write_int (file, SESSION_DCC_CHILD_PID, ptr_dcc->child_pid));
- rc = rc && (session_write_int (file, SESSION_DCC_CHILD_READ, ptr_dcc->child_read));
- rc = rc && (session_write_int (file, SESSION_DCC_CHILD_WRITE, ptr_dcc->child_write));
- rc = rc && (session_write_id (file, SESSION_DCC_END));
-
- if (!rc)
- return 0;
- }
- return 1;
-}*/
-
-/*
- * session_save_history: save history into session file
- * (from last to first, to restore it in good order)
- */
-
-/*int
-session_save_history (FILE *file, t_history *last_history)
-{
- int rc;
- t_history *ptr_history;
-
- rc = 1;
- rc = rc && (session_write_id (file, SESSION_OBJ_HISTORY));
- ptr_history = last_history;
- while (ptr_history)
- {
- rc = rc && (session_write_str (file, SESSION_HIST_TEXT, ptr_history->text));
- ptr_history = ptr_history->prev_history;
- }
- rc = rc && (session_write_id (file, SESSION_HIST_END));
- return rc;
-}*/
-
-/*
- * session_save_line: save a buffer line into session file
- */
-
-/*int
-session_save_line (FILE *file, t_gui_line *line)
-{
- int rc;
-
- rc = 1;
- rc = rc && (session_write_id (file, SESSION_OBJ_LINE));
- rc = rc && (session_write_int (file, SESSION_LINE_LENGTH, line->length));
- rc = rc && (session_write_int (file, SESSION_LINE_LENGTH_ALIGN, line->length_align));
- rc = rc && (session_write_int (file, SESSION_LINE_LOG_WRITE, line->log_write));
- rc = rc && (session_write_int (file, SESSION_LINE_WITH_MESSAGE, line->line_with_message));
- rc = rc && (session_write_int (file, SESSION_LINE_WITH_HIGHLIGHT, line->line_with_highlight));
- rc = rc && (session_write_str (file, SESSION_LINE_DATA, line->data));
- rc = rc && (session_write_int (file, SESSION_LINE_OFS_AFTER_DATE, line->ofs_after_date));
- rc = rc && (session_write_int (file, SESSION_LINE_OFS_START_MESSAGE, line->ofs_start_message));
- rc = rc && (session_write_str (file, SESSION_LINE_NICK, line->nick));
- rc = rc && (session_write_buf (file, SESSION_LINE_DATE, &(line->date), sizeof (time_t)));
- rc = rc && (session_write_id (file, SESSION_LINE_END));
- return rc;
-}*/
-
-/*
- * session_save_buffers: save all buffers into session file
- */
-
-/*int
-session_save_buffers (FILE *file)
-{
- int rc;
- t_gui_buffer *ptr_buffer;
- t_gui_line *ptr_line;
-
- rc = 1;
-
- for (ptr_buffer = gui_buffers; ptr_buffer;
- ptr_buffer = ptr_buffer->next_buffer)
- {
- rc = rc && (session_write_id (file, SESSION_OBJ_BUFFER));
- rc = rc && (session_write_str (file, SESSION_BUFF_SERVER, GUI_SERVER(ptr_buffer) ? GUI_SERVER(ptr_buffer)->name : NULL));
- rc = rc && (session_write_str (file, SESSION_BUFF_CHANNEL, GUI_CHANNEL(ptr_buffer) ? GUI_CHANNEL(ptr_buffer)->name : NULL));
- rc = rc && (session_write_int (file, SESSION_BUFF_TYPE, ptr_buffer->type));
- rc = rc && (session_write_int (file, SESSION_BUFF_ALL_SERVERS, ptr_buffer->all_servers));
- rc = rc && (session_write_id (file, SESSION_BUFF_END));
-
- if (!rc)
- return 0;
+ /* save buffer lines */
for (ptr_line = ptr_buffer->lines; ptr_line;
ptr_line = ptr_line->next_line)
{
- if (!session_save_line (file, ptr_line))
+ ptr_infolist = infolist_new ();
+ if (!ptr_infolist)
+ return 0;
+ if (!gui_buffer_line_add_to_infolist (ptr_infolist, ptr_line))
+ {
+ infolist_free (ptr_infolist);
+ return 0;
+ }
+ rc = upgrade_file_write_object (upgrade_file,
+ UPGRADE_WEECHAT_TYPE_BUFFER_LINE,
+ ptr_infolist);
+ infolist_free (ptr_infolist);
+ if (!rc)
return 0;
}
- if (!session_save_history (file, ptr_buffer->last_history))
- return 0;
+ /* save command/text history of buffer */
+ if (ptr_buffer->history)
+ {
+ rc = upgrade_weechat_save_history (upgrade_file,
+ ptr_buffer->last_history);
+ if (!rc)
+ return 0;
+ }
}
- return 1;
-}*/
-
-/*
- * session_save_uptime: save uptime into session file
- */
-
-/*int
-session_save_uptime (FILE *file)
-{
- int rc;
-
- rc = 1;
-
- rc = rc && (session_write_id (file, SESSION_OBJ_UPTIME));
- rc = rc && (session_write_buf (file, SESSION_UPT_START_TIME, &weechat_start_time, sizeof (time_t)));
- rc = rc && (session_write_id (file, SESSION_UPT_END));
- return rc;
-}*/
-
-/*
- * session_save_hotlist: save hotlist into session file
- */
-
-/*int
-session_save_hotlist (FILE *file)
-{
- int rc;
- t_weechat_hotlist *ptr_hotlist;
- rc = 1;
-
- for (ptr_hotlist = weechat_hotlist; ptr_hotlist;
- ptr_hotlist = ptr_hotlist->next_hotlist)
- {
- rc = rc && (session_write_id (file, SESSION_OBJ_HOTLIST));
- rc = rc && (session_write_int (file, SESSION_HOTL_PRIORITY, ptr_hotlist->priority));
- rc = rc && (session_write_str (file, SESSION_HOTL_SERVER, (ptr_hotlist->server) ? ptr_hotlist->server->name : NULL));
- rc = rc && (session_write_int (file, SESSION_HOTL_BUFFER_NUMBER, ptr_hotlist->buffer->number));
- rc = rc && (session_write_buf (file, SESSION_HOTL_CREATION_TIME, &(ptr_hotlist->creation_time), sizeof (struct timeval)));
- rc = rc && (session_write_id (file, SESSION_HOTL_END));
-
- if (!rc)
- return 0;
- }
- return rc;
-}*/
-
-/*
- * session_save: save current session
- */
-
-/*int
-session_save (const char *filename)
-{
- FILE *file;
- int rc;
-
- if ((file = fopen (filename, "wb")) == NULL)
- return 0;
-
- rc = 1;
- rc = rc && (session_write_str (file, -1, SESSION_SIGNATURE));
- rc = rc && (session_save_servers (file));
- rc = rc && (session_save_dcc (file));
- rc = rc && (session_save_history (file, history_global_last));
- rc = rc && (session_save_buffers (file));
- rc = rc && (session_save_uptime (file));
- rc = rc && (session_save_hotlist (file));
-
- fclose (file);
-
- return rc;
-}*/
-
-/* ========================================================================== */
-
-/*
- * session_crash: stop WeeChat if problem during session loading
- */
-
-void
-session_crash (FILE *file, const char *message, ...)
-{
- char buf[4096];
- va_list argptr;
-
- va_start (argptr, message);
- vsnprintf (buf, sizeof (buf) - 1, message, argptr);
- va_end (argptr);
-
- fclose (file);
- gui_main_end (0);
- string_iconv_fprintf (stderr, "Error: %s\n", buf);
- string_iconv_fprintf (stderr,
- _("Last operation with session file was at position %ld, "
- "read of %d bytes\n"),
- session_last_read_pos,
- session_last_read_length);
- string_iconv_fprintf (stderr,
- _("Please send %s/%s, %s/%s and "
- "above messages to WeeChat developers for support.\n"
- "Be careful, private info may be in these files.\n"),
- weechat_home,
- WEECHAT_LOG_NAME,
- weechat_home,
- WEECHAT_SESSION_NAME);
- exit (EXIT_FAILURE);
+ return 1;
}
/*
- * session_read_int: read integer from file
+ * upgrade_weechat_save_uptime: save uptime info to upgrade file
*/
int
-session_read_int (FILE *file, int *value)
+upgrade_weechat_save_uptime (struct t_upgrade_file *upgrade_file)
{
- char type;
+ struct t_infolist *ptr_infolist;
+ struct t_infolist_item *ptr_item;
+ int rc;
- session_last_read_pos = ftell (file);
- session_last_read_length = sizeof (char);
+ ptr_infolist = infolist_new ();
+ if (!ptr_infolist)
+ return 0;
- if (fread ((void *)(&type), sizeof (char), 1, file) == 0)
+ ptr_item = infolist_new_item (ptr_infolist);
+ if (!ptr_item)
+ {
+ infolist_free (ptr_infolist);
return 0;
- if (type != SESSION_TYPE_INT)
+ }
+ if (!infolist_new_var_time (ptr_item, "start_time", weechat_start_time))
{
- session_crash (file, _("wrong type in file (expected: %d, read: %d)"),
- SESSION_TYPE_INT, type);
+ infolist_free (ptr_infolist);
return 0;
}
- session_last_read_pos = ftell (file);
- session_last_read_length = sizeof (int);
+ rc = upgrade_file_write_object (upgrade_file,
+ UPGRADE_WEECHAT_TYPE_UPTIME,
+ ptr_infolist);
+ infolist_free (ptr_infolist);
- if (value)
- return (fread ((void *)value, sizeof (int), 1, file) > 0);
- else
- return (fseek (file, sizeof (int), SEEK_CUR) >= 0);
+ return rc;
}
/*
- * session_read_str: read string from file
+ * upgrade_weechat_save_hotlist: save hotlist info to upgrade file
*/
int
-session_read_str (FILE *file, char **string)
+upgrade_weechat_save_hotlist (struct t_upgrade_file *upgrade_file)
{
- char type;
- int length;
-
- if (string && *string)
- free (*string);
-
- session_last_read_pos = ftell (file);
- session_last_read_length = sizeof (char);
-
- if (fread ((void *)(&type), sizeof (char), 1, file) == 0)
- return 0;
- if (type != SESSION_TYPE_STR)
- {
- session_crash (file, _("wrong type in file (expected: %d, read: %d)"),
- SESSION_TYPE_STR, type);
- return 0;
- }
-
- session_last_read_pos = ftell (file);
- session_last_read_length = sizeof (int);
-
- if (fread ((void *)(&length), sizeof (int), 1, file) == 0)
- return 0;
-
- if (length == 0)
- {
- if (string)
- (*string) = NULL;
- return 1;
- }
-
- session_last_read_pos = ftell (file);
- session_last_read_length = length;
+ struct t_infolist *ptr_infolist;
+ struct t_gui_hotlist *ptr_hotlist;
+ int rc;
- if (string)
+ for (ptr_hotlist = gui_hotlist; ptr_hotlist;
+ ptr_hotlist = ptr_hotlist->next_hotlist)
{
- (*string) = malloc (length + 1);
- if (!(*string))
+ ptr_infolist = infolist_new ();
+ if (!ptr_infolist)
return 0;
-
- if (fread ((void *)(*string), length, 1, file) == 0)
+ if (!gui_hotlist_add_to_infolist (ptr_infolist, ptr_hotlist))
{
- free (*string);
+ infolist_free (ptr_infolist);
return 0;
}
- (*string)[length] = '\0';
+ rc = upgrade_file_write_object (upgrade_file,
+ UPGRADE_WEECHAT_TYPE_HOTLIST,
+ ptr_infolist);
+ infolist_free (ptr_infolist);
+ if (!rc)
+ return 0;
}
- else
- return (fseek (file, length, SEEK_CUR) >= 0);
return 1;
}
/*
- * session_read_str_utf8: read string from file, then normalize UTF-8
+ * upgrade_weechat_save: save upgrade file
+ * return 1 if ok, 0 if error
*/
int
-session_read_str_utf8 (FILE *file, char **string)
+upgrade_weechat_save ()
{
int rc;
-
- rc = session_read_str (file, string);
- if (rc && *string)
- utf8_normalize (*string, '?');
-
- return rc;
-}
-
-/*
- * session_read_buf: read buffer from file
- */
-
-int
-session_read_buf (FILE *file, void *buffer, int length_expected)
-{
- char type;
- int length;
-
- session_last_read_pos = ftell (file);
- session_last_read_length = sizeof (char);
-
- if (fread ((void *)(&type), sizeof (char), 1, file) == 0)
- return 0;
- if (type != SESSION_TYPE_BUF)
- {
- session_crash (file, _("wrong type in file (expected: %d, read: %d)"),
- SESSION_TYPE_BUF, type);
- return 0;
- }
-
- session_last_read_pos = ftell (file);
- session_last_read_length = sizeof (int);
-
- if (fread ((void *)(&length), sizeof (int), 1, file) == 0)
- return 0;
- if ((length <= 0) || ((length_expected > 0) && (length != length_expected)))
- {
- session_crash (file, _("invalid length for a buffer"));
- return 0;
- }
+ struct t_upgrade_file *upgrade_file;
- session_last_read_pos = ftell (file);
- session_last_read_length = length;
-
- if (buffer)
- return (fread (buffer, length, 1, file) > 0);
- else
- return (fseek (file, length, SEEK_CUR) >= 0);
-}
-
-/*
- * session_read_buf_alloc: read buffer from file and allocate it in memory
- */
-
-int
-session_read_buf_alloc (FILE *file, void **buffer, int *buffer_length)
-{
- char type;
-
- session_last_read_pos = ftell (file);
- session_last_read_length = sizeof (char);
-
- if (fread ((void *)(&type), sizeof (char), 1, file) == 0)
- return 0;
- if (type != SESSION_TYPE_BUF)
- {
- session_crash (file, _("wrong type in file (expected: %d, read: %d)"),
- SESSION_TYPE_BUF, type);
- return 0;
- }
-
- session_last_read_pos = ftell (file);
- session_last_read_length = sizeof (int);
-
- if (fread ((void *)(buffer_length), sizeof (int), 1, file) == 0)
+ upgrade_file = upgrade_file_create (WEECHAT_UPGRADE_FILENAME, 1);
+ if (!upgrade_file)
return 0;
- if (*buffer_length <= 0)
- {
- session_crash (file, _("invalid length for a buffer"));
- return 0;
- }
-
- *buffer = malloc (*buffer_length);
-
- session_last_read_pos = ftell (file);
- session_last_read_length = *buffer_length;
-
- return (fread (*buffer, *buffer_length, 1, file) > 0);
-}
-
-/*
- * session_read_object: read an object in file
- */
-int
-session_read_object (FILE *file, int object_id, int type, void *target, int max_buf_length)
-{
- int object_id_read;
- char type_read;
-
- if (fread ((void *)(&object_id_read), sizeof (int), 1, file) == 0)
- {
- session_crash (file, _("object read error"));
- return 0;
- }
- if (object_id_read != object_id)
- {
- session_crash (file, _("wrong object (expected: %d, read: %d)"),
- object_id, object_id_read);
- return 0;
- }
+ rc = 1;
+ rc &= upgrade_weechat_save_history (upgrade_file, last_history_global);
+ rc &= upgrade_weechat_save_buffers (upgrade_file);
+ rc &= upgrade_weechat_save_uptime (upgrade_file);
+ rc &= upgrade_weechat_save_hotlist (upgrade_file);
- session_last_read_pos = ftell (file);
- session_last_read_length = sizeof (char);
+ upgrade_file_close (upgrade_file);
- if (fread ((void *)(&type_read), sizeof (char), 1, file) == 0)
- {
- session_crash (file, _("type read error"));
- return 0;
- }
- if (type_read != type)
- {
- session_crash (file, _("wrong type (expected: %d, read: %d)"),
- type, type_read);
- return 0;
- }
- if (fseek (file, sizeof (char) * (-1), SEEK_CUR) < 0)
- return 0;
- switch (type)
- {
- case SESSION_TYPE_INT:
- return session_read_int (file, (int *)target);
- case SESSION_TYPE_STR:
- return session_read_str (file, (char **)target);
- case SESSION_TYPE_BUF:
- return session_read_buf (file, target, max_buf_length);
- }
- return 0;
-}
-
-/*
- * session_read_ignore_value: ignore a value from file
- */
-
-int
-session_read_ignore_value (FILE *file)
-{
- char type;
-
- if (fread ((void *)(&type), sizeof (char), 1, file) == 0)
- return 0;
- if (fseek (file, sizeof (char) * (-1), SEEK_CUR) < 0)
- return 0;
- switch (type)
- {
- case SESSION_TYPE_INT:
- return session_read_int (file, NULL);
- case SESSION_TYPE_STR:
- return session_read_str (file, NULL);
- case SESSION_TYPE_BUF:
- return session_read_buf (file, NULL, 0);
- }
- return 0;
+ return rc;
}
/*
- * session_read_ignore_object: ignore an object from file
+ * upgrade_weechat_read_cb: callback for reading upgrade file
*/
int
-session_read_ignore_object (FILE *file)
+upgrade_weechat_read_cb (int object_id,
+ struct t_infolist *infolist)
{
- int object_id;
-
- while (1)
- {
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- return 0;
- if (feof (file))
- return 0;
- if (object_id == SESSION_OBJ_END)
- return 1;
- if (!session_read_ignore_value (file))
- return 0;
- }
-}
-
-/*
- * session_load_server: load server from file
- */
-
-/*int
-session_load_server (FILE *file)
-{
- int object_id, rc;
- char *server_name;
-#ifdef HAVE_GNUTLS
- void *session_data;
- size_t session_size;
- int session_size_int;
-#endif
-
- // read server name
- server_name = NULL;
- if (!session_read_object (file, SESSION_SERV_NAME, SESSION_TYPE_STR, &server_name, 0))
- {
- session_crash (file, _("server name not found"));
- return 0;
- }
-
- // use or allocate server
- log_printf (_("session: loading server \"%s\""),
- server_name);
- session_current_server = irc_server_search (server_name);
- if (session_current_server)
- log_printf (_("server found, updating values"));
- else
- {
- log_printf (_("server not found, creating new one"));
- session_current_server = irc_server_alloc ();
- if (!session_current_server)
- {
- free (server_name);
- session_crash (file, _("can't create new server"));
- return 0;
- }
- irc_server_init (session_current_server);
- session_current_server->name = strdup (server_name);
- }
- free (server_name);
+ char *type, *name, *prefix, *group_name;
+ struct t_gui_nick_group *ptr_group;
+ struct t_gui_buffer *ptr_buffer;
+ struct timeval creation_time;
+ void *buf;
+ int size;
- // read server values
- rc = 1;
- while (rc)
+ infolist_reset_item_cursor (infolist);
+ while (infolist_next (infolist))
{
- if (feof (file))
- {
- session_crash (file, _("unexpected end of file (reading server)"));
- return 0;
- }
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- return 0;
switch (object_id)
{
- case SESSION_SERV_END:
- return 1;
- case SESSION_SERV_AUTOCONNECT:
- rc = rc && (session_read_int (file, &(session_current_server->autoconnect)));
- break;
- case SESSION_SERV_AUTORECONNECT:
- rc = rc && (session_read_int (file, &(session_current_server->autoreconnect)));
- break;
- case SESSION_SERV_AUTORECONNECT_DELAY:
- rc = rc && (session_read_int (file, &(session_current_server->autoreconnect_delay)));
- break;
- case SESSION_SERV_TEMP_SERVER:
- rc = rc && (session_read_int (file, &(session_current_server->temp_server)));
- break;
- case SESSION_SERV_ADDRESS:
- rc = rc && (session_read_str (file, &(session_current_server->address)));
- break;
- case SESSION_SERV_PORT:
- rc = rc && (session_read_int (file, &(session_current_server->port)));
- break;
- case SESSION_SERV_IPV6:
- rc = rc && (session_read_int (file, &(session_current_server->ipv6)));
- break;
- case SESSION_SERV_SSL:
- rc = rc && (session_read_int (file, &(session_current_server->ssl)));
- break;
- case SESSION_SERV_PASSWORD:
- rc = rc && (session_read_str (file, &(session_current_server->password)));
- break;
- case SESSION_SERV_NICK1:
- rc = rc && (session_read_str (file, &(session_current_server->nick1)));
- break;
- case SESSION_SERV_NICK2:
- rc = rc && (session_read_str (file, &(session_current_server->nick2)));
- break;
- case SESSION_SERV_NICK3:
- rc = rc && (session_read_str (file, &(session_current_server->nick3)));
- break;
- case SESSION_SERV_USERNAME:
- rc = rc && (session_read_str (file, &(session_current_server->username)));
- break;
- case SESSION_SERV_REALNAME:
- rc = rc && (session_read_str (file, &(session_current_server->realname)));
- break;
- case SESSION_SERV_HOSTNAME:
- rc = rc && (session_read_str (file, &(session_current_server->hostname)));
- break;
- case SESSION_SERV_COMMAND:
- rc = rc && (session_read_str (file, &(session_current_server->command)));
- break;
- case SESSION_SERV_COMMAND_DELAY:
- rc = rc && (session_read_int (file, &(session_current_server->command_delay)));
- break;
- case SESSION_SERV_AUTOJOIN:
- rc = rc && (session_read_str (file, &(session_current_server->autojoin)));
- break;
- case SESSION_SERV_AUTOREJOIN:
- rc = rc && (session_read_int (file, &(session_current_server->autorejoin)));
- break;
- case SESSION_SERV_NOTIFY_LEVELS:
- rc = rc && (session_read_str (file, &(session_current_server->notify_levels)));
- break;
- case SESSION_SERV_CHILD_PID:
- rc = rc && (session_read_int (file, &(session_current_server->child_pid)));
- break;
- case SESSION_SERV_CHILD_READ:
- rc = rc && (session_read_int (file, &(session_current_server->child_read)));
- break;
- case SESSION_SERV_CHILD_WRITE:
- rc = rc && (session_read_int (file, &(session_current_server->child_write)));
- break;
- case SESSION_SERV_SOCK:
- rc = rc && (session_read_int (file, &(session_current_server->sock)));
- break;
- case SESSION_SERV_IS_CONNECTED:
- rc = rc && (session_read_int (file, &(session_current_server->is_connected)));
- break;
- case SESSION_SERV_SSL_CONNECTED:
- rc = rc && (session_read_int (file, &(session_current_server->ssl_connected)));
- break;
-#ifdef HAVE_GNUTLS
- case SESSION_SERV_GNUTLS_SESS:
- if (gnutls_init (&(session_current_server->gnutls_sess), GNUTLS_CLIENT) != 0)
+ case UPGRADE_WEECHAT_TYPE_HISTORY:
+ if (upgrade_current_buffer)
+ {
+ gui_history_buffer_add (upgrade_current_buffer,
+ infolist_string (infolist, "text"));
+ }
+ else
{
- session_crash (file, _("gnutls init error"));
- return 0;
+ gui_history_global_add (infolist_string (infolist, "text"));
}
- gnutls_set_default_priority (session_current_server->gnutls_sess);
- gnutls_certificate_type_set_priority (session_current_server->gnutls_sess, gnutls_cert_type_prio);
- gnutls_protocol_set_priority (session_current_server->gnutls_sess, gnutls_prot_prio);
- gnutls_credentials_set (session_current_server->gnutls_sess, GNUTLS_CRD_CERTIFICATE, gnutls_xcred);
- session_data = NULL;
- rc = rc && (session_read_buf_alloc (file, &session_data, &session_size_int));
- if (rc)
+ break;
+ case UPGRADE_WEECHAT_TYPE_BUFFER:
+ /* create buffer if it was created by a plugin (ie not weechat
+ main buffer) */
+ if (infolist_string (infolist, "plugin_name"))
{
- session_size = session_size_int;
- gnutls_session_set_data (session_current_server->gnutls_sess, session_data, session_size);
- free (session_data);
- gnutls_transport_set_ptr (session_current_server->gnutls_sess,
- (gnutls_transport_ptr) ((unsigned long) session_current_server->sock));
- if (gnutls_handshake (session_current_server->gnutls_sess) < 0)
+ upgrade_current_buffer = gui_buffer_new (
+ NULL,
+ infolist_string (infolist, "category"),
+ infolist_string (infolist, "name"),
+ NULL, NULL,
+ NULL, NULL);
+ if (upgrade_current_buffer)
{
- session_crash (file, _("gnutls handshake failed"));
- return 0;
+ if (infolist_integer (infolist, "current_buffer"))
+ upgrade_set_current_buffer = upgrade_current_buffer;
+ upgrade_current_buffer->plugin_name_for_upgrade =
+ strdup (infolist_string (infolist, "plugin_name"));
+ upgrade_current_buffer->nicklist_case_sensitive =
+ infolist_integer (infolist, "nicklist_case_sensitive");
+ upgrade_current_buffer->nicklist_display_groups =
+ infolist_integer (infolist, "nicklist_display_groups");
}
}
+ else
+ upgrade_current_buffer = gui_buffers;
break;
-#endif
- case SESSION_SERV_UNTERMINATED_MESSAGE:
- rc = rc && (session_read_str (file, &(session_current_server->unterminated_message)));
- break;
- case SESSION_SERV_NICK:
- rc = rc && (session_read_str (file, &(session_current_server->nick)));
- break;
- case SESSION_SERV_NICK_MODES:
- rc = rc && (session_read_str (file, &(session_current_server->nick_modes)));
- break;
- case SESSION_SERV_PREFIX:
- rc = rc && (session_read_str (file, &(session_current_server->prefix)));
- break;
- case SESSION_SERV_RECONNECT_START:
- rc = rc && (session_read_buf (file, &(session_current_server->reconnect_start), sizeof (time_t)));
- break;
- case SESSION_SERV_COMMAND_TIME:
- rc = rc && (session_read_buf (file, &(session_current_server->command_time), sizeof (time_t)));
- break;
- case SESSION_SERV_RECONNECT_JOIN:
- rc = rc && (session_read_int (file, &(session_current_server->reconnect_join)));
- break;
- case SESSION_SERV_IS_AWAY:
- rc = rc && (session_read_int (file, &(session_current_server->is_away)));
- break;
- case SESSION_SERV_AWAY_MESSAGE:
- rc = rc && (session_read_str (file, &(session_current_server->away_message)));
- break;
- case SESSION_SERV_AWAY_TIME:
- rc = rc && (session_read_buf (file, &(session_current_server->away_time), sizeof (time_t)));
- break;
- case SESSION_SERV_LAG:
- rc = rc && (session_read_int (file, &(session_current_server->lag)));
- break;
- case SESSION_SERV_LAG_CHECK_TIME:
- rc = rc && (session_read_buf (file, &(session_current_server->lag_check_time), sizeof (struct timeval)));
- break;
- case SESSION_SERV_LAG_NEXT_CHECK:
- rc = rc && (session_read_buf (file, &(session_current_server->lag_next_check), sizeof (time_t)));
- break;
- case SESSION_SERV_CHARSET_DECODE_ISO__UNUSED:
- rc = rc && (session_read_ignore_value (file));
- break;
- case SESSION_SERV_CHARSET_DECODE_UTF__UNUSED:
- rc = rc && (session_read_ignore_value (file));
- break;
- case SESSION_SERV_CHARSET_ENCODE__UNUSED:
- rc = rc && (session_read_ignore_value (file));
- break;
- default:
- log_printf (_("session: warning: ignoring value from "
- "server (object id: %d)"),
- object_id);
- rc = rc && (session_read_ignore_value (file));
- break;
- }
- }
- return 0;
-}*/
-
-/*
- * session_load_channel: load channel from file
- */
-
-/*int
-session_load_channel (FILE *file)
-{
- int object_id, rc, channel_type;
- char *channel_name;
-
- // check if server is allocated for this channel
- if (!session_current_server)
- {
- session_crash (file, _("channel found without server"));
- return 0;
- }
-
- // read channel type
- if (!session_read_object (file, SESSION_CHAN_TYPE, SESSION_TYPE_INT, &channel_type, 0))
- {
- session_crash (file, _("channel type not found"));
- return 0;
- }
-
- // read channel name
- channel_name = NULL;
- if (!session_read_object (file, SESSION_CHAN_NAME, SESSION_TYPE_STR, &channel_name, 0))
- {
- session_crash (file, _("channel name not found"));
- return 0;
- }
-
- // allocate channel
- log_printf (_("session: loading channel \"%s\""),
- channel_name);
- session_current_channel = irc_channel_new (session_current_server,
- channel_type,
- channel_name);
- free (channel_name);
- if (!session_current_channel)
- {
- session_crash (file, _("can't create new channel"));
- return 0;
- }
-
- // read channel values
- rc = 1;
- while (rc)
- {
- if (feof (file))
- {
- session_crash (file, _("unexpected end of file (reading channel)"));
- return 0;
- }
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- return 0;
- switch (object_id)
- {
- case SESSION_CHAN_END:
- return 1;
- case SESSION_CHAN_TOPIC:
- rc = rc && (session_read_str_utf8 (file, &(session_current_channel->topic)));
- break;
- case SESSION_CHAN_MODES:
- rc = rc && (session_read_str (file, (char **)(&(session_current_channel->modes))));
- break;
- case SESSION_CHAN_LIMIT:
- rc = rc && (session_read_int (file, &(session_current_channel->limit)));
- break;
- case SESSION_CHAN_KEY:
- rc = rc && (session_read_str (file, &(session_current_channel->key)));
- break;
- case SESSION_CHAN_NICKS_COUNT:
- rc = rc && (session_read_int (file, &(session_current_channel->nicks_count)));
- // will be incremented when adding nicks
- session_current_channel->nicks_count = 0;
- break;
- case SESSION_CHAN_CHECKING_AWAY:
- rc = rc && (session_read_int (file, &(session_current_channel->checking_away)));
- break;
- case SESSION_CHAN_AWAY_MESSAGE:
- rc = rc && (session_read_str (file, &(session_current_channel->away_message)));
- break;
- case SESSION_CHAN_CYCLE:
- rc = rc && (session_read_int (file, &(session_current_channel->cycle)));
- break;
- case SESSION_CHAN_CLOSE:
- rc = rc && (session_read_int (file, &(session_current_channel->close)));
- break;
- case SESSION_CHAN_DISPLAY_CREATION_DATE:
- rc = rc && (session_read_int (file, &(session_current_channel->display_creation_date)));
- break;
- default:
- log_printf (_("session: warning: ignoring value from "
- "channel (object id: %d)"),
- object_id);
- rc = rc && (session_read_ignore_value (file));
- break;
- }
- }
- return 0;
-}*/
-
-/*
- * session_load_nick: load nick from file
- */
-
-/*int
-session_load_nick (FILE *file)
-{
- int rc, object_id;
- char *nick_name;
- t_irc_nick *nick;
-
- // check if channel is allocated for this nick
- if (!session_current_channel)
- {
- session_crash (file, _("nick found without channel"));
- return 0;
- }
-
- // read nick name
- nick_name = NULL;
- if (!session_read_object (file, SESSION_NICK_NICK, SESSION_TYPE_STR, &nick_name, 0))
- {
- session_crash (file, _("nick name not found"));
- return 0;
- }
-
- // allocate nick
- nick = irc_nick_new (session_current_server, session_current_channel,
- nick_name, 0, 0, 0, 0, 0, 0, 0);
- free (nick_name);
- if (!nick)
- {
- session_crash (file, _("can't create new nick"));
- return 0;
- }
-
- // read nick values
- rc = 1;
- while (rc)
- {
- if (feof (file))
- {
- session_crash (file, _("unexpected end of file (reading nick)"));
- return 0;
- }
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- return 0;
- switch (object_id)
- {
- case SESSION_NICK_END:
- return 1;
- case SESSION_NICK_FLAGS:
- rc = rc && (session_read_int (file, &(nick->flags)));
- break;
- case SESSION_NICK_COLOR:
- rc = rc && (session_read_int (file, &(nick->color)));
- break;
- case SESSION_NICK_HOST:
- rc = rc && (session_read_str (file, &(nick->host)));
- break;
- default:
- log_printf (_("session: warning: ignoring value from "
- "nick (object id: %d)"),
- object_id);
- rc = rc && (session_read_ignore_value (file));
+ case UPGRADE_WEECHAT_TYPE_BUFFER_LINE:
+ /* add line to current buffer */
+ if (upgrade_current_buffer)
+ {
+ gui_chat_line_add (
+ upgrade_current_buffer,
+ infolist_time (infolist, "date"),
+ infolist_time (infolist, "date_printed"),
+ infolist_string (infolist, "tags"),
+ infolist_string (infolist, "prefix"),
+ infolist_string (infolist, "message"));
+ }
break;
- }
- }
- return 0;
-}*/
-
-/*
- * session_load_dcc: load DCC from file
- */
-
-/*int
-session_load_dcc (FILE *file)
-{
- int object_id, rc;
- t_irc_dcc *dcc;
- char *string;
- t_irc_server *ptr_server;
- t_irc_channel *ptr_channel;
-
- // allocate DCC
- dcc = irc_dcc_alloc ();
- if (!dcc)
- {
- session_crash (file, _("can't create new DCC"));
- return 0;
- }
-
- log_printf (_("session: loading DCC"));
-
- // read DCC values
- ptr_server = NULL;
- ptr_channel = NULL;
- rc = 1;
- while (rc)
- {
- if (feof (file))
- {
- session_crash (file, _("unexpected end of file (reading DCC)"));
- return 0;
- }
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- return 0;
- switch (object_id)
- {
- case SESSION_DCC_END:
- return 1;
- case SESSION_DCC_SERVER:
- string = NULL;
- rc = rc && (session_read_str (file, &string));
- if (!rc)
- return 0;
- if (string && string[0])
+ case UPGRADE_WEECHAT_TYPE_NICKLIST:
+ if (upgrade_current_buffer)
{
- ptr_server = irc_server_search (string);
- if (!ptr_server)
+ upgrade_current_buffer->nicklist = 1;
+ ptr_group = NULL;
+ type = infolist_string (infolist, "type");
+ if (type)
{
- session_crash (file, _("server not found for DCC"));
- return 0;
+ if (strcmp (type, "group") == 0)
+ {
+ name = infolist_string (infolist, "name");
+ if (name && (strcmp (name, "root") != 0))
+ {
+ group_name = infolist_string (infolist, "parent_name");
+ if (group_name)
+ ptr_group = gui_nicklist_search_group (upgrade_current_buffer,
+ NULL,
+ group_name);
+ ptr_group = gui_nicklist_add_group (
+ upgrade_current_buffer,
+ ptr_group,
+ name,
+ infolist_string (infolist, "color"),
+ infolist_integer (infolist, "visible"));
+ }
+ }
+ else if (strcmp (type, "nick") == 0)
+ {
+ group_name = infolist_string (infolist, "group_name");
+ if (group_name)
+ ptr_group = gui_nicklist_search_group (upgrade_current_buffer,
+ NULL,
+ group_name);
+ prefix = infolist_string (infolist, "prefix");
+ gui_nicklist_add_nick (
+ upgrade_current_buffer,
+ ptr_group,
+ infolist_string (infolist, "name"),
+ infolist_string (infolist, "color"),
+ (prefix) ? prefix[0] : ' ',
+ infolist_string (infolist, "prefix_color"),
+ infolist_integer (infolist, "visible"));
+ }
}
- dcc->server = ptr_server;
}
break;
- case SESSION_DCC_CHANNEL:
- if (!ptr_server)
+ case UPGRADE_WEECHAT_TYPE_UPTIME:
+ weechat_start_time = infolist_time (infolist, "start_time");
+ break;
+ case UPGRADE_WEECHAT_TYPE_HOTLIST:
+ if (!hotlist_reset)
{
- session_crash (file, _("DCC with channel but without server"));
- return 0;
+ gui_hotlist_free_all (&gui_hotlist, &last_gui_hotlist);
+ hotlist_reset = 1;
}
- string = NULL;
- rc = rc && (session_read_str (file, &string));
- if (!rc)
- return 0;
- if (string && string[0])
+ ptr_buffer = gui_buffer_search_by_number (infolist_integer (infolist, "buffer_number"));
+ if (ptr_buffer)
{
- ptr_channel = irc_channel_search_any (ptr_server, string);
- if (!ptr_channel)
+ buf = infolist_buffer (infolist, "creation_time", &size);
+ if (buf)
{
- session_crash (file, _("channel not found for DCC"));
- return 0;
+ memcpy (&creation_time, buf, size);
+ gui_hotlist_add (ptr_buffer,
+ infolist_integer (infolist, "priority"),
+ &creation_time,
+ 1);
}
- dcc->channel = ptr_channel;
- ptr_channel->dcc_chat = dcc;
}
break;
- case SESSION_DCC_TYPE:
- rc = rc && (session_read_int (file, &(dcc->type)));
- break;
- case SESSION_DCC_STATUS:
- rc = rc && (session_read_int (file, &(dcc->status)));
- break;
- case SESSION_DCC_START_TIME:
- rc = rc && (session_read_buf (file, &(dcc->start_time), sizeof (time_t)));
- break;
- case SESSION_DCC_START_TRANSFER:
- rc = rc && (session_read_buf (file, &(dcc->start_transfer), sizeof (time_t)));
- break;
- case SESSION_DCC_ADDR:
- rc = rc && (session_read_buf (file, &(dcc->addr), sizeof (unsigned long)));
- break;
- case SESSION_DCC_PORT:
- rc = rc && (session_read_int (file, &(dcc->port)));
- break;
- case SESSION_DCC_NICK:
- rc = rc && (session_read_str (file, &(dcc->nick)));
- break;
- case SESSION_DCC_SOCK:
- rc = rc && (session_read_int (file, &(dcc->sock)));
- break;
- case SESSION_DCC_UNTERMINATED_MESSAGE:
- rc = rc && (session_read_str (file, &(dcc->unterminated_message)));
- break;
- case SESSION_DCC_FILE:
- rc = rc && (session_read_int (file, &(dcc->file)));
- break;
- case SESSION_DCC_FILENAME:
- rc = rc && (session_read_str (file, &(dcc->filename)));
- break;
- case SESSION_DCC_LOCAL_FILENAME:
- rc = rc && (session_read_str (file, &(dcc->local_filename)));
- break;
- case SESSION_DCC_FILENAME_SUFFIX:
- rc = rc && (session_read_int (file, &(dcc->filename_suffix)));
- break;
- case SESSION_DCC_SIZE:
- rc = rc && (session_read_buf (file, &(dcc->size), sizeof (unsigned long)));
- break;
- case SESSION_DCC_POS:
- rc = rc && (session_read_buf (file, &(dcc->pos), sizeof (unsigned long)));
- break;
- case SESSION_DCC_ACK:
- rc = rc && (session_read_buf (file, &(dcc->ack), sizeof (unsigned long)));
- break;
- case SESSION_DCC_START_RESUME:
- rc = rc && (session_read_buf (file, &(dcc->start_resume), sizeof (unsigned long)));
- break;
- case SESSION_DCC_LAST_CHECK_TIME:
- rc = rc && (session_read_buf (file, &(dcc->last_check_time), sizeof (time_t)));
- break;
- case SESSION_DCC_LAST_CHECK_POS:
- rc = rc && (session_read_buf (file, &(dcc->last_check_pos), sizeof (unsigned long)));
- break;
- case SESSION_DCC_LAST_ACTIVITY:
- rc = rc && (session_read_buf (file, &(dcc->last_activity), sizeof (time_t)));
- break;
- case SESSION_DCC_BYTES_PER_SEC:
- rc = rc && (session_read_buf (file, &(dcc->bytes_per_sec), sizeof (unsigned long)));
- break;
- case SESSION_DCC_ETA:
- rc = rc && (session_read_buf (file, &(dcc->eta), sizeof (unsigned long)));
- break;
- case SESSION_DCC_CHILD_PID:
- rc = rc && (session_read_int (file, &(dcc->child_pid)));
- break;
- case SESSION_DCC_CHILD_READ:
- rc = rc && (session_read_int (file, &(dcc->child_read)));
- break;
- case SESSION_DCC_CHILD_WRITE:
- rc = rc && (session_read_int (file, &(dcc->child_write)));
- break;
- default:
- log_printf (_("session: warning: ignoring value from "
- "DCC (object id: %d)"),
- object_id);
- rc = rc && (session_read_ignore_value (file));
- break;
- }
- }
- return 0;
-}*/
-
-/*
- * session_load_history: load history from file (global or for a buffer)
- */
-
-/*int
-session_load_history (FILE *file)
-{
- int object_id, rc;
- char *text;
-
- if (session_current_buffer)
- log_printf (_("session: loading buffer history"));
- else
- log_printf (_("session: loading global history"));
-
- // read history values
- rc = 1;
- while (rc)
- {
- if (feof (file))
- {
- session_crash (file, _("unexpected end of file (reading history)"));
- return 0;
- }
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- return 0;
- switch (object_id)
- {
- case SESSION_HIST_END:
- return 1;
- case SESSION_HIST_TEXT:
- text = NULL;
- if (!session_read_str_utf8 (file, &text))
- return 0;
- if (session_current_buffer)
- gui_history_buffer_add (session_current_buffer, text);
- else
- gui_history_global_add (text);
- free (text);
- break;
- default:
- log_printf (_("session: warning: ignoring value from "
- "history (object id: %d)"),
- object_id);
- rc = rc && (session_read_ignore_value (file));
- break;
- }
- }
- return 0;
-}*/
-
-/*
- * session_load_buffer: load buffer from file
- */
-
-/*int
-session_load_buffer (FILE *file)
-{
- int object_id, rc;
- char *server_name, *channel_name;
- int buffer_type;
- t_irc_server *ptr_server;
- t_irc_channel *ptr_channel;
-
- // read server name
- server_name = NULL;
- if (!session_read_object (file, SESSION_BUFF_SERVER, SESSION_TYPE_STR, &server_name, 0))
- {
- session_crash (file, _("server name not found for buffer"));
- return 0;
- }
-
- // read channel name
- channel_name = NULL;
- if (!session_read_object (file, SESSION_BUFF_CHANNEL, SESSION_TYPE_STR, &channel_name, 0))
- {
- session_crash (file, _("channel name not found for buffer"));
- return 0;
- }
-
- // read buffer type
- if (!session_read_object (file, SESSION_BUFF_TYPE, SESSION_TYPE_INT, &buffer_type, 0))
- {
- session_crash (file, _("buffer type not found"));
- return 0;
- }
-
- // allocate buffer
- log_printf (_("session: loading buffer (server: %s, channel: %s, type: %d)"),
- (server_name) ? server_name : "-",
- (channel_name) ? channel_name : "-",
- buffer_type);
- ptr_server = NULL;
- ptr_channel = NULL;
- if (server_name)
- {
- ptr_server = irc_server_search (server_name);
- if (!ptr_server)
- {
- session_crash (file, _("server not found for buffer"));
- return 0;
- }
- }
-
- if (channel_name)
- {
- ptr_channel = irc_channel_search_any_without_buffer (ptr_server, channel_name);
- if (!ptr_channel)
- {
- session_crash (file, _("channel not found for buffer"));
- return 0;
- }
- }
-
- session_current_buffer = gui_buffer_new (gui_windows, weechat_protocols,
- ptr_server,
- ptr_channel, buffer_type, 1);
- if (!session_current_buffer)
- {
- session_crash (file, _("can't create new buffer"));
- return 0;
- }
-
- free (server_name);
- free (channel_name);
-
- // read buffer values
- rc = 1;
- while (rc)
- {
- if (feof (file))
- {
- session_crash (file, _("unexpected end of file (reading buffer)"));
- return 0;
- }
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- return 0;
- switch (object_id)
- {
- case SESSION_BUFF_END:
- return 1;
- case SESSION_BUFF_ALL_SERVERS:
- rc = rc && (session_read_int (file, &(session_current_buffer->all_servers)));
- break;
- default:
- log_printf (_("session: warning: ignoring value from "
- "buffer (object id: %d)"),
- object_id);
- rc = rc && (session_read_ignore_value (file));
- break;
}
}
- return 0;
-}*/
-
-/*
- * session_load_line: load buffer line from file
- */
-
-/*int
-session_load_line (FILE *file)
-{
- int object_id, rc;
- t_gui_line *line;
- // check if buffer is allocated for this line
- if (!session_current_buffer)
- {
- session_crash (file, _("line found without buffer"));
- return 0;
- }
-
- // allocate line
- line = gui_buffer_line_new (session_current_buffer, time (NULL));
- if (!line)
- {
- session_crash (file, _("can't create new line"));
- return 0;
- }
-
- // read line values
- rc = 1;
- while (rc)
- {
- if (feof (file))
- {
- session_crash (file, _("unexpected end of file (reading line)"));
- return 0;
- }
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- return 0;
- switch (object_id)
- {
- case SESSION_LINE_END:
- return 1;
- case SESSION_LINE_LENGTH:
- rc = rc && (session_read_int (file, &(line->length)));
- break;
- case SESSION_LINE_LENGTH_ALIGN:
- rc = rc && (session_read_int (file, &(line->length_align)));
- break;
- case SESSION_LINE_LOG_WRITE:
- rc = rc && (session_read_int (file, &(line->log_write)));
- break;
- case SESSION_LINE_WITH_MESSAGE:
- rc = rc && (session_read_int (file, &(line->line_with_message)));
- break;
- case SESSION_LINE_WITH_HIGHLIGHT:
- rc = rc && (session_read_int (file, &(line->line_with_highlight)));
- break;
- case SESSION_LINE_DATA:
- rc = rc && (session_read_str_utf8 (file, &(line->data)));
- break;
- case SESSION_LINE_OFS_AFTER_DATE:
- rc = rc && (session_read_int (file, &(line->ofs_after_date)));
- break;
- case SESSION_LINE_OFS_START_MESSAGE:
- rc = rc && (session_read_int (file, &(line->ofs_start_message)));
- break;
- case SESSION_LINE_NICK:
- rc = rc && (session_read_str (file, &(line->nick)));
- break;
- case SESSION_LINE_DATE:
- rc = rc && (session_read_buf (file, &(line->date), sizeof (time_t)));
- break;
- default:
- log_printf (_("session: warning: ignoring value from "
- "line (object id: %d)"),
- object_id);
- rc = rc && (session_read_ignore_value (file));
- break;
- }
- }
- return 0;
-}*/
-
-/*
- * session_load_uptime: load uptime from file
- */
-
-/*int
-session_load_uptime (FILE *file)
-{
- int object_id, rc;
-
- // read uptime values
- rc = 1;
- while (rc)
- {
- if (feof (file))
- {
- session_crash (file, _("unexpected end of file (reading uptime)"));
- return 0;
- }
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- return 0;
- switch (object_id)
- {
- case SESSION_UPT_END:
- return 1;
- case SESSION_UPT_START_TIME:
- rc = rc && (session_read_buf (file, &weechat_start_time, sizeof (time_t)));
- break;
- default:
- log_printf (_("session: warning: ignoring value from "
- "uptime (object id: %d)"),
- object_id);
- rc = rc && (session_read_ignore_value (file));
- break;
- }
- }
- return 0;
-}*/
+ return WEECHAT_RC_OK;
+}
/*
- * session_load_hotlist: load hotlist from file
+ * upgrade_weechat_load: load upgrade file
+ * return 1 if ok, 0 if error
*/
-/*int
-session_load_hotlist (FILE *file)
+int
+upgrade_weechat_load ()
{
- int object_id, rc;
- int priority;
- struct timeval creation_time;
- char *server_name;
- t_irc_server *ptr_server;
- int buffer_number;
- t_gui_buffer *ptr_buffer;
-
- priority = 0;
- creation_time.tv_sec = 0;
- creation_time.tv_usec = 0;
- ptr_server = NULL;
- ptr_buffer = NULL;
+ int rc;
+ struct t_upgrade_file *upgrade_file;
- // read hotlist values
- rc = 1;
- while (rc)
- {
- if (feof (file))
- {
- session_crash (file, _("unexpected end of file (reading hotlist)"));
- return 0;
- }
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- return 0;
- switch (object_id)
- {
- case SESSION_HOTL_END:
- hotlist_add (priority, &creation_time, ptr_server, ptr_buffer, 1);
- return 1;
- case SESSION_HOTL_PRIORITY:
- rc = rc && (session_read_int (file, &priority));
- break;
- case SESSION_HOTL_SERVER:
- server_name = NULL;
- if (!session_read_str (file, &server_name))
- return 0;
- ptr_server = irc_server_search (server_name);
- free (server_name);
- break;
- case SESSION_HOTL_BUFFER_NUMBER:
- rc = rc && (session_read_int (file, &buffer_number));
- ptr_buffer = gui_buffer_search_by_number (buffer_number);
- break;
- case SESSION_HOTL_CREATION_TIME:
- rc = rc && (session_read_buf (file, &creation_time, sizeof (struct timeval)));
- break;
- default:
- log_printf (_("session: warning: ignoring value from "
- "history (object id: %d)"),
- object_id);
- rc = rc && (session_read_ignore_value (file));
- break;
- }
- }
- return 0;
-}*/
+ upgrade_file = upgrade_file_create (WEECHAT_UPGRADE_FILENAME, 0);
+ rc = upgrade_file_read (upgrade_file, &upgrade_weechat_read_cb);
-/*
- * session_load: load session from file
- */
-
-/*int
-session_load (const char *filename)
-{
- FILE *file;
- char *signature;
- int object_id;
- t_irc_server *ptr_server;
-
- session_current_server = NULL;
- session_current_channel = NULL;
- session_current_buffer = NULL;
-
- session_last_read_pos = -1;
- session_last_read_length = -1;
-
- if ((file = fopen (filename, "rb")) == NULL)
- {
- session_crash (file, _("session file not found"));
- return 0;
- }
-
- signature = NULL;
- if (!session_read_str (file, &signature))
- {
- session_crash (file, _("signature not found"));
- return 0;
- }
- if (!signature || (strcmp (signature, SESSION_SIGNATURE) != 0))
- {
- session_crash (file, _("bad session signature"));
- return 0;
- }
- free (signature);
+ if (upgrade_set_current_buffer)
+ gui_window_switch_to_buffer (gui_current_window,
+ upgrade_set_current_buffer);
- while (!feof (file))
- {
- if (fread ((void *)(&object_id), sizeof (int), 1, file) == 0)
- {
- if (feof (file))
- break;
- session_crash (file, _("object id not found"));
- return 0;
- }
- switch (object_id)
- {
- case SESSION_OBJ_SERVER:
- if (!session_load_server (file))
- {
- session_crash (file, _("failed to load server"));
- return 0;
- }
- break;
- case SESSION_OBJ_CHANNEL:
- if (!session_load_channel (file))
- {
- session_crash (file, _("failed to load channel"));
- return 0;
- }
- break;
- case SESSION_OBJ_NICK:
- if (!session_load_nick (file))
- {
- session_crash (file, _("failed to load nick"));
- return 0;
- }
- break;
- case SESSION_OBJ_DCC:
- if (!session_load_dcc (file))
- {
- session_crash (file, _("failed to load DCC"));
- return 0;
- }
- break;
- case SESSION_OBJ_HISTORY:
- if (!session_load_history (file))
- {
- session_crash (file, _("failed to load history"));
- return 0;
- }
- break;
- case SESSION_OBJ_BUFFER:
- if (!session_load_buffer (file))
- {
- session_crash (file, _("failed to load buffer"));
- return 0;
- }
- break;
- case SESSION_OBJ_LINE:
- if (!session_load_line (file))
- {
- session_crash (file, _("failed to load line"));
- return 0;
- }
- break;
- case SESSION_OBJ_UPTIME:
- if (!session_load_uptime (file))
- {
- session_crash (file, _("failed to load uptime"));
- return 0;
- }
- break;
- case SESSION_OBJ_HOTLIST:
- if (!session_load_hotlist (file))
- {
- session_crash (file, _("failed to load hotlist"));
- return 0;
- }
- break;
- default:
- log_printf (_("ignoring object (id: %d)"),
- object_id);
- if (!session_read_ignore_object (file))
- {
- session_crash (file, _("failed to ignore object (id: %d)"),
- object_id);
- return 0;
- }
- }
- }
-
- // assign a buffer to all connected servers
- for (ptr_server = irc_servers; ptr_server;
- ptr_server = ptr_server->next_server)
- {
- if ((ptr_server->is_connected) && (!ptr_server->buffer))
- ptr_server->buffer = gui_buffers;
- }
-
- gui_window_switch_to_buffer (gui_windows, gui_buffers);
- gui_window_redraw_buffer (gui_current_window->buffer);
-
- fclose (file);
-
- if (unlink (filename) < 0)
- {
- gui_printf_error_nolog (gui_current_window->buffer,
- _("Warning: can't delete session file (%s)\n"),
- filename);
- }
-
- gui_printf_info_nolog (gui_current_window->buffer,
- _("Upgrade completed successfully\n"));
-
- return 1;
-}*/
+ return rc;
+}
diff --git a/src/core/wee-upgrade.h b/src/core/wee-upgrade.h
index 3662199ac..8cef12570 100644
--- a/src/core/wee-upgrade.h
+++ b/src/core/wee-upgrade.h
@@ -20,186 +20,23 @@
#ifndef __WEECHAT_UPGRADE_H
#define __WEECHAT_UPGRADE_H 1
-#define WEECHAT_SESSION_NAME "weechat_session.bin"
+#include "wee-upgrade-file.h"
-#define SESSION_SIGNATURE "== WeeChat Upgrade file v1.0 - binary, do not edit! =="
+#define WEECHAT_UPGRADE_FILENAME "weechat"
/* For developers: please add new values ONLY AT THE END of enums */
-enum t_session_type
+enum t_upgrade_weechat_type
{
- SESSION_TYPE_INT = 0,
- SESSION_TYPE_STR,
- SESSION_TYPE_BUF
+ UPGRADE_WEECHAT_TYPE_HISTORY = 0,
+ UPGRADE_WEECHAT_TYPE_BUFFER,
+ UPGRADE_WEECHAT_TYPE_NICKLIST,
+ UPGRADE_WEECHAT_TYPE_BUFFER_LINE,
+ UPGRADE_WEECHAT_TYPE_UPTIME,
+ UPGRADE_WEECHAT_TYPE_HOTLIST,
};
-enum t_session_object
-{
- SESSION_OBJ_END = 0,
- SESSION_OBJ_SERVER,
- SESSION_OBJ_CHANNEL,
- SESSION_OBJ_NICK,
- SESSION_OBJ_DCC,
- SESSION_OBJ_HISTORY,
- SESSION_OBJ_BUFFER,
- SESSION_OBJ_LINE,
- SESSION_OBJ_UPTIME,
- SESSION_OBJ_HOTLIST
-};
-
-enum t_session_server
-{
- SESSION_SERV_END = 0,
- SESSION_SERV_NAME,
- SESSION_SERV_AUTOCONNECT,
- SESSION_SERV_AUTORECONNECT,
- SESSION_SERV_AUTORECONNECT_DELAY,
- SESSION_SERV_TEMP_SERVER,
- SESSION_SERV_ADDRESS,
- SESSION_SERV_PORT,
- SESSION_SERV_IPV6,
- SESSION_SERV_SSL,
- SESSION_SERV_PASSWORD,
- SESSION_SERV_NICK1,
- SESSION_SERV_NICK2,
- SESSION_SERV_NICK3,
- SESSION_SERV_USERNAME,
- SESSION_SERV_REALNAME,
- SESSION_SERV_COMMAND,
- SESSION_SERV_COMMAND_DELAY,
- SESSION_SERV_AUTOJOIN,
- SESSION_SERV_AUTOREJOIN,
- SESSION_SERV_NOTIFY_LEVELS,
- SESSION_SERV_CHILD_PID,
- SESSION_SERV_CHILD_READ,
- SESSION_SERV_CHILD_WRITE,
- SESSION_SERV_SOCK,
- SESSION_SERV_IS_CONNECTED,
- SESSION_SERV_SSL_CONNECTED,
- SESSION_SERV_GNUTLS_SESS,
- SESSION_SERV_UNTERMINATED_MESSAGE,
- SESSION_SERV_NICK,
- SESSION_SERV_RECONNECT_START,
- SESSION_SERV_RECONNECT_JOIN,
- SESSION_SERV_IS_AWAY,
- SESSION_SERV_AWAY_TIME,
- SESSION_SERV_LAG,
- SESSION_SERV_LAG_CHECK_TIME,
- SESSION_SERV_LAG_NEXT_CHECK,
- SESSION_SERV_CHARSET_DECODE_ISO__UNUSED,
- SESSION_SERV_CHARSET_DECODE_UTF__UNUSED,
- SESSION_SERV_CHARSET_ENCODE__UNUSED,
- SESSION_SERV_HOSTNAME,
- SESSION_SERV_NICK_MODES,
- SESSION_SERV_AWAY_MESSAGE,
- SESSION_SERV_PREFIX,
- SESSION_SERV_COMMAND_TIME
-};
-
-enum t_session_channel
-{
- SESSION_CHAN_END = 0,
- SESSION_CHAN_TYPE,
- SESSION_CHAN_NAME,
- SESSION_CHAN_TOPIC,
- SESSION_CHAN_MODES,
- SESSION_CHAN_LIMIT,
- SESSION_CHAN_KEY,
- SESSION_CHAN_NICKS_COUNT,
- SESSION_CHAN_CHECKING_AWAY,
- SESSION_CHAN_AWAY_MESSAGE,
- SESSION_CHAN_CYCLE,
- SESSION_CHAN_CLOSE,
- SESSION_CHAN_DISPLAY_CREATION_DATE
-};
-
-enum t_session_nick
-{
- SESSION_NICK_END = 0,
- SESSION_NICK_NICK,
- SESSION_NICK_FLAGS,
- SESSION_NICK_COLOR,
- SESSION_NICK_HOST
-};
-
-enum t_session_dcc
-{
- SESSION_DCC_END = 0,
- SESSION_DCC_SERVER,
- SESSION_DCC_CHANNEL,
- SESSION_DCC_TYPE,
- SESSION_DCC_STATUS,
- SESSION_DCC_START_TIME,
- SESSION_DCC_START_TRANSFER,
- SESSION_DCC_ADDR,
- SESSION_DCC_PORT,
- SESSION_DCC_NICK,
- SESSION_DCC_SOCK,
- SESSION_DCC_UNTERMINATED_MESSAGE,
- SESSION_DCC_FILE,
- SESSION_DCC_FILENAME,
- SESSION_DCC_LOCAL_FILENAME,
- SESSION_DCC_FILENAME_SUFFIX,
- SESSION_DCC_SIZE,
- SESSION_DCC_POS,
- SESSION_DCC_ACK,
- SESSION_DCC_START_RESUME,
- SESSION_DCC_LAST_CHECK_TIME,
- SESSION_DCC_LAST_CHECK_POS,
- SESSION_DCC_LAST_ACTIVITY,
- SESSION_DCC_BYTES_PER_SEC,
- SESSION_DCC_ETA,
- SESSION_DCC_CHILD_PID,
- SESSION_DCC_CHILD_READ,
- SESSION_DCC_CHILD_WRITE
-};
-
-enum t_session_history
-{
- SESSION_HIST_END = 0,
- SESSION_HIST_TEXT
-};
-
-enum t_session_buffer
-{
- SESSION_BUFF_END = 0,
- SESSION_BUFF_SERVER,
- SESSION_BUFF_CHANNEL,
- SESSION_BUFF_TYPE,
- SESSION_BUFF_ALL_SERVERS
-};
-
-enum t_session_line
-{
- SESSION_LINE_END = 0,
- SESSION_LINE_LENGTH,
- SESSION_LINE_LENGTH_ALIGN,
- SESSION_LINE_LOG_WRITE,
- SESSION_LINE_WITH_MESSAGE,
- SESSION_LINE_WITH_HIGHLIGHT,
- SESSION_LINE_DATA,
- SESSION_LINE_OFS_AFTER_DATE,
- SESSION_LINE_OFS_START_MESSAGE,
- SESSION_LINE_NICK,
- SESSION_LINE_DATE
-};
-
-enum t_session_uptime
-{
- SESSION_UPT_END = 0,
- SESSION_UPT_START_TIME
-};
-
-enum t_session_hotlist
-{
- SESSION_HOTL_END = 0,
- SESSION_HOTL_PRIORITY,
- SESSION_HOTL_SERVER,
- SESSION_HOTL_BUFFER_NUMBER,
- SESSION_HOTL_CREATION_TIME
-};
-
-int session_save (const char *filename);
-int session_load (const char *filename);
+int upgrade_weechat_save ();
+int upgrade_weechat_load ();
#endif /* wee-upgrade.h */
diff --git a/src/core/weechat.c b/src/core/weechat.c
index 8a4fa6388..e28519a78 100644
--- a/src/core/weechat.c
+++ b/src/core/weechat.c
@@ -58,6 +58,7 @@
#include "wee-log.h"
#include "wee-network.h"
#include "wee-string.h"
+#include "wee-upgrade.h"
#include "wee-utf8.h"
#include "wee-util.h"
#include "../gui/gui-chat.h"
@@ -68,7 +69,7 @@
char *weechat_argv0 = NULL; /* WeeChat binary file name (argv[0])*/
-char *weechat_session = NULL; /* session file (/upgrade) */
+int weechat_upgrading; /* =1 if WeeChat is upgrading */
time_t weechat_start_time; /* start time (used by /uptime cmd) */
int weechat_quit; /* = 1 if quit request from user */
int weechat_sigsegv = 0; /* SIGSEGV received? */
@@ -151,7 +152,7 @@ weechat_parse_args (int argc, char *argv[])
int i;
weechat_argv0 = strdup (argv[0]);
- weechat_session = NULL;
+ weechat_upgrading = 0;
weechat_home = NULL;
weechat_server_cmd_line = 0;
weechat_auto_load_plugins = 1;
@@ -195,18 +196,9 @@ weechat_parse_args (int argc, char *argv[])
{
weechat_auto_load_plugins = 0;
}
- else if (strcmp (argv[i], "--session") == 0)
+ else if (strcmp (argv[i], "--upgrade") == 0)
{
- if (i + 1 < argc)
- weechat_session = strdup (argv[++i]);
- else
- {
- string_iconv_fprintf (stderr,
- _("Error: missing argument for \"%s\" "
- "option\n"),
- "--session");
- weechat_shutdown (EXIT_FAILURE, 0);
- }
+ weechat_upgrading = 1;
}
else if ((strcmp (argv[i], "-v") == 0)
|| (strcmp (argv[i], "--version") == 0))
@@ -383,7 +375,7 @@ main (int argc, char *argv[])
util_catch_signal (SIGQUIT, SIG_IGN); /* ignore SIGQUIT signal */
util_catch_signal (SIGPIPE, SIG_IGN); /* ignore SIGPIPE signal */
util_catch_signal (SIGSEGV,
- &debug_sigsegv); /* crash dump for SIGSEGV signal */
+ &debug_sigsegv); /* crash dump for SIGSEGV signal */
hook_init (); /* initialize hooks */
debug_init (); /* hook signals for debug */
gui_main_pre_init (&argc, &argv); /* pre-initiliaze interface */
@@ -398,11 +390,11 @@ main (int argc, char *argv[])
if (config_weechat_read () < 0) /* read WeeChat configuration */
exit (EXIT_FAILURE);
gui_main_init (); /* init WeeChat interface */
- //if (weechat_session)
- //session_load (weechat_session); /* load previous session if asked */
+ if (weechat_upgrading)
+ upgrade_weechat_load (); /* upgrade with session file */
weechat_welcome_message (); /* display WeeChat welcome message */
command_startup (0); /* command executed before plugins */
- plugin_init (weechat_auto_load_plugins, /* init plugin interface(s) */
+ plugin_init (weechat_auto_load_plugins, /* init plugin interface(s) */
argc, argv);
command_startup (1); /* command executed after plugins */