1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-09 03:03:12 +02:00

Reintroduce /upgrade command, working only with core and IRC plugin today

Command will be improved in near future and other plugins like xfer
will be modified to manage upgrade process.
This commit is contained in:
Sebastien Helleu
2008-08-19 23:22:52 +02:00
parent ff1983533b
commit b76d7e4a5c
68 changed files with 4122 additions and 3725 deletions
+2
View File
@@ -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)
+4
View File
@@ -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 \
+20 -59
View File
@@ -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;
ptr_binary = (argc > 1) ? argv_eol[1] : weechat_argv0;
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
gui_chat_printf (NULL,
_("Upgrading WeeChat..."));
/* send "upgrade" signal to plugins */
hook_signal_send ("upgrade", WEECHAT_HOOK_SIGNAL_STRING, NULL);
if (!upgrade_weechat_save ())
{
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;
}
}
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_info_nolog (NULL,
_("Upgrading WeeChat..."));
if (!session_save (filename))
{
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;
+201
View File
@@ -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"
@@ -2104,6 +2105,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
*/
+3
View File
@@ -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 ();
+3
View File
@@ -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 ();
+708
View File
@@ -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);
}
}
}
}
+105
View File
@@ -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 */
+715
View File
@@ -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);
}
+59
View File
@@ -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 */
+308 -1735
View File
File diff suppressed because it is too large Load Diff
+11 -174
View File
@@ -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 */
+9 -17
View File
@@ -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 */