Use GLib 2.6's gstdio functions. This should fix gaim not liking non-ascii filenames in win32.
--- a/plugins/mailchk.c Wed Feb 09 09:58:22 2005 -0500
+++ b/plugins/mailchk.c Wed Feb 09 19:07:39 2005 -0500
@@ -33,7 +33,7 @@
filename = g_strconcat("/var/spool/mail/", g_get_user_name(), NULL);
- if (stat(filename, &s) < 0) {
+ if (g_stat(filename, &s) < 0) { --- a/plugins/spellchk.c Wed Feb 09 09:58:22 2005 -0500
+++ b/plugins/spellchk.c Wed Feb 09 19:07:39 2005 -0500
@@ -340,11 +340,11 @@
gaim_debug(GAIM_DEBUG_ERROR, "spellchk",
"Error writing to %s: %m\n", tempfilename);
+ g_unlink(tempfilename); - rename(tempfilename, name);
+ g_rename(tempfilename, name); --- a/plugins/tcl/tcl.c Wed Feb 09 09:58:22 2005 -0500
+++ b/plugins/tcl/tcl.c Wed Feb 09 19:07:39 2005 -0500
@@ -161,8 +161,7 @@
int len, found = 0, err = 0, nelems;
- if ((fp = fopen(plugin->path, "r")) == NULL)
+ if ((fp = g_fopen(plugin->path, "r")) == NULL) if (fstat(fileno(fp), &st)) {
--- a/src/Makefile.mingw Wed Feb 09 09:58:22 2005 -0500
+++ b/src/Makefile.mingw Wed Feb 09 19:07:39 2005 -0500
@@ -173,7 +173,7 @@
@@ -202,7 +202,7 @@
all: $(TARGET).exe $(TARGET).dll
cp $(GAIM_SRC)/gaim.exe $(GAIM_SRC)/gaim.dll $(GAIM_INSTALL_DIR)
$(IDLETRACK_TOP)/idletrack.dll:
--- a/src/account.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/account.c Wed Feb 09 19:07:39 2005 -0500
@@ -1379,16 +1379,16 @@
gaim_debug(GAIM_DEBUG_INFO, "accounts", "Writing accounts to disk.\n");
- fp = fopen(user_dir, "r");
+ fp = g_fopen(user_dir, "r"); - mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
+ g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR); filename = g_build_filename(user_dir, "accounts.xml.save", NULL);
- if ((fp = fopen(filename, "w")) != NULL) {
+ if ((fp = g_fopen(filename, "w")) != NULL) { fprintf(fp, "<?xml version='1.0' encoding='UTF-8' ?>\n\n");
@@ -1409,16 +1409,16 @@
- if (stat(filename, &st) || (st.st_size == 0)) {
+ if (g_stat(filename, &st) || (st.st_size == 0)) { gaim_debug_error("accounts", "Failed to save accounts\n");
filename_real = g_build_filename(user_dir, "accounts.xml", NULL);
- if (rename(filename, filename_real) < 0) {
+ if (g_rename(filename, filename_real) < 0) { gaim_debug(GAIM_DEBUG_ERROR, "accounts", "Error renaming %s to %s\n",
filename, filename_real);
--- a/src/blist.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/blist.c Wed Feb 09 19:07:39 2005 -0500
@@ -1969,7 +1969,7 @@
name = g_build_filename(gaim_user_dir(), "blist.xml~", NULL);
- if ((backup = fopen(name, "w"))) {
+ if ((backup = g_fopen(name, "w"))) { fwrite(contents, length, 1, backup);
chmod(name, S_IRUSR | S_IWUSR);
@@ -2399,15 +2399,15 @@
- file = fopen(user_dir, "r");
+ file = g_fopen(user_dir, "r"); - mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
+ g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR); filename = g_build_filename(user_dir, "blist.xml.save", NULL);
- if ((file = fopen(filename, "w"))) {
+ if ((file = g_fopen(filename, "w"))) { gaim_blist_write(file, NULL);
chmod(filename, S_IRUSR | S_IWUSR);
@@ -2418,16 +2418,16 @@
- if (stat(filename, &st) || (st.st_size == 0)) {
+ if (g_stat(filename, &st) || (st.st_size == 0)) { gaim_debug_error("blist", "Failed to save blist\n");
filename_real = g_build_filename(user_dir, "blist.xml", NULL);
- if (rename(filename, filename_real) < 0)
+ if (g_rename(filename, filename_real) < 0) gaim_debug(GAIM_DEBUG_ERROR, "blist save",
"Error renaming %s to %s\n", filename, filename_real);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buddyicon.c Wed Feb 09 19:07:39 2005 -0500
@@ -0,0 +1,453 @@
+ * @file icon.c Buddy Icon API + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#include "conversation.h" +static GHashTable *account_cache = NULL; +static char *cache_dir = NULL; +static gboolean icon_caching = TRUE; +gaim_buddy_icon_create(GaimAccount *account, const char *username) + GHashTable *icon_cache; + icon = g_new0(GaimBuddyIcon, 1); + gaim_buddy_icon_set_account(icon, account); + gaim_buddy_icon_set_username(icon, username); + icon_cache = g_hash_table_lookup(account_cache, account); + if (icon_cache == NULL) + icon_cache = g_hash_table_new(g_str_hash, g_str_equal); + g_hash_table_insert(account_cache, account, icon_cache); + g_hash_table_insert(icon_cache, + (char *)gaim_buddy_icon_get_username(icon), icon); +gaim_buddy_icon_new(GaimAccount *account, const char *username, + void *icon_data, size_t icon_len) + g_return_val_if_fail(account != NULL, NULL); + g_return_val_if_fail(username != NULL, NULL); + g_return_val_if_fail(icon_data != NULL, NULL); + g_return_val_if_fail(icon_len > 0, NULL); + icon = gaim_buddy_icons_find(account, username); + icon = gaim_buddy_icon_create(account, username); + gaim_buddy_icon_ref(icon); + gaim_buddy_icon_set_data(icon, icon_data, icon_len); + gaim_buddy_icon_unref(icon); + /* We don't take a reference here. gaim_buddy_icon_set_data() makes blist.c or + conversation.c, or both, do that for us. +gaim_buddy_icon_destroy(GaimBuddyIcon *icon) + GaimConversation *conv; + GHashTable *icon_cache; + g_return_if_fail(icon != NULL); + if (icon->ref_count > 0) + /* If the ref count is greater than 0, then we weren't called from + * gaim_buddy_icon_unref(). So we go through and ask everyone to + * unref us. Then we return, since we know somewhere along the + * line we got called recursively by one of the unrefs, and the + * icon is already destroyed. + account = gaim_buddy_icon_get_account(icon); + username = gaim_buddy_icon_get_username(icon); + conv = gaim_find_conversation_with_account(username, account); + if (conv != NULL && gaim_conversation_get_type(conv) == GAIM_CONV_IM) + gaim_conv_im_set_icon(GAIM_CONV_IM(conv), NULL); + for (list = sl = gaim_find_buddies(account, username); sl != NULL; + GaimBuddy *buddy = (GaimBuddy *)sl->data; + gaim_buddy_set_icon(buddy, NULL); + icon_cache = g_hash_table_lookup(account_cache, + gaim_buddy_icon_get_account(icon)); + if (icon_cache != NULL) + g_hash_table_remove(icon_cache, gaim_buddy_icon_get_username(icon)); + if (icon->username != NULL) + g_free(icon->username); + if (icon->data != NULL) +gaim_buddy_icon_ref(GaimBuddyIcon *icon) + g_return_val_if_fail(icon != NULL, NULL); +gaim_buddy_icon_unref(GaimBuddyIcon *icon) + g_return_val_if_fail(icon != NULL, NULL); + if (icon->ref_count <= 0) + if (icon->ref_count == 0) + gaim_buddy_icon_destroy(icon); +gaim_buddy_icon_update(GaimBuddyIcon *icon) + GaimConversation *conv; + g_return_if_fail(icon != NULL); + account = gaim_buddy_icon_get_account(icon); + username = gaim_buddy_icon_get_username(icon); + for (list = sl = gaim_find_buddies(account, username); sl != NULL; + GaimBuddy *buddy = (GaimBuddy *)sl->data; + gaim_buddy_set_icon(buddy, icon); + conv = gaim_find_conversation_with_account(username, account); + if (conv != NULL && gaim_conversation_get_type(conv) == GAIM_CONV_IM) + gaim_conv_im_set_icon(GAIM_CONV_IM(conv), icon); +gaim_buddy_icon_cache(GaimBuddyIcon *icon, GaimBuddy *buddy) + g_return_if_fail(icon != NULL); + g_return_if_fail(buddy != NULL); + if (!gaim_buddy_icons_is_caching()) + data = gaim_buddy_icon_get_data(icon, &len); + random = g_strdup_printf("%x", g_random_int()); + dirname = gaim_buddy_icons_get_cache_dir(); + filename = g_build_filename(dirname, random, NULL); + old_icon = gaim_blist_node_get_string((GaimBlistNode*)buddy, "buddy_icon"); + if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) + gaim_debug_info("buddy icons", "Creating icon cache directory.\n"); + if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) + gaim_debug_error("buddy icons", + "Unable to create directory %s: %s\n", + dirname, strerror(errno)); + if ((file = g_fopen(filename, "wb")) != NULL) + fwrite(data, 1, len, file); + if(!g_stat(old_icon, &st)) + filename = g_build_filename(dirname, old_icon, NULL); + if(!g_stat(filename, &st)) + gaim_blist_node_set_string((GaimBlistNode *)buddy, "buddy_icon", random); +gaim_buddy_icon_set_account(GaimBuddyIcon *icon, GaimAccount *account) + g_return_if_fail(icon != NULL); + g_return_if_fail(account != NULL); + icon->account = account; +gaim_buddy_icon_set_username(GaimBuddyIcon *icon, const char *username) + g_return_if_fail(icon != NULL); + g_return_if_fail(username != NULL); + if (icon->username != NULL) + g_free(icon->username); + icon->username = g_strdup(username); +gaim_buddy_icon_set_data(GaimBuddyIcon *icon, void *data, size_t len) + g_return_if_fail(icon != NULL); + if (icon->data != NULL) + if (data != NULL && len > 0) + icon->data = g_memdup(data, len); + gaim_buddy_icon_update(icon); +gaim_buddy_icon_get_account(const GaimBuddyIcon *icon) + g_return_val_if_fail(icon != NULL, NULL); +gaim_buddy_icon_get_username(const GaimBuddyIcon *icon) + g_return_val_if_fail(icon != NULL, NULL); +gaim_buddy_icon_get_data(const GaimBuddyIcon *icon, size_t *len) + g_return_val_if_fail(icon != NULL, NULL); +gaim_buddy_icons_set_for_user(GaimAccount *account, const char *username, + void *icon_data, size_t icon_len) + g_return_if_fail(account != NULL); + g_return_if_fail(username != NULL); + if (icon_data == NULL || icon_len == 0) + GaimBuddyIcon *buddy_icon; + buddy_icon = gaim_buddy_icons_find(account, username); + if (buddy_icon != NULL) + gaim_buddy_icon_destroy(buddy_icon); + gaim_buddy_icon_new(account, username, icon_data, icon_len); +gaim_buddy_icons_find(GaimAccount *account, const char *username) + GHashTable *icon_cache; + GaimBuddyIcon *ret = NULL; + g_return_val_if_fail(account != NULL, NULL); + g_return_val_if_fail(username != NULL, NULL); + icon_cache = g_hash_table_lookup(account_cache, account); + if ((icon_cache == NULL) || ((ret = g_hash_table_lookup(icon_cache, username)) == NULL)) { + GaimBuddy *b = gaim_find_buddy(account, username); + if ((file = gaim_blist_node_get_string((GaimBlistNode*)b, "buddy_icon")) == NULL) + if (!g_stat(file, &st)) + filename = g_strdup(file); + filename = g_build_filename(gaim_buddy_icons_get_cache_dir(), file, NULL); + if (!g_stat(filename, &st)) { + FILE *f = g_fopen(filename, "rb"); + char *data = g_malloc(st.st_size); + fread(data, 1, st.st_size, f); + ret = gaim_buddy_icon_create(account, username); + gaim_buddy_icon_ref(ret); + gaim_buddy_icon_set_data(ret, data, st.st_size); + gaim_buddy_icon_unref(ret); +gaim_buddy_icons_set_caching(gboolean caching) + icon_caching = caching; +gaim_buddy_icons_is_caching(void) +gaim_buddy_icons_set_cache_dir(const char *dir) + g_return_if_fail(cache_dir != NULL); + cache_dir = g_strdup(dir); +gaim_buddy_icons_get_cache_dir(void) +gaim_buddy_icons_get_handle() + account_cache = g_hash_table_new_full( + g_direct_hash, g_direct_equal, + NULL, (GFreeFunc)g_hash_table_destroy); + cache_dir = g_build_filename(gaim_user_dir(), "icons", NULL); +gaim_buddy_icons_uninit() + g_hash_table_destroy(account_cache); --- a/src/ft.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/ft.c Wed Feb 09 19:07:39 2005 -0500
@@ -170,7 +170,7 @@
xfer = (GaimXfer *)user_data;
- if (stat(filename, &st) != 0) {
+ if (g_stat(filename, &st) != 0) { if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) {
gaim_xfer_request_accepted(xfer, filename);
@@ -367,7 +367,7 @@
- if (stat(filename, &st) == -1) {
+ if (g_stat(filename, &st) == -1) { gaim_xfer_show_file_error(xfer, filename);
@@ -789,7 +789,7 @@
GaimXferType type = gaim_xfer_get_type(xfer);
- xfer->dest_fp = fopen(gaim_xfer_get_local_filename(xfer),
+ xfer->dest_fp = g_fopen(gaim_xfer_get_local_filename(xfer), type == GAIM_XFER_RECEIVE ? "wb" : "rb");
if (xfer->dest_fp == NULL) {
--- a/src/gtkaccount.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/gtkaccount.c Wed Feb 09 19:07:39 2005 -0500
@@ -306,7 +306,7 @@
GTK_FILE_SELECTION(dialog->icon_filesel)));
- if (!filename || stat(filename, &st))
+ if (!filename || g_stat(filename, &st)) @@ -522,7 +522,7 @@
format = gdk_pixbuf_get_file_info (path, &width, &height);
loader = gdk_pixbuf_loader_new();
- if (!stat(path, &st) && (file = fopen(path, "rb")) != NULL) {
+ if (!g_stat(path, &st) && (file = g_fopen(path, "rb")) != NULL) { data = g_malloc(st.st_size);
fread(data, 1, st.st_size, file);
@@ -588,7 +588,7 @@
if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) {
gaim_debug_info("buddyicon", "Creating icon cache directory.\n");
- if (mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) {
+ if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { gaim_debug_error("buddyicon",
"Unable to create directory %s: %s\n",
dirname, strerror(errno));
--- a/src/gtkconv.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/gtkconv.c Wed Feb 09 19:07:39 2005 -0500
@@ -901,7 +901,7 @@
- if ((fp = fopen(filename, "w+")) == NULL) {
+ if ((fp = g_fopen(filename, "w+")) == NULL) { gaim_notify_error(conv, NULL, _("Unable to open file."), NULL);
@@ -2616,7 +2616,7 @@
- if ((fp = fopen(filename, "wb")) == NULL) {
+ if ((fp = g_fopen(filename, "wb")) == NULL) { gaim_notify_error(conv, NULL, _("Unable to open file."), NULL);
@@ -5817,7 +5817,7 @@
"%s" G_DIR_SEPARATOR_S "gaimicon-%s.%d",
g_get_tmp_dir(), gaim_conversation_get_name(conv), getpid());
- if (!(file = fopen(filename, "wb")))
+ if (!(file = g_fopen(filename, "wb"))) fwrite(data, 1, len, file);
@@ -5825,7 +5825,7 @@
gtkconv->u.im->anim = gdk_pixbuf_animation_new_from_file(filename, &err);
/* make sure we remove the file as soon as possible */
gaim_debug(GAIM_DEBUG_ERROR, "gtkconv",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gtkdebug.c Wed Feb 09 19:07:39 2005 -0500
@@ -0,0 +1,537 @@
+ * @file gtkdebug.c GTK+ Debug API + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + guint timestamps_handle; +static char debug_fg_colors[][8] = { + "#000000", /**< All debug levels. */ + "#666666", /**< Misc. */ + "#000000", /**< Information. */ + "#660000", /**< Warnings. */ + "#FF0000", /**< Errors. */ + "#FF0000", /**< Fatal errors. */ +static DebugWindow *debug_win = NULL; +debug_window_destroy(GtkWidget *w, GdkEvent *event, void *unused) + if (debug_win->timestamps_handle != 0) + gaim_prefs_disconnect_callback(debug_win->timestamps_handle); + /* If the "Save Log" dialog is open then close it */ + gaim_request_close_with_handle(debug_win); + gaim_prefs_set_bool("/gaim/gtk/debug/enabled", FALSE); +configure_cb(GtkWidget *w, GdkEventConfigure *event, DebugWindow *win) + if (GTK_WIDGET_VISIBLE(w)) { + gaim_prefs_set_int("/gaim/gtk/debug/width", event->width); + gaim_prefs_set_int("/gaim/gtk/debug/height", event->height); +do_find_cb(GtkWidget *widget, gint response, struct _find *f) + gtk_imhtml_search_find(GTK_IMHTML(f->window->text), + gtk_entry_get_text(GTK_ENTRY(f->entry))); + case GTK_RESPONSE_DELETE_EVENT: + case GTK_RESPONSE_CLOSE: + gtk_imhtml_search_clear(GTK_IMHTML(f->window->text)); + gtk_widget_destroy(f->window->find); + f->window->find = NULL; +find_cb(GtkWidget *w, DebugWindow *win) + GtkWidget *hbox, *img, *label; + gtk_window_present(GTK_WINDOW(win->find)); + f = g_malloc(sizeof(struct _find)); + win->find = gtk_dialog_new_with_buttons(_("Find"), + GTK_WINDOW(win->window), GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + GTK_STOCK_FIND, GTK_RESPONSE_OK, NULL); + gtk_dialog_set_default_response(GTK_DIALOG(win->find), + g_signal_connect(G_OBJECT(win->find), "response", + G_CALLBACK(do_find_cb), f); + gtk_container_set_border_width(GTK_CONTAINER(win->find), 6); + gtk_window_set_resizable(GTK_WINDOW(win->find), FALSE); + gtk_dialog_set_has_separator(GTK_DIALOG(win->find), FALSE); + gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(win->find)->vbox), 12); + gtk_container_set_border_width( + GTK_CONTAINER(GTK_DIALOG(win->find)->vbox), 6); + hbox = gtk_hbox_new(FALSE, 12); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(win->find)->vbox), + img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, + gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); + gtk_misc_set_alignment(GTK_MISC(img), 0, 0); + gtk_dialog_set_response_sensitive(GTK_DIALOG(win->find), + GTK_RESPONSE_OK, FALSE); + label = gtk_label_new(NULL); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Search for:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + f->entry = gtk_entry_new(); + gtk_entry_set_activates_default(GTK_ENTRY(f->entry), TRUE); + gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(f->entry)); + g_signal_connect(G_OBJECT(f->entry), "changed", + G_CALLBACK(gaim_gtk_set_sensitive_if_input), + gtk_box_pack_start(GTK_BOX(hbox), f->entry, FALSE, FALSE, 0); + gtk_widget_show_all(win->find); + gtk_widget_grab_focus(f->entry); +save_writefile_cb(void *user_data, const char *filename) + DebugWindow *win = (DebugWindow *)user_data; + if ((fp = g_fopen(filename, "w+")) == NULL) { + gaim_notify_error(win, NULL, _("Unable to open file."), NULL); + tmp = gtk_imhtml_get_text(GTK_IMHTML(win->text), NULL, NULL); + fprintf(fp, "Gaim Debug log : %s\n", gaim_date_full()); + fprintf(fp, "%s", tmp); +save_cb(GtkWidget *w, DebugWindow *win) + gaim_request_file(win, _("Save Debug Log"), "gaim-debug.log", TRUE, + G_CALLBACK(save_writefile_cb), NULL, win); +clear_cb(GtkWidget *w, DebugWindow *win) + gtk_imhtml_clear(GTK_IMHTML(win->text)); +pause_cb(GtkWidget *w, DebugWindow *win) + win->paused = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)); +timestamps_cb(GtkWidget *w, DebugWindow *win) + win->timestamps = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)); + gaim_prefs_set_bool("/gaim/gtk/debug/timestamps", win->timestamps); +timestamps_pref_cb(const char *name, GaimPrefType type, gpointer value, + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data), GPOINTER_TO_INT(value)); + win = g_new0(DebugWindow, 1); + width = gaim_prefs_get_int("/gaim/gtk/debug/width"); + height = gaim_prefs_get_int("/gaim/gtk/debug/height"); + GAIM_DIALOG(win->window); + gaim_debug(GAIM_DEBUG_INFO, "gtkdebug", "Setting dimensions to %d, %d\n", + gtk_window_set_default_size(GTK_WINDOW(win->window), width, height); + gtk_window_set_role(GTK_WINDOW(win->window), "debug"); + gtk_window_set_title(GTK_WINDOW(win->window), _("Debug Window")); + g_signal_connect(G_OBJECT(win->window), "delete_event", + G_CALLBACK(debug_window_destroy), NULL); + g_signal_connect(G_OBJECT(win->window), "configure_event", + G_CALLBACK(configure_cb), win); + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(win->window), vbox); + if (gaim_prefs_get_bool("/gaim/gtk/debug/toolbar")) { + /* Setup our top button bar thingie. */ + toolbar = gtk_toolbar_new(); + gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH_HORIZ); + gtk_toolbar_set_icon_size(GTK_TOOLBAR(toolbar), + GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0); + gtk_toolbar_insert_stock(GTK_TOOLBAR(toolbar), GTK_STOCK_FIND, + NULL, NULL, G_CALLBACK(find_cb), win, -1); + gtk_toolbar_insert_stock(GTK_TOOLBAR(toolbar), GTK_STOCK_SAVE, + NULL, NULL, G_CALLBACK(save_cb), win, -1); + gtk_toolbar_insert_stock(GTK_TOOLBAR(toolbar), GTK_STOCK_CLEAR, + NULL, NULL, G_CALLBACK(clear_cb), win, -1); + gtk_toolbar_insert_space(GTK_TOOLBAR(toolbar), -1); + image = gtk_image_new_from_stock(GAIM_STOCK_PAUSE, GTK_ICON_SIZE_MENU); + button = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), + GTK_TOOLBAR_CHILD_TOGGLEBUTTON, + NULL, _("Pause"), NULL, NULL, + image, G_CALLBACK(pause_cb), win); + button = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), + GTK_TOOLBAR_CHILD_TOGGLEBUTTON, + NULL, _("Timestamps"), NULL, NULL, + NULL, G_CALLBACK(timestamps_cb), + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), + gaim_prefs_get_bool("/gaim/gtk/debug/timestamps")); + win->timestamps_handle = + gaim_prefs_connect_callback("/gaim/gtk/debug/timestamps", + timestamps_pref_cb, button); + /* Now our scrolled window... */ + sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), + /* ... which has a gtkimhtml in it. */ + win->text = gtk_imhtml_new(NULL, NULL); + gtk_container_add(GTK_CONTAINER(sw), win->text); + /* Pack it in... Not like that, sicko. */ + gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); + gtk_widget_show_all(win->window); +debug_enabled_cb(const char *name, GaimPrefType type, gpointer value, + gaim_gtk_debug_window_show(); + gaim_gtk_debug_window_hide(); +gaim_glib_log_handler(const gchar *domain, GLogLevelFlags flags, + const gchar *msg, gpointer user_data) + char *new_domain = NULL; + if ((flags & G_LOG_LEVEL_ERROR) == G_LOG_LEVEL_ERROR) + level = GAIM_DEBUG_ERROR; + else if ((flags & G_LOG_LEVEL_CRITICAL) == G_LOG_LEVEL_CRITICAL) + level = GAIM_DEBUG_FATAL; + else if ((flags & G_LOG_LEVEL_WARNING) == G_LOG_LEVEL_WARNING) + level = GAIM_DEBUG_WARNING; + else if ((flags & G_LOG_LEVEL_MESSAGE) == G_LOG_LEVEL_MESSAGE) + level = GAIM_DEBUG_INFO; + else if ((flags & G_LOG_LEVEL_INFO) == G_LOG_LEVEL_INFO) + level = GAIM_DEBUG_INFO; + else if ((flags & G_LOG_LEVEL_DEBUG) == G_LOG_LEVEL_DEBUG) + level = GAIM_DEBUG_MISC; + gaim_debug_warning("gtkdebug", + "Unknown glib logging level in %d\n", flags); + level = GAIM_DEBUG_MISC; /* This will never happen. */ + new_msg = gaim_utf8_try_convert(msg); + new_domain = gaim_utf8_try_convert(domain); + gaim_debug(level, (new_domain != NULL ? new_domain : "g_log"), + if (new_domain != NULL) +gaim_glib_dummy_print_handler(const gchar *string) +gaim_gtk_debug_init(void) + /* Debug window preferences. */ + * NOTE: This must be set before prefs are loaded, and the callbacks + * set after they are loaded, since prefs sets the enabled + * preference here and that loads the window, which calls the + * configure event, which overrides the width and height! :P + gaim_prefs_add_none("/gaim/gtk/debug"); + gaim_prefs_add_bool("/gaim/gtk/debug/enabled", FALSE); + gaim_prefs_add_bool("/gaim/gtk/debug/timestamps", FALSE); + gaim_prefs_add_bool("/gaim/gtk/debug/toolbar", TRUE); + gaim_prefs_add_int("/gaim/gtk/debug/width", 450); + gaim_prefs_add_int("/gaim/gtk/debug/height", 250); + gaim_prefs_connect_callback("/gaim/gtk/debug/enabled", + debug_enabled_cb, NULL); +#define REGISTER_G_LOG_HANDLER(name) \ + g_log_set_handler((name), G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL \ + | G_LOG_FLAG_RECURSION, \ + gaim_glib_log_handler, NULL) + /* Register the glib/gtk log handlers. */ + REGISTER_G_LOG_HANDLER(NULL); + REGISTER_G_LOG_HANDLER("Gdk"); + REGISTER_G_LOG_HANDLER("Gtk"); + REGISTER_G_LOG_HANDLER("GdkPixbuf"); + REGISTER_G_LOG_HANDLER("GLib"); + REGISTER_G_LOG_HANDLER("GModule"); + REGISTER_G_LOG_HANDLER("GLib-GObject"); + REGISTER_G_LOG_HANDLER("GThread"); + g_set_print_handler(gaim_glib_dummy_print_handler); +gaim_gtk_debug_window_show(void) + debug_win = debug_window_new(); + gtk_widget_show(debug_win->window); + gaim_prefs_set_bool("/gaim/gtk/debug/enabled", TRUE); +gaim_gtk_debug_window_hide(void) + if (debug_win != NULL) { + gtk_widget_destroy(debug_win->window); + debug_window_destroy(NULL, NULL, NULL); +gaim_gtk_debug_print(GaimDebugLevel level, const char *category, + const char *format, va_list args) + timestamps = gaim_prefs_get_bool("/gaim/gtk/debug/timestamps"); + arg_s = g_strdup_vprintf(format, args); + if (category == NULL) { + * If the category is not NULL, then do timestamps. + time_t mtime = time(NULL); + strftime(mdate, sizeof(mdate), "%H:%M:%S", localtime(&mtime)); + ts_s = g_strdup_printf("(%s) ", mdate); + if (gaim_prefs_get_bool("/gaim/gtk/debug/enabled") && + debug_win != NULL && !debug_win->paused) { + gchar *esc_s, *cat_s, *utf8_s, *s; + cat_s = g_strdup_printf("<b>%s:</b> ", category); + esc_s = g_markup_escape_text(arg_s, -1); + s = g_strdup_printf("<font color=\"%s\">%s%s%s</font>", + debug_fg_colors[level], ts_s, cat_s, esc_s); + utf8_s = gaim_utf8_try_convert(s); + if (level == GAIM_DEBUG_FATAL) { + s = g_strdup_printf("<b>%s</b>", temp); + gtk_imhtml_append_text(GTK_IMHTML(debug_win->text), s, 0); + g_print("%s%s", ts_s, arg_s); + g_print("%s%s: %s", ts_s, category, arg_s); +static GaimDebugUiOps ops = +gaim_gtk_debug_get_ui_ops(void) --- a/src/gtkimhtml.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/gtkimhtml.c Wed Feb 09 19:07:39 2005 -0500
@@ -147,7 +147,7 @@
gaim_debug_info("imhtml clipboard", "from clipboard: %s\n", clipboard);
- fd = fopen("e:\\gaimcb.txt", "wb");
+ fd = g_fopen("e:\\gaimcb.txt", "wb"); fprintf(fd, "%s", clipboard);
--- a/src/gtkprefs.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/gtkprefs.c Wed Feb 09 19:07:39 2005 -0500
@@ -585,7 +585,7 @@
theme_install_theme(path, data);
--- a/src/internal.h Wed Feb 09 09:58:22 2005 -0500
+++ b/src/internal.h Wed Feb 09 19:07:39 2005 -0500
@@ -113,11 +113,27 @@
+#if GLIB_CHECK_VERSION(2,6,0) +# include <glib/gstdio.h> +#if !GLIB_CHECK_VERSION(2,6,0) +# define g_freopen freopen +# define g_remove remove +# define g_unlink unlink +# define g_rename rename /* stupid, stupid, stupid */
/* This is a workaround for the fact that G_GINT64_MODIFIER and
* G_GUINT64_FORMAT are wrong, even in Glib >= 2.4 */
--- a/src/log.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/log.c Wed Feb 09 19:07:39 2005 -0500
@@ -392,7 +392,7 @@
log->logger_data = data = g_new0(struct generic_logger_data, 1);
- data->file = fopen(path, "a");
+ data->file = g_fopen(path, "a"); gaim_debug(GAIM_DEBUG_ERROR, "log",
"Could not create log file %s\n", path);
@@ -447,7 +447,7 @@
struct generic_logger_data *data = log->logger_data;
- if (!data->path || stat(data->path, &st))
+ if (!data->path || g_stat(data->path, &st)) @@ -490,7 +490,7 @@
char *filename = g_build_filename(dir, date, NULL);
- log->logger_data = fopen(filename, "a");
+ log->logger_data = g_fopen(filename, "a"); gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename);
@@ -851,7 +851,7 @@
- if (!(file = fopen(gaim_stringref_value(pathref), "rb"))) {
+ if (!(file = g_fopen(gaim_stringref_value(pathref), "rb"))) { gaim_stringref_unref(pathref);
@@ -962,7 +962,7 @@
- if (stat(pathstr, &st))
+ if (g_stat(pathstr, &st)) @@ -976,7 +976,7 @@
static char * old_logger_read (GaimLog *log, GaimLogReadFlags *flags)
struct old_logger_data *data = log->logger_data;
- FILE *file = fopen(gaim_stringref_value(data->pathref), "rb");
+ FILE *file = g_fopen(gaim_stringref_value(data->pathref), "rb"); char *read = g_malloc(data->length + 1);
fseek(file, data->offset, SEEK_SET);
fread(read, data->length, 1, file);
--- a/src/pounce.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/pounce.c Wed Feb 09 19:07:39 2005 -0500
@@ -866,16 +866,16 @@
gaim_debug(GAIM_DEBUG_INFO, "pounces", "Writing pounces to disk.\n");
- fp = fopen(user_dir, "r");
+ fp = g_fopen(user_dir, "r"); - mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
+ g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR); filename = g_build_filename(user_dir, "pounces.xml.save", NULL);
- if ((fp = fopen(filename, "w")) != NULL) {
+ if ((fp = g_fopen(filename, "w")) != NULL) { fprintf(fp, "<?xml version='1.0' encoding='UTF-8' ?>\n\n");
@@ -896,16 +896,16 @@
- if (stat(filename, &st) || (st.st_size == 0)) {
+ if (g_stat(filename, &st) || (st.st_size == 0)) { gaim_debug_error("pounces", "Failed to save pounces\n");
filename_real = g_build_filename(user_dir, "pounces.xml", NULL);
- if (rename(filename, filename_real) < 0) {
+ if (g_rename(filename, filename_real) < 0) { gaim_debug(GAIM_DEBUG_ERROR, "pounces", "Error renaming %s to %s\n",
filename, filename_real);
--- a/src/prefs.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/prefs.c Wed Feb 09 19:07:39 2005 -0500
@@ -784,15 +784,15 @@
gaim_debug(GAIM_DEBUG_INFO, "prefs", "writing prefs out to disk.\n");
- file = fopen(user_dir, "r");
+ file = g_fopen(user_dir, "r"); - mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
+ g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR); filename = g_build_filename(user_dir, "prefs.xml.save", NULL);
- if((file = fopen(filename, "w"))) {
+ if((file = g_fopen(filename, "w"))) { gaim_prefs_write(file, NULL, 0);
chmod(filename, S_IRUSR | S_IWUSR);
@@ -803,15 +803,15 @@
- if (stat(filename, &st) || (st.st_size == 0)) {
+ if (g_stat(filename, &st) || (st.st_size == 0)) { gaim_debug_error("prefs", "Failed to save prefs\n");
filename_real = g_build_filename(user_dir, "prefs.xml", NULL);
- if(rename(filename, filename_real) < 0)
+ if(g_rename(filename, filename_real) < 0) gaim_debug(GAIM_DEBUG_ERROR, "prefs", "Error renaming %s to %s\n",
filename, filename_real);
--- a/src/protocols/msn/directconn.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/msn/directconn.c Wed Feb 09 19:07:39 2005 -0500
@@ -189,7 +189,7 @@
str = g_strdup_printf("%s/msntest/w%.4d.bin", g_get_home_dir(), directconn->c);
- FILE *tf = fopen(str, "w");
+ FILE *tf = g_fopen(str, "w"); fwrite(buffer, 1, buf_size, tf);
@@ -208,7 +208,7 @@
str = g_strdup_printf("/home/revo/msntest/w%.4d.bin", directconn->c);
- FILE *tf = fopen(str, "w");
+ FILE *tf = g_fopen(str, "w"); fwrite(&len, 1, sizeof(len), tf);
fwrite(data, 1, len, tf);
@@ -331,7 +331,7 @@
str = g_strdup_printf("/home/revo/msntest/r%.4d.bin", directconn->c);
- FILE *tf = fopen(str, "w");
+ FILE *tf = g_fopen(str, "w"); fwrite(body, 1, len, tf);
--- a/src/protocols/msn/msn.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/msn/msn.c Wed Feb 09 19:07:39 2005 -0500
@@ -354,7 +354,7 @@
- if ((fp = fopen(filename, "rb")) == NULL)
+ if ((fp = g_fopen(filename, "rb")) == NULL) --- a/src/protocols/msn/notification.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/msn/notification.c Wed Feb 09 19:07:39 2005 -0500
@@ -914,7 +914,7 @@
if (session->passport_info.file != NULL)
- unlink(session->passport_info.file);
+ g_unlink(session->passport_info.file); g_free(session->passport_info.file);
@@ -967,7 +967,7 @@
"Error closing temp passport file: %s\n",
- unlink(session->passport_info.file);
+ g_unlink(session->passport_info.file); g_free(session->passport_info.file);
session->passport_info.file = NULL;
--- a/src/protocols/msn/session.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/msn/session.c Wed Feb 09 19:07:39 2005 -0500
@@ -87,7 +87,7 @@
if (session->passport_info.file != NULL)
- unlink(session->passport_info.file);
+ g_unlink(session->passport_info.file); g_free(session->passport_info.file);
--- a/src/protocols/msn/slplink.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/msn/slplink.c Wed Feb 09 19:07:39 2005 -0500
@@ -46,7 +46,7 @@
dir = send ? "send" : "recv";
c = send ? m_sc++ : m_rc++;
tmp = g_strdup_printf("%s/msntest/%s/%03d", g_get_home_dir(), dir, c);
+ tf = g_fopen(tmp, "wb"); pload = msn_message_gen_payload(msg, &pload_size);
fwrite(pload, 1, pload_size, tf);
@@ -502,7 +502,7 @@
- fopen(gaim_xfer_get_local_filename(slpmsg->slpcall->xfer),
+ g_fopen(gaim_xfer_get_local_filename(slpmsg->slpcall->xfer), @@ -636,7 +636,7 @@
- if (stat(file_path, &st) == 0)
+ if (g_stat(file_path, &st) == 0) --- a/src/protocols/msn/slpmsg.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/msn/slpmsg.c Wed Feb 09 19:07:39 2005 -0500
@@ -114,9 +114,9 @@
- slpmsg->fp = fopen(file_name, "rb");
+ slpmsg->fp = g_fopen(file_name, "rb"); - if (stat(file_name, &st) == 0)
+ if (g_stat(file_name, &st) == 0) slpmsg->size = st.st_size;
--- a/src/protocols/msn/user.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/msn/user.c Wed Feb 09 19:07:39 2005 -0500
@@ -173,11 +173,11 @@
g_return_if_fail(user != NULL);
- if (filename == NULL || stat(filename, &st) == -1)
+ if (filename == NULL || g_stat(filename, &st) == -1) msn_user_set_object(user, NULL);
- else if ((fp = fopen(filename, "rb")) != NULL)
+ else if ((fp = g_fopen(filename, "rb")) != NULL) --- a/src/protocols/oscar/oscar.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/oscar/oscar.c Wed Feb 09 19:07:39 2005 -0500
@@ -3297,9 +3297,9 @@
- if (!stat(iconfile, &st)) {
+ if (!g_stat(iconfile, &st)) { char *buf = g_malloc(st.st_size);
- file = fopen(iconfile, "rb");
+ file = g_fopen(iconfile, "rb"); /* XXX - Use g_file_get_contents() */
int len = fread(buf, 1, st.st_size, file);
@@ -4627,9 +4627,9 @@
const char *iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc));
aim_ssi_delicon(od->sess);
- } else if (!stat(iconfile, &st)) {
+ } else if (!g_stat(iconfile, &st)) { char *buf = g_malloc(st.st_size);
- FILE *file = fopen(iconfile, "rb");
+ FILE *file = g_fopen(iconfile, "rb"); /* XXX - Use g_file_get_contents()? */
fread(buf, 1, st.st_size, file);
@@ -5441,8 +5441,8 @@
- if (iconfile && !stat(iconfile, &st)) {
- FILE *file = fopen(iconfile, "rb");
+ if (iconfile && !g_stat(iconfile, &st)) { + FILE *file = g_fopen(iconfile, "rb"); char *buf = g_malloc(st.st_size);
/* XXX - Use g_file_get_contents()? */
@@ -6723,9 +6723,9 @@
const char *iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc));
aim_ssi_delicon(od->sess);
- } else if (!stat(iconfile, &st)) {
+ } else if (!g_stat(iconfile, &st)) { char *buf = g_malloc(st.st_size);
- FILE *file = fopen(iconfile, "rb");
+ FILE *file = g_fopen(iconfile, "rb"); /* XXX - Use g_file_get_contents()? */
fread(buf, 1, st.st_size, file);
@@ -7225,9 +7225,9 @@
aim_ssi_delicon(od->sess);
- } else if (!stat(iconfile, &st)) {
+ } else if (!g_stat(iconfile, &st)) { char *buf = g_malloc(st.st_size);
- file = fopen(iconfile, "rb");
+ file = g_fopen(iconfile, "rb"); --- a/src/protocols/rendezvous/rendezvous.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/rendezvous/rendezvous.c Wed Feb 09 19:07:39 2005 -0500
@@ -464,10 +464,10 @@
g_return_val_if_fail(filename != NULL, NULL);
- if (stat(filename, &st))
+ if (g_stat(filename, &st)) - if (!(file = fopen(filename, "rb")))
+ if (!(file = g_fopen(filename, "rb"))) --- a/src/protocols/silc/buddy.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/silc/buddy.c Wed Feb 09 19:07:39 2005 -0500
@@ -917,10 +917,10 @@
/* Create dir if it doesn't exist */
- if ((stat(filename, &st)) == -1) {
+ if ((g_stat(filename, &st)) == -1) { if (pw->pw_uid == geteuid())
+ g_mkdir(filename, 0755); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/silc/ft.c Wed Feb 09 19:07:39 2005 -0500
@@ -0,0 +1,408 @@
+ Author: Pekka Riikonen <priikone@silcnet.org> + Copyright (C) 2004 Pekka Riikonen + 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; version 2 of the License. + 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. +#include "silcincludes.h" +/****************************** File Transfer ********************************/ +/* This implements the secure file transfer protocol (SFTP) using the SILC + SFTP library implementation. The API we use from the SILC Toolkit is the + SILC Client file transfer API, as it provides a simple file transfer we + need in this case. We could use the SILC SFTP API directly, but it would + be an overkill since we'd effectively re-implement the file transfer what + the SILC Client's file transfer API already provides. + From Gaim we do NOT use the FT API to do the transfer as it is very limiting. + In fact it does not suite to file transfers like SFTP at all. For example, + it assumes that read operations are synchronous what they are not in SFTP. + It also assumes that the file transfer socket is to be handled by the Gaim + eventloop, and this naturally is something we don't want to do in case of + SILC Toolkit. The FT API suites well to purely stream based file transfers + like HTTP GET and similar. + For this reason, we directly access the Gaim GKT FT API and hack the FT + API to merely provide the user interface experience and all the magic + is done in the SILC Toolkit. Ie. we update the statistics information in + the FT API for user interface, and that's it. A bit dirty but until the + FT API gets better this is the way to go. Good thing that FT API allowed + SilcClientEntry client_entry; + SilcClientFileName completion; + void *completion_context; +silcgaim_ftp_monitor(SilcClient client, + SilcClientConnection conn, + SilcClientMonitorStatus status, + SilcClientFileError error, + SilcClientEntry client_entry, + SilcGaimXfer xfer = context; + GaimConnection *gc = xfer->sg->gc; + if (status == SILC_CLIENT_FILE_MONITOR_CLOSED) { + gaim_xfer_unref(xfer->xfer); + if (status == SILC_CLIENT_FILE_MONITOR_KEY_AGREEMENT) + if (status == SILC_CLIENT_FILE_MONITOR_ERROR) { + if (error == SILC_CLIENT_FILE_NO_SUCH_FILE) { + g_snprintf(tmp, sizeof(tmp), "No such file %s", + filepath ? filepath : "[N/A]"); + gaim_notify_error(gc, _("Secure File Transfer"), + _("Error during file transfer"), tmp); + } else if (error == SILC_CLIENT_FILE_PERMISSION_DENIED) { + gaim_notify_error(gc, _("Secure File Transfer"), + _("Error during file transfer"), + _("Permission denied")); + } else if (error == SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED) { + gaim_notify_error(gc, _("Secure File Transfer"), + _("Error during file transfer"), + _("Key agreement failed")); + } else if (error == SILC_CLIENT_FILE_UNKNOWN_SESSION) { + gaim_notify_error(gc, _("Secure File Transfer"), + _("Error during file transfer"), + _("File transfer sessions does not exist")); + gaim_notify_error(gc, _("Secure File Transfer"), + _("Error during file transfer"), NULL); + silc_client_file_close(client, conn, session_id); + gaim_xfer_unref(xfer->xfer); + /* Update file transfer UI */ + if (!offset && filesize) + gaim_xfer_set_size(xfer->xfer, filesize); + if (offset && filesize) { + xfer->xfer->bytes_sent = offset; + xfer->xfer->bytes_remaining = filesize - offset; + gaim_xfer_update_progress(xfer->xfer); + if (status == SILC_CLIENT_FILE_MONITOR_SEND || + status == SILC_CLIENT_FILE_MONITOR_RECEIVE) { + if (offset == filesize) { + /* Download finished */ + gaim_xfer_set_completed(xfer->xfer, TRUE); + silc_client_file_close(client, conn, session_id); +silcgaim_ftp_cancel(GaimXfer *x) + SilcGaimXfer xfer = x->data; + xfer->xfer->status = GAIM_XFER_STATUS_CANCEL_LOCAL; + gaim_xfer_update_progress(xfer->xfer); + silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id); +silcgaim_ftp_ask_name_cancel(GaimXfer *x) + SilcGaimXfer xfer = x->data; + /* Cancel the transmission */ + xfer->completion(NULL, xfer->completion_context); + silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id); +silcgaim_ftp_ask_name_ok(GaimXfer *x) + SilcGaimXfer xfer = x->data; + name = gaim_xfer_get_local_filename(x); + xfer->completion(name, xfer->completion_context); +silcgaim_ftp_ask_name(SilcClient client, + SilcClientConnection conn, + const char *remote_filename, + SilcClientFileName completion, + void *completion_context, + SilcGaimXfer xfer = context; + xfer->completion = completion; + xfer->completion_context = completion_context; + gaim_xfer_set_init_fnc(xfer->xfer, silcgaim_ftp_ask_name_ok); + gaim_xfer_set_request_denied_fnc(xfer->xfer, silcgaim_ftp_ask_name_cancel); + /* Request to save the file */ + gaim_xfer_set_filename(xfer->xfer, remote_filename); + gaim_xfer_request(xfer->xfer); +silcgaim_ftp_request_result(GaimXfer *x) + SilcGaimXfer xfer = x->data; + SilcClientFileError status; + GaimConnection *gc = xfer->sg->gc; + if (gaim_xfer_get_status(x) != GAIM_XFER_STATUS_ACCEPTED) + /* Start the file transfer */ + status = silc_client_file_receive(xfer->sg->client, xfer->sg->conn, + silcgaim_ftp_monitor, xfer, + NULL, xfer->session_id, + silcgaim_ftp_ask_name, xfer); + case SILC_CLIENT_FILE_OK: + case SILC_CLIENT_FILE_UNKNOWN_SESSION: + gaim_notify_error(gc, _("Secure File Transfer"), + _("No file transfer session active"), NULL); + case SILC_CLIENT_FILE_ALREADY_STARTED: + gaim_notify_error(gc, _("Secure File Transfer"), + _("File transfer already started"), NULL); + case SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED: + gaim_notify_error(gc, _("Secure File Transfer"), + _("Could not perform key agreement for file transfer"), + gaim_notify_error(gc, _("Secure File Transfer"), + _("Could not start the file transfer"), NULL); + gaim_xfer_unref(xfer->xfer); + g_free(xfer->hostname); +silcgaim_ftp_request_denied(GaimXfer *x) +void silcgaim_ftp_request(SilcClient client, SilcClientConnection conn, + SilcClientEntry client_entry, SilcUInt32 session_id, + const char *hostname, SilcUInt16 port) + GaimConnection *gc = client->application; + SilcGaim sg = gc->proto_data; + xfer = silc_calloc(1, sizeof(*xfer)); + silc_client_file_close(sg->client, sg->conn, xfer->session_id); + xfer->client_entry = client_entry; + xfer->session_id = session_id; + xfer->hostname = g_strdup(hostname); + xfer->xfer = gaim_xfer_new(xfer->sg->account, GAIM_XFER_RECEIVE, + xfer->client_entry->nickname); + silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id); + g_free(xfer->hostname); + gaim_xfer_set_init_fnc(xfer->xfer, silcgaim_ftp_request_result); + gaim_xfer_set_request_denied_fnc(xfer->xfer, silcgaim_ftp_request_denied); + gaim_xfer_set_cancel_recv_fnc(xfer->xfer, silcgaim_ftp_cancel); + xfer->xfer->remote_ip = g_strdup(hostname); + xfer->xfer->remote_port = port; + xfer->xfer->data = xfer; + /* File transfer request */ + gaim_xfer_request(xfer->xfer); +silcgaim_ftp_send_cancel(GaimXfer *x) + SilcGaimXfer xfer = x->data; + silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id); + gaim_xfer_unref(xfer->xfer); + g_free(xfer->hostname); +silcgaim_ftp_send(GaimXfer *x) + SilcGaimXfer xfer = x->data; + char *local_ip = NULL, *remote_ip = NULL; + name = gaim_xfer_get_local_filename(x); + /* Do the same magic what we do with key agreement (see silcgaim_buddy.c) + to see if we are behind NAT. */ + if (silc_net_check_local_by_sock(xfer->sg->conn->sock->sock, + /* Check if the IP is private */ + if (silcgaim_ip_is_private(local_ip)) { + /* Local IP is private, resolve the remote server IP to see whether + we are talking to Internet or just on LAN. */ + if (silc_net_check_host_by_sock(xfer->sg->conn->sock->sock, NULL, + if (silcgaim_ip_is_private(remote_ip)) + /* We assume we are in LAN. Let's provide the connection point. */ + if (local && !local_ip) + local_ip = silc_net_localip(); + silc_client_file_send(xfer->sg->client, xfer->sg->conn, + silcgaim_ftp_monitor, xfer, + local_ip, 0, !local, xfer->client_entry, + name, &xfer->session_id); +silcgaim_ftp_send_file_resolved(SilcClient client, + SilcClientConnection conn, + SilcClientEntry *clients, + SilcUInt32 clients_count, + GaimConnection *gc = client->application; + g_snprintf(tmp, sizeof(tmp), + _("User %s is not present in the network"), + (const char *)context); + gaim_notify_error(gc, _("Secure File Transfer"), + _("Cannot send file"), tmp); + silcgaim_ftp_send_file(client->application, (const char *)context, NULL); +void silcgaim_ftp_send_file(GaimConnection *gc, const char *name, const char *file) + SilcGaim sg = gc->proto_data; + SilcClient client = sg->client; + SilcClientConnection conn = sg->conn; + SilcClientEntry *clients; + SilcUInt32 clients_count; + if (!silc_parse_userfqdn(name, &nickname, NULL)) + silc_log_set_debug_string("*client*,*ftp*"); + /* Find client entry */ + clients = silc_client_get_clients_local(client, conn, nickname, name, + silc_client_get_clients(client, conn, nickname, NULL, + silcgaim_ftp_send_file_resolved, + xfer = silc_calloc(1, sizeof(*xfer)); + xfer->client_entry = clients[0]; + xfer->xfer = gaim_xfer_new(xfer->sg->account, GAIM_XFER_SEND, + xfer->client_entry->nickname); + silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id); + g_free(xfer->hostname); + gaim_xfer_set_init_fnc(xfer->xfer, silcgaim_ftp_send); + gaim_xfer_set_request_denied_fnc(xfer->xfer, silcgaim_ftp_request_denied); + gaim_xfer_set_cancel_send_fnc(xfer->xfer, silcgaim_ftp_send_cancel); + xfer->xfer->data = xfer; + /* Choose file to send */ + gaim_xfer_request_accepted(xfer->xfer, file); + gaim_xfer_request(xfer->xfer); --- a/src/protocols/silc/ops.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/silc/ops.c Wed Feb 09 19:07:39 2005 -0500
@@ -1469,7 +1469,7 @@
case SILC_CLIENT_CONN_SUCCESS_RESUME:
gaim_connection_set_state(gc, GAIM_CONNECTED);
- unlink(silcgaim_session_file(gaim_account_get_username(sg->account)));
+ g_unlink(silcgaim_session_file(gaim_account_get_username(sg->account))); /* Send any UMODEs configured for account */
reject_watch = gaim_account_get_bool(sg->account, "reject-watch", FALSE);
@@ -1489,7 +1489,7 @@
case SILC_CLIENT_CONN_ERROR:
gaim_connection_error(gc, _("Error during connecting to SILC Server"));
- unlink(silcgaim_session_file(gaim_account_get_username(sg->account)));
+ g_unlink(silcgaim_session_file(gaim_account_get_username(sg->account))); case SILC_CLIENT_CONN_ERROR_KE:
@@ -1504,7 +1504,7 @@
gaim_connection_error(gc,
_("Resuming detached session failed. "
"Press Reconnect to create new connection."));
- unlink(silcgaim_session_file(gaim_account_get_username(sg->account)));
+ g_unlink(silcgaim_session_file(gaim_account_get_username(sg->account))); case SILC_CLIENT_CONN_ERROR_TIMEOUT:
@@ -1531,7 +1531,7 @@
SilcGaim sg = gc->proto_data;
if (sg->resuming && !sg->detaching)
- unlink(silcgaim_session_file(gaim_account_get_username(sg->account)));
+ g_unlink(silcgaim_session_file(gaim_account_get_username(sg->account))); @@ -1822,7 +1822,7 @@
/* Save the detachment data to file. */
file = silcgaim_session_file(gaim_account_get_username(sg->account));
silc_file_writefile(file, detach_data, detach_data_len);
--- a/src/protocols/silc/pk.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/silc/pk.c Wed Feb 09 19:07:39 2005 -0500
@@ -216,7 +216,7 @@
babbleprint = verify->babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
/* Check whether this key already exists */
- if (stat(ipf, &st) < 0 && (!hostf || stat(hostf, &st) < 0)) {
+ if (g_stat(ipf, &st) < 0 && (!hostf || g_stat(hostf, &st) < 0)) { /* Key does not exist, ask user to verify the key and save it */
silcgaim_verify_ask(name ? name : entity,
fingerprint, babbleprint, verify);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/silc/util.c Wed Feb 09 19:07:39 2005 -0500
@@ -0,0 +1,568 @@
+ Author: Pekka Riikonen <priikone@silcnet.org> + Copyright (C) 2004 Pekka Riikonen + 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; version 2 of the License. + 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. +#include "silcincludes.h" +/**************************** Utility Routines *******************************/ +static char str[256], str2[256]; +const char *silcgaim_silcdir(void) + const char *hd = gaim_home_dir(); + memset(str, 0, sizeof(str)); + g_snprintf(str, sizeof(str) - 1, "%s" G_DIR_SEPARATOR_S ".silc", hd ? hd : "/tmp"); + return (const char *)str; +const char *silcgaim_session_file(const char *account) + memset(str2, 0, sizeof(str2)); + g_snprintf(str2, sizeof(str2) - 1, "%s" G_DIR_SEPARATOR_S "%s_session", + silcgaim_silcdir(), account); + return (const char *)str2; +gboolean silcgaim_ip_is_private(const char *ip) + if (silc_net_is_ip4(ip)) { + if (!strncmp(ip, "10.", 3)) { + } else if (!strncmp(ip, "172.", 4) && strlen(ip) > 6) { + memset(tmp, 0, sizeof(tmp)); + strncpy(tmp, ip + 4, 2); + if (s >= 16 && s <= 31) + } else if (!strncmp(ip, "192.168.", 8)) { +/* This checks stats for various SILC files and directories. First it + checks if ~/.silc directory exist and is owned by the correct user. If + it doesn't exist, it will create the directory. After that it checks if + user's Public and Private key files exists and creates them if needed. */ +gboolean silcgaim_check_silc_dir(GaimConnection *gc) + char filename[256], file_public_key[256], file_private_key[256]; + char servfilename[256], clientfilename[256], friendsfilename[256]; + pw = getpwuid(getuid()); + gaim_debug_error("silc", "silc: %s\n", strerror(errno)); + g_snprintf(filename, sizeof(filename) - 1, "%s", silcgaim_silcdir()); + g_snprintf(servfilename, sizeof(servfilename) - 1, "%s" G_DIR_SEPARATOR_S "serverkeys", + g_snprintf(clientfilename, sizeof(clientfilename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys", + g_snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s" G_DIR_SEPARATOR_S "friends", + * Check ~/.silc directory + if ((g_stat(filename, &st)) == -1) { + /* If dir doesn't exist */ + if (pw->pw_uid == geteuid()) { + if ((g_mkdir(filename, 0755)) == -1) { + gaim_debug_error("silc", "Couldn't create '%s' directory\n", filename); + gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", + gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", filename, strerror(errno)); + /* Check the owner of the dir */ + if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { + gaim_debug_error("silc", "You don't seem to own '%s' directory\n", + * Check ~./silc/serverkeys directory + if ((g_stat(servfilename, &st)) == -1) { + /* If dir doesn't exist */ + if (pw->pw_uid == geteuid()) { + if ((g_mkdir(servfilename, 0755)) == -1) { + gaim_debug_error("silc", "Couldn't create '%s' directory\n", servfilename); + gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", + gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", + servfilename, strerror(errno)); + * Check ~./silc/clientkeys directory + if ((g_stat(clientfilename, &st)) == -1) { + /* If dir doesn't exist */ + if (pw->pw_uid == geteuid()) { + if ((g_mkdir(clientfilename, 0755)) == -1) { + gaim_debug_error("silc", "Couldn't create '%s' directory\n", clientfilename); + gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", + gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", + clientfilename, strerror(errno)); + * Check ~./silc/friends directory + if ((g_stat(friendsfilename, &st)) == -1) { + /* If dir doesn't exist */ + if (pw->pw_uid == geteuid()) { + if ((g_mkdir(friendsfilename, 0755)) == -1) { + gaim_debug_error("silc", "Couldn't create '%s' directory\n", friendsfilename); + gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", + gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", + friendsfilename, strerror(errno)); + * Check Public and Private keys + g_snprintf(file_public_key, sizeof(file_public_key) - 1, "%s", + gaim_prefs_get_string("/plugins/prpl/silc/pubkey")); + g_snprintf(file_private_key, sizeof(file_public_key) - 1, "%s", + gaim_prefs_get_string("/plugins/prpl/silc/privkey")); + if ((g_stat(file_public_key, &st)) == -1) { + /* If file doesn't exist */ + gaim_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); + silc_create_key_pair(SILCGAIM_DEF_PKCS, + file_public_key, file_private_key, NULL, + (gc->account->password == NULL) ? "" : gc->account->password, + NULL, NULL, NULL, FALSE); + g_stat(file_public_key, &st); + gaim_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n", + file_public_key, strerror(errno)); + /* Check the owner of the public key */ + if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { + gaim_debug_error("silc", "You don't seem to own your public key!?\n"); + if ((g_stat(file_private_key, &st)) == -1) { + /* If file doesn't exist */ + gaim_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); + silc_create_key_pair(SILCGAIM_DEF_PKCS, + file_public_key, file_private_key, NULL, + (gc->account->password == NULL) ? "" : gc->account->password, + NULL, NULL, NULL, FALSE); + g_stat(file_private_key, &st); + gaim_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n", + file_private_key, strerror(errno)); + /* Check the owner of the private key */ + if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { + gaim_debug_error("silc", "You don't seem to own your private key!?\n"); + /* Check the permissions for the private key */ + if ((st.st_mode & 0777) != 0600) { + gaim_debug_warning("silc", "Wrong permissions in your private key file `%s'!\n" + "Trying to change them ... ", file_private_key); + if ((chmod(file_private_key, 0600)) == -1) { + gaim_debug_error("silc", + "Failed to change permissions for private key file!\n" + "Permissions for your private key file must be 0600.\n"); + gaim_debug_warning("silc", "Done.\n\n"); +struct passwd *getpwuid(uid_t uid) { + struct passwd *pwd = calloc(1, sizeof(struct passwd)); +void silcgaim_show_public_key(SilcGaim sg, + const char *name, SilcPublicKey public_key, + GCallback callback, void *context) + SilcPublicKeyIdentifier ident; + char *fingerprint, *babbleprint; + SilcUInt32 pk_len, key_len = 0; + ident = silc_pkcs_decode_identifier(public_key->identifier); + pk = silc_pkcs_public_key_encode(public_key, &pk_len); + fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); + babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); + if (silc_pkcs_alloc(public_key->name, &pkcs)) { + key_len = silc_pkcs_public_key_set(pkcs, public_key); + /* Hint for translators: Please check the tabulator width here and in + the next strings (short strings: 2 tabs, longer strings 1 tab, + sum: 3 tabs or 24 characters) */ + g_string_append_printf(s, _("Real Name: \t%s\n"), ident->realname); + g_string_append_printf(s, _("User Name: \t%s\n"), ident->username); + g_string_append_printf(s, _("EMail: \t\t%s\n"), ident->email); + g_string_append_printf(s, _("Host Name: \t%s\n"), ident->host); + g_string_append_printf(s, _("Organization: \t%s\n"), ident->org); + g_string_append_printf(s, _("Country: \t%s\n"), ident->country); + g_string_append_printf(s, _("Algorithm: \t%s\n"), public_key->name); + g_string_append_printf(s, _("Key Length: \t%d bits\n"), (int)key_len); + g_string_append_printf(s, "\n"); + g_string_append_printf(s, _("Public Key Fingerprint:\n%s\n\n"), fingerprint); + g_string_append_printf(s, _("Public Key Babbleprint:\n%s"), babbleprint); + buf = g_string_free(s, FALSE); + gaim_request_action(NULL, _("Public Key Information"), + _("Public Key Information"), + silc_free(fingerprint); + silc_free(babbleprint); + silc_pkcs_free_identifier(ident); +silcgaim_get_attr(SilcDList attrs, SilcAttribute attribute) + SilcAttributePayload attr = NULL; + silc_dlist_start(attrs); + while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) + if (attribute == silc_attribute_get_attribute(attr)) +void silcgaim_get_umode_string(SilcUInt32 mode, char *buf, + memset(buf, 0, buf_size); + if ((mode & SILC_UMODE_SERVER_OPERATOR) || + (mode & SILC_UMODE_ROUTER_OPERATOR)) { + strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ? + (mode & SILC_UMODE_ROUTER_OPERATOR) ? + "[SILC operator] " : "[unknown mode] "); + if (mode & SILC_UMODE_GONE) + strcat(buf, "[away] "); + if (mode & SILC_UMODE_INDISPOSED) + strcat(buf, "[indisposed] "); + if (mode & SILC_UMODE_BUSY) + strcat(buf, "[busy] "); + if (mode & SILC_UMODE_PAGE) + strcat(buf, "[wake me up] "); + if (mode & SILC_UMODE_HYPER) + strcat(buf, "[hyperactive] "); + if (mode & SILC_UMODE_ROBOT) + strcat(buf, "[robot] "); + if (mode & SILC_UMODE_ANONYMOUS) + strcat(buf, "[anonymous] "); + if (mode & SILC_UMODE_BLOCK_PRIVMSG) + strcat(buf, "[blocks private messages] "); + if (mode & SILC_UMODE_DETACHED) + strcat(buf, "[detached] "); + if (mode & SILC_UMODE_REJECT_WATCHING) + strcat(buf, "[rejects watching] "); + if (mode & SILC_UMODE_BLOCK_INVITE) + strcat(buf, "[blocks invites] "); +void silcgaim_get_chmode_string(SilcUInt32 mode, char *buf, + memset(buf, 0, buf_size); + if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) + strcat(buf, "[permanent] "); + if (mode & SILC_CHANNEL_MODE_PRIVATE) + strcat(buf, "[private] "); + if (mode & SILC_CHANNEL_MODE_SECRET) + strcat(buf, "[secret] "); + if (mode & SILC_CHANNEL_MODE_SECRET) + strcat(buf, "[secret] "); + if (mode & SILC_CHANNEL_MODE_PRIVKEY) + strcat(buf, "[private key] "); + if (mode & SILC_CHANNEL_MODE_INVITE) + strcat(buf, "[invite only] "); + if (mode & SILC_CHANNEL_MODE_TOPIC) + strcat(buf, "[topic restricted] "); + if (mode & SILC_CHANNEL_MODE_ULIMIT) + strcat(buf, "[user count limit] "); + if (mode & SILC_CHANNEL_MODE_PASSPHRASE) + strcat(buf, "[passphrase auth] "); + if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) + strcat(buf, "[public key auth] "); + if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) + strcat(buf, "[users silenced] "); + if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) + strcat(buf, "[operators silenced] "); +void silcgaim_get_chumode_string(SilcUInt32 mode, char *buf, + memset(buf, 0, buf_size); + if (mode & SILC_CHANNEL_UMODE_CHANFO) + strcat(buf, "[founder] "); + if (mode & SILC_CHANNEL_UMODE_CHANOP) + strcat(buf, "[operator] "); + if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) + strcat(buf, "[blocks messages] "); + if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) + strcat(buf, "[blocks user messages] "); + if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) + strcat(buf, "[blocks robot messages] "); + if (mode & SILC_CHANNEL_UMODE_QUIET) + strcat(buf, "[quieted] "); +silcgaim_parse_attrs(SilcDList attrs, char **moodstr, char **statusstr, + char **contactstr, char **langstr, char **devicestr, + char **tzstr, char **geostr) + SilcAttributePayload attr; + SilcAttributeMood mood = 0; + SilcAttributeContact contact; + SilcAttributeObjDevice device; + SilcAttributeObjGeo geo; + attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_STATUS_MOOD); + if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) { + if (mood & SILC_ATTRIBUTE_MOOD_HAPPY) + g_string_append_printf(s, "[%s] ", _("Happy")); + if (mood & SILC_ATTRIBUTE_MOOD_SAD) + g_string_append_printf(s, "[%s] ", _("Sad")); + if (mood & SILC_ATTRIBUTE_MOOD_ANGRY) + g_string_append_printf(s, "[%s] ", _("Angry")); + if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS) + g_string_append_printf(s, "[%s] ", _("Jealous")); + if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED) + g_string_append_printf(s, "[%s] ", _("Ashamed")); + if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE) + g_string_append_printf(s, "[%s] ", _("Invincible")); + if (mood & SILC_ATTRIBUTE_MOOD_INLOVE) + g_string_append_printf(s, "[%s] ", _("In Love")); + if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY) + g_string_append_printf(s, "[%s] ", _("Sleepy")); + if (mood & SILC_ATTRIBUTE_MOOD_BORED) + g_string_append_printf(s, "[%s] ", _("Bored")); + if (mood & SILC_ATTRIBUTE_MOOD_EXCITED) + g_string_append_printf(s, "[%s] ", _("Excited")); + if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS) + g_string_append_printf(s, "[%s] ", _("Anxious")); + g_string_free(s, FALSE); + g_string_free(s, TRUE); + attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_STATUS_FREETEXT); + memset(tmp, 0, sizeof(tmp)); + if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) + *statusstr = g_strdup(tmp); + attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_CONTACT); + if (attr && silc_attribute_get_object(attr, &contact, sizeof(contact))) { + if (contact & SILC_ATTRIBUTE_CONTACT_CHAT) + g_string_append_printf(s, "[%s] ", _("Chat")); + if (contact & SILC_ATTRIBUTE_CONTACT_EMAIL) + g_string_append_printf(s, "[%s] ", _("Email")); + if (contact & SILC_ATTRIBUTE_CONTACT_CALL) + g_string_append_printf(s, "[%s] ", _("Phone")); + if (contact & SILC_ATTRIBUTE_CONTACT_PAGE) + g_string_append_printf(s, "[%s] ", _("Paging")); + if (contact & SILC_ATTRIBUTE_CONTACT_SMS) + g_string_append_printf(s, "[%s] ", _("SMS")); + if (contact & SILC_ATTRIBUTE_CONTACT_MMS) + g_string_append_printf(s, "[%s] ", _("MMS")); + if (contact & SILC_ATTRIBUTE_CONTACT_VIDEO) + g_string_append_printf(s, "[%s] ", _("Video Conferencing")); + g_string_free(s, FALSE); + g_string_free(s, TRUE); + attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_LANGUAGE); + memset(tmp, 0, sizeof(tmp)); + if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) + *langstr = g_strdup(tmp); + attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_DEVICE_INFO); + memset(&device, 0, sizeof(device)); + if (attr && silc_attribute_get_object(attr, &device, sizeof(device))) { + if (device.type == SILC_ATTRIBUTE_DEVICE_COMPUTER) + g_string_append_printf(s, "%s: ", _("Computer")); + if (device.type == SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE) + g_string_append_printf(s, "%s: ", _("Mobile Phone")); + if (device.type == SILC_ATTRIBUTE_DEVICE_PDA) + g_string_append_printf(s, "%s: ", _("PDA")); + if (device.type == SILC_ATTRIBUTE_DEVICE_TERMINAL) + g_string_append_printf(s, "%s: ", _("Terminal")); + g_string_append_printf(s, "%s %s %s %s", + device.manufacturer ? device.manufacturer : "", + device.version ? device.version : "", + device.model ? device.model : "", + device.language ? device.language : ""); + g_string_free(s, FALSE); + g_string_free(s, TRUE); + attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_TIMEZONE); + memset(tmp, 0, sizeof(tmp)); + if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) + *tzstr = g_strdup(tmp); + attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_GEOLOCATION); + memset(&geo, 0, sizeof(geo)); + if (attr && silc_attribute_get_object(attr, &geo, sizeof(geo))) + *geostr = g_strdup_printf("%s %s %s (%s)", + geo.longitude ? geo.longitude : "", + geo.latitude ? geo.latitude : "", + geo.altitude ? geo.altitude : "", + geo.accuracy ? geo.accuracy : ""); --- a/src/protocols/toc/toc.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/toc/toc.c Wed Feb 09 19:07:39 2005 -0500
@@ -1676,7 +1676,7 @@
- ft->file = fopen(ft->filename, "w");
+ ft->file = g_fopen(ft->filename, "w"); buf = g_strdup_printf(_("Could not open %s for writing!"), ft->filename);
gaim_notify_error(ft->gc, NULL, buf, strerror(errno));
@@ -1691,7 +1691,7 @@
buf = g_strdup_printf("%s/%s", ft->filename, ft->hdr.name);
- ft->file = fopen(buf, "w");
+ ft->file = g_fopen(buf, "w"); buf = g_strdup_printf("Could not open %s/%s for writing!", ft->filename,
@@ -1839,7 +1839,7 @@
read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8));
- stat(ft->filename, &st);
+ g_stat(ft->filename, &st); fortime = localtime(&st.st_mtime);
basename = g_path_get_basename(ft->filename);
g_snprintf(buf, sizeof(buf), "%2d/%2d/%4d %2d:%2d %8ld %s\r\n",
@@ -1981,7 +1981,7 @@
ft = g_new0(struct file_transfer, 1);
ft->filename = g_strdup(dirname);
- ft->file = fopen(ft->filename, "r");
+ ft->file = g_fopen(ft->filename, "r"); buf = g_strdup_printf("Unable to open %s for transfer.", ft->filename);
gaim_notify_error(ft->gc, NULL, buf, NULL);
@@ -1990,7 +1990,7 @@
- if (stat(dirname, &ft->st)) {
+ if (g_stat(dirname, &ft->st)) { buf = g_strdup_printf("Unable to examine %s.", dirname);
gaim_notify_error(ft->gc, NULL, buf, NULL);
--- a/src/protocols/trepia/trepia.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/trepia/trepia.c Wed Feb 09 19:07:39 2005 -0500
@@ -1152,10 +1152,10 @@
TrepiaSession *session = gc->proto_data;
- if (!stat(filename, &sb)) {
+ if (!g_stat(filename, &sb)) { - if ((fp = fopen(filename, "rb")) != NULL) {
+ if ((fp = g_fopen(filename, "rb")) != NULL) { char *buf = g_malloc(sb.st_size + 1);
--- a/src/protocols/yahoo/yahoo_picture.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/yahoo/yahoo_picture.c Wed Feb 09 19:07:39 2005 -0500
@@ -484,8 +484,8 @@
yahoo_send_picture_update(gc, 0);
/* TODO: check if we're connected and tell everyone we ain't not one no more */
- } else if (!stat(iconfile, &st)) {
- file = fopen(iconfile, "rb");
+ } else if (!g_stat(iconfile, &st)) { + file = g_fopen(iconfile, "rb"); GString *s = g_string_sized_new(st.st_size);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/zephyr/ZGetWGPort.c Wed Feb 09 19:07:39 2005 -0500
@@ -0,0 +1,42 @@
+/* This file is part of the Project Athena Zephyr Notification System. + * It contains source for the ZGetWGPort function. + * Created by: Robert French + * Copyright (c) 1987 by the Massachusetts Institute of Technology. + * For copying and distribution information, see the file +static char rcsid_ZGetWGPort_c[] = "$Header$"; + char *envptr, name[128]; + envptr = getenv("WGFILE"); + (void) sprintf(name, "/tmp/wg.%d", getuid()); + if (!(fp = g_fopen(envptr, "r"))) + /* if fscanf fails, return -1 via wgport */ + if (fscanf(fp, "%d", &wgport) != 1) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/zephyr/ZVariables.c Wed Feb 09 19:07:39 2005 -0500
@@ -0,0 +1,192 @@
+/* This file is part of the Project Athena Zephyr Notification System. + * It contains source for the ZGetVariable, ZSetVariable, and ZUnsetVariable + * Created by: Robert French + * Copyright (c) 1987 by the Massachusetts Institute of Technology. + * For copying and distribution information, see the file +static char rcsid_ZVariables_c[] = "$Header$"; +static int get_localvarfile __P((char *bfr)); +static char *get_varval __P((char *fn, char *val)); +static int varline __P((char *bfr, char *var)); + char varfile[128], *ret; + if (get_localvarfile(varfile)) + if ((ret = get_varval(varfile, var)) != ZERR_NONE) + sprintf(varfile, "%s/zephyr.vars", CONFDIR); + return (get_varval(varfile, var)); +Code_t ZSetVariable(var, value) + char varfile[128], varfilebackup[128], varbfr[512]; + if (get_localvarfile(varfile)) + return (ZERR_INTERNAL); + (void) strcpy(varfilebackup, varfile); + (void) strcat(varfilebackup, ".backup"); + if (!(fpout = g_fopen(varfilebackup, "w"))) + if ((fpin = g_fopen(varfile, "r")) != NULL) { + while (fgets(varbfr, sizeof varbfr, fpin) != (char *) 0) { + if (varbfr[strlen(varbfr)-1] < ' ') + varbfr[strlen(varbfr)-1] = '\0'; + if (varline(varbfr, var)) { + fprintf(fpout, "%s = %s\n", var, value); + fprintf(fpout, "%s\n", varbfr); + (void) fclose(fpin); /* don't care about errs on input */ + fprintf(fpout, "%s = %s\n", var, value); + if (fclose(fpout) == EOF) + return(EIO); /* can't rely on errno */ + if (g_rename(varfilebackup, varfile)) +Code_t ZUnsetVariable(var) + char varfile[128], varfilebackup[128], varbfr[512]; + if (get_localvarfile(varfile)) + return (ZERR_INTERNAL); + (void) strcpy(varfilebackup, varfile); + (void) strcat(varfilebackup, ".backup"); + if (!(fpout = g_fopen(varfilebackup, "w"))) + if ((fpin = g_fopen(varfile, "r")) != NULL) { + while (fgets(varbfr, sizeof varbfr, fpin) != (char *) 0) { + if (varbfr[strlen(varbfr)-1] < ' ') + varbfr[strlen(varbfr)-1] = '\0'; + if (!varline(varbfr, var)) + fprintf(fpout, "%s\n", varbfr); + (void) fclose(fpin); /* don't care about read close errs */ + if (fclose(fpout) == EOF) + return(EIO); /* errno isn't reliable */ + if (g_rename(varfilebackup, varfile)) +static int get_localvarfile(bfr) + envptr = gaim_home_dir(); + (void) strcpy(bfr, envptr); + if (!(pwd = getpwuid((int) getuid()))) { + fprintf(stderr, "Zephyr internal failure: Can't find your entry in /etc/passwd\n"); + (void) strcpy(bfr, pwd->pw_dir); + (void) strcat(bfr, "/"); + (void) strcat(bfr, ".zephyr.vars"); +static char *get_varval(fn, var) + static char varbfr[512]; + while (fgets(varbfr, sizeof varbfr, fp) != (char *) 0) { + if (varbfr[strlen(varbfr)-1] < ' ') + varbfr[strlen(varbfr)-1] = '\0'; + if (!(i = varline(varbfr, var))) + (void) fclose(fp); /* open read-only, don't care */ + (void) fclose(fp); /* open read-only, don't care */ +/* If the variable in the line bfr[] is the same as var, return index to + the variable value, else return 0. */ +static int varline(bfr, var) + if (!bfr[0] || bfr[0] == '#') /* comment or null line */ + while (*cp && !isspace(*cp) && (*cp != '=')) +#define max(a,b) ((a > b) ? (a) : (b)) + if (strncasecmp(bfr, var, max(strlen(var),cp - bfr))) + return(0); /* var is not the var in + while (*cp && isspace(*cp)) /* space up to variable value */ + return (cp - bfr); /* return index */ --- a/src/protocols/zephyr/zephyr.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/protocols/zephyr/zephyr.c Wed Feb 09 19:07:39 2005 -0500
@@ -1315,7 +1315,7 @@
fname = g_strdup_printf("%s/.zephyr.subs", gaim_home_dir());
+ f = g_fopen(fname, "r"); @@ -1411,7 +1411,7 @@
filename = g_strconcat(gaim_home_dir(), "/.anyone", NULL);
- if ((fd = fopen(filename, "r")) != NULL) {
+ if ((fd = g_fopen(filename, "r")) != NULL) { while (fgets(buff, BUFSIZ, fd)) {
@@ -1716,7 +1716,7 @@
fname = g_strdup_printf("%s/.zephyr.subs", gaim_home_dir());
- fd = fopen(fname, "w");
+ fd = g_fopen(fname, "w"); @@ -1778,7 +1778,7 @@
zephyr_account* zephyr = gc->proto_data;
fname = g_strdup_printf("%s/.anyone", gaim_home_dir());
- fd = fopen(fname, "w");
+ fd = g_fopen(fname, "w"); --- a/src/status.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/status.c Wed Feb 09 19:07:39 2005 -0500
@@ -206,16 +206,16 @@
gaim_debug(GAIM_DEBUG_INFO, "status", "Saving statuses to disk\n");
- fp = fopen(user_dir, "r");
+ fp = g_fopen(user_dir, "r"); - mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
+ g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR); filename = g_build_filename(user_dir, "status.xml.save", NULL);
- if ((fp = fopen(filename, "w")) != NULL) {
+ if ((fp = g_fopen(filename, "w")) != NULL) { fprintf(fp, "<?xml version='1.0' encoding='UTF-8' ?>\n\n");
@@ -238,7 +238,7 @@
filename_real = g_build_filename(user_dir, "status.xml", NULL);
- if (rename(filename, filename_real) < 0) {
+ if (g_rename(filename, filename_real) < 0) { gaim_debug(GAIM_DEBUG_ERROR, "status", "Error renaming %s to %s\n",
filename, filename_real);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/themes.c Wed Feb 09 19:07:39 2005 -0500
@@ -0,0 +1,263 @@
+ * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#include "conversation.h" + struct smiley_list *next; +GSList *smiley_themes = NULL; +struct smiley_theme *current_smiley_theme; +void smiley_themeize(GtkWidget *imhtml) + struct smiley_list *list; + if (!current_smiley_theme) + gtk_imhtml_remove_smileys(GTK_IMHTML(imhtml)); + list = current_smiley_theme->list; + char *sml = !strcmp(list->sml, "default") ? NULL : list->sml; + GSList *icons = list->smileys; + gtk_imhtml_associate_smiley(GTK_IMHTML(imhtml), sml, icons->data); +void load_smiley_theme(const char *file, gboolean load) + FILE *f = g_fopen(file, "r"); + struct smiley_theme *theme=NULL; + struct smiley_list *list = NULL; + GSList *lst = smiley_themes; + struct smiley_theme *thm = lst->data; + if (!strcmp(thm->path, file)) { + theme = g_new0(struct smiley_theme, 1); + theme->path = g_strdup(file); + smiley_themes = g_slist_append(smiley_themes, theme); + dirname = g_path_get_dirname(file); + if (current_smiley_theme) { + GSList *already_freed = NULL; + struct smiley_list *wer = current_smiley_theme->list, *wer2; + GtkIMHtmlSmiley *uio = wer->smileys->data; + g_object_unref(uio->icon); + if (!g_slist_find(already_freed, uio->file)) { + already_freed = g_slist_append(already_freed, uio->file); + wer->smileys=g_slist_remove(wer->smileys, uio); + current_smiley_theme->list = NULL; + g_slist_free(already_freed); + current_smiley_theme = theme; + if (!fgets(buf, sizeof(buf), f)) { + if (buf[0] == '#' || buf[0] == '\0') + if (*i == '[' && strchr(i, ']') && load) { + struct smiley_list *child = g_new0(struct smiley_list, 1); + child->sml = g_strndup(i+1, strchr(i, ']') - i - 1); + } else if (!g_ascii_strncasecmp(i, "Name=", strlen("Name="))) { + theme->name = g_strdup(i+ strlen("Name=")); + theme->name[strlen(theme->name)-1] = 0; + } else if (!g_ascii_strncasecmp(i, "Description=", strlen("Description="))) { + theme->desc = g_strdup(i + strlen("Description=")); + theme->desc[strlen(theme->desc)-1] = 0; + } else if (!g_ascii_strncasecmp(i, "Icon=", strlen("Icon="))) { + theme->icon = g_build_filename(dirname, i + strlen("Icon="), NULL); + theme->icon[strlen(theme->icon)-1] = 0; + } else if (!g_ascii_strncasecmp(i, "Author=", strlen("Author="))) { + theme->author = g_strdup(i + strlen("Author=")); + theme->author[strlen(theme->author)-1] = 0; + } else if (load && list) { + gboolean hidden = FALSE; + if (*i == '!' && *(i + 1) == ' ') { + sfile = g_build_filename(dirname, l, NULL); + GtkIMHtmlSmiley *smiley = g_new0(GtkIMHtmlSmiley, 1); + smiley->smile = g_strdup(l); + smiley->hidden = hidden; + list->smileys = g_slist_append(list->smileys, smiley); + for (cnv = gaim_get_conversations(); cnv != NULL; cnv = cnv->next) { + GaimConversation *conv = cnv->data; + if (GAIM_IS_GTK_CONVERSATION(conv)) { + smiley_themeize(GAIM_GTK_CONVERSATION(conv)->imhtml); + smiley_themeize(GAIM_GTK_CONVERSATION(conv)->entry); +void smiley_theme_probe() + probedirs[0] = g_build_filename(DATADIR, "pixmaps", "gaim", "smileys", NULL); + probedirs[1] = g_build_filename(gaim_user_dir(), "smileys", NULL); + for (l=0; probedirs[l]; l++) { + dir = g_dir_open(probedirs[l], 0, NULL); + while ((file = g_dir_read_name(dir))) { + path = g_build_filename(probedirs[l], file, "theme", NULL); + /* Here we check to see that the theme has proper syntax. + * We set the second argument to FALSE so that it doesn't load + load_smiley_theme(path, FALSE); + g_mkdir(probedirs[l], S_IRUSR | S_IWUSR | S_IXUSR); +GSList *get_proto_smileys(const char *id) { + GaimPlugin *proto = gaim_find_prpl(id); + struct smiley_list *list, *def; + if(!current_smiley_theme) + if(!current_smiley_theme->list) + def = list = current_smiley_theme->list; + if(!strcmp(list->sml, "default")) + else if(proto && !strcmp(proto->info->name, list->sml)) + return list ? list->smileys : def->smileys; --- a/src/util.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/util.c Wed Feb 09 19:07:39 2005 -0500
@@ -1927,7 +1927,7 @@
- if (mkdir(dir, mode) < 0) {
+ if (g_mkdir(dir, mode) < 0) { gaim_debug_warning("build_dir", "mkdir: %s\n", strerror(errno));
@@ -1972,7 +1972,7 @@
"Problem creating the template\n");
- if( (fp = fopen( result, "w+" )) == NULL ) {
+ if( (fp = g_fopen( result, "w+" )) == NULL ) { gaim_debug(GAIM_DEBUG_ERROR, "gaim_mkstemp",
"Couldn't fopen() %s\n", result);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/win32/libc_interface.c Wed Feb 09 19:07:39 2005 -0500
@@ -0,0 +1,376 @@
+ * File: libc_interface.c + * Date: October 14, 2002 + * Description: libc interface for Windows api + * Copyright (C) 2002-2003, Herman Bloggs <hermanator12002@yahoo.com> + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#include "libc_internal.h" +#if !GLIB_CHECK_VERSION(2,6,0) +# define g_remove remove +static char errbuf[1024]; +static int wgaim_is_socket( int fd ) { + unsigned int optlen = sizeof(int); + if( (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void*)&optval, &optlen)) == SOCKET_ERROR ) { + int error = WSAGetLastError(); + if( error == WSAENOTSOCK ) + gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "wgaim_is_socket: getsockopt returned error: %d\n", error); +int wgaim_socket (int namespace, int style, int protocol) { + ret = socket( namespace, style, protocol ); + if( ret == INVALID_SOCKET ) { + errno = WSAGetLastError(); +int wgaim_connect(int socket, struct sockaddr *addr, u_long length) { + ret = connect( socket, addr, length ); + if( ret == SOCKET_ERROR ) { + errno = WSAGetLastError(); + if( errno == WSAEWOULDBLOCK ) + errno = WSAEINPROGRESS; +int wgaim_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlenptr) { + if(getsockopt(socket, level, optname, optval, optlenptr) == SOCKET_ERROR ) { + errno = WSAGetLastError(); +int wgaim_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen) { + if(setsockopt(socket, level, optname, optval, optlen) == SOCKET_ERROR ) { + errno = WSAGetLastError(); +int wgaim_getsockname(int socket, struct sockaddr *addr, socklen_t *lenptr) { + if(getsockname(socket, addr, lenptr) == SOCKET_ERROR) { + errno = WSAGetLastError(); +int wgaim_bind(int socket, struct sockaddr *addr, socklen_t length) { + if(bind(socket, addr, length) == SOCKET_ERROR) { + errno = WSAGetLastError(); +int wgaim_listen(int socket, unsigned int n) { + if(listen(socket, n) == SOCKET_ERROR) { + errno = WSAGetLastError(); +/* This is not a full implementation of fcntl. Update as needed.. */ +int wgaim_fcntl(int socket, int command, int val) { + ret = ioctlsocket(socket, FIONBIO, &imode); + ret = ioctlsocket(socket, FIONBIO, &imode); + if( ret == SOCKET_ERROR ) { + errno = WSAGetLastError(); + gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "wgaim_fcntl: Unsupported command\n"); +int wgaim_ioctl(int fd, int command, void* val) { + if (ioctlsocket(fd, FIONBIO, (unsigned long *)val) == SOCKET_ERROR) { + errno = WSAGetLastError(); +int wgaim_inet_aton(const char *name, struct in_addr *addr) { + if((addr->s_addr = inet_addr(name)) == INADDR_NONE) +struct hostent* wgaim_gethostbyname(const char *name) { + if((hp = gethostbyname(name)) == NULL) { + errno = WSAGetLastError(); +char* wgaim_strerror( int errornum ) { + if( errornum > WSABASEERR ) { + sprintf( errbuf, "Windows socket error #%d", errornum ); + return strerror( errornum ); + * We need to figure out whether fd is a file or socket handle. +int wgaim_read(int fd, void *buf, unsigned int size) { + if( wgaim_is_socket(fd) ) { + if( (ret = recv(fd, buf, size, 0)) == SOCKET_ERROR ) { + errno = WSAGetLastError(); + /* connection has been gracefully closed */ + /* success reading socket */ + /* fd is not a socket handle.. pass it off to read */ + return read(fd, buf, size); +int wgaim_write(int fd, const void *buf, unsigned int size) { + if( wgaim_is_socket(fd) ) { + if( (ret = send(fd, buf, size, 0)) == SOCKET_ERROR ) { + errno = WSAGetLastError(); + return write(fd, buf, size); +int wgaim_close(int fd) { + if( wgaim_is_socket(fd) ) { + if( (ret = closesocket(fd)) == SOCKET_ERROR ) { + errno = WSAGetLastError(); +int wgaim_gethostname(char *name, size_t size) { + if(gethostname(name, size) == SOCKET_ERROR) { + errno = WSAGetLastError(); +int wgaim_gettimeofday(struct timeval *p, struct timezone *z) { + struct _timeb timebuffer; + z->tz_minuteswest = _timezone/60; + z->tz_dsttime = _daylight; + p->tv_sec = timebuffer.time; /* seconds since 1-1-1970 */ + p->tv_usec = timebuffer.millitm*1000; /* microseconds */ +#if !GLIB_CHECK_VERSION(2,6,0) +int wgaim_rename (const char *oldname, const char *newname) { + struct _stat oldstat, newstat; + if(_stat(oldname, &oldstat) == 0) { + if(_stat(newname, &newstat) == 0) { + if(_S_ISDIR(oldstat.st_mode)) { + if(!_S_ISDIR(newstat.st_mode)) { + return rename(oldname, newname); + /* This is not quite right.. If newname is empty and + is not a sub dir of oldname, newname should be + deleted and oldname should be renamed. + gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "wgaim_rename does not behave here as it should\n"); + return rename(oldname, newname); + /* oldname is not a dir */ + if(_S_ISDIR(newstat.st_mode)) { + /* newname is not a dir */ + return rename(oldname, newname); + /* newname doesn't exist */ + return rename(oldname, newname); + /* oldname doesn't exist */ +struct tm * wgaim_localtime_r (const time_t *time, struct tm *resultp) { + tmptm = localtime(time); + return memcpy(resultp, tmptm, sizeof(struct tm)); --- a/src/win32/libc_interface.h Wed Feb 09 09:58:22 2005 -0500
+++ b/src/win32/libc_interface.h Wed Feb 09 19:07:39 2005 -0500
@@ -27,6 +27,7 @@
#include "libc_internal.h"
extern int wgaim_socket(int namespace, int style, int protocol);
@@ -67,7 +68,9 @@
#define fcntl( fd, command, val ) \
wgaim_fcntl( fd, command, val )
-#define open( args... ) _open( args )
+#if !GLIB_CHECK_VERSION(2,6,0) +# define open( args... ) _open( args ) extern int wgaim_inet_aton(const char *name, struct in_addr *addr);
@@ -90,10 +93,6 @@
#define strerror( errornum ) \
wgaim_strerror( errornum )
-extern char* wgaim_strsep(char **stringp, const char *delim);
-#define strsep( stringp, delim ) \
-wgaim_strsep( stringp, delim )
#define bzero( dest, size ) memset( dest, 0, size )
@@ -126,12 +125,18 @@
#define snprintf _snprintf
#define vsnprintf _vsnprintf
+#if !GLIB_CHECK_VERSION(2,6,0) +/* I think that this can probably go away, in favor of g_rename() */ extern int wgaim_rename(const char *oldname, const char *newname);
#define rename( oldname, newname ) \
wgaim_rename( oldname, newname )
+#if !GLIB_CHECK_VERSION(2,6,0) #define mkdir(a,b) _mkdir((a))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/win32/untar.c Wed Feb 09 19:07:39 2005 -0500
@@ -0,0 +1,633 @@
+/*#define VERSION "1.4"*/ + * Untar extracts files from an uncompressed tar archive, or one which + * has been compressed with gzip. Usually such archives will have file + * names that end with ".tar" or ".tgz" respectively, although untar + * doesn't depend on any naming conventions. For a summary of the + * command-line options, run untar with no arguments. + * Untar doesn't require any special libraries or compile-time flags. + * A simple "cc untar.c -o untar" (or the local equivalent) is + * sufficient. Even "make untar" works, without needing a Makefile. + * For Microsoft Visual C++, the command is "cl /D_WEAK_POSIX untar.c" + * (for 32 bit compilers) or "cl /F 1400 untar.c" (for 16-bit). + * IF YOU SEE COMPILER WARNINGS, THAT'S NORMAL; you can ignore them. + * Most of the warnings could be eliminated by adding #include <string.h> + * but that isn't portable -- some systems require <strings.h> and + * <malloc.h>, for example. Because <string.h> isn't quite portable, + * and isn't really necessary in the context of this program, it isn't + * Untar only requires the <stdio.h> header. It uses old-style function + * definitions. It opens all files in binary mode. Taken together, + * this means that untar should compile & run on just about anything. + * If your system supports the POSIX chmod(2), utime(2), link(2), and + * symlink(2) calls, then you may wish to compile with -D_POSIX_SOURCE, + * which will enable untar to use those system calls to restore the + * timestamp and permissions of the extracted files, and restore links. + * (For Linux, _POSIX_SOURCE is always defined.) + * For systems which support some POSIX features but not enough to support + * -D_POSIX_SOURCE, you might be able to use -D_WEAK_POSIX. This allows + * untar to restore time stamps and file permissions, but not links. + * This should work for Microsoft systems, and hopefully others as well. + * AUTHOR & COPYRIGHT INFO: + * Written by Steve Kirkendall, kirkenda@cs.pdx.edu + * Placed in public domain, 6 October 1995 + * Portions derived from inflate.c -- Not copyrighted 1992 by Mark Adler + * version c10p1, 10 January 1993 + * Altered by Herman Bloggs <hermanator12002@yahoo.com> + * Changes: Stripped out gz compression code, added better interface for +#if GLIB_CHECK_VERSION(2,6,0) +# include <glib/gstdio.h> +#define mkdir(a,b) _mkdir((a)) +#define untar_error( error, args... ) gaim_debug(GAIM_DEBUG_ERROR, "untar", error, ## args ) +#define untar_warning( warning, args... ) gaim_debug(GAIM_DEBUG_WARNING, "untar", warning, ## args ) +#define untar_verbose( args... ) gaim_debug(GAIM_DEBUG_INFO, "untar", ## args ) +#define WSIZE 32768 /* size of decompression buffer */ +#define TSIZE 512 /* size of a "tape" block */ +#define CR 13 /* carriage-return character */ +#define LF 10 /* line-feed character */ +typedef unsigned char Uchar_t; +typedef unsigned short Ushort_t; +typedef unsigned long Ulong_t; + char filename[100]; /* 0 name of next file */ + char mode[8]; /* 100 Permissions and type (octal digits) */ + char owner[8]; /* 108 Owner ID (ignored) */ + char group[8]; /* 116 Group ID (ignored) */ + char size[12]; /* 124 Bytes in file (octal digits) */ + char mtime[12]; /* 136 Modification time stamp (octal digits)*/ + char checksum[8]; /* 148 Header checksum (ignored) */ + char type; /* 156 File type (see below) */ + char linkto[100]; /* 157 Linked-to name */ + char brand[8]; /* 257 Identifies tar version (ignored) */ + char ownername[32]; /* 265 Name of owner (ignored) */ + char groupname[32]; /* 297 Name of group (ignored) */ + char devmajor[8]; /* 329 Device major number (ignored) */ + char defminor[8]; /* 337 Device minor number (ignored) */ + char prefix[155]; /* 345 Prefix of name (optional) */ + char RESERVED[12]; /* 500 Pad header size to 512 bytes */ +#define ISREGULAR(hdr) ((hdr).type < '1' || (hdr).type > '6') +static const char *inname = NULL; /* name of input archive */ +static FILE *infp = NULL; /* input byte stream */ +static FILE *outfp = NULL; /* output stream, for file currently being extracted */ +static Ulong_t outsize = 0; /* number of bytes remainin in file currently being extracted */ +static char **only = NULL; /* array of filenames to extract/list */ +static int nonlys = 0; /* number of filenames in "only" array; 0=extract all */ +static int didabs = 0; /* were any filenames affected by the absence of -p? */ +static untar_opt untarops = 0; /* Untar options */ +/* Options checked during untar process */ +#define LISTING (untarops & UNTAR_LISTING) /* 1 if listing, 0 if extracting */ +#define QUIET (untarops & UNTAR_QUIET) /* 1 to write nothing to stdout, 0 for normal chatter */ +#define VERBOSE (untarops & UNTAR_VERBOSE) /* 1 to write extra information to stdout */ +#define FORCE (untarops & UNTAR_FORCE) /* 1 to overwrite existing files, 0 to skip them */ +#define ABSPATH (untarops & UNTAR_ABSPATH) /* 1 to allow leading '/', 0 to strip leading '/' */ +#define CONVERT (untarops & UNTAR_CONVERT) /* 1 to convert newlines, 0 to leave unchanged */ +/*----------------------------------------------------------------------------*/ +/* create a file for writing. If necessary, create the directories leading up + * to that file as well. +static FILE *createpath(name) + char *name; /* pathname of file to create */ + /* if we aren't allowed to overwrite and this file exists, return NULL */ + if (!FORCE && access(name, 0) == 0) + untar_warning("%s: exists, will not overwrite without \"FORCE option\"\n", name); + /* first try creating it the easy way */ + fp = g_fopen(name, CONVERT ? "w" : "wb"); + /* Else try making all of its directories, and then try creating + for (i = 0; name[i]; i++) + /* If this is a slash, then temporarily replace the '/' + * with a '\0' and do a mkdir() on the resulting string. + * Ignore errors for now. + (void)g_mkdir(name, 0777); + fp = g_fopen(name, CONVERT ? "w" : "wb"); + untar_error("Error opening: %s\n", name); +/* Create a link, or copy a file. If the file is copied (not linked) then +static void linkorcopy(src, dst, sym) + char *src; /* name of existing source file */ + char *dst; /* name of new destination file */ + int sym; /* use symlink instead of link */ + /* Open the source file. We do this first to make sure it exists */ + fpsrc = g_fopen(src, "rb"); + untar_error("Error opening: %s\n", src); + /* Create the destination file. On POSIX systems, this is just to + * make sure the directory path exists. + fpdst = createpath(dst); + /* error message already given */ + /* first try to link it over, instead of copying */ + /* This story had a happy ending */ + /* Dang. Reopen the destination again */ + fpdst = g_fopen(dst, "wb"); + /* This *can't* fail */ +# endif /* _WEAK_POSIX */ +#endif /* _POSIX_SOURCE */ + while ((c = getc(fpsrc)) != EOF) + untar_warning("%s: copy instead of link\n", dst); +/* This calls fwrite(), possibly after converting CR-LF to LF */ +static void cvtwrite(blk, size, fp) + Uchar_t *blk; /* the block to be written */ + Ulong_t size; /* number of characters to be written */ + FILE *fp; /* file to write to */ + static Uchar_t mod[TSIZE]; + for (i = j = 0; i < size; i++) + /* convert LF to local newline convention */ + /* If CR-LF pair, then delete the CR */ + else if (blk[i] == CR && (i+1 >= size || blk[i+1] == LF)) + /* other characters copied literally */ + fwrite(blk, (size_t)size, sizeof(Uchar_t), fp); +/* Compute the checksum of a tar header block, and return it as a long int. + * The checksum can be computed using either POSIX rules (unsigned bytes) + * or Sun rules (signed bytes). +static long checksum(tblk, sunny) + tar_t *tblk; /* buffer containing the tar header block */ + int sunny; /* Boolean: Sun-style checksums? (else POSIX) */ + /* compute the sum of the first 148 bytes -- everything up to but not + * including the checksum field itself. + for (scan = (char *)tblk; scan < tblk->checksum; scan++) + if (sunny && (*scan & 0x80) != 0) + /* for the 8 bytes of the checksum field, add blanks to the sum */ + sum += ' ' * sizeof tblk->checksum; + scan += sizeof tblk->checksum; + /* finish counting the sum of the rest of the block */ + for (; scan < (char *)tblk + sizeof *tblk; scan++) + if (sunny && (*scan & 0x80) != 0) +/* list files in an archive, and optionally extract them as well */ +static int untar_block(Uchar_t *blk) { + static char nbuf[256];/* storage space for prefix+name, combined */ + static char *name,*n2;/* prefix and name, combined */ + static int first = 1;/* Boolean: first block of archive? */ + long sum; /* checksum for this block */ + static mode_t mode; /* file permissions */ + static struct utimbuf timestamp; /* file timestamp */ + /* make a local copy of the block, and treat it as a tar header */ + tblk[0] = *(tar_t *)blk; + /* process each type of tape block differently */ + /* data block, but not the last one */ + cvtwrite(blk, (Ulong_t)TSIZE, outfp); + /* last data block of current file */ + cvtwrite(blk, outsize, outfp); + utime(nbuf, ×tamp); + else if ((tblk)->filename[0] == '\0') + /* end-of-archive marker */ + untar_warning("Removed leading slashes because \"ABSPATH option\" wasn't given.\n"); + /* half-assed verification -- does it look like header? */ + if ((tblk)->filename[99] != '\0' + || ((tblk)->size[0] < '0' + && (tblk)->size[0] != ' ') + || (tblk)->size[0] > '9') + untar_error("%s: not a valid tar file\n", inname); + untar_error("Garbage detected; preceding file may be damaged\n"); + /* combine prefix and filename */ + memset(nbuf, 0, sizeof nbuf); + strncpy(name, (tblk)->prefix, sizeof (tblk)->prefix); + strncat(name + strlen(name), (tblk)->filename, + sizeof (tblk)->filename); + strncpy(name, (tblk)->filename, + sizeof (tblk)->filename); + /* Convert any backslashes to forward slashes, and guard + * against doubled-up slashes. (Some DOS versions of "tar" + * get this wrong.) Also strip off leading slashes. + if (!ABSPATH && (*name == '/' || *name == '\\')) + for (n2 = nbuf; *name; name++) + || (ABSPATH && n2 == nbuf) + || (n2 != nbuf && n2[-1] != '/')) + /* verify the checksum */ + for (sum = 0L, i = 0; i < sizeof((tblk)->checksum); i++) + if ((tblk)->checksum[i] >= '0' + && (tblk)->checksum[i] <= '7') + sum = sum * 8 + (tblk)->checksum[i] - '0'; + if (sum != checksum(tblk, 0) && sum != checksum(tblk, 1)) + untar_error("Garbage detected; preceding file may be damaged\n"); + untar_error("%s: header has bad checksum for %s\n", inname, nbuf); + /* From this point on, we don't care whether this is the first + * block or not. Might as well reset the "first" flag now. + /* if last character of name is '/' then assume directory */ + if (*nbuf && nbuf[strlen(nbuf) - 1] == '/') + /* convert file size */ + for (outsize = 0L, i = 0; i < sizeof((tblk)->size); i++) + if ((tblk)->size[i] >= '0' && (tblk)->size[i] <= '7') + outsize = outsize * 8 + (tblk)->size[i] - '0'; + /* convert file timestamp */ + for (timestamp.modtime=0L, i=0; i < sizeof((tblk)->mtime); i++) + if ((tblk)->mtime[i] >= '0' && (tblk)->mtime[i] <= '7') + timestamp.modtime = timestamp.modtime * 8 + + (tblk)->mtime[i] - '0'; + timestamp.actime = timestamp.modtime; + /* convert file permissions */ + for (mode = i = 0; i < sizeof((tblk)->mode); i++) + if ((tblk)->mode[i] >= '0' && (tblk)->mode[i] <= '7') + mode = mode * 8 + (tblk)->mode[i] - '0'; + /* If we have an "only" list, and this file isn't in it, + && strcmp(only[i], nbuf) + && (strncmp(only[i], nbuf, strlen(only[i])) + || nbuf[strlen(only[i])] != '/'); + ISREGULAR(*tblk) ? '-' : ("hlcbdp"[(tblk)->type - '1']), + untar_verbose("%s\n", nbuf); + /* if link, then do the link-or-copy thing */ + if (tblk->type == '1' || tblk->type == '2') + untar_verbose(" -> %s\n", tblk->linkto); + linkorcopy(tblk->linkto, nbuf, tblk->type == '2'); + /* If directory, then make a weak attempt to create it. + * Ideally we would do the "create path" thing, but that + * seems like more trouble than it's worth since traditional + * tar archives don't contain directories anyway. + else if (mkdir(nbuf, mode) == 0) + else if (g_mkdir(nbuf, 0755) == 0) + untar_verbose("%s\n", n2); + /* if not a regular file, then skip it */ + untar_verbose(" ignored\n"); + /* print file statistics */ + untar_verbose(" (%ld byte%s, %ld tape block%s)\n", + outsize == 1 ? "" : "s", + (outsize + TSIZE - 1) / TSIZE, + (outsize > 0 && outsize <= TSIZE) ? "" : "s"); + /* if extracting, then try to create the file */ + outfp = createpath(nbuf); + /* if file is 0 bytes long, then we're done already! */ + if (outsize == 0 && outfp) + utime(nbuf, ×tamp); +/* Process an archive file. This involves reading the blocks one at a time + * and passing them to a untar() function. +int untar(const char *filename, const char* destdir, untar_opt options) { + char curdir[_MAX_PATH]; + infp = g_fopen(filename, "rb"); + untar_error("Error opening: %s\n", filename); + /* Set current directory */ + if(!GetCurrentDirectory(_MAX_PATH, curdir)) { + untar_error("Could not get current directory (error %d).\n", GetLastError()); + if(!SetCurrentDirectory(destdir)) { + untar_error("Could not set current directory to (error %d): %s\n", GetLastError(), destdir); + /* send each block to the untar_block() function */ + while (fread(slide, 1, TSIZE, infp) == TSIZE) { + if(!untar_block(slide)) { + untar_error("untar failure: %s\n", filename); + if (outsize > 0 && ret) { + untar_warning("Last file might be truncated!\n"); + if(!SetCurrentDirectory(curdir)) { + untar_error("Could not set current dir back to original (error %d).\n", GetLastError()); + /* close the archive file. */ --- a/src/win32/win32dep.c Wed Feb 09 09:58:22 2005 -0500
+++ b/src/win32/win32dep.c Wed Feb 09 19:07:39 2005 -0500
@@ -27,9 +27,16 @@
+#if GLIB_CHECK_VERSION(2,6,0) +# include <glib/gstdio.h> +# define g_unlink unlink #include <gdk/gdkwin32.h>
@@ -56,16 +63,14 @@
-typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATH)(HWND, int, HANDLE, DWORD, LPTSTR);
+typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATHA)(HWND, int, HANDLE, DWORD, LPSTR); +typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATHW)(HWND, int, HANDLE, DWORD, LPWSTR); SHGFP_TYPE_CURRENT = 0, // current value for user, verify it exists
SHGFP_TYPE_DEFAULT = 1, // default value, may not exist
-#define CSIDL_APPDATA 0x001a
-#define CSIDL_FLAG_CREATE 0x8000
typedef BOOL (CALLBACK* LPFNFLASHWINDOWEX)(PFLASHWINFO);
@@ -78,7 +83,7 @@
-static char app_data_dir[MAX_PATH] = "C:";
+static char app_data_dir[MAX_PATH + 1] = "C:"; static char install_dir[MAXPATHLEN];
static char lib_dir[MAXPATHLEN];
static char locale_dir[MAXPATHLEN];
@@ -94,7 +99,8 @@
LPFNFLASHWINDOWEX MyFlashWindowEx = NULL;
-LPFNSHGETFOLDERPATH MySHGetFolderPath = NULL;
+LPFNSHGETFOLDERPATHA MySHGetFolderPathA = NULL; +LPFNSHGETFOLDERPATHW MySHGetFolderPathW = NULL; FARPROC wgaim_find_and_loadproc(char*, char*);
extern void wgaim_gtkspell_init();
@@ -142,136 +148,15 @@
MyFlashWindowEx = (LPFNFLASHWINDOWEX)wgaim_find_and_loadproc("user32.dll", "FlashWindowEx" );
-static char* base_name(char* path) {
- while((tmp=strchr(tmp, '\\'))) {
-BOOL folder_exists(char *folder) {
- WIN32_FIND_DATA fileinfo;
- memset(&fileinfo, 0, sizeof(WIN32_FIND_DATA));
- if((fh=FindFirstFile(folder, &fileinfo))) {
- if(fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- SetLastError(ERROR_SUCCESS);
- SetLastError(ERROR_FILE_EXISTS);
-/* Recursively create directories in the dest path */
-static BOOL CreateDirectoryR(char *dest) {
- static BOOL start = TRUE;
- char *str = g_strdup(dest);
- ret = CreateDirectoryR(str);
- while((tmp1=strchr(tmp1, '\\'))) {
- CreateDirectoryR(dest);
- if(CreateDirectory(dest, NULL) == 0 && GetLastError() != ERROR_ALREADY_EXISTS) {
- gaim_debug(GAIM_DEBUG_ERROR, "wgaim",
- "Error creating directory: %s. Errno: %u\n",
- dest, (UINT)GetLastError());
-static BOOL move_folder(char *src, char* dest, char* copytitle, BOOL overwrite) {
- SHFILEOPSTRUCT dirmove;
- g_return_val_if_fail(src!=NULL, ret);
- g_return_val_if_fail(dest!=NULL, ret);
- if(!folder_exists(src)) {
- gaim_debug(GAIM_DEBUG_WARNING, "wgaim",
- "move_folder: Source folder %s, does not exist\n", src);
- char *dstpath = g_strdup_printf("%s\\%s", dest, base_name(src));
- if(folder_exists(dstpath)) {
- gaim_debug(GAIM_DEBUG_WARNING, "wgaim",
- "move_folder: Destination Folder %s, already exists\n", dstpath);
- /* Create dest folder if it doesn't exist */
- if(!CreateDirectoryR(dest)) {
- gaim_debug(GAIM_DEBUG_ERROR, "wgaim", "Error creating directory: %s\n", dest);
- tsrc = g_strdup_printf("%s%c", src, '\0');
- tdest = g_strdup_printf("%s%c", dest, '\0');
- memset(&dirmove, 0, sizeof(SHFILEOPSTRUCT));
- dirmove.wFunc = FO_MOVE;
- dirmove.fFlags = FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS;
- dirmove.hNameMappings = 0;
- dirmove.lpszProgressTitle = copytitle;
- if(SHFileOperation(&dirmove)==0)
static void wgaim_debug_print(GaimDebugLevel level, const char *category, const char *format, va_list args) {
- char *str = g_strdup_vprintf(format, args);
- printf("%s%s%s", category?category:"", category?": ":"",str);
+ str = g_strdup_vprintf(format, args); + str = g_strdup(format); + printf("%s%s%s", category?category:"", category?": ":"",str); static GaimDebugUiOps ops = {
@@ -448,7 +333,7 @@
if((fin = gzopen(in, "rb"))) {
- if(!(fout = fopen(out, "wb"))) {
+ if(!(fout = g_fopen(out, "wb"))) { gaim_debug(GAIM_DEBUG_ERROR, "wgaim_gz_decompress", "Error opening file: %s\n", out);
@@ -491,7 +376,7 @@
gaim_debug(GAIM_DEBUG_ERROR, "wgaim_gz_untar", "Failure untaring %s\n", tmpfile);
@@ -569,13 +454,33 @@
/* Set app data dir, used by gaim_home_dir */
newenv = (char*)g_getenv("GAIMHOME");
- if((MySHGetFolderPath = (LPFNSHGETFOLDERPATH)wgaim_find_and_loadproc("shfolder.dll", "SHGetFolderPathA"))) {
- MySHGetFolderPath(NULL,
- NULL, SHGFP_TYPE_CURRENT, app_data_dir);
- strcpy(app_data_dir, "C:");
+#if GLIB_CHECK_VERSION(2,6,0) + if ((MySHGetFolderPathW = (LPFNSHGETFOLDERPATHW) wgaim_find_and_loadproc("shfolder.dll", "SHGetFolderPathW"))) { + wchar_t utf_16_dir[MAX_PATH +1]; + MySHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, + SHGFP_TYPE_CURRENT, utf_16_dir); + temp = g_utf16_to_utf8(utf_16_dir, -1, NULL, NULL, NULL); + g_strlcpy(app_data_dir, temp, sizeof(app_data_dir)); + } else if ((MySHGetFolderPathA = (LPFNSHGETFOLDERPATHA) wgaim_find_and_loadproc("shfolder.dll", "SHGetFolderPathA"))) { + char locale_dir[MAX_PATH + 1]; + MySHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, + SHGFP_TYPE_CURRENT, locale_dir); + temp = g_locale_to_utf8(locale_dir, -1, NULL, NULL, NULL); + g_strlcpy(app_data_dir, temp, sizeof(app_data_dir)); + if ((MySHGetFolderPathA = (LPFNSHGETFOLDERPATHA) wgaim_find_and_loadproc("shfolder.dll", "SHGetFolderPathA"))) { + MySHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, + SHGFP_TYPE_CURRENT, app_data_dir); + strcpy(app_data_dir, "C:"); g_strlcpy(app_data_dir, newenv, sizeof(app_data_dir));