diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/core/Makefile.am | 4 | ||||
-rw-r--r-- | src/core/wee-command.c | 75 | ||||
-rw-r--r-- | src/core/wee-config-file.c | 201 | ||||
-rw-r--r-- | src/core/wee-config-file.h | 3 | ||||
-rw-r--r-- | src/core/wee-debug.c | 3 | ||||
-rw-r--r-- | src/core/wee-infolist.c | 708 | ||||
-rw-r--r-- | src/core/wee-infolist.h | 105 | ||||
-rw-r--r-- | src/core/wee-upgrade-file.c | 715 | ||||
-rw-r--r-- | src/core/wee-upgrade-file.h | 59 | ||||
-rw-r--r-- | src/core/wee-upgrade.c | 1975 | ||||
-rw-r--r-- | src/core/wee-upgrade.h | 185 | ||||
-rw-r--r-- | src/core/weechat.c | 26 |
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 */ |