# HG changeset patch # User Rob Flynn # Date 1034306041 0 # Node ID 9682c0e022c66efe6856436025e19c8c38300841 # Parent afc5bb164c5a7573b4f27201b7848555502b1831 [gaim-migrate @ 3753] Yeah this will probably break a lot of shit knowing my luck. But hey, I really don't care what people thnk. committer: Tailor Script diff -r afc5bb164c5a -r 9682c0e022c6 ChangeLog.win32 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ChangeLog.win32 Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,18 @@ +version 0.60 alpha 2 (10/9/02) + * Perl functionality added + * PNGs work + * Path issues fixed for Win9x + * Added g command line flag for logging of GTK and GLIB debugging. + * No more console in Win9x for glib logging (when not debugging). + * URL links now work. + * Plugins: autorecon, iconaway, spellchk and ticker now work. + * Language translations are working. + * Using GTK 2.0.6 (Some GTK bugs fixed since 2.0.3) + * Gadu-Gadu works + * gtkimhtml copying to clipboard works. Selecting text copies it to + the clipboard. + * Gaim now minimizes to the system tray. + * Various other feature updates from the Gaim crew. Read ChangeLog :) + +version 0.60 alpha 1 (9/13/2002) + * Initial alpha release diff -r afc5bb164c5a -r 9682c0e022c6 Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,140 @@ +# Makefile.mingw +# +# Author: hermanator12002@yahoo.com +# Date 9/11/02 +# Description: Top Makefile for win32 (mingw) port of Gaim +# + +GAIM_SRC = ./src +GAIM_PROTOS = $(GAIM_SRC)/protocols +GAIM_PLUGINS = ./plugins +GAIM_PIXMAPS = ./pixmaps +GAIM_INSTALL_DIR = ./win32-install-dir +GTK_TOP = ../win32-dev/gtk_2_0 +GTK_LIBS = $(GTK_TOP)/lib +PERL_TOP = ../win32-dev/perl56 +OSCAR = $(GAIM_PROTOS)/oscar +YAHOO = $(GAIM_PROTOS)/yahoo +MSN = $(GAIM_PROTOS)/msn +TOC = $(GAIM_PROTOS)/toc +IRC = $(GAIM_PROTOS)/irc +JABBER = $(GAIM_PROTOS)/jabber +NAPSTER = $(GAIM_PROTOS)/napster +GG = $(GAIM_PROTOS)/gg +PO = ./po + +NEEDED_DLLS = $(GTK_LIBS)/libgdk-win32-2.0-0.dll \ + $(GTK_LIBS)/libglib-2.0-0.dll \ + $(GTK_LIBS)/libintl-1.dll \ + $(GTK_LIBS)/iconv.dll \ + $(GTK_LIBS)/libgmodule-2.0-0.dll \ + $(GTK_LIBS)/libgtk-win32-2.0-0.dll \ + $(GTK_LIBS)/libgdk_pixbuf-2.0-0.dll \ + $(GTK_LIBS)/libgobject-2.0-0.dll \ + $(GTK_LIBS)/libgthread-2.0-0.dll \ + $(GTK_TOP)/bin/libjpeg.dll \ + $(GTK_TOP)/bin/libpng.dll \ + $(GTK_TOP)/bin/libtiff.dll \ + $(GTK_TOP)/bin/zlib.dll \ + $(GTK_LIBS)/libpango-1.0-0.dll \ + $(GTK_LIBS)/libpangoft2-1.0-0.dll \ + $(GTK_LIBS)/libpangowin32-1.0-0.dll \ + $(GTK_LIBS)/libatk-1.0-0.dll \ + $(PERL_TOP)/perl56.dll + +# For Gtk 2.0.3 +# $(GTK_LIBS)/libjpeg6b.dll \ +# $(GTK_LIBS)/libpng-3.dll \ +# $(GTK_LIBS)/libtiff.dll \ +# $(GTK_LIBS)/libz.dll \ + +# For Gtk 2.0.6 +# $(GTK_TOP)/bin/libjpeg.dll \ +# $(GTK_TOP)/bin/libpng.dll \ +# $(GTK_TOP)/bin/libtiff.dll \ +# $(GTK_TOP)/bin/zlib.dll \ + + + + +PIXMAPS_DIALOGS = $(GAIM_PIXMAPS)/gaim_error.png \ + $(GAIM_PIXMAPS)/gaim_info.png \ + $(GAIM_PIXMAPS)/gaim_warning.png \ + $(GAIM_PIXMAPS)/gaim_question.png + +PIXMAPS_BUTTONS = $(GAIM_PIXMAPS)/edit.png + +PIXMAPS = $(GAIM_PIXMAPS)/away.png \ + $(GAIM_PIXMAPS)/connect.png \ + $(GAIM_PIXMAPS)/msgpend.png \ + $(GAIM_PIXMAPS)/msgunread.png \ + $(GAIM_PIXMAPS)/offline.png \ + $(GAIM_PIXMAPS)/online.png + + +## +## Don't forget to change STATIC_PROTO_INIT, in config.h.mingw if you +## change the status of a protocol (static/plugin) +## + +OSCAR_TYPE = PLUGIN +YAHOO_TYPE = PLUGIN +MSN_TYPE = PLUGIN +TOC_TYPE = PLUGIN +IRC_TYPE = PLUGIN +JABBER_TYPE = PLUGIN +NAPSTER_TYPE = PLUGIN +GG_TYPE = PLUGIN + +all: + cp config.h.mingw config.h + $(MAKE) TYPE='$(OSCAR_TYPE)' -C $(OSCAR) -f Makefile.mingw + $(MAKE) TYPE='$(YAHOO_TYPE)' -C $(YAHOO) -f Makefile.mingw + $(MAKE) TYPE='$(MSN_TYPE)' -C $(MSN) -f Makefile.mingw + $(MAKE) TYPE='$(TOC_TYPE)' -C $(TOC) -f Makefile.mingw + $(MAKE) TYPE='$(IRC_TYPE)' -C $(IRC) -f Makefile.mingw + $(MAKE) TYPE='$(JABBER_TYPE)' -C $(JABBER) -f Makefile.mingw + $(MAKE) TYPE='$(GG_TYPE)' -C $(GG) -f Makefile.mingw + $(MAKE) -C $(GAIM_SRC) -f Makefile.mingw + $(MAKE) -C $(GAIM_PLUGINS) -f Makefile.mingw + + +install: all + mkdir -p $(GAIM_INSTALL_DIR)/plugins + mkdir -p $(GAIM_INSTALL_DIR)/pixmaps/gaim/dialogs + mkdir -p $(GAIM_INSTALL_DIR)/pixmaps/gaim/buttons + $(MAKE) -C $(PO) -f Makefile.mingw install + $(MAKE) -C $(GAIM_SRC) -f Makefile.mingw install + $(MAKE) -C $(GAIM_PLUGINS) -f Makefile.mingw install + $(MAKE) TYPE='$(OSCAR_TYPE)' -C $(OSCAR) -f Makefile.mingw install + $(MAKE) TYPE='$(YAHOO_TYPE)' -C $(YAHOO) -f Makefile.mingw install + $(MAKE) TYPE='$(MSN_TYPE)' -C $(MSN) -f Makefile.mingw install + $(MAKE) TYPE='$(TOC_TYPE)' -C $(TOC) -f Makefile.mingw install + $(MAKE) TYPE='$(IRC_TYPE)' -C $(IRC) -f Makefile.mingw install + $(MAKE) TYPE='$(JABBER_TYPE)' -C $(JABBER) -f Makefile.mingw install + $(MAKE) TYPE='$(GG_TYPE)' -C $(GG) -f Makefile.mingw install + cp $(NEEDED_DLLS) $(GAIM_INSTALL_DIR) + cp $(PIXMAPS_DIALOGS) $(GAIM_INSTALL_DIR)/pixmaps/gaim/dialogs + cp $(PIXMAPS_BUTTONS) $(GAIM_INSTALL_DIR)/pixmaps/gaim/buttons + cp $(PIXMAPS) $(GAIM_INSTALL_DIR)/pixmaps/gaim + mkdir -p $(GAIM_INSTALL_DIR)/lib/gtk-2.0 + cp -R $(GTK_LIBS)/gtk-2.0/2.0.0 $(GAIM_INSTALL_DIR)/lib/gtk-2.0 + cp -R $(GTK_LIBS)/pango $(GAIM_INSTALL_DIR)/lib + cp -R $(GTK_TOP)/etc $(GAIM_INSTALL_DIR) + +installer: + makensis.exe gaim-installer.nsi + +clean: + $(MAKE) -C $(PO) -f Makefile.mingw clean + $(MAKE) -C $(OSCAR) -f Makefile.mingw clean + $(MAKE) -C $(YAHOO) -f Makefile.mingw clean + $(MAKE) -C $(MSN) -f Makefile.mingw clean + $(MAKE) -C $(TOC) -f Makefile.mingw clean + $(MAKE) -C $(IRC) -f Makefile.mingw clean + $(MAKE) -C $(JABBER) -f Makefile.mingw clean + $(MAKE) -C $(GG) -f Makefile.mingw clean + $(MAKE) -C $(GAIM_SRC) -f Makefile.mingw clean + $(MAKE) -C $(GAIM_PLUGINS) -f Makefile.mingw clean + rm -rf config.h $(GAIM_INSTALL_DIR) + rm -rf Install-Gaim*.exe diff -r afc5bb164c5a -r 9682c0e022c6 PROGRAMMING_NOTES --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PROGRAMMING_NOTES Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,22 @@ +Notes on keeping GAIM OS independant +------------------------------------ + +General +------- +- Use G_DIR_SEPARATOR_S and G_DIR_SEPARATOR for paths + +- Use g_getenv, g_snprintf, g_vsnprintf + +- Use gaim_home_dir instead of g_get_home_dir or g_getenv("HOME") + + +PLUGINS & PROTOS +---------------- + +- G_MODULE_EXPORT all functions which are to be accessed from outside the + scope of its "dll" or "so". (E.G. gaim_plugin_init) + +- G_MODULE_IMPORT all global variables which are located outside your + dynamic library. (E.G. connections) + + (Not doing this will cause "Memory Access Violations" in Win32) diff -r afc5bb164c5a -r 9682c0e022c6 README.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,110 @@ +How to build Gaim using MinGw +============================= + +Set Up Build Environment +------------------------ + +- Install Cygwin bash shell (www.cygwin.com). + +- Install MinGw v1.1 (http://www.mingw.org) + Make sure to read the installation instructions. Make sure to set MinGw's + bin directory in your PATH (in .bash_login), before Cygwin's bin dir + (so that mingw's build tools are used over cygwin's). + +Install LIBs, DLLs and headers used by GAIM +------------------------------------------- + + Assuming you have the gaim sources in ~/gaim, you will need to do the + fowllowing: + + GTK & GLIB (v 2.0.6 as of writing) + ---------------------------------- + + $ mkdir -p ~/win32-dev/gtk_2_0/zips + + Download the following from thw win32 download page at www.gtk.org to the + zips dir you just created: + + atk-1.0.3-20020821.zip + atk-dev-1.0.3-20020821.zip + gettext-dev-0.10.40-20020904.zip + glib-2.0.6-20020802.zip + glib-dev-2.0.6-20020802.zip + gtk+-2.0.6-20020921.zip + gtk+-dev-2.0.6-20020921.zip + libiconv-1.7-w32.bin.zip + libintl-0.10.40-tml-20020904.zip + libjpeg-6b-bin.zip + libpng-1.2.4-1-bin.zip + pango-1.0.4-20020921.zip + pango-dev-1.0.4-20020921.zip + tiff-3.5.7-bin.zip + zlib-1.1.4-bin.zip + + $ cd ~/win32-dev/gtk_2_0/zips + $ unzip -d .. + + $ cd .. + $ cp lib/libintl-1.dll ./bin + $ cd libiconv-1.7-w32.bin + $ cp iconv.exe ../bin + $ cp iconv.lib ../lib + $ cp localcharset.dll ../lib + $ cp iconv.dll ../lib + $ cp iconv.dll ../bin + $ cp iconv.h ../include/ + $ cp libcharset.h ../include/ + + NOTE: If you use a more recent versions of any of these packages, you may + need to move files around so that they can be found when Gaim is built. + + Perl56 + ------ + + Download perl-5.6.1 from www.cpan.org. You can build perl56 yourself if + you have MS Visual C++, or you can download a win32 binary distribution + (I tried SiePerl successfully). In either case make sure you do the + following: + + $ mkdir -p ~/win32-dev/perl56 + + Copy Perl's "CORE" directory to ~/win32-dev/perl56 as well as "perl56.dll" + and "perl56.lib". + + +Build Gaim +---------- + + $ cd ~/gaim + $ make -f Makefile.mingw install + +Run Gaim +-------- + + $ cd ~/gaim/win32-install-dir + $ ./gaim.exe + + That's it.. + + Note: If you wish to build an install exe of Gaim, then you need to install + NSIS from http://www.nullsoft.com/free/nsis/ making sure to place its + binary dir in your PATH. Then... + + $ cd ~/gaim/win32-install-dir + $ make -f Makefile.mingw installer + +Debugging +--------- + + There is quite a good "Just In Time" debugger for MinGw: + http://mefriss1.swan.ac.uk/~jfonseca/gnu-win32/software/drmingw/ + + +Happy Gaiming... +Herman Bloggs + + + + + + diff -r afc5bb164c5a -r 9682c0e022c6 VERSION --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VERSION Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,1 @@ +0.60a2 diff -r afc5bb164c5a -r 9682c0e022c6 gaim-installer.nsi --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gaim-installer.nsi Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,58 @@ +; Installer script for win32 Gaim +; Generated NSIS script file (generated by makensitemplate.phtml 0.21) +; Herman on Sep 11 02 @ 21:52 + +; NOTE: this .NSI script is designed for NSIS v1.8+ + +Name "Gaim 0.60 alpha 2 (Win32)" +OutFile "Install-Gaim0.60a2.exe" +Icon .\pixmaps\gaim-install.ico + +; Some default compiler settings (uncomment and change at will): +; SetCompress auto ; (can be off or force) +; SetDatablockOptimize on ; (can be off) +; CRCCheck on ; (can be off) +; AutoCloseWindow false ; (can be true for the window go away automatically at end) +; ShowInstDetails hide ; (can be show to have them shown, or nevershow to disable) +; SetDateSave off ; (can be on to have files restored to their orginal date) + +InstallDir "$PROGRAMFILES\Gaim" +InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Gaim" "" +DirShow show ; (make this hide to not let the user change it) +DirText "Select the directory to install Gaim in:" + + +Section "" ; (default section) +SetOutPath "$INSTDIR" +; add files / whatever that need to be installed here. +File /r .\win32-install-dir\*.* +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Gaim" "" "$INSTDIR" +WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\Gaim" "DisplayName" "Gaim (remove only)" +WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\Gaim" "UninstallString" '"$INSTDIR\uninst.exe"' +; write out uninstaller +WriteUninstaller "$INSTDIR\uninst.exe" +SectionEnd ; end of default section + +Section "Gaim Start Menu Group" + SetOutPath "$SMPROGRAMS\Gaim" + CreateShortCut "$SMPROGRAMS\Gaim\Gaim.lnk" \ + "$INSTDIR\gaim.exe" + CreateShortCut "$SMPROGRAMS\Gaim\Unistall.lnk" \ + "$INSTDIR\uninst.exe" +SectionEnd + + + +; begin uninstall settings/section +UninstallText "This will uninstall Gaim from your system" + +Section Uninstall +; add delete commands to delete whatever files/registry keys/etc you installed here. +RMDir /r "$SMPROGRAMS\Gaim" +DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Gaim" +DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Gaim" +RMDir /r "$INSTDIR" +SectionEnd ; end of uninstall section + +; eof + diff -r afc5bb164c5a -r 9682c0e022c6 pixmaps/gaim-install.ico Binary file pixmaps/gaim-install.ico has changed diff -r afc5bb164c5a -r 9682c0e022c6 pixmaps/gaim.ico Binary file pixmaps/gaim.ico has changed diff -r afc5bb164c5a -r 9682c0e022c6 plugins/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,106 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of Gaim Plugins +# + +# +# PATHS +# + +GAIM_PLUGINS := . +GAIM_TOP := .. +GTK_TOP := ../../win32-dev/gtk_2_0 +OSCAR_ROOT := ../src/protocols/oscar +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir +TICKER := ./ticker + +## +## VARIABLE DEFINITIONS +## + +VERSION := $(shell cat $(GAIM_TOP)/VERSION) + +# Compiler Options + +CC = gcc.exe + +CFLAGS = -O2 -Wall -Werror -mno-cygwin -fnative-struct + +DEFINES = -DGTK_ENABLE_BROKEN -DVERSION=\"$(VERSION)\" + +.SUFFIXES: +.SUFFIXES: .c .dll + +## +## INCLUDE MAKEFILES +## + + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(OSCAR_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP) \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 -lglib-2.0 -lgdk-win32-2.0 -lgobject-2.0 -lgmodule-2.0 -lintl -lws2_32 -liberty -lgaim + +## +## RULES +## + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: plugins + $(MAKE) -C $(TICKER) -f Makefile.mingw + +install: + cp $(GAIM_PLUGINS)/*.dll $(GAIM_PLUGINS)/*.pl $(GAIM_INSTALL_DIR)/plugins + $(MAKE) -C $(TICKER) -f Makefile.mingw install + +# +# BUILD Plugin +# + +.c.dll: + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o tmp$@.o -c $< + dlltool -D $@ -z $@.def tmp$@.o + gcc -mdll -o junk.tmp -Wl,--base-file,$@.base tmp$@.o $(LIB_PATHS) $(LIBS) + dlltool -D $@ -b $@.base -e $@.exp -d $@.def + gcc -mdll -o $@ tmp$@.o -Wl,$@.exp $(LIB_PATHS) $(LIBS) + rm -rf $@.base $@.def $@.exp junk.tmp + +plugins: autorecon.dll iconaway.dll spellchk.dll + + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf *.dll + $(MAKE) -C $(TICKER) -f Makefile.mingw clean diff -r afc5bb164c5a -r 9682c0e022c6 plugins/autorecon.c --- a/plugins/autorecon.c Fri Oct 11 02:10:08 2002 +0000 +++ b/plugins/autorecon.c Fri Oct 11 03:14:01 2002 +0000 @@ -2,6 +2,10 @@ #include "gaim.h" #include "prpl.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #define INITIAL 8000 #define MAXTIME 1024000 @@ -9,14 +13,6 @@ static guint tim = 0; -char *name() { - return "Auto Reconnect"; -} - -char *description() { - return "When you are kicked offline, this reconnects you."; -} - static gboolean do_signon(gpointer data) { struct aim_user *u = data; if (g_slist_index(aim_users, u) < 0) @@ -41,7 +37,19 @@ } } -char *gaim_plugin_init(GModule *handle) { +/* + * EXPORTED FUNCTIONS + */ + +G_MODULE_EXPORT char *name() { + return "Auto Reconnect"; +} + +G_MODULE_EXPORT char *description() { + return "When you are kicked offline, this reconnects you."; +} + +G_MODULE_EXPORT char *gaim_plugin_init(GModule *handle) { hash = g_hash_table_new(g_int_hash, g_int_equal); gaim_signal_connect(handle, event_signoff, reconnect, NULL); @@ -49,7 +57,7 @@ return NULL; } -void gaim_plugin_remove() { +G_MODULE_EXPORT void gaim_plugin_remove() { if (tim) g_source_remove(tim); g_hash_table_destroy(hash); diff -r afc5bb164c5a -r 9682c0e022c6 plugins/chatlist.c --- a/plugins/chatlist.c Fri Oct 11 02:10:08 2002 +0000 +++ b/plugins/chatlist.c Fri Oct 11 03:14:01 2002 +0000 @@ -10,6 +10,9 @@ #include #include +#ifdef _WIN32 +#include "win32dep.h" +#endif #define AOL_SRCHSTR "aim:GoChat?RoomName=" @@ -293,7 +296,7 @@ parent = NULL; } -GtkWidget *gaim_plugin_config_gtk() +G_MODULE_EXPORT GtkWidget *gaim_plugin_config_gtk() { GtkWidget *ret, *vbox; GtkWidget *list1, *list2; @@ -390,14 +393,14 @@ setup_buddy_chats(); } -char *gaim_plugin_init(GModule *m) +G_MODULE_EXPORT char *gaim_plugin_init(GModule *m) { restore_chat_prefs(); gaim_signal_connect(m, event_signon, handle_signon, NULL); return NULL; } -void gaim_plugin_remove() +G_MODULE_EXPORT void gaim_plugin_remove() { if (parent) gtk_widget_destroy(parent); @@ -428,12 +431,12 @@ return &desc; } -char *name() +G_MODULE_EXPORT char *name() { return "Chat List"; } -char *description() +G_MODULE_EXPORT char *description() { return "Allows you to add chat rooms to your buddy list. Click the configure button to choose" " which rooms."; diff -r afc5bb164c5a -r 9682c0e022c6 plugins/iconaway.c --- a/plugins/iconaway.c Fri Oct 11 02:10:08 2002 +0000 +++ b/plugins/iconaway.c Fri Oct 11 03:14:01 2002 +0000 @@ -1,14 +1,18 @@ -#include "../config.h" +#define GAIM_PLUGINS #include "gaim.h" #include +#ifdef _WIN32 +#include "win32dep.h" +#endif + void *handle; -extern GtkWidget *imaway; -extern GtkWidget *blist; -extern GtkWidget *all_chats; -extern GtkWidget *all_convos; +G_MODULE_IMPORT GtkWidget *imaway; +G_MODULE_IMPORT GtkWidget *blist; +G_MODULE_IMPORT GtkWidget *all_chats; +G_MODULE_IMPORT GtkWidget *all_convos; #ifdef USE_APPLET extern void applet_destroy_buddy(); @@ -25,7 +29,11 @@ gtk_window_iconify(GTK_WINDOW(all_chats)); } -char *gaim_plugin_init(GModule *h) { +/* + * EXPORTED FUNCTIONS + */ + +G_MODULE_EXPORT char *gaim_plugin_init(GModule *h) { handle = h; gaim_signal_connect(handle, event_away, iconify_windows, NULL); @@ -34,7 +42,7 @@ } struct gaim_plugin_description desc; -struct gaim_plugin_description *gaim_plugin_desc() { +G_MODULE_EXPORT struct gaim_plugin_description *gaim_plugin_desc() { desc.api_version = PLUGIN_API_VERSION; desc.name = g_strdup("Iconify on away"); desc.version = g_strdup(VERSION); @@ -44,10 +52,10 @@ return &desc; } -char *name() { +G_MODULE_EXPORT char *name() { return "Iconify On Away"; } -char *description() { +G_MODULE_EXPORT char *description() { return "Iconifies the away box and the buddy list when you go away."; } diff -r afc5bb164c5a -r 9682c0e022c6 plugins/spellchk.c --- a/plugins/spellchk.c Fri Oct 11 02:10:08 2002 +0000 +++ b/plugins/spellchk.c Fri Oct 11 03:14:01 2002 +0000 @@ -18,6 +18,9 @@ #include #include #include +#ifdef _WIN32 +#include "win32dep.h" +#endif struct replace_words { char *bad; @@ -136,35 +139,7 @@ free(ibuf); } -char *gaim_plugin_init(GModule *handle) { - load_conf(); - gaim_signal_connect(handle, event_im_send, substitute_words, NULL); - gaim_signal_connect(handle, event_chat_send, substitute_words, NULL); - return NULL; -} - -void gaim_plugin_remove() { -} - -struct gaim_plugin_description desc; -struct gaim_plugin_description *gaim_plugin_desc() { - desc.api_version = PLUGIN_API_VERSION; - desc.name = g_strdup("Text replacement"); - desc.version = g_strdup(VERSION); - desc.description = g_strdup("Replaces text in outgoing messages according to user-defined rules."); - desc.authors = g_strdup("Eric Warmehoven <eric@warmenhoven.org>"); - desc.url = g_strdup(WEBSITE); - return &desc; -} - -char *name() { - return "IM Spell Check"; -} - -char *description() { - return "Watches outgoing IM text and corrects common spelling errors."; -} static int num_words(char *m) { int count = 0; @@ -358,7 +333,41 @@ } } -GtkWidget *gaim_plugin_config_gtk() { +/* + * EXPORTED FUNCTIONS + */ + +G_MODULE_EXPORT char *gaim_plugin_init(GModule *handle) { + load_conf(); + + gaim_signal_connect(handle, event_im_send, substitute_words, NULL); + gaim_signal_connect(handle, event_chat_send, substitute_words, NULL); + return NULL; +} + +G_MODULE_EXPORT void gaim_plugin_remove() { +} + +struct gaim_plugin_description desc; +G_MODULE_EXPORT struct gaim_plugin_description *gaim_plugin_desc() { + desc.api_version = PLUGIN_API_VERSION; + desc.name = g_strdup("Text replacement"); + desc.version = g_strdup(VERSION); + desc.description = g_strdup("Replaces text in outgoing messages according to user-defined rules."); + desc.authors = g_strdup("Eric Warmehoven <eric@warmenhoven.org>"); + desc.url = g_strdup(WEBSITE); + return &desc; +} + +G_MODULE_EXPORT char *name() { + return "IM Spell Check"; +} + +G_MODULE_EXPORT char *description() { + return "Watches outgoing IM text and corrects common spelling errors."; +} + +G_MODULE_EXPORT GtkWidget *gaim_plugin_config_gtk() { GtkWidget *ret, *vbox, *win; GtkWidget *hbox; GtkWidget *button; diff -r afc5bb164c5a -r 9682c0e022c6 plugins/ticker/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/ticker/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,137 @@ +# +# Makefile.mingw +# +# Description: Makefile for ticker plugin. +# + +# +# PATHS +# + +INCLUDE_DIR := . + +GTK_TOP := ../../../win32-dev/gtk_2_0 +GAIM_TOP := ../.. +TICKER_ROOT := . +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir +DLL_INSTALL_DIR := $(GAIM_INSTALL_DIR)/plugins + +## +## VARIABLE DEFINITIONS +## + +TARGET = ticker + +VERSION := $(shell cat $(GAIM_TOP)/VERSION) + +# Compiler Options + +CC = gcc.exe + +CFLAGS = -O2 -Werror -Wall -mno-cygwin -fnative-struct + +DEFINES = -DGTK_ENABLE_BROKEN -DVERSION=\"$(VERSION)\" + + +## +## INCLUDE MAKEFILES +## + + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(TICKER_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src + + +## +## SOURCES, OBJECTS +## + +C_SRC = ticker.c \ + gtkticker.c + + +OBJECTS = $(C_SRC:%.c=%.o) + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 -lglib-2.0 -lgdk-win32-2.0 -lgmodule-2.0 -lgobject-2.0 -lws2_32 -lintl -lgaim + + +## +## RULES +## + +# How to make a C file + +%.o: %.c + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: $(TARGET).dll + +install: + cp $(TICKER_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + + +## +## BUILD Dependencies +## + +$(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + +## +## BUILD DLL +## + +$(TARGET).def: $(OBJECTS) + dlltool --dllname $(TARGET).dll -z $(TARGET).def \ + $(OBJECTS) + +$(TARGET).base: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + gcc -mdll -o junk.tmp -Wl,--base-file,$@ $(OBJECTS) $(LIB_PATHS) $(LIBS) + rm -rf junk.tmp + +$(TARGET).exp: $(TARGET).def $(TARGET).base + dlltool --dllname $(TARGET).dll --base-file $(TARGET).base \ + --output-exp $(TARGET).exp --def $(TARGET).def + rm -rf $(TARGET).base + +$(TARGET).dll: $(OBJECTS) $(TARGET).exp $(GAIM_TOP)/src/gaim.lib + gcc -mdll -o $(TARGET).dll $(OBJECTS) -Wl,$(TARGET).exp $(LIB_PATHS) $(LIBS) + rm -rf $(TARGET).exp + + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).def diff -r afc5bb164c5a -r 9682c0e022c6 plugins/ticker/ticker.c --- a/plugins/ticker/ticker.c Fri Oct 11 02:10:08 2002 +0000 +++ b/plugins/ticker/ticker.c Fri Oct 11 03:14:01 2002 +0000 @@ -31,6 +31,9 @@ #include "gaim.h" #include "prpl.h" #include "pixmaps/no_icon.xpm" +#ifdef _WIN32 +#include "win32dep.h" +#endif static GtkWidget *tickerwindow = NULL; static GtkWidget *ticker; @@ -49,6 +52,10 @@ gboolean userclose = FALSE; GtkWidget *msgw; +/* for win32 compatability */ +G_MODULE_IMPORT GSList *connections; +G_MODULE_IMPORT GtkWidget *blist; + void BuddyTickerDestroyWindow( GtkWidget *window ); void BuddyTickerCreateWindow( void ); void BuddyTickerAddUser( char *name, char *alias, GdkPixmap *pm, GdkBitmap *bm ); @@ -372,7 +379,7 @@ } void signoff_cb(struct gaim_connection *gc) { - if (!connections->next) { + if (connections && !connections->next) { gtk_widget_destroy(tickerwindow); tickerwindow = NULL; ticker = NULL; @@ -401,7 +408,19 @@ gdk_bitmap_unref(bm); } -char *gaim_plugin_init(GModule *h) { +/* + * EXPORTED FUNCTIONS + */ + +G_MODULE_EXPORT char *name() { + return "Buddy Ticker"; +} + +G_MODULE_EXPORT char *description() { + return "Scrolls online buddies from your buddy list."; +} + +G_MODULE_EXPORT char *gaim_plugin_init(GModule *h) { handle = h; gaim_signal_connect(h, event_buddy_signon, signon_cb, NULL); @@ -414,11 +433,11 @@ return NULL; } -void gaim_plugin_remove() { - gtk_widget_destroy(tickerwindow); +G_MODULE_EXPORT void gaim_plugin_remove() { + BuddyTickerDestroyWindow(tickerwindow); } struct gaim_plugin_description desc; -struct gaim_plugin_description *gaim_plugin_desc() { +G_MODULE_EXPORT struct gaim_plugin_description *gaim_plugin_desc() { desc.api_version = PLUGIN_API_VERSION; desc.name = g_strdup("Ticker"); desc.version = g_strdup(VERSION); diff -r afc5bb164c5a -r 9682c0e022c6 po/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/po/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,113 @@ +# Makefile.mingw +# +# Description: Makefile to generate mo files +# + +PACKAGE = gaim + + +srcdir = . +top_srcdir = .. +GAIM_INSTALL_DIR = ../win32-install-dir +LOCALEDIR = $(GAIM_INSTALL_DIR)/locale +CC = gcc +GTK_BIN = ../../win32-dev/gtk_2_0/bin +GMSGFMT = $(GTK_BIN)/msgfmt +MSGFMT = $(GTK_BIN)/msgfmt +XGETTEXT = $(GTK_BIN)/xgettext +MSGMERGE = $(GTK_BIN)/msgmerge + + +.SUFFIXES: +.SUFFIXES: .c .o .po .pot .pox .gmo .mo + + +## +## SOURCES, OBJECTS +## + +CATALOGS = bg.gmo cs.gmo da.gmo de.gmo es.gmo fi.gmo fr.gmo hu.gmo it.gmo ja.gmo ko.gmo nl.gmo pl.gmo ro.gmo ru.gmo sk.gmo sv.gmo zh_CN.gmo zh_TW.gmo + +POTFILES = \ + ../plugins/docklet/docklet.c \ + ../plugins/chatlist.c \ + ../plugins/gtik.c \ + ../src/protocols/gg/gg.c \ + ../src/protocols/icq/gaim_icq.c \ + ../src/protocols/irc/irc.c \ + ../src/protocols/jabber/jabber.c \ + ../src/protocols/msn/msn.c \ + ../src/protocols/napster/napster.c \ + ../src/protocols/oscar/oscar.c \ + ../src/protocols/toc/toc.c \ + ../src/protocols/yahoo/yahoo.c \ + ../src/protocols/zephyr/zephyr.c \ + ../src/about.c \ + ../src/aim.c \ + ../src/away.c \ + ../src/buddy.c \ + ../src/buddy_chat.c \ + ../src/conversation.c \ + ../src/dialogs.c \ + ../src/gaimrc.c \ + ../src/html.c \ + ../src/module.c \ + ../src/multi.c \ + ../src/perl.c \ + ../src/plugins.c \ + ../src/prefs.c \ + ../src/prpl.c \ + ../src/server.c \ + ../src/sound.c + + +## +## RULES +## + +.pot.pox: + $(MAKE) $(PACKAGE).pot + $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + rm -f $@ && $(GMSGFMT) --statistics -o $@ $< + + +## +## TARGETS +## + + +all: $(CATALOGS) + +$(PACKAGE).pot: $(POTFILES) POTFILES.in + $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \ + --add-comments --keyword=_ --keyword=N_ \ + --files-from=$(srcdir)/POTFILES.in \ + && test ! -f $(PACKAGE).po \ + || ( rm -f $(srcdir)/$(PACKAGE).pot \ + && mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot ) + +install: all + mkdir -p $(LOCALEDIR) + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\.gmo$$//'`; \ + dir=$(LOCALEDIR)/$$lang/LC_MESSAGES; \ + mkdir -p $$dir; \ + if test -r $$cat; then \ + cp $$cat $$dir/$(PACKAGE).mo; \ + echo "installing $$cat as $$dir/$(PACKAGE).mo"; \ + else \ + cp $(srcdir)/$$cat $$dir/$(PACKAGE).mo; \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE).mo"; \ + fi; \ + done + +clean: + rm -f *.gmo *.pot *.pox diff -r afc5bb164c5a -r 9682c0e022c6 sounds/BuddyArrive.wav Binary file sounds/BuddyArrive.wav has changed diff -r afc5bb164c5a -r 9682c0e022c6 sounds/BuddyLeave.wav Binary file sounds/BuddyLeave.wav has changed diff -r afc5bb164c5a -r 9682c0e022c6 sounds/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sounds/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,15 @@ +# Makefile for creating wave data include files (mingw win32) + +all: wav2h.exe hfiles + +wav2h.exe: + gcc -c wav2h.c -o wav2h.o + gcc -o wav2h.exe wav2h.o + +%.h: %.wav wav2h.exe + ./wav2h.exe $< + +hfiles: BuddyArrive.h BuddyLeave.h Send.h Receive.h RedAlert.h + +clean: + rm -rf *.o *.exe *.h \ No newline at end of file diff -r afc5bb164c5a -r 9682c0e022c6 sounds/Receive.wav Binary file sounds/Receive.wav has changed diff -r afc5bb164c5a -r 9682c0e022c6 sounds/RedAlert.wav Binary file sounds/RedAlert.wav has changed diff -r afc5bb164c5a -r 9682c0e022c6 sounds/Send.wav Binary file sounds/Send.wav has changed diff -r afc5bb164c5a -r 9682c0e022c6 src/about.c --- a/src/about.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/about.c Fri Oct 11 03:14:01 2002 +0000 @@ -81,7 +81,8 @@ GdkBitmap *bm; GtkWidget *hbox; GtkWidget *button; - GtkWidget *text; + GtkWidget *view; + GtkTextBuffer *buffer; GtkWidget *sw; char abouttitle[45]; @@ -131,20 +132,44 @@ gtk_box_pack_start(GTK_BOX(fbox), label, TRUE, TRUE, 0); gtk_widget_show(label); - text = gtk_text_new(NULL, NULL); + view = gtk_text_view_new (); + + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); - gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, - _("Active Developers\n====================\nRob Flynn (maintainer) [ rob@marko.net ]\nSean Egan (coder) [ bj91704@binghamton.edu ]\n\nCrazy Patch Writers\n===================\nBenjamin Miller\nDecklin Foster\nNathan Walp\nMark Doliner\n\nRetired Developers\n===================\nJim Duchek\nEric Warmenhoven [ warmenhoven@yahoo.com ]\nMark Spencer (original author) [ markster@marko.net ]"), 394); + gtk_text_buffer_set_text (buffer, + "Active Developers\n" + "=================\n" + "Rob Flynn (maintainer) [ rob@marko.net ]\n" + "Sean Egan (coder) [ bj91704@binghamton.edu ]\n" + "\n" + "Crazy Patch Writers\n" + "===================\n" + "Benjamin Miller\n" + "Decklin Foster\n" + "Nathan Walp\n" + "Mark Doliner\n" + "\n" + "WIN32 Port\n" + "==========\n" + "Herman Bloggs [ hermanator12002@yahoo.com ]\n" + "\n" + "Retired Developers\n" + "==================\n" + "Jim Duchek\n" + "Eric Warmenhoven [ warmenhoven@yahoo.com ]\n" + "Mark Spencer (original author) [ markster@marko.net ]\n" + "\n", + -1); sw = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - gtk_container_add(GTK_CONTAINER(sw), text); + gtk_container_add(GTK_CONTAINER(sw), view); gtk_widget_set_usize(GTK_WIDGET(sw), -1, 150); gtk_widget_show(sw); gtk_box_pack_start(GTK_BOX(fbox), sw, TRUE, TRUE, 0); - gtk_widget_show(text); + gtk_widget_show(view); /* Close Button */ diff -r afc5bb164c5a -r 9682c0e022c6 src/aim.c --- a/src/aim.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/aim.c Fri Oct 11 03:14:01 2002 +0000 @@ -23,20 +23,26 @@ #include #endif #ifdef GAIM_PLUGINS +#ifndef _WIN32 #include +#endif #endif /* GAIM_PLUGINS */ #include +#ifdef _WIN32 +#include +#else #include -#include #include -#include #include -#include #include #include -#include #include #include +#endif /* _WIN32 */ +#include +#include +#include +#include #include #include #include @@ -51,6 +57,9 @@ #include "locale.h" #include "gtkspell.h" #include +#ifdef _WIN32 +#include "win32dep.h" +#endif static gchar *aspell_cmd[] = { "aspell", "--sug-mode=fast","-a", NULL }; static gchar *ispell_cmd[] = { "ispell", "-a", NULL }; @@ -72,6 +81,9 @@ char *opt_away_arg = NULL; char *opt_rcfile_arg = NULL; int opt_debug = 0; +#ifdef _WIN32 +int opt_gdebug = 0; +#endif #if HAVE_SIGNAL_H /* @@ -243,6 +255,7 @@ } mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_wmclass(GTK_WINDOW(mainwindow), "login", "Gaim"); gtk_window_set_policy(GTK_WINDOW(mainwindow), FALSE, FALSE, TRUE); gtk_signal_connect(GTK_OBJECT(mainwindow), "delete_event", @@ -427,6 +440,7 @@ } #endif +#ifndef _WIN32 static gboolean socket_readable(GIOChannel *source, GIOCondition cond, gpointer ud) { guchar type; @@ -480,16 +494,16 @@ GdkPixbuf *icon = NULL; /* use the nice PNG icon for all the windows */ - icon = gdk_pixbuf_new_from_file(DATADIR "/pixmaps/gaim.png",NULL); + icon = gdk_pixbuf_new_from_file(DATADIR G_DIR_SEPARATOR_S "pixmaps" G_DIR_SEPARATOR_S "gaim.png",NULL); if (icon) { icons = g_list_append(icons,icon); gtk_window_set_default_icon_list(icons); g_object_unref(G_OBJECT(icon)); } else { - debug_printf("Failed to load icon from %s/pixmaps/gaim.png\n",DATADIR); + debug_printf("Failed to load icon from %s" G_DIR_SEPARATOR_S "pixmaps" G_DIR_SEPARATOR_S "gaim.png\n",DATADIR); } - g_snprintf(name, sizeof(name), "%s/gaim_%s.%d", g_get_tmp_dir(), g_get_user_name(), gaim_session); + g_snprintf(name, sizeof(name), "%s" G_DIR_SEPARATOR_S "gaim_%s.%d", g_get_tmp_dir(), g_get_user_name(), gaim_session); UI_fd = gaim_connect_to_session(0); if (UI_fd < 0) @@ -499,6 +513,7 @@ g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR, socket_readable, NULL); return 0; } +#endif /* _WIN32 */ static void set_first_user(char *name) { @@ -518,8 +533,35 @@ save_prefs(); } +#ifdef _WIN32 +/* WIN32 print and log handlers */ + +static void gaim_dummy_print( const gchar* string ) { + return; +} + +static void gaim_dummy_log_handler (const gchar *domain, + GLogLevelFlags flags, + const gchar *msg, + gpointer user_data) { + return; +} + +static void gaim_log_handler (const gchar *domain, + GLogLevelFlags flags, + const gchar *msg, + gpointer user_data) { + debug_printf("%s - %s\n", domain, msg); + g_log_default_handler(domain, flags, msg, user_data); +} +#endif + /* FUCKING GET ME A TOWEL! */ +#ifdef _WIN32 +int gaim_main(int argc, char *argv[]) +#else int main(int argc, char *argv[]) +#endif { int opt_acct = 0, opt_help = 0, opt_version = 0, opt_login = 0, opt_nologin = 0, do_login_ret = -1; char *opt_user_arg = NULL, *opt_login_arg = NULL; @@ -672,7 +714,13 @@ /* scan command-line options */ opterr = 1; - while ((opt = getopt_long(argc, argv, "adhu:f:vn", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, +#ifndef _WIN32 + "adhu:f:vn", +#else + "adghu:f:vn", +#endif + long_options, NULL)) != -1) { switch (opt) { case 'u': /* set user */ opt_user = 1; @@ -696,6 +744,11 @@ case 'n': /* don't autologin */ opt_nologin = 1; break; +#ifdef _WIN32 + case 'g': /* debug GTK and GLIB */ + opt_gdebug = 1; + break; +#endif case '?': default: show_usage(1, argv[0]); @@ -704,6 +757,42 @@ } } +#ifdef _WIN32 + /* We don't want a console window.. */ + /* + * Any calls to the glib logging functions, result in a call to AllocConsole(). + * ME and 98 will in such cases produce a console window (2000 not), despite + * being built as a windows app rather than a console app. So we should either + * ignore messages by setting dummy log handlers, or redirect messages. + * This requires setting handlers for all domains (any lib which uses g_logging). + */ + + g_log_set_handler ("Gdk", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), + NULL); + g_log_set_handler ("Gtk", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), + NULL); + g_log_set_handler ("GLib", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), + NULL); + g_log_set_handler ("GModule", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), + NULL); + g_log_set_handler ("GLib-GObject", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), + NULL); + g_log_set_handler ("GThread", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), + NULL); + + /* g_print also makes a call to AllocConsole(), therefore a handler needs to be + set here aswell */ + if(!opt_debug) + g_set_print_handler( gaim_dummy_print ); + +#endif + /* show help message */ if (opt_help) { show_usage(0, argv[0]); @@ -720,7 +809,9 @@ #endif load_prefs(); core_main(); +#ifndef _WIN32 ui_main(); +#endif /* set the default username */ if (opt_user_arg != NULL) { @@ -731,6 +822,7 @@ if (misc_options & OPT_MISC_DEBUG) show_debug(); +#ifndef _WIN32 /*If ispell fails to start, try using aspell in ispell compatibitity mode. Gabber does this the same way -- lorien420@myrealbox.com*/ if (convo_options & OPT_CONVO_CHECK_SPELLING){ @@ -744,7 +836,7 @@ debug_printf("gtkspell started with ispell\n"); } } - +#endif static_proto_init(); /* deal with --login */ @@ -763,11 +855,16 @@ account_editor(NULL, NULL); } else if ((do_login_ret == -1) && !connections) show_login(); +#ifdef _WIN32 + /* Various win32 initializations */ + wgaim_init(); +#endif gtk_main(); - +#ifndef _WIN32 if (convo_options & OPT_CONVO_CHECK_SPELLING) gtkspell_stop(); +#endif core_quit(); /* don't need ui_quit here because ui doesn't create anything */ diff -r afc5bb164c5a -r 9682c0e022c6 src/browser.c --- a/src/browser.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/browser.c Fri Oct 11 03:14:01 2002 +0000 @@ -30,9 +30,14 @@ #ifdef HAVE_CONFIG_H #include #endif +#ifdef _WIN32 +#include +#else +#include +#include +#endif #include #include -#include #include @@ -40,7 +45,6 @@ #include #include -#include #include "gaim.h" #ifndef _WIN32 @@ -652,8 +656,9 @@ void add_bookmark(GtkWidget *w, char *url) { } -void open_url_nw(GtkWidget *w, char *url) +void open_url(GtkWidget *w, char *url) { + ShellExecute(NULL, NULL, url, NULL, ".\\", 0); } diff -r afc5bb164c5a -r 9682c0e022c6 src/buddy.c --- a/src/buddy.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/buddy.c Fri Oct 11 03:14:01 2002 +0000 @@ -23,7 +23,9 @@ #include #endif #ifdef GAIM_PLUGINS +#ifndef _WIN32 #include +#endif #endif /* GAIM_PLUGINS */ #include #include @@ -31,13 +33,24 @@ #include #include #include +#include + +#ifdef _WIN32 +#include +#else #include -#include +#include +#endif #include #include #include "prpl.h" #include "gaim.h" + +#ifdef _WIN32 +#include "win32dep.h" +#endif + #include "pixmaps/login_icon.xpm" #include "pixmaps/logout_icon.xpm" #include "pixmaps/no_icon.xpm" @@ -1619,6 +1632,7 @@ } } if (b->options & OPT_POUNCE_COMMAND) { +#ifndef _WIN32 int pid = fork(); if (pid == 0) { @@ -1630,6 +1644,7 @@ execvp(args[0], args); _exit(0); } +#endif /*_WIN32*/ } if (b->options & OPT_POUNCE_SOUND) { if (strlen(b->sound)) @@ -2853,6 +2868,13 @@ gtk_container_add(GTK_CONTAINER(tbox), edittree); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(tbox), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + +#ifdef _WIN32 + /* Set filter to enable win32 systray minimization */ + gdk_window_add_filter (GTK_WIDGET(blist)->window, + wgaim_window_filter, + NULL); +#endif } void show_buddy_list() diff -r afc5bb164c5a -r 9682c0e022c6 src/conversation.c --- a/src/conversation.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/conversation.c Fri Oct 11 03:14:01 2002 +0000 @@ -23,16 +23,22 @@ #include #endif #include +#ifndef _WIN32 #include +#include +#include +#include +#else +#ifdef small +#undef small +#endif +#endif /*_WIN32*/ #include #include -#include #include #include #include #include -#include -#include #include #include "gtkimhtml.h" #include @@ -40,6 +46,10 @@ #include "gtkspell.h" #include "prpl.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #include "pixmaps/bold.xpm" #include "pixmaps/italic.xpm" #include "pixmaps/underline.xpm" @@ -440,7 +450,7 @@ { char buf[BUF_LONG]; GtkWidget *window = gtk_file_selection_new(_("Gaim - Save Conversation")); - g_snprintf(buf, sizeof(buf), "%s/%s.log", g_get_home_dir(), normalize(c->name)); + g_snprintf(buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S "%s.log", gaim_home_dir(), normalize(c->name)); gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), buf); gtk_object_set_user_data(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), c); gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), @@ -497,7 +507,7 @@ { char buf[BUF_LONG]; GtkWidget *window = gtk_file_selection_new(_("Gaim - Insert Image")); - g_snprintf(buf, sizeof(buf), "%s/", g_get_home_dir()); + g_snprintf(buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S, gaim_home_dir()); gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), buf); gtk_object_set_user_data(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), c); gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), @@ -1058,9 +1068,11 @@ } else if (event->keyval == 'z') { key_is_typing = FALSE; gtk_signal_emit_stop_by_name(GTK_OBJECT(entry), "key_press_event"); +#ifndef _WIN32 XIconifyWindow(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(c->window->window), ((_XPrivDisplay)GDK_DISPLAY())->default_screen); +#endif } @@ -1360,8 +1372,14 @@ if (err < 0) { if (err == -E2BIG) do_error_dialog(_("Unable to send message. The message is too large"), NULL, GAIM_ERROR); +#ifndef _WIN32 else if (err == -ENOTCONN) debug_printf("Not yet connected\n"); +#else + else if (err == SOCKET_ERROR) + if( WSAENOTCONN == WSAGetLastError() ) + debug_printf("Not yet connected\n"); +#endif else do_error_dialog(_("Unable to send message"), NULL, GAIM_ERROR); } else { @@ -3476,7 +3494,7 @@ c->save_icon = gtk_file_selection_new(_("Gaim - Save Icon")); gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(c->save_icon)); - g_snprintf(buf, BUF_LEN - 1, "%s/%s.icon", g_get_home_dir(), c->name); + g_snprintf(buf, BUF_LEN - 1, "%s" G_DIR_SEPARATOR_S "%s.icon", gaim_home_dir(), c->name); gtk_file_selection_set_filename(GTK_FILE_SELECTION(c->save_icon), buf); gtk_signal_connect(GTK_OBJECT(c->save_icon), "delete_event", GTK_SIGNAL_FUNC(des_save_icon), c); @@ -3613,7 +3631,7 @@ /* this is such an evil hack, i don't know why i'm even considering it. * we'll do it differently when gdk-pixbuf-loader isn't leaky anymore. */ - g_snprintf(filename, sizeof(filename), "%s/gaimicon-%s.%d", g_get_tmp_dir(), c->name, getpid()); + g_snprintf(filename, sizeof(filename), "%s" G_DIR_SEPARATOR_S "gaimicon-%s.%d", g_get_tmp_dir(), c->name, getpid()); file = fopen(filename, "w"); if (!file) return; diff -r afc5bb164c5a -r 9682c0e022c6 src/core.c --- a/src/core.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/core.c Fri Oct 11 03:14:01 2002 +0000 @@ -27,10 +27,17 @@ #include #include #include + +#ifdef _WIN32 +#include +#include +#else #include -#include #include #include +#endif + +#include #include #include #include @@ -40,6 +47,10 @@ #include "gaim.h" #include "gaim-socket.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + static gint UI_fd = -1; int gaim_session = 0; GSList *uis = NULL; @@ -132,6 +143,7 @@ g_free(data); } +#ifndef _WIN32 static void meta_handler(struct UI *ui, guchar subtype, guchar *data) { struct gaim_cui_packet *p; @@ -443,8 +455,9 @@ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) != -1) { mode_t m = umask(0177); saddr.sun_family = AF_UNIX; - g_snprintf(saddr.sun_path, sizeof(saddr.sun_path), "%s/gaim_%s.%d", - g_get_tmp_dir(), g_get_user_name(), gaim_session); + + g_snprintf(saddr.sun_path, sizeof(saddr.sun_path), "%s" G_DIR_SEPARATOR_S "gaim_%s.%d", + g_get_tmp_dir(), g_get_user_name(), gaim_session); if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) != -1) listen(fd, 100); else { @@ -458,6 +471,7 @@ g_log(NULL, G_LOG_LEVEL_CRITICAL, "Unable to open socket: %s", strerror(errno)); return fd; } +#endif /*! _WIN32*/ int core_main() { @@ -465,6 +479,7 @@ GMainLoop *loop; */ +#ifndef _WIN32 GIOChannel *channel; UI_fd = open_socket(); @@ -474,6 +489,32 @@ channel = g_io_channel_unix_new(UI_fd); g_io_add_watch(channel, G_IO_IN, socket_readable, NULL); g_io_channel_unref(channel); +#endif + +#ifdef _WIN32 + WORD wVersionRequested; + WSADATA wsaData; + int err; + + wVersionRequested = MAKEWORD( 2, 2 ); + + err = WSAStartup( wVersionRequested, &wsaData ); + if ( err != 0 ) { + return 1; + } + + /* Confirm that the winsock DLL supports 2.2 */ + /* Note that if the DLL supports versions greater than + 2.2 in addition to 2.2, it will still return 2.2 in + wVersion since that is the version we requested. */ + + if ( LOBYTE( wsaData.wVersion ) != 2 || + HIBYTE( wsaData.wVersion ) != 2 ) { + debug_printf("Could not find a usable WinSock DLL. Oh well.\n"); + WSACleanup( ); + return 1; + } +#endif /* _WIN32 */ /* loop = g_main_new(TRUE); @@ -485,9 +526,13 @@ void core_quit() { +#ifndef _WIN32 char buf[1024]; close(UI_fd); - sprintf(buf, "%s/gaim_%s.%d", g_get_tmp_dir(), g_get_user_name(), gaim_session); + sprintf(buf, "%s" G_DIR_SEPARATOR_S "gaim_%s.%d", g_get_tmp_dir(), g_get_user_name(), gaim_session); unlink(buf); debug_printf("Removed core\n"); +#else + WSACleanup( ); +#endif } diff -r afc5bb164c5a -r 9682c0e022c6 src/dialogs.c --- a/src/dialogs.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/dialogs.c Fri Oct 11 03:14:01 2002 +0000 @@ -25,17 +25,22 @@ #include #include #include -#include #include #include #include #include + +#ifdef _WIN32 +#include +#else #include +#include #include #include #include -#include #include +#endif + #include #include @@ -44,6 +49,10 @@ #include "gtkimhtml.h" #include "prpl.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #include "pixmaps/gnome_preferences.xpm" #include "pixmaps/cancel.xpm" #include "pixmaps/save.xpm" @@ -2609,7 +2618,7 @@ gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(c->log_dialog)); - g_snprintf(buf, BUF_LEN - 1, "%s/%s.log", getenv("HOME"), normalize(c->name)); + g_snprintf(buf, BUF_LEN - 1, "%s" G_DIR_SEPARATOR_S "%s.log", gaim_home_dir(), normalize(c->name)); gtk_object_set_user_data(GTK_OBJECT(c->log_dialog), "log dialog"); gtk_file_selection_set_filename(GTK_FILE_SELECTION(c->log_dialog), buf); gtk_signal_connect(GTK_OBJECT(c->log_dialog), "delete_event", @@ -3365,7 +3374,7 @@ gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(importdialog)); - g_snprintf(buf, BUF_LEN - 1, "%s/", getenv("HOME")); + g_snprintf(buf, BUF_LEN - 1, "%s" G_DIR_SEPARATOR_S, gaim_home_dir()); gtk_file_selection_set_filename(GTK_FILE_SELECTION(importdialog), buf); gtk_signal_connect(GTK_OBJECT(importdialog), "destroy", @@ -3885,9 +3894,8 @@ name = gtk_object_get_user_data(GTK_OBJECT(filesel)); tmp = gaim_user_dir(); - g_snprintf(filename, PATHSIZE, "%s/logs/%s%s", tmp, + g_snprintf(filename, PATHSIZE, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s%s", tmp, name ? normalize(name) : "system", name ? ".log" : ""); - g_free(tmp); file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(filesel)); strncpy(path, file, PATHSIZE - 1); @@ -3924,7 +3932,7 @@ GtkWidget *filesel; gchar buf[BUF_LEN]; - g_snprintf(buf, BUF_LEN - 1, "%s/%s%s", getenv("HOME"), + g_snprintf(buf, BUF_LEN - 1, "%s" G_DIR_SEPARATOR_S "%s%s", gaim_home_dir(), name ? normalize(name) : "system", name ? ".log" : ""); filesel = gtk_file_selection_new(_("Gaim - Save Log File")); @@ -3953,9 +3961,8 @@ char *tmp; tmp = gaim_user_dir(); - g_snprintf(filename, 256, "%s/logs/%s%s", tmp, + g_snprintf(filename, 256, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s%s", tmp, name ? normalize(name) : "system", name ? ".log" : ""); - g_free(tmp); if ((remove(filename)) == -1) { g_snprintf(buf, 256, _("Couldn't remove file %s." ), filename); @@ -4025,12 +4032,10 @@ if (view->name) { char *tmp = gaim_user_dir(); - g_snprintf(filename, 256, "%s/logs/%s.log", tmp, normalize(view->name)); - g_free(tmp); + g_snprintf(filename, 256, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s.log", tmp, normalize(view->name)); } else { char *tmp = gaim_user_dir(); - g_snprintf(filename, 256, "%s/logs/system", tmp); - g_free(tmp); + g_snprintf(filename, 256, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "system", tmp); } if ((fp = fopen(filename, "r")) == NULL) { g_snprintf(buf, BUF_LONG, "Couldn't open log file %s.", filename); @@ -4174,8 +4179,7 @@ if (name) { char *tmp = gaim_user_dir(); - g_snprintf(filename, 256, "%s/logs/%s.log", tmp, normalize(name)); - g_free(tmp); + g_snprintf(filename, 256, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s.log", tmp, normalize(name)); if ((fp = fopen(filename, "r")) == NULL) { g_snprintf(buf, BUF_LONG, "Couldn't open log file %s", filename); do_error_dialog(buf, strerror(errno), GAIM_ERROR); @@ -4557,7 +4561,6 @@ if (!perl_last_dir) { temp = gaim_user_dir(); buf = g_strconcat(temp, G_DIR_SEPARATOR_S, NULL); - g_free(temp); } else { buf = g_strconcat(perl_last_dir, G_DIR_SEPARATOR_S, NULL); } diff -r afc5bb164c5a -r 9682c0e022c6 src/ft.c --- a/src/ft.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/ft.c Fri Oct 11 03:14:01 2002 +0000 @@ -461,8 +461,11 @@ /* Two functions, one recursive, just to make a directory. Yuck. */ static int ft_mkdir_help(char *dir) { int ret; - +#ifndef _WIN32 ret = mkdir(dir, 0775); +#else + ret = _mkdir(dir); +#endif if (ret) { char *index = strrchr(dir, G_DIR_SEPARATOR); if (!index) @@ -471,7 +474,11 @@ ret = ft_mkdir_help(dir); *index = G_DIR_SEPARATOR; if (!ret) +#ifndef _WIN32 ret = mkdir(dir, 0775); +#else + ret = _mkdir(dir); +#endif } return ret; diff -r afc5bb164c5a -r 9682c0e022c6 src/gaim.h --- a/src/gaim.h Fri Oct 11 02:10:08 2002 +0000 +++ b/src/gaim.h Fri Oct 11 03:14:01 2002 +0000 @@ -385,8 +385,15 @@ extern gint sort_awaymsg_list(gconstpointer, gconstpointer); /* Functions in html.c */ +struct g_url { + char address[255]; + int port; + char page[255]; +}; + extern void grab_url(char *, gboolean, void (*callback)(gpointer, char *), gpointer); extern gchar *strip_html(gchar *); +struct g_url *parse_url(char *url); /* Functions in idle.c */ extern gint check_idle(gpointer); @@ -447,6 +454,7 @@ extern char *stylize(gchar *, int); extern void show_usage (int, char *); extern int do_auto_login (char *); +extern char *gaim_home_dir(); extern char *gaim_user_dir(); extern void strncpy_nohtml(gchar *, const gchar *, size_t); extern void strncpy_withhtml(gchar *, const gchar *, size_t); diff -r afc5bb164c5a -r 9682c0e022c6 src/gaimrc.c --- a/src/gaimrc.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/gaimrc.c Fri Oct 11 03:14:01 2002 +0000 @@ -23,18 +23,25 @@ #include #endif #include + +#ifndef _WIN32 #include +#include +#endif #include #include -#include #include #include #include "gaim.h" #include "prpl.h" #include "proxy.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + /* for people like myself, who are too lazy to add an away msg :) */ #define BORING_DEFAULT_AWAY_MSG "sorry, i ran out for a while. bbl" #define MAX_VALUES 10 @@ -51,12 +58,15 @@ guint away_options; guint away_resend; -int report_idle, web_browser; +int report_idle; +int web_browser; struct save_pos blist_pos; struct window_size conv_size, buddy_chat_size; char web_command[2048]; char *sound_file[NUM_SOUNDS]; +#ifndef _WIN32 char sound_cmd[2048]; +#endif struct parse { char option[256]; @@ -831,7 +841,17 @@ if (misc_options & OPT_MISC_BUDDY_TICKER) { #ifdef GAIM_PLUGINS - load_plugin(LIBDIR "/ticker.so"); + gchar* buf; + + buf = g_strconcat(LIBDIR, G_DIR_SEPARATOR_S, +#ifndef _WIN32 + "ticker.so", +#else + "ticker.dll", +#endif + NULL); + load_plugin(buf); + g_free(buf); #endif misc_options &= ~OPT_MISC_BUDDY_TICKER; } @@ -881,8 +901,9 @@ for (i = 0; i < NUM_SOUNDS; i++) sound_file[i] = NULL; +#ifndef _WIN32 sound_cmd[0] = 0; - +#endif while (buf[0] != '}') { if (buf[0] == '#') continue; @@ -891,10 +912,12 @@ return; p = parse_line(buf, &parse_buffer); - +#ifndef _WIN32 if (!strcmp(p->option, "sound_cmd")) { g_snprintf(sound_cmd, sizeof(sound_cmd), "%s", p->value[0]); - } else if (!strncmp(p->option, "sound", strlen("sound"))) { + } else +#endif + if (!strncmp(p->option, "sound", strlen("sound"))) { i = p->option[strlen("sound")] - 'A'; if (p->value[0][0]) @@ -912,7 +935,9 @@ fprintf(f, "\tsound%c { %s }\n", i + 'A', sound_file[i]); else fprintf(f, "\tsound%c { }\n", i + 'A'); +#ifndef _WIN32 fprintf(f, "\tsound_cmd { %s }\n", sound_cmd); +#endif fprintf(f, "}\n"); } @@ -1192,11 +1217,16 @@ if (opt_rcfile_arg) g_snprintf(buf, sizeof(buf), "%s", opt_rcfile_arg); - else if (getenv("HOME")) - g_snprintf(buf, sizeof(buf), "%s/.gaimrc", getenv("HOME")); + else if (gaim_home_dir()) + g_snprintf(buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S ".gaimrc", gaim_home_dir()); else { +#ifndef _WIN32 set_defaults(); return; +#else + /* Pre Win 2000 there are no home dirs... */ + g_snprintf(buf, sizeof(buf), "C:" G_DIR_SEPARATOR_S ".gaimrc"); +#endif } if ((f = fopen(buf, "r"))) { @@ -1254,13 +1284,20 @@ FILE *f; char buf[BUF_LONG]; - if (opt_rcfile_arg) + if (opt_rcfile_arg) { g_snprintf(buf, sizeof(buf), "%s", opt_rcfile_arg); - else if (getenv("HOME")) - g_snprintf(buf, sizeof(buf), "%s/.gaimrc", getenv("HOME")); - else + } + else if (gaim_home_dir()) { + g_snprintf(buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S ".gaimrc", gaim_home_dir()); + } + else { +#ifndef _WIN32 return; - +#else + /* Pre Win 2000, there are no home dirs.. */ + g_snprintf(buf, sizeof(buf), "C:" G_DIR_SEPARATOR_S ".gaimrc"); +#endif + } if ((f = fopen(buf, "w"))) { fprintf(f, "# .gaimrc v%d\n", 4); gaimrc_write_users(f); @@ -1273,8 +1310,12 @@ #endif gaimrc_write_proxy(f); fclose(f); +#ifndef _WIN32 chmod(buf, S_IRUSR | S_IWUSR); +#endif } + else + debug_printf("Error opening .gaimrc\n"); } diff -r afc5bb164c5a -r 9682c0e022c6 src/gtkimhtml.c --- a/src/gtkimhtml.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/gtkimhtml.c Fri Oct 11 03:14:01 2002 +0000 @@ -23,9 +23,15 @@ #include #endif #include "gtkimhtml.h" + +#ifndef _WIN32 #include +#include +#else +#include +#endif + #include -#include #include #include #include @@ -36,6 +42,12 @@ #include #endif +#ifdef _WIN32 +/* GDK_SELECTION_PRIMARY is ignored win32 GTK */ +#undef GDK_SELECTION_PRIMARY +#define GDK_SELECTION_PRIMARY GDK_SELECTION_CLIPBOARD +#endif + #include #include @@ -1684,10 +1696,10 @@ const gchar *filename; FILE *f; filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(is->savedialog)); - g_print("Saving %s\n", filename); + debug_printf("Saving %s\n", filename); if (! (f=fopen(filename, "w"))) { /* There should be some sort of dialog */ - g_print("Could not open file for writing.\n"); + debug_printf("Could not open file for writing.\n"); gtk_widget_destroy(is->savedialog); g_free(is); return; @@ -2086,6 +2098,19 @@ static const gchar* gtk_imhtml_get_font_name (PangoFontDescription *font) { +#if 0 +#ifndef _WIN32 + return gdk_x11_font_get_name(font); +#else +#if 0 + /* win32 gdkfont.h says this is temporary - GTK 2.0.3 */ + return gdk_font_full_name_get(font); +#else + /* So i can build with GTK 2.0.6 */ + return "-unknown-arial-normal-r-normal---18--108-120-120-p-0-microsoft-vietnamese-unknown-arial-normal-r-normal---18--108-120-120-p-0-microsoft-vietnamese27"; +#endif +#endif +#endif return pango_font_description_get_family(font); } @@ -3328,7 +3353,7 @@ if (!gdk_pixbuf_loader_write(load, imagedata, img->len, &err)) - g_print("IM Image corrupt or unreadable.\n"); + debug_printf("IM Image corrupt or unreadable.\n"); else imagepb = gdk_pixbuf_loader_get_pixbuf(load); img->pb = imagepb; diff -r afc5bb164c5a -r 9682c0e022c6 src/gtkspell.c --- a/src/gtkspell.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/gtkspell.c Fri Oct 11 03:14:01 2002 +0000 @@ -19,9 +19,15 @@ #include #include + +#ifndef _WIN32 #include #include -#include +#include +#else +#include +#endif + #include #include #include @@ -163,15 +169,18 @@ void gtkspell_stop() { +#ifndef _WIN32 if (gtkspell_running()) { kill(spell_pid, SIGHUP); spell_pid = 0; close(fd_read[0]); close(fd_write[1]); } +#endif } int gtkspell_start(char *path, char * args[]) { +#ifndef _WIN32 int fd_error[2]; if (gtkspell_running()) { @@ -268,6 +277,7 @@ /* put ispell into terse mode. * this makes it not respond on correctly spelled words. */ writetext("!\n"); +#endif /*!_WIN32*/ return 0; } diff -r afc5bb164c5a -r 9682c0e022c6 src/html.c --- a/src/html.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/html.c Fri Oct 11 03:14:01 2002 +0000 @@ -25,23 +25,24 @@ #include #include #include + +#ifndef _WIN32 #include #include -#include "gaim.h" -#include #include #include #include +#else +#include +#include +#endif + +#include #include #include +#include "gaim.h" #include "proxy.h" -struct g_url { - char address[255]; - int port; - char page[255]; -}; - gchar *strip_html(gchar *text) { int i, j, k; @@ -74,7 +75,7 @@ return text2; } -static struct g_url *parse_url(char *url) +struct g_url *parse_url(char *url) { struct g_url *test = g_new0(struct g_url, 1); char scan_info[255]; @@ -143,22 +144,37 @@ if (!gunk->sentreq) { char buf[256]; +#ifdef _WIN32 + int imode=1; +#endif g_snprintf(buf, sizeof(buf), "GET %s%s HTTP/1.0\r\n\r\n", gunk->full ? "" : "/", gunk->full ? gunk->url : gunk->website->page); debug_printf("Request: %s\n", buf); +#ifdef _WIN32 + send(sock, buf, strlen(buf), 0); + ioctlsocket(sock, FIONBIO, (unsigned long *)&imode); +#else write(sock, buf, strlen(buf)); fcntl(sock, F_SETFL, O_NONBLOCK); +#endif gunk->sentreq = TRUE; gunk->inpa = gaim_input_add(sock, GAIM_INPUT_READ, grab_url_callback, dat); return; } +#ifdef _WIN32 + if (recv(sock, &data, 1, 0) > 0 || WSAEWOULDBLOCK == WSAGetLastError()) { + if (WSAEWOULDBLOCK == WSAGetLastError()) { + WSASetLastError(0); + return; + } +#else if (read(sock, &data, 1) > 0 || errno == EWOULDBLOCK) { if (errno == EWOULDBLOCK) { errno = 0; return; } - +#endif if (!gunk->startsaving) { if (data == '\r') return; @@ -175,15 +191,22 @@ gunk->webdata = g_realloc(gunk->webdata, gunk->len); gunk->webdata[gunk->len - 1] = data; } +#ifdef _WIN32 + } else if (WSAETIMEDOUT == WSAGetLastError()) { +#else } else if (errno != ETIMEDOUT) { - +#endif gunk->webdata = g_realloc(gunk->webdata, gunk->len + 1); gunk->webdata[gunk->len] = 0; debug_printf(_("Received: '%s'\n"), gunk->webdata); gaim_input_remove(gunk->inpa); +#ifdef _WIN32 + closesocket(sock); +#else close(sock); +#endif gunk->callback(gunk->data, gunk->webdata); if (gunk->webdata) g_free(gunk->webdata); @@ -192,7 +215,11 @@ g_free(gunk); } else { gaim_input_remove(gunk->inpa); +#ifdef _WIN32 + closesocket(sock); +#else close(sock); +#endif gunk->callback(gunk->data, NULL); if (gunk->webdata) g_free(gunk->webdata); diff -r afc5bb164c5a -r 9682c0e022c6 src/list.c --- a/src/list.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/list.c Fri Oct 11 03:14:01 2002 +0000 @@ -25,7 +25,12 @@ #include #include #include +#ifndef _WIN32 #include +#else +#include +#include +#endif #include "gaim.h" #include "prpl.h" @@ -668,14 +673,14 @@ file = gaim_user_dir(); if (file != (char *)NULL) { - g_snprintf(path, sizeof path, "%s/%s.%d.blist", file, g_screenname, gc->protocol); + g_snprintf(path, sizeof path, "%s" G_DIR_SEPARATOR_S "%s.%d.blist", file, g_screenname, gc->protocol); if (!stat(path, &sbuf)) { debug_printf("%s exists.\n", path); ret = TRUE; } else { char path2[PATHSIZE]; debug_printf("%s does not exist.\n", path); - g_snprintf(path2, sizeof path2, "%s/%s.blist", file, g_screenname); + g_snprintf(path2, sizeof path2, "%s" G_DIR_SEPARATOR_S "%s.blist", file, g_screenname); if (!stat(path2, &sbuf)) { debug_printf("%s exists, moving to %s\n", path2, path); if (rename(path2, path)) @@ -684,7 +689,6 @@ ret = TRUE; } } - g_free(file); } g_free(g_screenname); return ret; @@ -706,8 +710,7 @@ char *file = gaim_user_dir(); if (file != (char *)NULL) { - sprintf(path, "%s/%s.%d.blist", file, g_screenname, gc->protocol); - g_free(file); + sprintf(path, "%s" G_DIR_SEPARATOR_S "%s.%d.blist", file, g_screenname, gc->protocol); g_free(g_screenname); } else { g_free(g_screenname); @@ -787,25 +790,32 @@ strcpy(buf, file); dir = fopen(buf, "r"); if (!dir) +#ifndef _WIN32 mkdir(buf, S_IRUSR | S_IWUSR | S_IXUSR); +#else + _mkdir(buf); +#endif else fclose(dir); g_screenname = get_screenname_filename(g->username); - sprintf(path, "%s/%s.%d.blist", file, g_screenname, g->protocol); + sprintf(path, "%s" G_DIR_SEPARATOR_S "%s.%d.blist", file, g_screenname, g->protocol); if ((f = fopen(path, "w"))) { debug_printf("writing %s\n", path); toc_build_config(g, buf, 8192 - 1, TRUE); fprintf(f, "%s\n", buf); fclose(f); +#ifdef _WIN32 + _chmod(buf, _S_IWRITE); +#else chmod(path, S_IRUSR | S_IWUSR); +#endif } else { debug_printf("unable to write %s\n", path); } g_free(g_screenname); - g_free(file); } static gboolean is_blocked(struct buddy *b) diff -r afc5bb164c5a -r 9682c0e022c6 src/module.c --- a/src/module.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/module.c Fri Oct 11 03:14:01 2002 +0000 @@ -47,6 +47,10 @@ #include #include +#ifdef _WIN32 +#include "win32dep.h" +#endif + /* ------------------ Global Variables ----------------------- */ GList *plugins = NULL; @@ -88,8 +92,7 @@ gchar *path; struct gaim_plugin_description *plugdes; struct gaim_plugin *plug; - char userspace[128]; - char *probedirs[] = {LIBDIR, &userspace, 0}; + char *probedirs[3]; int l; #if GAIM_PLUGINS char *(*gaim_plugin_init)(GModule *); @@ -100,14 +103,22 @@ GModule *handle; #endif - g_snprintf(userspace, sizeof(userspace), "%s" G_DIR_SEPARATOR_S ".gaim", g_get_home_dir()); + probedirs[0] = LIBDIR; + probedirs[1] = gaim_user_dir(); + probedirs[2] = 0; for (l=0; probedirs[l]; l++) { dir = g_dir_open(probedirs[l], 0, NULL); if (dir) { while ((file = g_dir_read_name(dir))) { #ifdef GAIM_PLUGINS - if (is_so_file(file, ".so") && g_module_supported()) { + if (is_so_file(file, +#ifndef _WIN32 + ".so" +#else + ".dll" +#endif + ) && g_module_supported()) { path = g_build_filename(probedirs[l], file, NULL); handle = g_module_open(path, 0); if (!handle) { diff -r afc5bb164c5a -r 9682c0e022c6 src/multi.c --- a/src/multi.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/multi.c Fri Oct 11 03:14:01 2002 +0000 @@ -454,7 +454,7 @@ gtk_file_selection_set_filename(GTK_FILE_SELECTION(dlg), tmp); g_free(tmp); } else { - g_snprintf(buf, sizeof(buf), "%s/", g_get_home_dir()); + g_snprintf(buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S, gaim_home_dir()); gtk_file_selection_set_filename(GTK_FILE_SELECTION(dlg), buf); } diff -r afc5bb164c5a -r 9682c0e022c6 src/perl.c --- a/src/perl.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/perl.c Fri Oct 11 03:14:01 2002 +0000 @@ -35,20 +35,32 @@ #ifdef USE_PERL #define group perl_group - +#ifdef _WIN32 +/* This took me an age to figure out.. without this __declspec(dllimport) + * will be ignored. + */ +#define HASATTRIBUTE +#endif #include #ifndef _SEM_SEMUN_UNDEFINED #define HAS_UNION_SEMUN #endif #include #include +#ifndef _WIN32 #include +#endif #include #include #include #undef PACKAGE #include +#ifndef _WIN32 #include +#else +/* We're using perl's win32 port of this */ +#define dirent direct +#endif #include #undef group @@ -61,6 +73,9 @@ #ifdef DEBUG #undef DEBUG #endif +#ifdef _WIN32 +#undef pipe +#endif #include "gaim.h" #include "prpl.h" @@ -185,11 +200,11 @@ sv = GvSV(gv_fetchpv("@", TRUE, SVt_PV)); if (SvTRUE(sv)) { - snprintf(buf, 512, "Perl error: %s\n", SvPV(sv, count)); + g_snprintf(buf, 512, "Perl error: %s\n", SvPV(sv, count)); debug_printf(buf); POPs; } else if (count != 1) { - snprintf(buf, 512, "Perl error: expected 1 value from %s, " + g_snprintf(buf, 512, "Perl error: expected 1 value from %s, " "got: %d\n", function, count); debug_printf(buf); } else { diff -r afc5bb164c5a -r 9682c0e022c6 src/prefs.c --- a/src/prefs.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/prefs.c Fri Oct 11 03:14:01 2002 +0000 @@ -96,6 +96,11 @@ static int notebook_page = 0; static GtkTreeIter plugin_iter; +/* + * PROTOTYPES + */ +GtkTreeIter *prefs_notebook_add_page(char*, GdkPixbuf*, GtkWidget*, GtkTreeIter*, GtkTreeIter*, int); + void delete_prefs(GtkWidget *asdf, void *gdsa) { int v; @@ -211,7 +216,9 @@ proxytype = proxytype_new; default_away = default_away_new; fontsize = fontsize_new; +#ifndef _WIN32 g_snprintf(sound_cmd, sizeof(sound_cmd), "%s", sound_cmd_new); +#endif g_snprintf(web_command, sizeof(web_command), "%s", web_command_new); memcpy(&conv_size, &conv_size_new, sizeof(struct window_size)); memcpy(&conv_size, &conv_size_new, sizeof(struct window_size)); @@ -653,7 +660,8 @@ gtk_container_set_border_width (GTK_CONTAINER (ret), 12); sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - +#ifndef _WIN32 + /* Registered default browser is used by Windows */ vbox = make_frame (ret, _("Browser Selection")); label = gaim_dropdown(vbox, "_Browser", &web_browser_new, -1, "Netscape", BROWSER_NETSCAPE, @@ -682,10 +690,13 @@ gtk_entry_set_text(GTK_ENTRY(browser_entry), web_command_new); gtk_signal_connect(GTK_OBJECT(browser_entry), "changed", GTK_SIGNAL_FUNC(browser_print_option), NULL); - +#endif /* end !_WIN32 */ vbox = make_frame (ret, _("Browser Options")); - gaim_button(_("Open new _window by default"), &misc_options_new, OPT_MISC_BROWSER_POPUP, vbox); - + label = gaim_button(_("Open new _window by default"), &misc_options_new, OPT_MISC_BROWSER_POPUP, vbox); +#ifdef _WIN32 + /* Until I figure out how to implement this on windows */ + gtk_widget_set_sensitive(label, FALSE); +#endif gtk_widget_show_all(ret); return ret; } @@ -740,6 +751,7 @@ gaim_button(_("_No sounds when you log in"), &sound_options_new, OPT_SOUND_SILENT_SIGNON, vbox); gaim_button(_("_Sounds while away"), &sound_options_new, OPT_SOUND_WHEN_AWAY, vbox); +#ifndef _WIN32 vbox = make_frame (ret, _("Sound Method")); dd = gaim_dropdown(vbox, "_Method", &sound_options_new, OPT_SOUND_BEEP | OPT_SOUND_ESD | OPT_SOUND_ARTSC | OPT_SOUND_NAS | OPT_SOUND_NORMAL | @@ -779,7 +791,7 @@ gtk_widget_set_sensitive(sndcmd, (sound_options_new & OPT_SOUND_CMD)); gtk_box_pack_start(GTK_BOX(hbox), sndcmd, TRUE, TRUE, 5); gtk_signal_connect(GTK_OBJECT(sndcmd), "focus_out_event", GTK_SIGNAL_FUNC(sound_cmd_yeah), NULL); - +#endif /* _WIN32 */ gtk_widget_show_all(ret); return ret; } @@ -874,10 +886,18 @@ g_snprintf(buf, sizeof(buf), _("%s %s\n\n" "%s"), plug->desc.name, plug->desc.version, plug->desc.description); gtk_label_set_markup(GTK_LABEL(plugin_description), buf); - g_snprintf(buf, sizeof(buf), _("%s %s\n\n" - "Written by:\t%s\n" - "URL:\t%s\n" - "File name:\t %s"), + g_snprintf(buf, sizeof(buf), +#ifndef _WIN32 + _("%s %s\n\n" + "Written by:\t%s\n" + "URL:\t%s\n" + "File name:\t%s"), +#else + _("%s %s\n\n" + "Written by: %s\n" + "URL: %s\n" + "File name: %s"), +#endif plug->desc.name, plug->desc.version, plug->desc.authors, plug->desc.url, plug->path); gtk_label_set_markup(GTK_LABEL(plugin_details), buf); g_value_unset (&val); @@ -910,7 +930,7 @@ prefs_notebook_add_page(plug->desc.name, NULL, config(), plug->iter, &plugin_iter, notebook_page++); if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(prefstree), &plugin_iter) == 1) { /* Expand the tree for the first plugin added */ - GtkTreePath *path2 = gtk_tree_model_get_path(prefstree, &plugin_iter); + GtkTreePath *path2 = gtk_tree_model_get_path(GTK_TREE_MODEL(prefstree), &plugin_iter); gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_v), path2, TRUE); gtk_tree_path_free (path2); } @@ -1030,14 +1050,14 @@ plugin_description = gtk_label_new(NULL); vp = gtk_viewport_new(NULL, NULL); - gtk_viewport_set_shadow_type(vp, GTK_SHADOW_NONE); + gtk_viewport_set_shadow_type(GTK_VIEWPORT(vp), GTK_SHADOW_NONE); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_NONE); - gtk_container_add(vp, plugin_description); - gtk_container_add(sw, vp); + gtk_container_add(GTK_CONTAINER(vp), plugin_description); + gtk_container_add(GTK_CONTAINER(sw), vp); - gtk_label_set_selectable(plugin_description, TRUE); - gtk_label_set_line_wrap(plugin_description, TRUE); + gtk_label_set_selectable(GTK_LABEL(plugin_description), TRUE); + gtk_label_set_line_wrap(GTK_LABEL(plugin_description), TRUE); gtk_misc_set_alignment(GTK_MISC(plugin_description), 0, 0); gtk_misc_set_padding(GTK_MISC(plugin_description), 6, 6); gtk_notebook_append_page(GTK_NOTEBOOK(nb), sw, gtk_label_new(_("Description"))); @@ -1048,14 +1068,14 @@ plugin_details = gtk_label_new(NULL); vp = gtk_viewport_new(NULL, NULL); - gtk_viewport_set_shadow_type(vp, GTK_SHADOW_NONE); + gtk_viewport_set_shadow_type(GTK_VIEWPORT(vp), GTK_SHADOW_NONE); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_NONE); - gtk_container_add(vp, plugin_details); - gtk_container_add(sw, vp); + gtk_container_add(GTK_CONTAINER(vp), plugin_details); + gtk_container_add(GTK_CONTAINER(sw), vp); - gtk_label_set_selectable(plugin_details, TRUE); - gtk_label_set_line_wrap(plugin_details, TRUE); + gtk_label_set_selectable(GTK_LABEL(plugin_details), TRUE); + gtk_label_set_line_wrap(GTK_LABEL(plugin_details), TRUE); gtk_misc_set_alignment(GTK_MISC(plugin_details), 0, 0); gtk_misc_set_padding(GTK_MISC(plugin_details), 6, 6); gtk_notebook_append_page(GTK_NOTEBOOK(nb), sw, gtk_label_new(_("Details"))); @@ -1171,7 +1191,7 @@ gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(sounddialog)); - g_snprintf(buf, BUF_LEN - 1, "%s/", last_sound_dir ? last_sound_dir : g_get_home_dir()); + g_snprintf(buf, BUF_LEN - 1, "%s" G_DIR_SEPARATOR_S, last_sound_dir ? last_sound_dir : gaim_home_dir()); gtk_file_selection_set_filename(GTK_FILE_SELECTION(sounddialog), buf); @@ -1519,8 +1539,10 @@ fontsize_new = fontsize; web_browser_new = web_browser; proxytype_new = proxytype; +#ifndef _WIN32 g_snprintf(sound_cmd_new, sizeof(sound_cmd_new), "%s", sound_cmd); - g_snprintf(web_command_new, sizeof(web_command_new), "%s", +#endif + g_snprintf(web_command_new, sizeof(web_command_new), "%s", web_command ? web_command : "xterm -e lynx %%s"); g_snprintf(fontface_new, sizeof(fontface_new), fontface); memcpy(&conv_size_new, &conv_size, sizeof(struct window_size)); diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/gg/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/gg/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,151 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of libgg +# + +# +# PATHS +# + +INCLUDE_DIR := . +GTK_TOP := ../../../../win32-dev/gtk_2_0 +GAIM_TOP := ../../.. +GG_ROOT := . +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir + +## +## VARIABLE DEFINITIONS +## + +TARGET = libgg + +VERSION := $(shell cat $(GAIM_TOP)/VERSION) + +# Compiler Options + +CFLAGS = -O2 -Werror -Wall -mno-cygwin -fnative-struct + +DEFINES = -DAIM_BUILDDATE=\"`date +%Y%m%d`\" \ + -DAIM_BUILDTIME=\"`date +%H%M%S`\" \ + -DVERSION=\"$(VERSION)\" \ + -DHAVE_CONFIG_H + +# Static or Plugin... +ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR) +else +ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR)/plugins +endif +endif + + +## +## INCLUDE MAKEFILES +## + + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(GG_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src \ + + +## +## SOURCES, OBJECTS +## + +C_SRC = libgg.c \ + common.c \ + iconv_string.c \ + gg.c + +OBJECTS = $(C_SRC:%.c=%.o) + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 -lglib-2.0 -lgdk-win32-2.0 -lgmodule-2.0 -lgobject-2.0 -lintl -lgaim -lws2_32 + +# -liberty + + +## +## RULES +## + +# How to make a C file + +%.o: %.c + gcc $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: $(TARGET).dll + +install: + cp $(GG_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + + +## +## BUILD Dependencies +## + +$(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + +## +## BUILD DLL +## + +$(TARGET).def: $(OBJECTS) + dlltool --dllname $(TARGET).dll -z $(TARGET).def \ + $(OBJECTS) + +$(TARGET).base: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + gcc -mdll -o junk.tmp -Wl,--base-file,$@ $(OBJECTS) $(LIB_PATHS) $(LIBS) + rm -rf junk.tmp + +$(TARGET).exp: $(TARGET).def $(TARGET).base + dlltool --dllname $(TARGET).dll --base-file $(TARGET).base \ + --output-exp $(TARGET).exp --def $(TARGET).def + rm -rf $(TARGET).base + +$(TARGET).dll: $(OBJECTS) $(TARGET).exp $(GAIM_TOP)/src/gaim.lib + dlltool -D $(TARGET).dll -d $(TARGET).def -l $(TARGET).lib + gcc -mdll -o $(TARGET).dll $(OBJECTS) -Wl,$(TARGET).exp $(LIB_PATHS) $(LIBS) + rm -rf $(TARGET).exp + + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).lib + rm -rf $(TARGET).def diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/gg/common.c --- a/src/protocols/gg/common.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/gg/common.c Fri Oct 11 03:14:01 2002 +0000 @@ -1,4 +1,4 @@ -/* $Id: common.c 3516 2002-08-29 01:47:15Z seanegan $ */ +/* $Id: common.c 3753 2002-10-11 03:14:01Z robflynn $ */ /* * (C) Copyright 2001 Wojtek Kaniewski , @@ -20,21 +20,24 @@ #include #include +#ifndef _WIN32 #include -#include #include #include #include +#include #include +#include #include +#else +#include +#endif #include -#include #include #ifndef _AIX # include #endif #include -#include #include #ifdef sun #include @@ -84,7 +87,7 @@ va_start(ap, format); - if ((size = vsnprintf(buf, 0, format, ap)) < 1) { + if ((size = g_vsnprintf(buf, 0, format, ap)) < 1) { size = 128; do { size *= 2; @@ -93,14 +96,14 @@ return NULL; } buf = tmp; - res = vsnprintf(buf, size, format, ap); + res = g_vsnprintf(buf, size, format, ap); } while (res == size - 1); } else { if (!(buf = malloc(size + 1))) return NULL; } - vsnprintf(buf, size + 1, format, ap); + g_vsnprintf(buf, size + 1, format, ap); va_end(ap); @@ -156,20 +159,31 @@ */ int gg_connect(void *addr, int port, int async) { - int sock, one = 1; + int sock, ret, one = 1; struct sockaddr_in sin; struct in_addr *a = addr; gg_debug(GG_DEBUG_FUNCTION, "** gg_connect(%s, %d, %d);\n", inet_ntoa(*a), port, async); if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { - gg_debug(GG_DEBUG_MISC, "-- socket() failed. errno = %d (%s)\n", errno, strerror(errno)); + gg_debug(GG_DEBUG_MISC, "-- socket() failed. errno = %d" +#ifndef _WIN32 + " (%s)\n", errno, strerror(errno) +#else + "\n", WSAGetLastError() +#endif + ); return -1; } if (async) { +#ifndef _WIN32 if (ioctl(sock, FIONBIO, &one) == -1) { gg_debug(GG_DEBUG_MISC, "-- ioctl() failed. errno = %d (%s)\n", errno, strerror(errno)); +#else + if (ioctlsocket(sock, FIONBIO, (unsigned long *)&one) == SOCKET_ERROR) { + gg_debug(GG_DEBUG_MISC, "-- ioctlsocket() failed. errno = %d\n", WSAGetLastError()); +#endif return -1; } } @@ -178,11 +192,22 @@ sin.sin_family = AF_INET; sin.sin_addr.s_addr = a->s_addr; - if (connect(sock, (struct sockaddr*) &sin, sizeof(sin)) == -1) { + if ((ret = connect(sock, (struct sockaddr*) &sin, sizeof(sin))) == -1) { +#ifndef _WIN32 if (errno && (!async || errno != EINPROGRESS)) { gg_debug(GG_DEBUG_MISC, "-- connect() failed. errno = %d (%s)\n", errno, strerror(errno)); return -1; } +#else + if (ret == SOCKET_ERROR) { + gg_debug(GG_DEBUG_MISC, "-- connect() SOCKET_ERROR: %d\n", WSAGetLastError()); + if((WSAGetLastError() != WSAEWOULDBLOCK) && + (!async || WSAGetLastError() != WSAEINPROGRESS)) { + gg_debug(GG_DEBUG_MISC, "-- connect() failed. errno = %d\n", WSAGetLastError()); + return -1; + } + } +#endif gg_debug(GG_DEBUG_MISC, "-- connect() in progress\n"); } @@ -208,11 +233,19 @@ for (; length > 1; buf++, length--) { do { +#ifndef _WIN32 if ((ret = read(sock, buf, 1)) == -1 && errno != EINTR) { +#else + if ((ret = recv(sock, buf, 1, 0)) == SOCKET_ERROR && (WSAGetLastError() != WSAEINTR)) { +#endif *buf = 0; return; } +#ifndef _WIN32 } while (ret == -1 && errno == EINTR); +#else + } while (ret == SOCKET_ERROR && WSAGetLastError() == WSAEINTR); +#endif if (*buf == '\n') { buf++; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/gg/gg.c --- a/src/protocols/gg/gg.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/gg/gg.c Fri Oct 11 03:14:01 2002 +0000 @@ -1,6 +1,6 @@ /* * gaim - Gadu-Gadu Protocol Plugin - * $Id: gg.c 3680 2002-10-06 00:39:02Z seanegan $ + * $Id: gg.c 3753 2002-10-11 03:14:01Z robflynn $ * * Copyright (C) 2001 Arkadiusz Mi¶kiewicz * @@ -24,17 +24,22 @@ #include #endif +#ifndef _WIN32 #include #include -#include #include #include +#include +#else +#include +#endif + +#include #include #include #include #include #include -#include #include #include #ifdef HAVE_LANGINFO_CODESET @@ -51,6 +56,10 @@ #include "gaim.h" #include "proxy.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #include "pixmaps/protocols/gg/gg_suncloud.xpm" #include "pixmaps/protocols/gg/gg_sunred.xpm" #include "pixmaps/protocols/gg/gg_sunwhitered.xpm" @@ -85,6 +94,10 @@ #define UC_NORMAL 2 +/* for win32 compatability */ +G_MODULE_IMPORT GSList *connections; + + struct agg_data { struct gg_session *sess; int own_status; @@ -419,29 +432,38 @@ gg_free_event(e); } -static void login_callback(gpointer data, gint source, GaimInputCondition cond) +void login_callback(gpointer data, gint source, GaimInputCondition cond) { struct gaim_connection *gc = data; struct agg_data *gd = gc->proto_data; struct gg_event *e; - if (!g_slist_find(connections, data)) { + debug_printf("GG login_callback...\n"); + if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } - - if (gd->sess->fd != source) + debug_printf("Found GG connection\n"); + if (gd->sess->fd != source) { gd->sess->fd = source; - + debug_printf("Setting sess->fd to source\n"); + } if (source == -1) { hide_login_progress(gc, _("Unable to connect.")); signoff(gc); return; } - - if (gc->inpa == 0) + debug_printf("Source is valid.\n"); + if (gc->inpa == 0) { + debug_printf("login_callback.. checking gc->inpa .. is 0.. setting fd watch\n"); gc->inpa = gaim_input_add(gd->sess->fd, GAIM_INPUT_READ, login_callback, gc); - + debug_printf("Adding watch on fd\n"); + } + debug_printf("Checking State.\n"); switch (gd->sess->state) { case GG_STATE_READING_DATA: set_login_progress(gc, 2, _("Reading data")); @@ -456,9 +478,10 @@ set_login_progress(gc, 5, _("Exchanging key hash")); break; default: + debug_printf("No State found\n"); break; } - + debug_printf("gg_watch_fd\n"); if (!(e = gg_watch_fd(gd->sess))) { debug_printf("login_callback: gg_watch_fd failed - CRITICAL!\n"); hide_login_progress(gc, _("Critical error in GG library\n")); @@ -466,6 +489,37 @@ return; } + /* If we are GG_STATE_CONNECTING_GG then we still need to connect, as + we could not use proxy_connect in libgg.c */ + switch( gd->sess->state ) { + case GG_STATE_CONNECTING_GG: + { + struct in_addr ip; + char buf[256]; + + /* Remove watch on initial socket - now that we have ip and port of login server */ + gaim_input_remove(gc->inpa); + + ip.s_addr = gd->sess->server_ip; + gd->sess->fd = proxy_connect(inet_ntoa(ip), gd->sess->port, login_callback, gc); + + if (gd->sess->fd < 0) { + g_snprintf(buf, sizeof(buf), _("Connect to %s failed"), inet_ntoa(ip)); + hide_login_progress(gc, buf); + signoff(gc); + return; + } + break; + } + case GG_STATE_READING_KEY: + /* Set new watch on login server ip */ + if(gc->inpa) + gc->inpa = gaim_input_add(gd->sess->fd, GAIM_INPUT_READ, login_callback, gc); + debug_printf("Setting watch on connection with login server.\n"); + break; + }/* end switch() */ + + debug_printf("checking gg_event\n"); switch (e->type) { case GG_EVENT_NONE: /* nothing */ @@ -490,9 +544,10 @@ signoff(gc); break; default: + debug_printf("no gg_event\n"); break; } - + debug_printf("Returning from login_callback\n"); gg_free_event(e); } @@ -837,16 +892,25 @@ debug_printf("search_callback: g_slist_find error\n"); gaim_input_remove(hdata->inpa); g_free(hdata); +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } webdata = NULL; len = 0; - +#ifndef _WIN32 while (read(source, &read_data, 1) > 0 || errno == EWOULDBLOCK) { if (errno == EWOULDBLOCK) { errno = 0; +#else + while (recv(source, &read_data, 1, 0) > 0 || WSAEWOULDBLOCK == WSAGetLastError() ) { + if (WSAEWOULDBLOCK == WSAGetLastError()) { + WSASetLastError(0); +#endif continue; } @@ -862,7 +926,11 @@ webdata[len] = 0; gaim_input_remove(hdata->inpa); +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif debug_printf("http_results: type %d, webdata [%s]\n", hdata->type, webdata); @@ -905,7 +973,11 @@ debug_printf("http_req_callback: g_slist_find error\n"); g_free(request); g_free(hdata); +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -927,10 +999,18 @@ g_free(request); +#ifndef _WIN32 if (write(source, buf, strlen(buf)) < strlen(buf)) { +#else + if (send(source, buf, strlen(buf), 0) < strlen(buf)) { +#endif g_free(buf); g_free(hdata); +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif do_error_dialog(_("Error communicating with Gadu-Gadu server"), _("Gaim was unable to complete your request due to a problem " "communicating to the Gadu-Gadu HTTP server. Please try again " @@ -1221,7 +1301,7 @@ static struct prpl *my_protocol = NULL; -void gg_init(struct prpl *ret) +G_MODULE_EXPORT void gg_init(struct prpl *ret) { struct proto_user_opt *puo; ret->protocol = PROTO_GADUGADU; @@ -1272,7 +1352,7 @@ #ifndef STATIC -void *gaim_prpl_init(struct prpl *prpl) +G_MODULE_EXPORT void gaim_prpl_init(struct prpl *prpl) { gg_init(prpl); prpl->plug->desc.api_version = PLUGIN_API_VERSION; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/gg/libgg.c --- a/src/protocols/gg/libgg.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/gg/libgg.c Fri Oct 11 03:14:01 2002 +0000 @@ -1,4 +1,4 @@ -/* $Id: libgg.c 2859 2001-12-05 09:48:56Z warmenhoven $ */ +/* $Id: libgg.c 3753 2002-10-11 03:14:01Z robflynn $ */ /* * (C) Copyright 2001 Wojtek Kaniewski , @@ -18,23 +18,29 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#include +#ifndef _WIN32 #include #include #include #include #include +#include +#include +#else +#include +#include +#endif + +#include +#include +#include +#include #include -#include #include #ifndef _AIX # include #endif #include -#include #include #ifdef sun #include @@ -45,19 +51,24 @@ #endif #include "libgg.h" #include "config.h" +#include "gaim.h" +#include "proxy.h" -int gg_debug_level = 0; +int gg_debug_level = (GG_DEBUG_NET | GG_DEBUG_TRAFFIC | GG_DEBUG_DUMP | GG_DEBUG_FUNCTION | GG_DEBUG_MISC); int gg_http_use_proxy = 0; int gg_http_proxy_port = 0; char *gg_http_proxy_host = NULL; +/* temp -Herman */ +static int ping_outstanding = 0; + #ifndef lint static char rcsid[] #ifdef __GNUC__ __attribute__ ((unused)) #endif -= "$Id: libgg.c 2859 2001-12-05 09:48:56Z warmenhoven $"; += "$Id: libgg.c 3753 2002-10-11 03:14:01Z robflynn $"; #endif @@ -95,6 +106,7 @@ #endif } +#ifndef _WIN32 /* * gg_resolve() // funkcja wewnêtrzna * @@ -149,6 +161,7 @@ return 0; } +#endif /*!_WIN32*/ /* * gg_recv_packet() // funkcja wewnêtrzna @@ -165,6 +178,7 @@ struct gg_header h; char *buf = NULL; int ret = 0, offset, size = 0; + int sizeh = sizeof(struct gg_header); gg_debug(GG_DEBUG_FUNCTION, "** gg_recv_packet(...);\n"); @@ -174,21 +188,41 @@ } if (sess->recv_left < 1) { - while (ret != sizeof(h)) { - ret = read(sess->fd, &h, sizeof(h)); - gg_debug(GG_DEBUG_MISC, "-- header recv(..., %d) = %d\n", sizeof(h), ret); - if (ret < sizeof(h)) { + while (ret != sizeh) { +#ifndef _WIN32 + ret = read(sess->fd, &h, sizeh); + gg_debug(GG_DEBUG_MISC, "-- header recv(..., %d) = %d\n", sizeh, ret); + if (ret < sizeh) { if (errno != EINTR) { gg_debug(GG_DEBUG_MISC, "-- errno = %d (%s)\n", errno, strerror(errno)); return NULL; } } +#else + ret = recv(sess->fd, (char*)&h, sizeh, 0); + gg_debug(GG_DEBUG_MISC, "-- header recv(..., %d) = %d\n", sizeh, ret); + if (ret < sizeh) { + /* connection has been gracefully closed */ + if (ret == 0) { + gg_debug(GG_DEBUG_MISC, "Connection has been gracefully closed\n"); + WSASetLastError(WSAEDISCON); + return NULL; + } + else if (ret == SOCKET_ERROR) { + if(WSAGetLastError() != WSAEINTR) { + gg_debug(GG_DEBUG_MISC, "-- socket error = %d\n", WSAGetLastError()); + return NULL; + } + } + + } +#endif } h.type = fix32(h.type); h.length = fix32(h.length); } else { - memcpy(&h, sess->recv_buf, sizeof(h)); + memcpy(&h, sess->recv_buf, sizeh); } /* jakie¶ sensowne limity na rozmiar pakietu */ @@ -204,24 +238,29 @@ offset = sess->recv_done; buf = sess->recv_buf; } else { - if (!(buf = malloc(sizeof(h) + h.length + 1))) { + if (!(buf = malloc(sizeh + h.length + 1))) { gg_debug(GG_DEBUG_MISC, "-- not enough memory\n"); return NULL; } - memcpy(buf, &h, sizeof(h)); + memcpy(buf, &h, sizeh); offset = 0; size = h.length; } while (size > 0) { - ret = read(sess->fd, buf + sizeof(h) + offset, size); +#ifndef _WIN32 + ret = read(sess->fd, buf + sizeh + offset, size); +#else + ret = recv(sess->fd, buf + sizeh + offset, size, 0); +#endif gg_debug(GG_DEBUG_MISC, "-- body recv(..., %d) = %d\n", size, ret); if (ret > -1 && ret <= size) { offset += ret; size -= ret; } else if (ret == -1) { +#ifndef _WIN32 gg_debug(GG_DEBUG_MISC, "-- errno = %d (%s)\n", errno, strerror(errno)); if (errno == EAGAIN) { gg_debug(GG_DEBUG_MISC, "-- %d bytes received, %d left\n", offset, size); @@ -235,6 +274,13 @@ free(buf); return NULL; } +#else + gg_debug(GG_DEBUG_MISC, "-- errno = %d\n", WSAGetLastError()); + if (WSAGetLastError()!= WSAEINTR) { + free(buf); + return NULL; + } +#endif } } @@ -244,7 +290,7 @@ int i; gg_debug(GG_DEBUG_DUMP, ">> received packet (type=%.2x):", h.type); - for (i = 0; i < sizeof(h) + h.length; i++) + for (i = 0; i < sizeh + h.length; i++) gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char) buf[i]); gg_debug(GG_DEBUG_DUMP, "\n"); } @@ -306,9 +352,14 @@ } plen = sizeof(struct gg_header) + length + payload_length; - +#ifndef _WIN32 if ((res = write(sock, tmp, plen)) < plen) { gg_debug(GG_DEBUG_MISC, "-- write() failed. res = %d, errno = %d (%s)\n", res, errno, strerror(errno)); +#else + if ((res = send(sock, tmp, plen, 0)) < plen) { + gg_debug(GG_DEBUG_MISC, "-- send() failed. res = %d, errno = %d\n", + res, (res == SOCKET_ERROR) ? WSAGetLastError() : 0); +#endif free(tmp); return -1; } @@ -317,7 +368,7 @@ return 0; } - +#ifndef _WIN32 /* * gg_login() * @@ -419,6 +470,7 @@ return sess; } +#endif /*!_WIN32*/ /* * gg_free_session() @@ -458,7 +510,11 @@ } if (sess->state != GG_STATE_CONNECTED) { +#ifndef _WIN32 errno = ENOTCONN; +#else + WSASetLastError( WSAENOTCONN ); +#endif return -1; } @@ -517,7 +573,11 @@ } if (sess->state != GG_STATE_CONNECTED) { +#ifndef _WIN32 errno = ENOTCONN; +#else + WSASetLastError( WSAENOTCONN ); +#endif return -1; } @@ -553,13 +613,24 @@ } if (sess->state != GG_STATE_CONNECTED) { +#ifndef _WIN32 errno = ENOTCONN; +#else + WSASetLastError( WSAENOTCONN ); +#endif return -1; } gg_debug(GG_DEBUG_FUNCTION, "** gg_ping(...);\n"); - - return gg_send_packet(sess->fd, GG_PING, NULL, 0, NULL, 0); + + if(ping_outstanding) { + debug_printf("Trying to send ping, when we havn't been ponged on last ping\n"); + return 1; + } + else { + ping_outstanding = 1; + return gg_send_packet(sess->fd, GG_PING, NULL, 0, NULL, 0); + } } /* @@ -605,7 +676,11 @@ } if (sess->state != GG_STATE_CONNECTED) { +#ifndef _WIN32 errno = ENOTCONN; +#else + WSASetLastError( WSAENOTCONN ); +#endif return -1; } @@ -650,7 +725,11 @@ } if (sess->state != GG_STATE_CONNECTED) { +#ifndef _WIN32 errno = ENOTCONN; +#else + WSASetLastError( WSAENOTCONN ); +#endif return -1; } @@ -682,7 +761,11 @@ } if (sess->state != GG_STATE_CONNECTED) { +#ifndef _WIN32 errno = ENOTCONN; +#else + WSASetLastError( WSAENOTCONN ); +#endif return -1; } @@ -785,7 +868,7 @@ if (h->type == GG_PONG) { gg_debug(GG_DEBUG_MISC, "-- received a pong\n"); - + ping_outstanding = 0; sess->last_pong = time(NULL); } @@ -812,7 +895,9 @@ { struct gg_event *e; int res = 0; +#ifndef _WIN32 int port; +#endif if (!sess) { errno = EFAULT; @@ -829,6 +914,9 @@ e->type = GG_EVENT_NONE; switch (sess->state) { +#ifndef _WIN32 + /* Apparantly we will never be in this state as long as we are + using proxy_connect instead of gg_login - Herman */ case GG_STATE_RESOLVING: { struct in_addr a; @@ -887,7 +975,7 @@ break; } - +#endif /* !_WIN32 */ case GG_STATE_CONNECTING: { char buf[1024]; @@ -895,10 +983,16 @@ gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTING\n"); - if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) { + if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, +#ifndef _WIN32 + &res, +#else + (char*)&res, +#endif + &res_size) || res)) { +#if 0 struct in_addr *addr = (struct in_addr*) &sess->server_ip; gg_debug(GG_DEBUG_MISC, "-- http connection failed, errno = %d (%s), trying direct connection\n", res, strerror(res)); - if ((sess->fd = gg_connect(addr, GG_DEFAULT_PORT, sess->async)) == -1) { gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n"); if ((sess->fd = gg_connect(addr, GG_HTTPS_PORT, sess->async)) == -1) { @@ -913,20 +1007,26 @@ sess->state = GG_STATE_CONNECTING_GG; sess->check = GG_CHECK_WRITE; +#else + gg_debug(GG_DEBUG_MISC, "-- http connection failed, errno = %d\n", res); + e->type = GG_EVENT_CONN_FAILED; + e->event.failure = GG_FAILURE_CONNECTING; + sess->state = GG_STATE_IDLE; +#endif break; } gg_debug(GG_DEBUG_MISC, "-- http connection succeded, sending query\n"); if (gg_http_use_proxy) { - snprintf(buf, sizeof(buf) - 1, + g_snprintf(buf, sizeof(buf) - 1, "GET http://" GG_APPMSG_HOST "/appsvc/appmsg.asp?fmnumber=%lu HTTP/1.0\r\n" "Host: " GG_APPMSG_HOST "\r\n" "User-Agent: " GG_HTTP_USERAGENT "\r\n" "Pragma: no-cache\r\n" "\r\n", sess->uin); } else { - snprintf(buf, sizeof(buf) - 1, + g_snprintf(buf, sizeof(buf) - 1, "GET /appsvc/appmsg.asp?fmnumber=%lu HTTP/1.0\r\n" "Host: " GG_APPMSG_HOST "\r\n" "User-Agent: " GG_HTTP_USERAGENT "\r\n" @@ -935,10 +1035,12 @@ }; gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", buf); - +#ifndef _WIN32 if (write(sess->fd, buf, strlen(buf)) < strlen(buf)) { +#else + if (send(sess->fd, buf, strlen(buf), 0) < strlen(buf)) { +#endif gg_debug(GG_DEBUG_MISC, "-- sending query failed\n"); - errno = EIO; e->type = GG_EVENT_CONN_FAILED; e->event.failure = GG_FAILURE_WRITING; @@ -1010,8 +1112,10 @@ a.s_addr = inet_addr(host); sess->server_ip = a.s_addr; - - if ((sess->fd = gg_connect(&a, port, sess->async)) == -1) { +#if 0 + /* We need to watch this non-blocking socket so lets use proxy_connect + in gg.c - Herman */ + if((sess->fd = gg_connect(&a, port, sess->assync)) == -1) { gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n"); if ((sess->fd = gg_connect(&a, GG_HTTPS_PORT, sess->async)) == -1) { gg_debug(GG_DEBUG_MISC, "-- connection failed, errno = %d (%s)\n", errno, strerror(errno)); @@ -1022,7 +1126,9 @@ break; } } - +#else + sess->port = port; +#endif sess->state = GG_STATE_CONNECTING_GG; sess->check = GG_CHECK_WRITE; @@ -1035,7 +1141,13 @@ gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTING_GG\n"); - if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) { + if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, +#ifndef _WIN32 + &res, +#else + (char*)&res, +#endif + &res_size) || res)) { struct in_addr *addr = (struct in_addr*) &sess->server_ip; gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n"); @@ -1068,8 +1180,11 @@ gg_debug(GG_DEBUG_MISC, "== GG_STATE_READING_KEY\n"); if (!(h = gg_recv_packet(sess))) { +#ifndef _WIN32 gg_debug(GG_DEBUG_MISC, "-- gg_recv_packet() failed. errno = %d (%s)\n", errno, strerror(errno)); - +#else + gg_debug(GG_DEBUG_MISC, "-- gg_recv_packet() failed. errno = %d\n", WSAGetLastError()); +#endif e->type = GG_EVENT_CONN_FAILED; e->event.failure = GG_FAILURE_READING; sess->state = GG_STATE_IDLE; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/irc/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/irc/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,151 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of libirc +# + +# +# PATHS +# + +INCLUDE_DIR := . +GTK_TOP := ../../../../win32-dev/gtk_2_0 +GAIM_TOP := ../../.. +IRC_ROOT := . +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir + +## +## VARIABLE DEFINITIONS +## + +TARGET = libirc + +VERSION := $(shell cat $(GAIM_TOP)/VERSION) + +# Compiler Options + +CC = gcc + +CFLAGS = -O2 -Werror -Wall -mno-cygwin -fnative-struct + +DEFINES = -DAIM_BUILDDATE=\"`date +%Y%m%d`\" \ + -DAIM_BUILDTIME=\"`date +%H%M%S`\" \ + -DVERSION=\"$(VERSION)\" \ + -DHAVE_CONFIG_H + +# Static or Plugin... +ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR) +else +ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR)/plugins +endif +endif + + +## +## INCLUDE MAKEFILES +## + + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(IRC_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src + + +## +## SOURCES, OBJECTS +## + +C_SRC = irc.c + + +OBJECTS = $(C_SRC:%.c=%.o) + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 -lglib-2.0 -lgdk-win32-2.0 -lgmodule-2.0 -lgobject-2.0 -lws2_32 -lintl -lgaim + +# -liberty + + +## +## RULES +## + +# How to make a C file + +%.o: %.c + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: $(TARGET).dll + +install: + cp $(IRC_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + + +## +## BUILD Dependencies +## + +$(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + +## +## BUILD DLL +## + +$(TARGET).def: $(OBJECTS) + dlltool --dllname $(TARGET).dll -z $(TARGET).def \ + $(OBJECTS) + +$(TARGET).base: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + gcc -mdll -o junk.tmp -Wl,--base-file,$@ $(OBJECTS) $(LIB_PATHS) $(LIBS) + rm -rf junk.tmp + +$(TARGET).exp: $(TARGET).def $(TARGET).base + dlltool --dllname $(TARGET).dll --base-file $(TARGET).base \ + --output-exp $(TARGET).exp --def $(TARGET).def + rm -rf $(TARGET).base + +$(TARGET).dll: $(OBJECTS) $(TARGET).exp $(GAIM_TOP)/src/gaim.lib + dlltool -D $(TARGET).dll -d $(TARGET).def -l $(TARGET).lib + gcc -mdll -o $(TARGET).dll $(OBJECTS) -Wl,$(TARGET).exp $(LIB_PATHS) $(LIBS) + rm -rf $(TARGET).exp + + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).lib + rm -rf $(TARGET).def diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/irc/irc.c --- a/src/protocols/irc/irc.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/irc/irc.c Fri Oct 11 03:14:01 2002 +0000 @@ -25,8 +25,13 @@ #include +#ifndef _WIN32 +#include +#else +#include +#endif + #include -#include #include #include #include @@ -39,6 +44,10 @@ #include "gaim.h" #include "proxy.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #include "pixmaps/protocols/irc/irc_icon.xpm" #define IRC_BUF_LEN 4096 @@ -47,6 +56,10 @@ #define USEROPT_SERV 0 #define USEROPT_PORT 1 +/* for win32 compatability */ +G_MODULE_IMPORT GSList *connections; + + struct dcc_chat { struct gaim_connection *gc; @@ -64,6 +77,7 @@ char *name; int len; int watcher; + int awatcher; char ip[12]; int port; int fd; @@ -119,7 +133,11 @@ static int irc_write(int fd, char *data, int len) { debug_printf("IRC C: %s", data); +#ifndef _WIN32 return write(fd, data, len); +#else + return send(fd, data, len, 0); +#endif } static struct conversation *irc_find_chat(struct gaim_connection *gc, char *name) @@ -435,7 +453,11 @@ int n = 0, l; struct conversation *convo; debug_printf("THIS IS TOO MUCH EFFORT\n"); +#ifndef _WIN32 n = read (chat->fd, buffer, IRC_BUF_LEN); +#else + n = recv (chat->fd, buffer, IRC_BUF_LEN, 0); +#endif if (n > 0) { @@ -461,8 +483,6 @@ } static void irc_file_transfer_do(struct gaim_connection *gc, struct irc_file_transfer *ift) { - struct irc_data *id = (struct irc_data *)gc->proto_data; - /* Ok, we better be receiving some crap here boyeee */ if (transfer_in_do(ift->xfer, ift->fd, ift->name, ift->len)) { gaim_input_remove(ift->watcher); @@ -471,6 +491,19 @@ } +void irc_read_dcc_ack (gpointer data, gint source, GaimInputCondition condition) { + struct irc_file_transfer *ift = data; + struct irc_data *id = (struct irc_data *)ift->gc->proto_data; + int len; + guint32 ack; + + printf("I got here.\n"); + len = recv(source, (char *)&ack, 4, MSG_PEEK); + printf("Len is: %d\n", len); + printf("Ack is: %d\n", ack); + recv(source, (char *)&ack, 4, 0); +} + void dcc_send_callback (gpointer data, gint source, GaimInputCondition condition) { struct irc_file_transfer *ift = data; struct irc_data *id = (struct irc_data *)ift->gc->proto_data; @@ -488,6 +521,8 @@ return; } +// ift->awatcher = gaim_input_add(ift->fd, GAIM_INPUT_READ, irc_read_dcc_ack, ift); + if (transfer_out_do(ift->xfer, ift->fd, 0)) { gaim_input_remove(ift->watcher); ift->watcher = 0; @@ -1323,7 +1358,11 @@ gchar buf[1024]; gboolean off; +#ifndef _WIN32 i = read(idata->fd, buf, 1024); +#else + i = recv(idata->fd, buf, 1024, 0); +#endif if (i <= 0) { hide_login_progress_error(gc, "Read error"); signoff(gc); @@ -1374,7 +1413,11 @@ char buf[IRC_BUF_LEN]; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -1490,7 +1533,11 @@ if (gc->inpa) gaim_input_remove(gc->inpa); +#ifndef _WIN32 close(idata->fd); +#else + closesocket(idata->fd); +#endif g_free(gc->proto_data); } @@ -2011,7 +2058,6 @@ ift->xfer = transfer_out_add(gc, ift->sn); } - static struct irc_file_transfer *find_ift_by_xfer(struct gaim_connection *gc, struct file_transfer *xfer) { @@ -2030,7 +2076,6 @@ } static void irc_file_transfer_data_chunk(struct gaim_connection *gc, struct file_transfer *xfer, const char *data, int len) { - struct irc_data *id = (struct irc_data *)gc->proto_data; struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); guint32 pos; @@ -2113,10 +2158,7 @@ static void irc_file_transfer_in(struct gaim_connection *gc, struct file_transfer *xfer, int offset) { - struct irc_data *id = (struct irc_data *)gc->proto_data; struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); - struct sockaddr_in addr; - char *ip = (char *)malloc(32); ift->xfer = xfer; proxy_connect(ift->ip, ift->port, dcc_recv_callback, ift); @@ -2149,7 +2191,7 @@ chat->inpa = gaim_input_add (chat->fd, GAIM_INPUT_READ, dcc_chat_connected, chat); - snprintf (buf, sizeof buf, "\001DCC CHAT chat %s %d\001\n", + g_snprintf (buf, sizeof buf, "\001DCC CHAT chat %s %d\001\n", chat->ip_address, chat->port); irc_send_im (gc, who, buf, -1, 0); } @@ -2196,7 +2238,7 @@ static struct prpl *my_protocol = NULL; -void irc_init(struct prpl *ret) +G_MODULE_EXPORT void irc_init(struct prpl *ret) { struct proto_user_opt *puo; ret->protocol = PROTO_IRC; @@ -2240,8 +2282,7 @@ } #ifndef STATIC - -void *gaim_prpl_init(struct prpl* prpl) +G_MODULE_EXPORT void gaim_prpl_init(struct prpl* prpl) { irc_init(prpl); prpl->plug->desc.api_version = PLUGIN_API_VERSION; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/jabber/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/jabber/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,176 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of libjabber +# + +# +# PATHS +# + +INCLUDE_DIR := . +GTK_TOP := ../../../../win32-dev/gtk_2_0 +GAIM_TOP := ../../.. +JABBER_ROOT := . +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir + +## +## VARIABLE DEFINITIONS +## + +TARGET = libjabber + +VERSION := $(shell cat $(GAIM_TOP)/VERSION) + +# Compiler Options + +CC = gcc + +CFLAGS = -O2 -Werror -Wall -mno-cygwin -fnative-struct + +DEFINES = -DAIM_BUILDDATE=\"`date +%Y%m%d`\" \ + -DAIM_BUILDTIME=\"`date +%H%M%S`\" \ + -DVERSION=\"$(VERSION)\" \ + -DHAVE_CONFIG_H + +# Static or Plugin... +ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR) +else +ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR)/plugins +endif +endif + + +## +## INCLUDE MAKEFILES +## + + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(JABBER_ROOT) \ + -I$(JABBER_ROOT)/win32 \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src + + +## +## SOURCES, OBJECTS +## + +C_SRC = jabber.c \ + expat.c \ + genhash.c \ + hashtable.c \ + jconn.c \ + jid.c \ + jpacket.c \ + jutil.c \ + karma.c \ + log.c \ + pool.c \ + pproxy.c \ + rate.c \ + sha.c \ + snprintf.c \ + socket.c \ + str.c \ + xhash.c \ + xmlnode.c \ + xmlparse.c \ + xmlrole.c \ + xmltok.c \ + xstream.c \ + win32/posix.uname.c + + +OBJECTS = $(C_SRC:%.c=%.o) + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 -lglib-2.0 -lgdk-win32-2.0 -lgmodule-2.0 -lgobject-2.0 -lws2_32 -lintl -lgaim + +# -liberty + + +## +## RULES +## + +# How to make a C file + +%.o: %.c + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: $(TARGET).dll + +install: + cp $(JABBER_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + + +## +## BUILD Dependencies +## + +$(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + +## +## BUILD DLL +## + +$(TARGET).def: $(OBJECTS) + dlltool --dllname $(TARGET).dll -z $(TARGET).def \ + $(OBJECTS) + +$(TARGET).base: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + gcc -mdll -o junk.tmp -Wl,--base-file,$@ $(OBJECTS) $(LIB_PATHS) $(LIBS) + rm -rf junk.tmp + +$(TARGET).exp: $(TARGET).def $(TARGET).base + dlltool --dllname $(TARGET).dll --base-file $(TARGET).base \ + --output-exp $(TARGET).exp --def $(TARGET).def + rm -rf $(TARGET).base + +$(TARGET).dll: $(OBJECTS) $(TARGET).exp $(GAIM_TOP)/src/gaim.lib + dlltool -D $(TARGET).dll -d $(TARGET).def -l $(TARGET).lib + gcc -mdll -o $(TARGET).dll $(OBJECTS) -Wl,$(TARGET).exp $(LIB_PATHS) $(LIBS) + rm -rf $(TARGET).exp + + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf ./win32/*.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).lib + rm -rf $(TARGET).def diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/jabber/jabber.c --- a/src/protocols/jabber/jabber.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/jabber/jabber.c Fri Oct 11 03:14:01 2002 +0000 @@ -20,23 +20,27 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ - #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif - +#ifndef _WIN32 #include -#include -#include #include #include +#include +#include +#include +#else +#include +#include "utsname.h" +#endif + +#include #include #include #include #include -#include -#include #include #include "multi.h" #include "prpl.h" @@ -50,6 +54,10 @@ #include "jabber.h" #include "proxy.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #include "pixmaps/protocols/jabber/available.xpm" #include "pixmaps/protocols/jabber/available-away.xpm" #include "pixmaps/protocols/jabber/available-chat.xpm" @@ -57,6 +65,9 @@ #include "pixmaps/protocols/jabber/available-dnd.xpm" #include "pixmaps/protocols/jabber/available-error.xpm" +/* for win32 compatability */ +G_MODULE_IMPORT GSList *connections; + /* The priv member of gjconn's is a gaim_connection for now. */ #define GJ_GC(x) ((struct gaim_connection *)(x)->priv) @@ -140,6 +151,7 @@ time_t idle; gboolean die; GHashTable *buddies; + GSList *file_transfers; }; /* @@ -229,6 +241,8 @@ static void jabber_handlevcard(gjconn, xmlnode, char *); +static char *jabber_normalize(const char *s); + static char *create_valid_jid(const char *given, char *server, char *resource) { char *valid; @@ -492,7 +506,11 @@ gjab_send_raw(gjc, ""); gjc->state = JCONN_STATE_OFF; gjc->was_connected = 0; +#ifndef _WIN32 close(gjc->fd); +#else + closesocket(gjc->fd); +#endif gjc->fd = -1; XML_ParserFree(gjc->parser); gjc->parser = NULL; @@ -535,7 +553,11 @@ if (gjc && gjc->state != JCONN_STATE_OFF) { char *buf = xmlnode2str(x); if (buf) +#ifndef _WIN32 write(gjc->fd, buf, strlen(buf)); +#else + send(gjc->fd, buf, strlen(buf), 0); +#endif debug_printf("gjab_send: %s\n", buf); } } @@ -546,7 +568,11 @@ /* * JFIXME: No error detection?!?! */ +#ifndef _WIN32 if(write(gjc->fd, str, strlen(str)) < 0) { +#else + if(send(gjc->fd, str, strlen(str), 0) < 0) { +#endif fprintf(stderr, "DBG: Problem sending. Error: %d\n", errno); fflush(stderr); } @@ -636,8 +662,11 @@ if (!gjc || gjc->state == JCONN_STATE_OFF) return; - +#ifndef _WIN32 if ((len = read(gjc->fd, buf, sizeof(buf) - 1)) > 0) { +#else + if ((len = recv(gjc->fd, buf, sizeof(buf) - 1, 0)) > 0) { +#endif struct jabber_data *jd = GJ_GC(gjc)->proto_data; buf[len] = '\0'; debug_printf("input (len %d): %s\n", len, buf); @@ -727,7 +756,11 @@ gjconn gjc; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -1901,12 +1934,194 @@ xmlnode_free(x); } +struct jabber_file_transfer { + enum { JFT_SENDFILE_IN, JFT_SENDFILE_OUT } type; + struct file_transfer *xfer; + char *from; + struct g_url *url; + char *name; + GString *headers; + + int len; + int fd; + int watcher; + + gboolean sentreq; + gboolean newline; + gboolean startsaving; + + struct gaim_connection *gc; +}; + +static struct jabber_file_transfer *find_jft_by_xfer(struct gaim_connection *gc, + struct file_transfer *xfer) { + GSList *g = ((struct jabber_data *)gc->proto_data)->file_transfers; + struct jabber_file_transfer *f = NULL; + + while(g) { + f = (struct jabber_file_transfer *)g->data; + if(f->xfer == xfer) + break; + g = g->next; + f = NULL; + } + + return f; +} + +static void jabber_http_recv_callback(gpointer data, gint source, GaimInputCondition condition) { + struct jabber_file_transfer *jft = data; + char test; + + jft->fd = source; + if(!jft->sentreq) { + char buf[1024]; + g_snprintf(buf, sizeof(buf), "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", jft->url->page, jft->url->address); + write(source, buf, strlen(buf)); + fcntl(source, F_SETFL, O_NONBLOCK); + jft->sentreq = TRUE; + jft->watcher = gaim_input_add(source, GAIM_INPUT_READ, jabber_http_recv_callback,data); + return; + } + + if(!jft->startsaving) { + if(read(source, &test, sizeof(test)) > 0 || errno == EWOULDBLOCK) { + if(errno == EWOULDBLOCK) { + errno = 0; + return; + } + + jft->headers = g_string_append_c(jft->headers, test); + if(test == '\r') + return; + if(test == '\n') { + if(jft->newline) { + gchar *lenstr = strstr(jft->headers->str, "Content-Length: "); + if(lenstr) { + sscanf(lenstr, "Content-Length: %d", &jft->len); + } + jft->startsaving = TRUE; + } else + jft->newline = TRUE; + return; + } + jft->newline = FALSE; + return; + } else { + gaim_input_remove(jft->watcher); + close(source); + //FIXME: ft_cancel(NULL, jft->xfer); + } + return; + } + + /* we've parsed the headers, gotten the size, all is good. now we pass the reception of + * the file off to the core, and leave it in it's capable...err...hands?? */ + gaim_input_remove(jft->watcher); + jft->watcher = 0; + transfer_in_do(jft->xfer, jft->fd, jft->name, jft->len); +} + +static void jabber_file_transfer_cancel(struct gaim_connection *gc, struct file_transfer *xfer) { + struct jabber_data *jd = gc->proto_data; + struct jabber_file_transfer *jft = find_jft_by_xfer(gc, xfer);\ + xmlnode x,y; + + jd->file_transfers = g_slist_remove(jd->file_transfers, jft); + + gaim_input_remove(jft->watcher); + close(jft->fd); + + x = xmlnode_new_tag("iq"); + xmlnode_put_attrib(x, "type", "error"); + xmlnode_put_attrib(x, "to", jft->from); + y = xmlnode_insert_tag(x, "error"); + /* FIXME: need to handle other kinds of errors here */ + xmlnode_put_attrib(y, "code", "406"); + xmlnode_insert_cdata(y, "File Transfer Refused", -1); + + gjab_send(jd->gjc, x); + + xmlnode_free(x); + + g_string_free(jft->headers, TRUE); + g_free(jft->from); + g_free(jft->url); + g_free(jft->name); + + g_free(jft); +} + +static void jabber_file_transfer_done(struct gaim_connection *gc, struct file_transfer *xfer) { + struct jabber_data *jd = gc->proto_data; + struct jabber_file_transfer *jft = find_jft_by_xfer(gc, xfer); + xmlnode x; + + jd->file_transfers = g_slist_remove(jd->file_transfers, jft); + + gaim_input_remove(jft->watcher); + close(jft->fd); + + x = xmlnode_new_tag("iq"); + xmlnode_put_attrib(x, "type", "result"); + xmlnode_put_attrib(x, "to", jft->from); + + gjab_send(jd->gjc, x); + + xmlnode_free(x); + + g_string_free(jft->headers, TRUE); + g_free(jft->from); + g_free(jft->url); + g_free(jft->name); + + g_free(jft); +} + +static void jabber_file_transfer_in(struct gaim_connection *gc, struct file_transfer *xfer, int offset) { + struct jabber_file_transfer *jft = find_jft_by_xfer(gc, xfer); + + proxy_connect(jft->url->address, jft->url->port, jabber_http_recv_callback, jft); +} + +static void jabber_handleoob(gjconn gjc, xmlnode iqnode) { + struct jabber_file_transfer *jft; + struct jabber_data *jd = GJ_GC(gjc)->proto_data; + char *msg = NULL; + xmlnode querynode = xmlnode_get_tag(iqnode, "query"); + xmlnode urlnode,descnode; + + if(!querynode) + return; + urlnode = xmlnode_get_tag(querynode, "url"); + if(!urlnode) + return; + descnode = xmlnode_get_tag(querynode, "desc"); + if(descnode) + msg = xmlnode_get_data(descnode); + + jft = g_new0(struct jabber_file_transfer, 1); + jft->type = JFT_SENDFILE_IN; + jft->gc = GJ_GC(gjc); + jft->url = parse_url(xmlnode_get_data(urlnode)); + jft->from = g_strdup(xmlnode_get_attrib(iqnode, "from")); + jft->name = g_strdup(g_strrstr(jft->url->page,"/")); + if (!jft->name) + jft->name = g_strdup(jft->url->page); + jft->headers = g_string_new(""); + jft->len = -1; + + jd->file_transfers = g_slist_append(jd->file_transfers, jft); + + jft->xfer = transfer_in_add(GJ_GC(gjc), jft->from, jft->name, jft->len, 1, msg); +} + static void jabber_handlelast(gjconn gjc, xmlnode iqnode) { - xmlnode x, querytag; + xmlnode x, querytag; char *id, *from; struct jabber_data *jd = GJ_GC(gjc)->proto_data; char idle_time[32]; - + id = xmlnode_get_attrib(iqnode, "id"); from = xmlnode_get_attrib(iqnode, "from"); @@ -1979,6 +2194,8 @@ querynode = xmlnode_get_tag(p->x, "query"); if (NSCHECK(querynode, "jabber:iq:roster")) { jabber_handlebuddy(gjc, xmlnode_get_firstchild(querynode)); + } else if(NSCHECK(querynode, "jabber:iq:oob")) { + jabber_handleoob(gjc, p->x); } } else if (jpacket_subtype(p) == JPACKET__GET) { xmlnode querynode; @@ -2261,7 +2478,7 @@ xmlnode_insert_tag(y, "composing"); if (message && strlen(message)) { - char *utf8 = str_to_utf8(message); + char *utf8 = str_to_utf8((char*)message); y = xmlnode_insert_tag(x, "body"); xmlnode_insert_cdata(y, utf8, -1); g_free(utf8); @@ -2748,7 +2965,7 @@ g_free(subject); if (message && strlen(message)) { - char *utf8 = str_to_utf8(message); + char *utf8 = str_to_utf8((char*)message); y = xmlnode_insert_tag(x, "body"); xmlnode_insert_cdata(y, utf8, -1); g_free(utf8); @@ -3960,7 +4177,7 @@ static struct prpl *my_protocol = NULL; -void jabber_init(struct prpl *ret) +G_MODULE_EXPORT void jabber_init(struct prpl *ret) { /* the NULL's aren't required but they're nice to have */ struct proto_user_opt *puo; @@ -4009,7 +4226,12 @@ ret->send_typing = jabber_send_typing; ret->convo_closed = jabber_convo_closed; ret->rename_group = jabber_rename_group; - + ret->file_transfer_out = NULL; /* TODO */ + ret->file_transfer_in = jabber_file_transfer_in; + ret->file_transfer_data_chunk = NULL; /* TODO */ + ret->file_transfer_done = jabber_file_transfer_done; + ret->file_transfer_cancel = jabber_file_transfer_cancel; + puo = g_new0(struct proto_user_opt, 1); puo->label = g_strdup("Port:"); puo->def = g_strdup("5222"); @@ -4021,7 +4243,7 @@ #ifndef STATIC -void *gaim_prpl_init(struct prpl *prpl) +G_MODULE_EXPORT void gaim_prpl_init(struct prpl *prpl) { jabber_init(prpl); prpl->plug->desc.api_version = PLUGIN_API_VERSION; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/jabber/jabber.h --- a/src/protocols/jabber/jabber.h Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/jabber/jabber.h Fri Oct 11 03:14:01 2002 +0000 @@ -16,6 +16,18 @@ * Jabber * Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ */ +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include "win32dep.h" +#endif #include #include @@ -27,13 +39,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include #include #include #include diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/jabber/lib.h --- a/src/protocols/jabber/lib.h Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/jabber/lib.h Fri Oct 11 03:14:01 2002 +0000 @@ -1,3 +1,21 @@ +#ifdef HAVE_CONFIG_H +#include +#endif /* HAVE_CONFIG_H */ + +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include "win32dep.h" +#endif #include #include @@ -8,14 +26,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -151,11 +161,9 @@ #define NETSOCKET_CLIENT 1 #define NETSOCKET_UDP 2 -#ifndef WIN32 int make_netsocket(u_short port, char *host, int type); struct in_addr *make_addr(char *host); int set_fd_close_on_exec(int fd, int flag); -#endif /* --------------------------------------------------------- */ diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/jabber/libxode.h --- a/src/protocols/jabber/libxode.h Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/jabber/libxode.h Fri Oct 11 03:14:01 2002 +0000 @@ -1,3 +1,17 @@ +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#else + +#endif + #include #include #include @@ -7,15 +21,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include @@ -152,11 +157,9 @@ #define NETSOCKET_CLIENT 1 #define NETSOCKET_UDP 2 -#ifndef WIN32 int make_netsocket(u_short port, char *host, int type); struct in_addr *make_addr(char *host); int set_fd_close_on_exec(int fd, int flag); -#endif /* --------------------------------------------------------- */ diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/jabber/socket.c --- a/src/protocols/jabber/socket.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/jabber/socket.c Fri Oct 11 03:14:01 2002 +0000 @@ -148,6 +148,7 @@ return NULL; } +#ifndef _WIN32 /* Sets a file descriptor to close on exec. "flag" is 1 to close on exec, 0 to * leave open across exec. * -- EJB 7/31/2000 @@ -166,4 +167,5 @@ return 0; return fcntl(fd,F_SETFL,(long)newflags); } +#endif diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/jabber/win32/posix.uname.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/jabber/win32/posix.uname.c Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,135 @@ +/* + posix.uname.c - version 1.1 + Copyright (C) 1999, 2000 + Earnie Boyd and assigns + + Fills the utsname structure with the appropriate values. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1, 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 PARTICUALR PURPOSE. See the + GNU Lesser 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. + */ + +/* + Send bug reports to Earnie Boyd + */ + +#include "utsname.h" +#include +#include + +/* ANONYMOUS unions and structs are used from the windows header definitions. + These need to be defined for them to work correctly with gcc2.95.2-mingw. */ +/*#define _ANONYMOUS_STRUCT*/ +/*#define _ANONYMOUS_UNION*/ +#include +#include <_mingw.h> + +int +uname( struct utsname *uts ) +{ + DWORD sLength; + OSVERSIONINFO OS_version; + SYSTEM_INFO System_Info; + +/* XXX Should these be in the global runtime */ + enum WinOS {Win95, Win98, WinNT, unknown}; + int MingwOS; + + memset( uts, 0, sizeof ( *uts ) ); + OS_version.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + + GetVersionEx ( &OS_version ); + GetSystemInfo ( &System_Info ); + + strcpy( uts->sysname, "MINGW_" ); + switch( OS_version.dwPlatformId ) + { + case VER_PLATFORM_WIN32_NT: + strcat( uts->sysname, "WinNT" ); + MingwOS = WinNT; + break; + case VER_PLATFORM_WIN32_WINDOWS: + switch ( OS_version.dwMinorVersion ) + { + case 0: + strcat( uts->sysname, "Win95" ); + MingwOS = Win95; + break; + case 10: + strcat( uts->sysname, "Win98" ); + MingwOS = Win98; + break; + default: + strcat( uts->sysname, "Win??" ); + MingwOS = unknown; + break; + } + break; + default: + strcat( uts->sysname, "Win??" ); + MingwOS = unknown; + break; + } + + sprintf( uts->version, "%i", __MINGW32_MAJOR_VERSION ); + sprintf( uts->release, "%i", __MINGW32_MINOR_VERSION ); + + switch( System_Info.wProcessorArchitecture ) + { + case PROCESSOR_ARCHITECTURE_PPC: + strcpy( uts->machine, "ppc" ); + break; + case PROCESSOR_ARCHITECTURE_ALPHA: + strcpy( uts->machine, "alpha" ); + break; + case PROCESSOR_ARCHITECTURE_MIPS: + strcpy( uts->machine, "mips" ); + break; + case PROCESSOR_ARCHITECTURE_INTEL: + /* dwProcessorType is only valid in Win95 and Win98 + wProcessorLevel is only valid in WinNT */ + switch( MingwOS ) + { + case Win95: + case Win98: + switch( System_Info.dwProcessorType ) + { + case PROCESSOR_INTEL_386: + case PROCESSOR_INTEL_486: + case PROCESSOR_INTEL_PENTIUM: + sprintf( uts->machine, "i%ld", System_Info.dwProcessorType ); + break; + default: + strcpy( uts->machine, "i386" ); + break; + } + break; + case WinNT: + sprintf( uts->machine, "i%d86", System_Info.wProcessorLevel ); + break; + default: + strcpy( uts->machine, "unknown" ); + break; + } + break; + default: + strcpy( uts->machine, "unknown" ); + break; + } + + sLength = sizeof ( uts->nodename ) - 1; + GetComputerNameA( uts->nodename, &sLength ); + return 1; +} + diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/jabber/win32/utsname.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/jabber/win32/utsname.h Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,23 @@ +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct utsname +{ + char sysname[20]; + char nodename[20]; + char release[20]; + char version[20]; + char machine[20]; +}; + +int uname (struct utsname *); + +#ifdef __cplusplus +} +#endif + +#endif diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/msn/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/msn/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,151 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of libmsn +# + +# +# PATHS +# + +INCLUDE_DIR := . +GTK_TOP := ../../../../win32-dev/gtk_2_0 +GAIM_TOP := ../../.. +MSN_ROOT := . +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir + +## +## VARIABLE DEFINITIONS +## + +TARGET = libmsn + +VERSION := $(shell cat $(GAIM_TOP)/VERSION) + +# Compiler Options + +CC = gcc + +CFLAGS = -O2 -Werror -Wall -mno-cygwin -fnative-struct + +DEFINES = -DAIM_BUILDDATE=\"`date +%Y%m%d`\" \ + -DAIM_BUILDTIME=\"`date +%H%M%S`\" \ + -DVERSION=\"$(VERSION)\" \ + -DHAVE_CONFIG_H + +# Static or Plugin... +ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR) +else +ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR)/plugins +endif +endif + + +## +## INCLUDE MAKEFILES +## + + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(MSN_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src + + +## +## SOURCES, OBJECTS +## + +C_SRC = msn.c + + +OBJECTS = $(C_SRC:%.c=%.o) + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 -lglib-2.0 -lgdk-win32-2.0 -lgmodule-2.0 -lgobject-2.0 -lws2_32 -lintl -lgaim + +# -liberty + + +## +## RULES +## + +# How to make a C file + +%.o: %.c + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: $(TARGET).dll + +install: + cp $(MSN_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + + +## +## BUILD Dependencies +## + +$(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + +## +## BUILD DLL +## + +$(TARGET).def: $(OBJECTS) + dlltool --dllname $(TARGET).dll -z $(TARGET).def \ + $(OBJECTS) + +$(TARGET).base: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + gcc -mdll -o junk.tmp -Wl,--base-file,$@ $(OBJECTS) $(LIB_PATHS) $(LIBS) + rm -rf junk.tmp + +$(TARGET).exp: $(TARGET).def $(TARGET).base + dlltool --dllname $(TARGET).dll --base-file $(TARGET).base \ + --output-exp $(TARGET).exp --def $(TARGET).def + rm -rf $(TARGET).base + +$(TARGET).dll: $(OBJECTS) $(TARGET).exp $(GAIM_TOP)/src/gaim.lib + dlltool -D $(TARGET).dll -d $(TARGET).def -l $(TARGET).lib + gcc -mdll -o $(TARGET).dll $(OBJECTS) -Wl,$(TARGET).exp $(LIB_PATHS) $(LIBS) + rm -rf $(TARGET).exp + + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).lib + rm -rf $(TARGET).def diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/msn/msn.c --- a/src/protocols/msn/msn.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/msn/msn.c Fri Oct 11 03:14:01 2002 +0000 @@ -1,16 +1,27 @@ #include "config.h" +#ifndef _WIN32 +#include +#else +#include +#include +#endif + + #include #include #include #include -#include #include #include "gaim.h" #include "prpl.h" #include "proxy.h" #include "md5.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #include "pixmaps/protocols/msn/msn_online.xpm" #include "pixmaps/protocols/msn/msn_away.xpm" #include "pixmaps/protocols/msn/msn_occ.xpm" @@ -64,6 +75,9 @@ #include "pixmaps/protocols/msn/msn_devil.xpm" #include "pixmaps/protocols/msn/msn_wink.xpm" +/* for win32 compatability */ +G_MODULE_IMPORT GSList *connections; + #define MSN_BUF_LEN 8192 #define MIME_HEADER "MIME-Version: 1.0\r\n" \ "Content-Type: text/plain; charset=UTF-8\r\n" \ @@ -168,7 +182,11 @@ static int msn_write(int fd, void *data, int len) { debug_printf("MSN C: %s", data); +#ifndef _WIN32 return write(fd, data, len); +#else + return send(fd, data, len, 0); +#endif } static char *url_decode(const char *msg) @@ -444,7 +462,11 @@ if (ms->inpa) gaim_input_remove(ms->inpa); +#ifndef _WIN32 close(ms->fd); +#else + closesocket(ms->fd); +#endif g_free(ms->rxqueue); if (ms->msg) g_free(ms->msguser); @@ -695,9 +717,11 @@ /* This is really stupid and I hate to put this here. */ if (ms->fd != source) ms->fd = source; - +#ifndef _WIN32 len = read(ms->fd, buf, sizeof(buf)); - +#else + len = recv(ms->fd, buf, sizeof(buf), 0); +#endif if (len <= 0) { msn_kill_switch(ms); return; @@ -773,7 +797,11 @@ char buf[MSN_BUF_LEN]; if (source == -1 || !g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif g_free(ms->sessid); g_free(ms->auth); g_free(ms); @@ -787,7 +815,11 @@ g_snprintf(buf, sizeof(buf), "ANS %d %s %s %s\r\n", ++ms->trId, gc->username, ms->auth, ms->sessid); if (msn_write(ms->fd, buf, strlen(buf)) < 0) { +#ifndef _WIN32 close(ms->fd); +#else + closesocket(ms->fd); +#endif g_free(ms->sessid); g_free(ms->auth); g_free(ms); @@ -805,7 +837,11 @@ char buf[MSN_BUF_LEN]; if (source == -1 || !g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif if (g_slist_find(connections, gc)) { msn_kill_switch(ms); do_error_dialog(_("Gaim was unable to send an MSN message"), @@ -1251,7 +1287,7 @@ GET_NEXT(tmp); passport = tmp; - snprintf(hippy, sizeof(hippy), "%s%lu%s", md->mspauth, time(NULL) - md->sl, gc->password); + g_snprintf(hippy, sizeof(hippy), "%s%lu%s", md->mspauth, time(NULL) - md->sl, gc->password); md5_init(&st); md5_append(&st, (const md5_byte_t *)hippy, strlen(hippy)); @@ -1268,32 +1304,35 @@ g_free(md->passport); } - fd = gaim_mkstemp(&(md->passport)); - fprintf(fd, "\n"); - fprintf(fd, "\n"); - fprintf(fd, "\n"); - fprintf(fd, "\n\n"); + if( (fd = gaim_mkstemp(&(md->passport))) == NULL ) { + debug_printf("Error opening temp file\n"); + } + else { + fprintf(fd, "\n"); + fprintf(fd, "\n"); + fprintf(fd, "\n"); + fprintf(fd, "\n\n"); - fprintf(fd, "\n"); - fprintf(fd, "
\n\n", passport); - fprintf(fd, "\n"); - fprintf(fd, "\n", gc->username); - fprintf(fd, "\n", gc->username); - fprintf(fd, "\n", md->sid); - fprintf(fd, "\n", md->kv); - fprintf(fd, "\n"); - fprintf(fd, "\n", time(NULL) - md->sl); - fprintf(fd, "\n", rru); - fprintf(fd, "\n", md->mspauth); - fprintf(fd, "\n", sendbuf); // Digest me - fprintf(fd, "\n"); - fprintf(fd, "\n"); - fprintf(fd, "
\n"); - fprintf(fd, "\n"); - fclose(fd); - + fprintf(fd, "\n"); + fprintf(fd, "
\n\n", passport); + fprintf(fd, "\n"); + fprintf(fd, "\n", gc->username); + fprintf(fd, "\n", gc->username); + fprintf(fd, "\n", md->sid); + fprintf(fd, "\n", md->kv); + fprintf(fd, "\n"); + fprintf(fd, "\n", time(NULL) - md->sl); + fprintf(fd, "\n", rru); + fprintf(fd, "\n", md->mspauth); + fprintf(fd, "\n", sendbuf); // Digest me + fprintf(fd, "\n"); + fprintf(fd, "\n"); + fprintf(fd, "
\n"); + fprintf(fd, "\n"); + fclose(fd); + } } else if (!g_strncasecmp(buf, "SYN", 3)) { } else if (!g_strncasecmp(buf, "USR", 3)) { } else if (!g_strncasecmp(buf, "XFR", 3)) { @@ -1341,7 +1380,11 @@ } ms->auth = g_strdup(tmp); } else { +#ifndef _WIN32 close(md->fd); +#else + closesocket(md->fd); +#endif gaim_input_remove(md->inpa); md->inpa = 0; md->fd = proxy_connect(host, port, msn_login_xfr_connect, gc); @@ -1431,8 +1474,11 @@ int cont = 1; int len; +#ifndef _WIN32 len = read(md->fd, buf, sizeof(buf)); - +#else + len = recv(md->fd, buf, sizeof(buf), 0); +#endif if (len <= 0) { hide_login_progress_error(gc, _("Error reading from server")); signoff(gc); @@ -1508,7 +1554,11 @@ char buf[MSN_BUF_LEN]; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -1644,7 +1694,11 @@ } else port = 1863; +#ifndef _WIN32 close(md->fd); +#else + closesocket(md->fd); +#endif gaim_input_remove(md->inpa); md->inpa = 0; md->fd = 0; @@ -1675,8 +1729,11 @@ int cont = 1; int len; +#ifndef _WIN32 len = read(md->fd, buf, sizeof(buf)); - +#else + len = recv(md->fd, buf, sizeof(buf), 0); +#endif if (len <= 0) { hide_login_progress(gc, _("Error reading from server")); signoff(gc); @@ -1730,7 +1787,11 @@ char buf[1024]; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -1777,7 +1838,11 @@ static void msn_close(struct gaim_connection *gc) { struct msn_data *md = gc->proto_data; +#ifndef _WIN32 close(md->fd); +#else + closesocket(md->fd); +#endif if (md->inpa) gaim_input_remove(md->inpa); g_free(md->rxqueue); @@ -2504,7 +2569,7 @@ static struct prpl *my_protocol = NULL; -void msn_init(struct prpl *ret) +G_MODULE_EXPORT void msn_init(struct prpl *ret) { struct proto_user_opt *puo; ret->protocol = PROTO_MSN; @@ -2554,25 +2619,25 @@ #ifndef STATIC -void *gaim_prpl_init(struct prpl *prpl) +G_MODULE_EXPORT void gaim_prpl_init(struct prpl *prpl) { msn_init(prpl); prpl->plug->desc.api_version = PLUGIN_API_VERSION; } -void gaim_plugin_remove() +G_MODULE_EXPORT void gaim_plugin_remove() { struct prpl *p = find_prpl(PROTO_MSN); if (p == my_protocol) unload_protocol(p); } -char *name() +G_MODULE_EXPORT char *name() { return "MSN"; } -char *description() +G_MODULE_EXPORT char *description() { return PRPL_DESC("MSN"); } diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/napster/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/napster/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,151 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of libnapster +# + +# +# PATHS +# + +INCLUDE_DIR := . +GTK_TOP := ../../../../win32-dev/gtk_2_0 +GAIM_TOP := ../../.. +NAPSTER_ROOT := . +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir + +## +## VARIABLE DEFINITIONS +## + +TARGET = libnapster + +VERSION := $(shell cat $(GAIM_TOP)/VERSION) + +# Compiler Options + +CC = gcc + +CFLAGS = -O2 -Werror -Wall -mno-cygwin -fnative-struct + +DEFINES = -DAIM_BUILDDATE=\"`date +%Y%m%d`\" \ + -DAIM_BUILDTIME=\"`date +%H%M%S`\" \ + -DVERSION=\"$(VERSION)\" \ + -DHAVE_CONFIG_H + +# Static or Plugin... +ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR) +else +ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR)/plugins +endif +endif + + +## +## INCLUDE MAKEFILES +## + + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(NAPSTER_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src + + +## +## SOURCES, OBJECTS +## + +C_SRC = napster.c + + +OBJECTS = $(C_SRC:%.c=%.o) + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 -lglib-2.0 -lgdk-win32-2.0 -lgmodule-2.0 -lgobject-2.0 -lws2_32 -lintl -lgaim + +# -liberty + + +## +## RULES +## + +# How to make a C file + +%.o: %.c + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: $(TARGET).dll + +install: + cp $(NAPSTER_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + + +## +## BUILD Dependencies +## + +$(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + +## +## BUILD DLL +## + +$(TARGET).def: $(OBJECTS) + dlltool --dllname $(TARGET).dll -z $(TARGET).def \ + $(OBJECTS) + +$(TARGET).base: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + gcc -mdll -o junk.tmp -Wl,--base-file,$@ $(OBJECTS) $(LIB_PATHS) $(LIBS) + rm -rf junk.tmp + +$(TARGET).exp: $(TARGET).def $(TARGET).base + dlltool --dllname $(TARGET).dll --base-file $(TARGET).base \ + --output-exp $(TARGET).exp --def $(TARGET).def + rm -rf $(TARGET).base + +$(TARGET).dll: $(OBJECTS) $(TARGET).exp $(GAIM_TOP)/src/gaim.lib + dlltool -D $(TARGET).dll -d $(TARGET).def -l $(TARGET).lib + gcc -mdll -o $(TARGET).dll $(OBJECTS) -Wl,$(TARGET).exp $(LIB_PATHS) $(LIBS) + rm -rf $(TARGET).exp + + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).lib + rm -rf $(TARGET).def diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/napster/napster.c --- a/src/protocols/napster/napster.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/napster/napster.c Fri Oct 11 03:14:01 2002 +0000 @@ -21,24 +21,37 @@ #include +#ifndef _WIN32 #include #include -#include #include #include +#include +#else +#include +#endif + +#include #include #include #include #include #include -#include #include #include "multi.h" #include "prpl.h" #include "gaim.h" #include "proxy.h" + +#ifdef _WIN32 +#include "win32dep.h" +#endif + #include "pixmaps/protocols/napster/napster.xpm" +/* for win32 compatability */ +G_MODULE_IMPORT GSList *connections; + #define NAP_BUF_LEN 4096 #define USEROPT_NAPSERVER 3 @@ -71,9 +84,15 @@ size = strlen(message); +#ifndef _WIN32 write(ndata->fd, &size, 2); write(ndata->fd, &command, 2); write(ndata->fd, message, size); +#else + send(ndata->fd, (char*)&size, 2, 0); + send(ndata->fd, (char*)&command, 2, 0); + send(ndata->fd, message, size, 0); +#endif } static int nap_send_im(struct gaim_connection *gc, char *who, char *message, int len, int flags) @@ -156,7 +175,13 @@ gchar **res; int i; - if (recv(source, header, 4, 0) != 4) { + if (recv(source, +#ifndef _WIN32 + header, +#else + (char*)header, +#endif + 4, 0) != 4) { hide_login_progress(gc, "Unable to read"); signoff(gc); return; @@ -358,12 +383,19 @@ unsigned short header[2]; int len; int command; - +#ifndef _WIN32 read(source, header, 4); +#else + recv(source, (char*)header, 4, 0); +#endif len = header[0]; command = header[1]; +#ifndef _WIN32 read(source, buf, len); +#else + recv(source, buf, len, 0); +#endif buf[len] = 0; /* If we have some kind of error, get outta here */ @@ -372,7 +404,11 @@ do_error_dialog(buf, NULL, GAIM_ERROR); gaim_input_remove(ndata->inpa); ndata->inpa = 0; +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif signoff(gc); return; } @@ -405,7 +441,11 @@ char buf[NAP_BUF_LEN]; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -551,7 +591,7 @@ static struct prpl *my_protocol = NULL; -void napster_init(struct prpl *ret) +G_MODULE_EXPORT void napster_init(struct prpl *ret) { struct proto_user_opt *puo; ret->add_buddies = nap_add_buddies; @@ -615,7 +655,7 @@ #ifndef STATIC -void *gaim_prpl_init(struct prpl *prpl) +G_MODULE_EXPORT void gaim_prpl_init(struct prpl *prpl) { napster_init(prpl); prpl->plug->desc.api_version = PLUGIN_API_VERSION; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/oscar/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/oscar/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,175 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of liboscar +# + +# +# PATHS +# + +OSCAR_ROOT := . +GTK_TOP := ../../../../win32-dev/gtk_2_0 +GAIM_TOP := ../../.. +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir + +## +## VARIABLE DEFINITIONS +## + +TARGET = liboscar + +VERSION := $(shell cat $(GAIM_TOP)/VERSION) + +# Compiler Options + +CC = gcc.exe $(GCOPTS) + +# Only use -g flag when building STATIC version +CFLAGS = -O2 -Wall -Werror + +DEFINES = -DHAVE_CONFIG_H \ + -DVERSION=\"$(VERSION)\" \ + -DAIM_BUILDDATE=\"`date +%Y%m%d`\" \ + -DAIM_BUILDTIME=\"`date +%H%M%S`\" + +# Static or Plugin... +ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR) +else + ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR)/plugins + endif +endif + + +## +## INCLUDE MAKEFILES +## + + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(OSCAR_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src + + +## +## SOURCES, OBJECTS +## + +C_SRC = admin.c \ + adverts.c \ + auth.c \ + bos.c \ + buddylist.c \ + chat.c \ + chatnav.c \ + conn.c \ + ft.c \ + icq.c \ + im.c \ + info.c \ + invite.c \ + meta.c \ + misc.c \ + msgcookie.c \ + popups.c \ + rxhandlers.c \ + rxqueue.c \ + search.c \ + service.c \ + snac.c \ + ssi.c \ + stats.c \ + tlv.c \ + translate.c \ + txqueue.c \ + util.c \ + oscar.c + + +OBJECTS = $(C_SRC:%.c=%.o) + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 -lglib-2.0 -lgdk-win32-2.0 -lgmodule-2.0 -lgobject-2.0 -lintl -lws2_32 -liberty -lgaim + + +## +## RULES +## + +# How to make a C file + +%.o: %.c + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: $(TARGET).dll + +install: + cp $(OSCAR_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + + +## +## BUILD Dependencies +## + +$(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + +## +## BUILD DLL +## + +$(TARGET).def: $(OBJECTS) + dlltool --dllname $(TARGET).dll -z $(TARGET).def --export-all-symbols $(OBJECTS) + +$(TARGET).base: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + gcc -mdll -o junk.tmp -Wl,--base-file,$@ $(OBJECTS) $(LIB_PATHS) $(LIBS) + rm -rf junk.tmp + +$(TARGET).exp: $(TARGET).def $(TARGET).base + dlltool --dllname $(TARGET).dll --base-file $(TARGET).base \ + --output-exp $(TARGET).exp --def $(TARGET).def + rm -rf $(TARGET).base + +$(TARGET).dll: $(OBJECTS) $(TARGET).exp $(GAIM_TOP)/src/gaim.lib + dlltool -D $(TARGET).dll -d $(TARGET).def -l $(TARGET).lib + gcc -mdll -o $(TARGET).dll $(OBJECTS) -Wl,$(TARGET).exp $(LIB_PATHS) $(LIBS) + rm -rf $(TARGET).exp + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).lib + rm -rf $(TARGET).def diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/oscar/aim.h --- a/src/protocols/oscar/aim.h Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/oscar/aim.h Fri Oct 11 03:14:01 2002 +0000 @@ -25,14 +25,13 @@ #include #include -#ifdef _WIN32 -#include -#include -#else +#ifndef _WIN32 #include #include #include #include +#else +#include #endif /* XXX adjust these based on autoconf-detected platform */ @@ -42,14 +41,6 @@ typedef fu32_t aim_snacid_t; typedef fu16_t flap_seqnum_t; -/* Portability stuff (DMP) */ - -#ifdef _WIN32 -#define sleep(x) Sleep((x)*1000) -#define snprintf _snprintf /* I'm not sure whats wrong with Microsoft here */ -#define close(x) closesocket(x) /* no comment */ -#endif - #if defined(mach) && defined(__APPLE__) #define gethostbyname(x) gethostbyname2(x, AF_INET) #endif @@ -707,6 +698,7 @@ int state; struct aim_fileheader_t fh; }; +#define OFT_TIMEOUT (60) struct aim_chat_roominfo { unsigned short exchange; @@ -866,6 +858,12 @@ fu32_t bgcolor; const char *rtfmsg; } rtfmsg; + struct { + fu16_t multiple; + fu16_t totfiles; + fu32_t totsize; + char *filename; + } sendfile; } info; void *destructor; /* used internally only */ }; @@ -893,15 +891,18 @@ faim_export aim_conn_t *aim_directim_connect(aim_session_t *, const char *sn, const char *addr, const fu8_t *cookie); faim_export int aim_send_im_ch2_geticqmessage(aim_session_t *sess, const char *sn, int type); -faim_export aim_conn_t *aim_sendfile_initiate(aim_session_t *, const char *destsn, const char *filename, fu16_t numfiles, fu32_t totsize); +faim_export aim_conn_t *aim_sendfile_initiate(aim_session_t *, const char *destsn, const char *filename, fu16_t numfiles, fu32_t totsize, char *cookret); faim_export int aim_send_im_ch4(aim_session_t *sess, char *sn, fu16_t type, fu8_t *message); faim_export int aim_mtn_send(aim_session_t *sess, fu16_t type1, char *sn, fu16_t type2); faim_export aim_conn_t *aim_getfile_initiate(aim_session_t *sess, aim_conn_t *conn, const char *destsn); faim_export int aim_oft_getfile_request(aim_session_t *sess, aim_conn_t *conn, const char *name, int size); +faim_export int aim_oft_sendfile_request(aim_session_t *sess, aim_conn_t *conn, + const char *name, int filesdone, int numfiles, int size, + int totsize); faim_export int aim_oft_getfile_ack(aim_session_t *sess, aim_conn_t *conn); -faim_export int aim_oft_getfile_end(aim_session_t *sess, aim_conn_t *conn); +faim_export int aim_oft_end(aim_session_t *sess, aim_conn_t *conn); /* aim_info.c */ #define AIM_CAPS_BUDDYICON 0x00000001 @@ -964,7 +965,11 @@ #define AIM_TRANSFER_DENY_DECLINE 0x0001 #define AIM_TRANSFER_DENY_NOTACCEPTING 0x0002 faim_export int aim_denytransfer(aim_session_t *sess, const char *sender, const char *cookie, unsigned short code); -faim_export aim_conn_t *aim_accepttransfer(aim_session_t *sess, aim_conn_t *conn, const char *sn, const fu8_t *cookie, const fu8_t *ip, fu16_t listingfiles, fu16_t listingtotsize, fu16_t listingsize, fu32_t listingchecksum, fu16_t rendid); +faim_export aim_conn_t *aim_accepttransfer(aim_session_t *sess, aim_conn_t *conn, const char *sn, const fu8_t *cookie, const fu8_t *ip, fu16_t port, fu16_t rendid, ...); +faim_export int aim_canceltransfer(aim_session_t *sess, aim_conn_t *conn, + const char *cookie, const char *sn, int rendid); +faim_export fu32_t aim_update_checksum(aim_session_t *sess, aim_conn_t *conn, + const unsigned char *buffer, int bufferlen); faim_export int aim_getinfo(aim_session_t *, aim_conn_t *, const char *, unsigned short); faim_export int aim_sendbuddyoncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info); diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/oscar/aim_internal.h --- a/src/protocols/oscar/aim_internal.h Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/oscar/aim_internal.h Fri Oct 11 03:14:01 2002 +0000 @@ -91,7 +91,7 @@ faim_internal int aim_tx_sendframe(aim_session_t *sess, aim_frame_t *cur); faim_internal flap_seqnum_t aim_get_next_txseqnum(aim_conn_t *); -faim_internal aim_frame_t *aim_tx_new(aim_session_t *sess, aim_conn_t *conn, fu8_t framing, fu8_t chan, int datalen); +faim_internal aim_frame_t *aim_tx_new(aim_session_t *sess, aim_conn_t *conn, fu8_t framing, fu16_t chan, int datalen); faim_internal void aim_frame_destroy(aim_frame_t *); faim_internal int aim_tx_enqueue(aim_session_t *, aim_frame_t *); faim_internal int aim_tx_printqueue(aim_session_t *); diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/oscar/conn.c --- a/src/protocols/oscar/conn.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/oscar/conn.c Fri Oct 11 03:14:01 2002 +0000 @@ -14,6 +14,8 @@ #include #include #include +#else +#include #endif /* @@ -317,7 +319,11 @@ { if (deadconn->fd >= 3) +#ifndef _WIN32 close(deadconn->fd); +#else + closesocket(deadconn->fd); +#endif deadconn->fd = -1; if (deadconn->handlerlist) aim_clearhandlers(deadconn); @@ -429,7 +435,11 @@ fd = socket(hp->h_addrtype, SOCK_STREAM, 0); if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { faimdprintf(sess, 0, "proxyconnect: unable to connect to proxy\n"); +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif return -1; } @@ -445,22 +455,40 @@ buf[2] = 0x00; i = 3; } - +#ifndef _WIN32 if (write(fd, buf, i) < i) { +#else + if (send(fd, buf, i, 0) < i) { +#endif *statusret = errno; +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif return -1; } - +#ifndef _WIN32 if (read(fd, buf, 2) < 2) { +#else + if (recv(fd, buf, 2, 0) < 2) { +#endif *statusret = errno; +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif return -1; } if ((buf[0] != 0x05) || (buf[1] == 0xff)) { *statusret = EINVAL; +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif return -1; } @@ -471,19 +499,39 @@ i += aimutil_putstr(buf+i, sess->socksproxy.username, strlen(sess->socksproxy.username)); i += aimutil_put8(buf+i, strlen(sess->socksproxy.password)); i += aimutil_putstr(buf+i, sess->socksproxy.password, strlen(sess->socksproxy.password)); +#ifndef _WIN32 if (write(fd, buf, i) < i) { +#else + if (send(fd, buf, i, 0) < i) { +#endif *statusret = errno; +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif return -1; } +#ifndef _WIN32 if (read(fd, buf, 2) < 2) { +#else + if (recv(fd, buf, 2, 0) < 2) { +#endif *statusret = errno; +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif return -1; } if ((buf[0] != 0x01) || (buf[1] != 0x00)) { *statusret = EINVAL; +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif return -1; } } @@ -495,27 +543,49 @@ i += aimutil_put8(buf+i, strlen(host)); i += aimutil_putstr(buf+i, host, strlen(host)); i += aimutil_put16(buf+i, port); - +#ifndef _WIN32 if (write(fd, buf, i) < i) { +#else + if (send(fd, buf, i, 0) < i) { +#endif *statusret = errno; +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif return -1; } +#ifndef _WIN32 if (read(fd, buf, 10) < 10) { +#else + if (recv(fd, buf, 10, 0) < 10) { +#endif *statusret = errno; +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif return -1; } if ((buf[0] != 0x05) || (buf[1] != 0x00)) { *statusret = EINVAL; +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif return -1; } } else { /* connecting directly */ struct sockaddr_in sa; struct hostent *hp; - +#ifdef _WIN32 + int imode = 1; + int w_errno = 0; +#endif if (!(hp = gethostbyname(host))) { *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR); return -1; @@ -529,17 +599,29 @@ fd = socket(hp->h_addrtype, SOCK_STREAM, 0); if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT) +#ifndef _WIN32 fcntl(fd, F_SETFL, O_NONBLOCK); /* XXX save flags */ - +#else + ioctlsocket(fd, FIONBIO, (unsigned long *)&imode); +#endif if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT) { +#ifndef _WIN32 if ((errno == EINPROGRESS) || (errno == EINTR)) { +#else + w_errno = WSAGetLastError(); + if ((w_errno == WSAEINPROGRESS) || (w_errno == WSAEINTR)) { +#endif if (statusret) *statusret |= AIM_CONN_STATUS_INPROGRESS; return fd; } } +#ifndef _WIN32 close(fd); +#else + closesocket(fd); +#endif fd = -1; } } @@ -987,7 +1069,12 @@ { fd_set fds, wfds; struct timeval tv; - int res, error = ETIMEDOUT; + int res; +#ifndef _WIN32 + int error = ETIMEDOUT; +#else + int error = 0; +#endif aim_rxcallback_t userfunc; if (!conn || (conn->fd == -1)) @@ -1004,7 +1091,11 @@ tv.tv_usec = 0; if ((res = select(conn->fd+1, &fds, &wfds, NULL, &tv)) == -1) { +#ifndef _WIN32 error = errno; +#else + error = WSAGetLastError(); +#endif aim_conn_close(conn); errno = error; return -1; @@ -1015,9 +1106,13 @@ if (FD_ISSET(conn->fd, &fds) || FD_ISSET(conn->fd, &wfds)) { int len = sizeof(error); - +#ifndef _WIN32 if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) error = errno; +#else + if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) < 0) + error = WSAGetLastError(); +#endif } if (error) { @@ -1025,9 +1120,9 @@ errno = error; return -1; } - +#ifndef _WIN32 fcntl(conn->fd, F_SETFL, 0); /* XXX should restore original flags */ - +#endif conn->status &= ~AIM_CONN_STATUS_INPROGRESS; if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE))) diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/oscar/ft.c --- a/src/protocols/oscar/ft.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/oscar/ft.c Fri Oct 11 03:14:01 2002 +0000 @@ -16,10 +16,12 @@ #include #include #include /* for aim_directim_initiate */ +#include /* for inet_ntoa */ +#else +#include "win32dep.h" +#endif -#include /* for inet_ntoa */ - -#endif +#include "gaim.h" /* TODO: o look for memory leaks.. there's going to be shitloads, i'm sure. @@ -32,6 +34,7 @@ }; static int listenestablish(fu16_t portnum); +static struct aim_fileheader_t *aim_oft_getfh(unsigned char *hdr); /** * aim_handlerendconnect - call this to accept OFT connections and set up the required structures @@ -56,13 +59,21 @@ return 0; /* not an error */ if (cliaddr.sa_family != AF_INET) { /* just in case IPv6 really is happening */ +#ifndef _WIN32 close(acceptfd); +#else + closesocket(acceptfd); +#endif aim_conn_close(cur); return -1; } if (!(newconn = aim_cloneconn(sess, cur))) { +#ifndef _WIN32 close(acceptfd); +#else + closesocket(acceptfd); +#endif aim_conn_close(cur); return -1; } @@ -85,11 +96,9 @@ ret = userfunc(sess, NULL, newconn, cur); } else if (newconn->subtype == AIM_CONN_SUBTYPE_OFT_GETFILE) { -#if 0 struct aim_filetransfer_priv *priv; aim_rxcallback_t userfunc; - newconn->priv = cur->priv; cur->priv = NULL; priv = (struct aim_filetransfer_priv *)newconn->priv; @@ -98,7 +107,19 @@ if ((userfunc = aim_callhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEINITIATE))) ret = userfunc(sess, NULL, newconn, cur); -#endif + } else if (newconn->subtype == AIM_CONN_SUBTYPE_OFT_SENDFILE) { + struct aim_filetransfer_priv *ft; + aim_rxcallback_t userfunc; + + /* The new conn automatically inherits the priv value + * of cur. */ + cur->priv = NULL; + ft = (struct aim_filetransfer_priv *)newconn->priv; + + snprintf(ft->ip, sizeof(ft->ip), "%s:%u", inet_ntoa(((struct sockaddr_in *)&cliaddr)->sin_addr), ntohs(((struct sockaddr_in *)&cliaddr)->sin_port)); + + if ((userfunc = aim_callhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEINITIATE))) + ret = userfunc(sess, NULL, newconn, cur); } else { faimdprintf(sess, 1,"Got a Connection on a listener that's not Rendezvous Closing conn.\n"); aim_conn_close(newconn); @@ -318,7 +339,11 @@ /* XXX switch to aim_cloneconn()? */ if (!(newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS_OUT, NULL))) { +#ifndef _WIN32 close(listenfd); +#else + closesocket(listenfd); +#endif return NULL; } @@ -346,12 +371,17 @@ * @filename: the name of the files you want to send * */ -faim_export aim_conn_t *aim_sendfile_initiate(aim_session_t *sess, const char *destsn, const char *filename, fu16_t numfiles, fu32_t totsize) +faim_export aim_conn_t *aim_sendfile_initiate(aim_session_t *sess, const char *destsn, const char *filename, fu16_t numfiles, fu32_t totsize, char *cookret) { aim_conn_t *newconn; aim_msgcookie_t *cookie; - struct aim_directim_intdata *priv; + struct aim_filetransfer_priv *ft; int listenfd; + + /* Due to other limitations, we can only initiate one + * sendfile transfer at a time, so it seems safe to + * restrict the listener to a single port. -- wtm + */ fu16_t port = 4443; fu8_t localip[4]; fu8_t ck[8]; @@ -362,35 +392,45 @@ if ((listenfd = listenestablish(port)) == -1) return NULL; - aim_request_sendfile(sess, destsn, filename, numfiles, totsize, localip, port, ck); + { + /* XXX */ + char *basename = g_path_get_basename(filename); + aim_request_sendfile(sess, destsn, basename, + numfiles, totsize, localip, port, ck); + g_free(basename); + } cookie = (aim_msgcookie_t *)calloc(1, sizeof(aim_msgcookie_t)); memcpy(cookie->cookie, ck, 8); - cookie->type = AIM_COOKIETYPE_OFTIM; + cookie->type = AIM_COOKIETYPE_OFTSEND; + memcpy(cookret, ck, 8); /* this one is for the cookie */ - priv = (struct aim_directim_intdata *)calloc(1, sizeof(struct aim_directim_intdata)); + ft = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)); - memcpy(priv->cookie, ck, 8); - strncpy(priv->sn, destsn, sizeof(priv->sn)); - cookie->data = priv; + memcpy(ft->cookie, ck, 8); + strncpy(ft->sn, destsn, sizeof(ft->sn)); + cookie->data = ft; aim_cachecookie(sess, cookie); - /* XXX switch to aim_cloneconn()? */ if (!(newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS_OUT, NULL))) { +#ifndef _WIN32 close(listenfd); +#else + closesocket(listenfd); +#endif return NULL; } /* this one is for the conn */ - priv = (struct aim_directim_intdata *)calloc(1, sizeof(struct aim_directim_intdata)); + ft = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)); - memcpy(priv->cookie, ck, 8); - strncpy(priv->sn, destsn, sizeof(priv->sn)); + memcpy(ft->cookie, ck, 8); + strncpy(ft->sn, destsn, sizeof(ft->sn)); newconn->fd = listenfd; newconn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE; - newconn->internal = priv; + newconn->priv = ft; newconn->lastactivity = time(NULL); faimdprintf(sess, 2,"faim: listening (fd = %d, unconnected)\n", newconn->fd); @@ -406,27 +446,23 @@ * * returns number closed, -1 on error. */ -faim_export unsigned int aim_oft_listener_clean(struct aim_session_t *sess, time_t age) +faim_export unsigned int aim_oft_listener_clean(aim_session_t *sess, + time_t age) { - struct aim_conn_t *cur; + aim_conn_t *cur; time_t now; unsigned int hit = 0; if (!sess) return -1; now = time(NULL); - faim_mutex_lock(&sess->connlistlock); for(cur = sess->connlist;cur; cur = cur->next) if (cur->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) { - faim_mutex_lock(&cur->active); if (cur->lastactivity < (now - age) ) { - faim_mutex_unlock(&cur->active); aim_conn_close(cur); hit++; - } else - faim_mutex_unlock(&cur->active); + } } - faim_mutex_unlock(&sess->connlistlock); return hit; } #endif @@ -533,11 +569,13 @@ * @sn: the screenname to send it to, * @cookie: the cookie used * @ip: the ip to connect to + * @port: the port to use + * @rendid: capability type (%AIM_CAPS_GETFILE or %AIM_CAPS_SENDFILE) + * * @listingfiles: number of files to share * @listingtotsize: total size of shared files * @listingsize: length of the listing file(buffer) * @listingchecksum: checksum of the listing - * @rendid: capability type (%AIM_CAPS_GETFILE or %AIM_CAPS_SENDFILE) * * Returns new connection or %NULL on error. * @@ -547,44 +585,80 @@ aim_conn_t *conn, const char *sn, const fu8_t *cookie, const fu8_t *ip, - fu16_t listingfiles, - fu16_t listingtotsize, - fu16_t listingsize, - fu32_t listingchecksum, - fu16_t rendid) + fu16_t port, + fu16_t rendid, + ...) { - return NULL; -#if 0 - struct command_tx_struct *newpacket, *newoft; - struct aim_conn_t *newconn; - struct aim_fileheader_t *fh; + aim_frame_t *newpacket; + aim_conn_t *newconn; struct aim_filetransfer_priv *priv; - struct aim_msgcookie_t *cachedcook; - int curbyte, i; + int i; + char addr[21]; if (!sess || !conn || !sn || !cookie || !ip) { return NULL; } - newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS, ip); + /* OSCAR CAP accept packet */ + + + if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x0002, 10+8+2+1+strlen(sn)+4+2+8+16))) { + return NULL; + } + + aim_putsnac(&newpacket->data, 0x0004, 0x0006, 0x0000, sess->snacid_next); + + for (i = 0; i < 8; i++) + aimbs_put8(&newpacket->data, cookie[i]); + + aimbs_put16(&newpacket->data, 0x0002); + aimbs_put8(&newpacket->data, strlen(sn)); + aimbs_putraw(&newpacket->data, sn, strlen(sn)); + aimbs_put16(&newpacket->data, 0x0005); + aimbs_put16(&newpacket->data, 0x001a); + aimbs_put16(&newpacket->data, AIM_RENDEZVOUS_ACCEPT); + + for (i = 0; i < 8; i++) /* yes, again... */ + aimbs_put8(&newpacket->data, cookie[i]); + + aim_putcap(&newpacket->data, rendid); + aim_tx_enqueue(sess, newpacket); + + + g_snprintf(addr, sizeof(addr), "%s:%d", ip, port); + newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS, addr); + + if (newconn->status & AIM_CONN_STATUS_CONNERR) { + return NULL; + } if (!newconn || (newconn->fd == -1)) { perror("aim_newconn"); faimdprintf(sess, 2, "could not connect to %s (fd: %i)\n", ip, newconn?newconn->fd:0); return newconn; - } else { - priv = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)); - - memcpy(priv->cookie, cookie, 8); - priv->state = 0; - strncpy(priv->sn, sn, MAXSNLEN); - strncpy(priv->ip, ip, sizeof(priv->ip)); - newconn->priv = (void *)priv; - - faimdprintf(sess, 2, "faim: connected to peer (fd = %d)\n", newconn->fd); } - if (rendid == AIM_CAPS_GETFILE) { + priv = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)); + + memcpy(priv->cookie, cookie, 8); + priv->state = 0; + strncpy(priv->sn, sn, MAXSNLEN); + strncpy(priv->ip, ip, sizeof(priv->ip)); + newconn->priv = (void *)priv; + + faimdprintf(sess, 2, "faim: connected to peer (fd = %d)\n", newconn->fd); + + if (rendid == AIM_CAPS_GETFILE) { + return NULL; /* This should never happen for now. -- wtm */ +#if 0 + struct aim_fileheader_t *fh; + aim_frame_t *newoft; + aim_msgcookie_t *cachedcook; + /* XXX take the following parameters fu16_t listingfiles, + fu16_t listingtotsize, + fu16_t listingsize, + fu32_t listingchecksum, */ + newconn->subtype = AIM_CONN_SUBTYPE_OFT_GETFILE; faimdprintf(sess, 2, "faim: getfile request accept\n"); @@ -595,7 +669,6 @@ return NULL; } - newoft->lock = 1; memcpy(newoft->hdr.oft.magic, "OFT2", 4); newoft->hdr.oft.hdr2len = 0x100 - 8; @@ -622,7 +695,7 @@ fh->nrecvd = 0x00000000; fh->recvcsum = 0x00000000; memset(fh->idstring, 0, sizeof(fh->idstring)); - memcpy(fh->idstring, "OFT_Windows ICBMFT V1.1 32", sizeof(fh->idstring)); + strncpy(fh->idstring, "OFT_Windows ICBMFT V1.1 32", sizeof(fh->idstring)); fh->flags = 0x02; fh->lnameoffset = 0x1a; fh->lsizeoffset = 0x10; @@ -633,10 +706,9 @@ fh->nencode = 0x0000; fh->nlanguage = 0x0000; memset(fh->name, 0, sizeof(fh->name)); - memcpy(fh->name, "listing.txt", sizeof(fh->name)); + strncpy(fh->name, "listing.txt", sizeof(fh->name)); if (!(newoft->hdr.oft.hdr2 = (char *)calloc(1,newoft->hdr.oft.hdr2len))) { - newoft->lock = 0; aim_frame_destroy(newoft); /* XXX: conn leak */ perror("calloc (1)"); @@ -648,10 +720,9 @@ if (!(aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, fh))) faimdprintf(sess, 1, "eek, bh fail!\n"); - newoft->lock = 0; aim_tx_enqueue(sess, newoft); - if (!(cachedcook = (struct aim_msgcookie_t *)calloc(1, sizeof(struct aim_msgcookie_t)))) { + if (!(cachedcook = (aim_msgcookie_t *)calloc(1, sizeof(aim_msgcookie_t)))) { faimdprintf(sess, 1, "faim: accepttransfer: couldn't calloc cachedcook. yeep!\n"); /* XXX: more cleanup, conn leak */ perror("calloc (2)"); @@ -662,44 +733,57 @@ memcpy(cachedcook->cookie, cookie, 8); cachedcook->type = AIM_COOKIETYPE_OFTGET; + /* XXX doesn't priv need to be copied so we don't + * double free? -- wtm + */ cachedcook->data = (void *)priv; if (aim_cachecookie(sess, cachedcook) == -1) faimdprintf(sess, 1, "faim: ERROR caching message cookie\n"); free(fh); - - /* OSCAR CAP accept packet */ - - if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+8+2+1+strlen(sn)+4+2+8+16))) { - return NULL; - } +#endif + + } else if (rendid == AIM_CAPS_SENDFILE) { + newconn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE; + priv->fh.recvcsum = 0xffff0000; } else { return NULL; } + + return newconn; +} + +/* conn is a BOS connection over which to send the cancel msg */ +faim_export int aim_canceltransfer(aim_session_t *sess, aim_conn_t *conn, + const char *cookie, const char *sn, int rendid) +{ + aim_frame_t *newpacket; + int i; + + if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x0002, 10+8+2+1+strlen(sn)+4+2+8+16))) { + return 1; + } - newpacket->lock = 1; - curbyte = aim_putsnac(newpacket->data, 0x0004, 0x0006, 0x0000, sess->snac_nextid); + aim_putsnac(&newpacket->data, 0x0004, 0x0006, 0x0000, sess->snacid_next); for (i = 0; i < 8; i++) - curbyte += aimutil_put8(newpacket->data+curbyte, cookie[i]); + aimbs_put8(&newpacket->data, cookie[i]); - curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); - curbyte += aimutil_put8(newpacket->data+curbyte, strlen(sn)); - curbyte += aimutil_putstr(newpacket->data+curbyte, sn, strlen(sn)); - curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); - curbyte += aimutil_put16(newpacket->data+curbyte, 0x001a); - curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002 /* accept*/); + aimbs_put16(&newpacket->data, 0x0002); + aimbs_put8(&newpacket->data, strlen(sn)); + aimbs_putraw(&newpacket->data, sn, strlen(sn)); + aimbs_put16(&newpacket->data, 0x0005); + aimbs_put16(&newpacket->data, 0x001a); + aimbs_put16(&newpacket->data, AIM_RENDEZVOUS_CANCEL); - for (i = 0;i < 8; i++) - curbyte += aimutil_put8(newpacket->data+curbyte, cookie[i]); - - curbyte += aim_putcap(newpacket->data+curbyte, 0x10, rendid); - newpacket->lock = 0; + for (i = 0; i < 8; i++) + aimbs_put8(&newpacket->data, cookie[i]); + + aim_putcap(&newpacket->data, rendid); aim_tx_enqueue(sess, newpacket); - return newconn; -#endif + return 0; } /** @@ -814,7 +898,7 @@ fh->nlanguage = 0x0000; /* memset(fh->name, 0, sizeof(fh->name)); */ - memcpy(fh->name, "listing.txt", sizeof(fh->name)); + strncpy(fh->name, "listing.txt", sizeof(fh->name)); memset(fh->name+strlen(fh->name), 0, 64-strlen(fh->name)); faimdprintf(sess, 2, "faim: OFT: listing fh name %s / %s\n", fh->name, (fh->name+(strlen(fh->name)))); @@ -858,7 +942,11 @@ if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0) break; /* success */ +#ifndef _WIN32 close(listenfd); +#else + closesocket(listenfd); +#endif } while ( (res = res->ai_next) ); if (!res) @@ -869,6 +957,8 @@ return -1; } + fcntl(listenfd, F_SETFL, O_NONBLOCK); + freeaddrinfo(ressave); return listenfd; #else @@ -883,7 +973,11 @@ if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) != 0) { perror("setsockopt(listenfd)"); +#ifndef _WIN32 close(listenfd); +#else + closesocket(listenfd); +#endif return -1; } @@ -893,14 +987,23 @@ if (bind(listenfd, (struct sockaddr *)&sockin, sizeof(struct sockaddr_in)) != 0) { perror("bind(listenfd)"); +#ifndef _WIN32 close(listenfd); +#else + closesocket(listenfd); +#endif return -1; } if (listen(listenfd, 4) != 0) { perror("listen(listenfd)"); +#ifndef _WIN32 close(listenfd); +#else + closesocket(listenfd); +#endif return -1; } + fcntl(listenfd, F_SETFL, O_NONBLOCK); return listenfd; #endif } @@ -916,7 +1019,7 @@ /* waiting on listing data */ int ret = 0; char *listing; - struct command_tx_struct *newoft; + aim_frame_t *newoft; if (!(listing = malloc(ft->fh.size))) return -1; @@ -927,7 +1030,6 @@ if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x120b, 0))) { faimdprintf(sess, 2, "faim: aim_get_command_rendezvous: getfile listing: tx_new OFT failed\n"); - faim_mutex_unlock(&conn->active); free(listing); aim_conn_close(conn); return -1; @@ -963,7 +1065,8 @@ if (ft->state == 3) { /* waiting on file data */ if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILERECEIVE)) ) - return userfunc(sess, NULL, conn, ft); + return userfunc(sess, NULL, conn, ft->fh.name, + ft->fh.size); return 0; } @@ -993,8 +1096,11 @@ static void connkill_sendfile(aim_session_t *sess, aim_conn_t *conn) { - - free(conn->internal); + /* XXX we don't free conn->priv here because it is currently + * freed in the caller. If that ever changes, we should + * free it here. -- wtm + */ + conn->priv = NULL; return; } @@ -1143,7 +1249,7 @@ struct aim_filetransfer_priv *ft; struct aim_fileheader_t *fh; struct aim_msgcookie_t *cook; - struct command_tx_struct *newoft; + aim_frame_t *newoft; aim_rxcallback_t userfunc; faimdprintf(sess, 2,"faim: rend: fileget 0x1108\n"); @@ -1259,9 +1365,9 @@ { #if 0 struct aim_filetransfer_priv *ft; - struct aim_msgcookie_t *cook; + aim_msgcookie_t *cook; struct aim_fileheader_t *fh; - struct command_tx_struct *newoft; + aim_frame_t *newoft; int i = 0; aim_rxcallback_t userfunc; @@ -1291,7 +1397,6 @@ return -1; } - newoft->lock = 1; memcpy(newoft->hdr.oft.magic, "OFT2", 4); newoft->hdr.oft.hdr2len = 0x100 - 8; @@ -1307,7 +1412,6 @@ aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, &(ft->fh)); - newoft->lock = 0; aim_tx_enqueue(sess, newoft); faimdprintf(sess, 2, "faim: OFT: OFT file header enqueued.\n"); @@ -1374,14 +1478,141 @@ #endif } +static int handlehdr_sendfile_sending(aim_session_t *sess, aim_conn_t *conn, fu8_t *hdr) +{ + struct aim_filetransfer_priv *ft; + struct aim_fileheader_t *fh; + aim_frame_t *newoft; + aim_rxcallback_t userfunc; + + fh = aim_oft_getfh(hdr); + + /* We receive a null cookie for the first file; we must fill + * it in to authenticate ourselves. -- wtm + */ + ft = conn->priv; + memcpy(&(fh->bcookie), ft->cookie, 8); + + memcpy(&(ft->fh), fh, sizeof(struct aim_fileheader_t)); + free(fh); + + if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0202, 0))) { + faimdprintf(sess, 2, "faim: send_final_transfer: tx_new OFT failed\n"); + return -1; + } + + memcpy(newoft->hdr.oft.magic, "OFT2", 4); + + newoft->hdr.oft.hdr2len = 0x100 - 8; + + if (!(newoft->hdr.oft.hdr2 = calloc(1,newoft->hdr.oft.hdr2len))) { + aim_frame_destroy(newoft); + return -1; + } + + if (!aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, + &(ft->fh))) { + return -1; + } + + aim_tx_enqueue(sess, newoft); + + faimdprintf(sess, 2, "faim: OFT: OFT 0x0202 enqueued.\n"); + + if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILEREQ)) == NULL) + return 1; + + { + char *cur; + /* Convert the directory separator: it is sent + * as ^A (0x01). + */ + while ((cur = strchr(ft->fh.name, 0x01))) { + *cur = G_DIR_SEPARATOR; + } + } + return userfunc(sess, NULL, conn, ft->fh.name, ft->fh.size); +} + + +/* + * These were originally described by Josh Myer: + * http://www.geocrawler.com/archives/3/896/2000/9/0/4291064/ + * -- wtm + */ +static int handlehdr_sendfile_resume(aim_session_t *sess, aim_conn_t *conn, fu8_t *hdr) { + aim_frame_t *newoft; + aim_msgcookie_t *cook; + struct aim_fileheader_t *fh; + struct aim_filetransfer_priv *ft; + + fh = aim_oft_getfh(hdr); + if (!(cook = aim_checkcookie(sess, fh->bcookie, AIM_COOKIETYPE_OFTSEND))) { + free(fh); + return -1; + } + ft = (struct aim_filetransfer_priv *)cook->data; + + ft->fh.nrecvd = fh->nrecvd; + ft->fh.recvcsum = fh->recvcsum; + strncpy(ft->fh.name, fh->name, sizeof(ft->fh.name)); + if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0106, 0))) { + faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); + free(fh); + return -1; + } + memcpy(newoft->hdr.oft.magic, "OFT2", 4); + newoft->hdr.oft.hdr2len = 0x100 - 8; + + if (!(newoft->hdr.oft.hdr2 = (unsigned char *)calloc(1,newoft->hdr.oft.hdr2len))) { + aim_frame_destroy(newoft); + return -1; + } + + if (!(aim_oft_buildheader(newoft->hdr.oft.hdr2, &(ft->fh)))) { + aim_frame_destroy(newoft); + free(fh); + return -1; + } + + aim_tx_enqueue(sess, newoft); + free(fh); + + return 0; +} + +static int handlehdr_sendfile_recv(aim_session_t *sess, aim_conn_t *conn, fu8_t *hdr) { + struct aim_fileheader_t *fh; + aim_msgcookie_t *cook; + int ret = 1; + struct aim_filetransfer_priv *ft; + aim_rxcallback_t userfunc; + + fh = aim_oft_getfh(hdr); + if (!(cook = aim_checkcookie(sess, fh->bcookie, AIM_COOKIETYPE_OFTSEND))) { + free(fh); + return -1; + } + ft = (struct aim_filetransfer_priv *)cook->data; + + faimdprintf(sess, 2, "faim: get_rend: looks like we're ready to send data.(oft 0x0202)\n"); + + if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILESEND)) ) + ret = userfunc(sess, NULL, conn, ft->fh.nrecvd); + + free(fh); + + return ret; +} + static int handlehdr_getfile_recv(aim_session_t *sess, aim_conn_t *conn, fu8_t *hdr) { #if 0 struct aim_fileheader_t *fh; - struct aim_filetransfer_priv *ft; struct aim_msgcookie_t *cook; int ret = 1; aim_rxcallback_t userfunc; + struct aim_filetransfer_priv *ft; fh = aim_oft_getfh(hdr); @@ -1405,6 +1636,30 @@ #endif } +static int handlehdr_sendfile_finish(aim_session_t *sess, aim_conn_t *conn, fu8_t *hdr) +{ + struct aim_fileheader_t *fh; + aim_msgcookie_t *cook; + aim_rxcallback_t userfunc; + + fh = aim_oft_getfh(hdr); + + if (!(cook = aim_checkcookie(sess, fh->bcookie, AIM_COOKIETYPE_OFTSEND))) { + free(fh); + return -1; + } + + faimdprintf(sess, 2, "faim: get_rend: looks like we're done with a transfer (oft 0x0204)\n"); + + debug_printf("wtm: they sent csum %x\n", fh->recvcsum); + + if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE)) ) + userfunc(sess, NULL, conn, fh->bcookie); + + free(fh); + return 0; +} + static int handlehdr_getfile_finish(aim_session_t *sess, aim_conn_t *conn, fu8_t *hdr) { #if 0 @@ -1444,13 +1699,13 @@ memset(hdrbuf1, 0, sizeof(hdrbuf1)); - /* I guess? I didn't understand any of that mess... */ - if (conn->subtype == AIM_CONN_SUBTYPE_OFT_GETFILE) + if (conn->subtype == AIM_CONN_SUBTYPE_OFT_GETFILE) { + /* This should never happen yet. -- wtm */ return getcommand_getfile(sess, conn); + } /* XXX fix all the error cases here */ if (aim_recv(conn->fd, hdrbuf1, 6) < 6) { - faimdprintf(sess, 2, "faim: rend: read error (fd: %i)\n", conn->fd); aim_conn_close(conn); @@ -1472,6 +1727,41 @@ hdrtype = aimutil_get16(hdr); + if (conn->subtype == AIM_CONN_SUBTYPE_OFT_SENDFILE) { + switch(hdrtype) { + case 0x0101: + ret = handlehdr_sendfile_sending(sess, conn, hdr); + break; + case 0x0205: + /* This seems equivalent to 0x0202, + * but has the nrecvd and nrecvcsum + * fields filled in. We send back a + * 0x0106, and get then a 0x0207 which + * we treat just like a 0x0202. -- wtm */ + ret = handlehdr_sendfile_resume(sess, + conn, hdr); + break; + case 0x0207: /* see above */; + case 0x0202: + ret = handlehdr_sendfile_recv(sess, conn, hdr); + break; + case 0x0204: + ret = handlehdr_sendfile_finish(sess, conn, hdr); + break; + default: + debug_printf("unknown header type %x received", hdrtype); + ret = -1; + break; + } + free(hdr); + if (ret == -1) + aim_conn_close(conn); + return ret; + } + + /* Shouldn't happen for now. --wtm */ + return -1; + if (hdrtype == 0x0001) ret = handlehdr_directim(sess, conn, hdr); else if (hdrtype == 0x1108) /* getfile listing.txt incoming tx->rx */ @@ -1501,7 +1791,6 @@ return ret; } -#if 0 /** * aim_oft_getfh - extracts an &aim_fileheader_t from buffer hdr. * @hdr: buffer to extract header from @@ -1572,80 +1861,60 @@ i += 64; return fh; } -#endif /** * aim_oft_checksum - calculate oft checksum of buffer * @buffer: buffer of data to checksum * @bufsize: size of buffer - * @checksum: pointer to integer to place result in (pointer!) + * @prevcheck: previous checksum * + * Prevcheck should be 0xFFFF0000 for each new file; you can have this + * checksum chunks of files in series if you just call it repeatedly in a + * for(; ; ) loop and don't reset the checksum between each call. And you + * thought we didn't care about you and your pathetic client's meomry + * footprint ;^) * - * Note that checksum is a pointer. Checksum should be filled with - * 0xFFFF0000 for each new file; you can have this checksum chunks of - * files in series if you just call it repeatedly in a for(; ; ) loop - * and don't reset the checksum between each call. And you thought we - * didn't care about you and your pathetic client's meomry footprint - * ;^) + * Thanks to Graham Booker for providing this improved checksum + * routine, which is simpler and should be more accurate than Josh + * Meyer's original code. -- wtm * - * - * Also, it's been said that this is incorrect as currently - * written. You were warned. + * This algorithim works every time I have tried it. The other fails + * sometimes. So, AOL who thought this up? It has got to be the weirdest + * checksum I have ever seen. */ -faim_export fu32_t aim_oft_checksum(aim_session_t *sess, const char *buffer, int bufsize, fu32_t *checksum) -{ - return 0xdeadbeef; -#if 0 - fu16_t check0, check1; - int i; - - check0 = ((*checksum & 0xFF000000) >> 16); - check1 = ((*checksum & 0x00ff0000) >> 16); - for(i = 0; i < bufsize; i++) { - if (i % 2) { /* use check1 -- second byte */ - if ( (short)buffer[i] > check1 ) { /* wrapping */ - check1 += 0x100; /* this is a cheap way to wrap */ +faim_export fu32_t aim_oft_checksum(const unsigned char *buffer, int bufferlen, int prevcheck) { + fu32_t check = (prevcheck >> 16) & 0xffff, oldcheck; + int i; + unsigned short val; + + for(i=0;i oldcheck) { + check--; + } + } + check = ((check & 0x0000ffff) + (check >> 16)); + check = ((check & 0x0000ffff) + (check >> 16)); + return check << 16; +} - /* if we're wrapping, decrement the other one */ - /* XXX: check this corner case */ - if (check0 == 0) - check0 = 0x00ff; - else - check0--; - } - check1 -= buffer[i]; - } else { /* use check0 -- first byte */ - if ( (short)buffer[i] > check0 ) { /* wrapping */ - check0 += 0x100; /* this is a cheap way to wrap */ - - /* if we're wrapping, decrement the other one */ - /* XXX: check this corner case */ - if (check1 == 0) - check1 = 0x00ff; - else - check1--; - } - check0 -= buffer[i]; - } - } +faim_export fu32_t aim_update_checksum(aim_session_t *sess, aim_conn_t *conn, + const unsigned char *buffer, int len) { + struct aim_filetransfer_priv *ft = conn->priv; - if (check0 > 0xff || check1 > 0xff) { - /* they shouldn't be able to do this. error! */ - faimdprintf(sess, 2, "check0 or check1 is too high: 0x%04x, 0x%04x\n", check0, check1); - return -1; - } + ft->fh.nrecvd += len; + ft->fh.recvcsum = aim_oft_checksum(buffer, len, ft->fh.recvcsum); - /* grab just the lowest byte; this should be clean, but just in - case */ - check0 &= 0xff; - check1 &= 0xff; + return 0; +} - *checksum = ((check0 * 0x1000000) + (check1 * 0x10000)); - return *checksum; -#endif -} - -#if 0 /** * aim_oft_buildheader - fills a buffer with network-order fh data * @dest: buffer to fill -- pre-alloced @@ -1655,7 +1924,7 @@ * DOES NOT DO BOUNDS CHECKING! * */ -static int oft_buildheader(unsigned char *dest, struct aim_fileheader_t *fh) +faim_export int aim_oft_buildheader(unsigned char *dest, struct aim_fileheader_t *fh) { int i, curbyte; if (!dest || !fh) @@ -1697,7 +1966,6 @@ curbyte += 64; return curbyte; } -#endif /** * aim_getfile_intitiate - Request an OFT getfile session @@ -1861,11 +2129,10 @@ * * returns -1 on error, 0 on successful enqueuing */ +#if 0 faim_export int aim_oft_getfile_request(aim_session_t *sess, aim_conn_t *conn, const char *name, int size) { - return -EINVAL; -#if 0 - struct command_tx_struct *newoft; + aim_frame_t *newoft; struct aim_filetransfer_priv *ft; if (!sess || !conn || !conn->priv || !name) return -1; @@ -1874,9 +2141,6 @@ faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); return -1; } - - newoft->lock = 1; - memcpy(newoft->hdr.oft.magic, "OFT2", 4); newoft->hdr.oft.hdr2len = 0x100 - 8; @@ -1892,22 +2156,109 @@ memset(ft->fh.name+strlen(name), 0, 1); if (!(newoft->hdr.oft.hdr2 = (unsigned char *)calloc(1,newoft->hdr.oft.hdr2len))) { - newoft->lock = 0; aim_frame_destroy(newoft); return -1; } if (!(aim_oft_buildheader(newoft->hdr.oft.hdr2, &(ft->fh)))) { - newoft->lock = 0; aim_frame_destroy(newoft); return -1; } - newoft->lock = 0; + aim_tx_enqueue(sess, newoft); + return 0; +} +#endif + +/* Identify a file that we are about to send by transmitting the + * appropriate header. + */ +faim_export int aim_oft_sendfile_request(aim_session_t *sess, aim_conn_t *conn, const char *name, int filesdone, int numfiles, int size, int totsize) +{ + aim_frame_t *newoft; + aim_msgcookie_t *cook; + struct aim_filetransfer_priv *ft = (struct aim_filetransfer_priv *)conn->priv; + struct aim_fileheader_t *fh; + + if (!sess || !conn || !name) + return -1; + + /* Authenticate whomever connected to our listener by checking + * that the correct cookie was proivided. */ + if (!(cook = aim_checkcookie(sess, ft->cookie, + AIM_COOKIETYPE_OFTSEND))) { + return -1; + } + + if (!(fh = (struct aim_fileheader_t*)calloc(1, sizeof(struct aim_fileheader_t)))) + return -1; + + fh->encrypt = 0x0000; + fh->compress = 0x0000; + fh->totfiles = numfiles; + fh->filesleft = numfiles - filesdone; + fh->totparts = 0x0001; + fh->partsleft = 0x0001; + fh->totsize = totsize; + fh->size = size; + fh->modtime = (int)time(NULL); /* we'll go with current time for now */ + fh->checksum = 0xffffffff; /* XXX: checksum ! */ + fh->rfcsum = 0x00000000; + fh->rfsize = 0x00000000; + fh->cretime = 0x00000000; + fh->rfcsum = 0x00000000; + fh->nrecvd = 0x00000000; /* always zero initially */ + fh->recvcsum = 0x00000000; /* ditto */ + + strncpy(fh->idstring, "OFT_Windows ICBMFT V1.1 32", sizeof(fh->idstring)); + fh->flags = 0x02; + fh->lnameoffset = 0x1a; + fh->lsizeoffset = 0x10; + memset(fh->dummy, 0, sizeof(fh->dummy)); + memset(fh->macfileinfo, 0, sizeof(fh->macfileinfo)); + + /* we need to figure out these encodings for filenames */ + fh->nencode = 0x0000; + fh->nlanguage = 0x0000; + + { + /* Don't "show full pathname to buddy", just because it is + * non-portable. -- wtm + */ + char *basename = g_path_get_basename(name); + strncpy(fh->name, basename, sizeof(fh->name)); + g_free(basename); + } + + memcpy(fh->bcookie, cook->cookie, 8); + /* Update both headers to be safe. */ + memcpy(&(ft->fh), fh, sizeof(struct aim_fileheader_t)); + memcpy(&(((struct aim_filetransfer_priv *)cook->data)->fh), fh, + sizeof(struct aim_fileheader_t)); + + if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0101, 0))) { + faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); + free(fh); + return -1; + } + memcpy(newoft->hdr.oft.magic, "OFT2", 4); + newoft->hdr.oft.hdr2len = 0x100 - 8; + + if (!(newoft->hdr.oft.hdr2 = (unsigned char *)calloc(1,newoft->hdr.oft.hdr2len))) { + aim_frame_destroy(newoft); + free(fh); + return -1; + } + + if (!(aim_oft_buildheader(newoft->hdr.oft.hdr2, fh))) { + aim_frame_destroy(newoft); + free(fh); + return -1; + } aim_tx_enqueue(sess, newoft); + free(fh); return 0; -#endif } /** @@ -1960,18 +2311,16 @@ } /** - * aim_oft_getfile_end - end a getfile. + * aim_oft_end - end a getfile/sendfile. * @sess: your session * @conn: the getfile connection * * call this before you close the getfile connection if you're on the * receiving/requesting end. */ -faim_export int aim_oft_getfile_end(aim_session_t *sess, aim_conn_t *conn) +faim_export int aim_oft_end(aim_session_t *sess, aim_conn_t *conn) { - return -EINVAL; -#if 0 - struct command_tx_struct *newoft; + aim_frame_t *newoft; struct aim_filetransfer_priv *ft; if (!sess || !conn || !conn->priv) @@ -1982,33 +2331,25 @@ return -1; } - newoft->lock = 1; - memcpy(newoft->hdr.oft.magic, "OFT2", 4); newoft->hdr.oft.hdr2len = 0x100 - 8; if (!(newoft->hdr.oft.hdr2 = (char *)calloc(1,newoft->hdr.oft.hdr2len))) { - newoft->lock = 0; aim_frame_destroy(newoft); return -1; } ft = (struct aim_filetransfer_priv *)conn->priv; ft->state = 4; /* no longer wanting data */ - ft->fh.nrecvd = ft->fh.size; - ft->fh.recvcsum = ft->fh.checksum; ft->fh.flags = 0x21; if (!(aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, &(ft->fh)))) { - newoft->lock = 0; aim_frame_destroy(newoft); return -1; } - newoft->lock = 0; aim_tx_enqueue(sess, newoft); return 0; -#endif /* 0 */ } diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/oscar/im.c --- a/src/protocols/oscar/im.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/oscar/im.c Fri Oct 11 03:14:01 2002 +0000 @@ -21,6 +21,10 @@ #define FAIM_INTERNAL #include +#ifdef _WIN32 +#include "win32dep.h" +#endif + /* * Takes a msghdr (and a length) and returns a client type * code. Note that this is *only a guess* and has a low likelihood @@ -722,7 +726,7 @@ aimbs_put16(&fr->data, 2+2+4+strlen(filename)+4); /* ? */ - aimbs_put16(&fr->data, 0x0001); + aimbs_put16(&fr->data, (numfiles > 1) ? 0x0002 : 0x0001); aimbs_put16(&fr->data, numfiles); aimbs_put32(&fr->data, totsize); aimbs_putraw(&fr->data, filename, strlen(filename)); @@ -730,6 +734,11 @@ /* ? */ aimbs_put32(&fr->data, 0x00000000); +#if 0 + /* from brian's patch (?) -- wtm */ + aimbs_put32(&fr->data, 0x00030000); +#endif + aim_tx_enqueue(sess, fr); return 0; @@ -1526,6 +1535,30 @@ return; } +static void incomingim_ch2_sendfile_free(aim_session_t *sess, struct aim_incomingim_ch2_args *args) +{ + free(args->info.sendfile.filename); +} + +static void incomingim_ch2_sendfile(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata) +{ + + args->destructor = (void *)incomingim_ch2_sendfile_free; + + if (servdata) { + /* 0x0001 for one file, 0x0002 for multiple files. */ + args->info.sendfile.multiple = aimbs_get16(servdata); + args->info.sendfile.totfiles = aimbs_get16(servdata); + args->info.sendfile.totsize = aimbs_get32(servdata); + args->info.sendfile.filename = aimbs_getstr(servdata, + servdata->len - (2+2+4+4)); + + aimbs_get32(servdata); /* 0x00030000 (?) */ + } + + return; +} + typedef void (*ch2_args_destructor_t)(aim_session_t *sess, struct aim_incomingim_ch2_args *args); static int incomingim_ch2(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, fu16_t channel, aim_userinfo_t *userinfo, aim_tlvlist_t *tlvlist, fu8_t *cookie) @@ -1697,6 +1730,8 @@ incomingim_ch2_chat(sess, mod, rx, snac, userinfo, &args, sdbsptr); else if (args.reqclass & AIM_CAPS_ICQSERVERRELAY) incomingim_ch2_icqserverrelay(sess, mod, rx, snac, userinfo, &args, sdbsptr); + else if (args.reqclass & AIM_CAPS_SENDFILE) + incomingim_ch2_sendfile(sess, mod, rx, snac, userinfo, &args, sdbsptr); if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) @@ -1995,6 +2030,16 @@ sn = aimbs_getstr(bs, snlen); reason = aimbs_get16(bs); + if (channel == 2) { + /* File transfer declined. */ + if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) + ret = userfunc(sess, rx, channel, sn, reason, ck); + + free(sn); + free(ck); + return ret; + } + switch (reason) { case 0x0003: { /* ICQ status message. Maybe other stuff too, you never know with these people. */ fu8_t statusmsgtype, *msg; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/oscar/meta.c --- a/src/protocols/oscar/meta.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/oscar/meta.c Fri Oct 11 03:14:01 2002 +0000 @@ -7,6 +7,10 @@ #define FAIM_INTERNAL #include +#ifdef _WIN32 +#include "win32dep.h" +#endif + faim_export char *aim_getbuilddate(void) { return AIM_BUILDDATE; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/oscar/oscar.c Fri Oct 11 03:14:01 2002 +0000 @@ -25,25 +25,35 @@ #include #endif - +#ifndef _WIN32 #include -#include -#include #include #include +#include +#include +#else +#include +#endif + +#include #include #include #include #include #include -#include #include +#include + #include "multi.h" #include "prpl.h" #include "gaim.h" #include "aim.h" #include "proxy.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #include "pixmaps/protocols/oscar/ab.xpm" #include "pixmaps/protocols/oscar/admin_icon.xpm" #include "pixmaps/protocols/oscar/aol_icon.xpm" @@ -73,7 +83,12 @@ #define AIMHASHDATA "http://gaim.sourceforge.net/aim_data.php3" -static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_IMIMAGE; +/* For win32 compatability */ +G_MODULE_IMPORT GSList *connections; +G_MODULE_IMPORT int report_idle; + +static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | + AIM_CAPS_IMIMAGE | AIM_CAPS_SENDFILE; /* Set AIM caps, because Gaim can still do them over ICQ and * Winicq doesn't mind. */ @@ -104,6 +119,7 @@ GSList *oscar_chats; GSList *direct_ims; + GSList *file_transfers; GSList *hasicons; GHashTable *supports_tn; @@ -156,6 +172,22 @@ fu8_t cookie[8]; }; +struct oscar_file_transfer { + enum { OFT_SENDFILE_IN, OFT_SENDFILE_OUT } type; + aim_conn_t *conn; + struct file_transfer *xfer; + char *sn; + char ip[64]; + fu16_t port; + fu8_t cookie[8]; + int totsize; + int filesdone; + int totfiles; + int watcher; +}; + +static struct oscar_file_transfer *oft_listening; + struct icon_req { char *user; time_t timestamp; @@ -242,6 +274,55 @@ return c; } +/* XXX there must be a better way than this.... -- wtm */ +static struct oscar_file_transfer *find_oft_by_conn(struct gaim_connection *gc, + aim_conn_t *conn) { + GSList *g = ((struct oscar_data *)gc->proto_data)->file_transfers; + struct oscar_file_transfer *f = NULL; + + while (g) { + f = (struct oscar_file_transfer *)g->data; + if (f->conn == conn) + break; + g = g->next; + f = NULL; + } + + return f; +} + +static struct oscar_file_transfer *find_oft_by_xfer(struct gaim_connection *gc, + struct file_transfer *xfer) { + GSList *g = ((struct oscar_data *)gc->proto_data)->file_transfers; + struct oscar_file_transfer *f = NULL; + + while (g) { + f = (struct oscar_file_transfer *)g->data; + if (f->xfer == xfer) + break; + g = g->next; + f = NULL; + } + + return f; +} + +static struct oscar_file_transfer *find_oft_by_cookie(struct gaim_connection *gc, + const char *cookie) { + GSList *g = ((struct oscar_data *)gc->proto_data)->file_transfers; + struct oscar_file_transfer *f = NULL; + + while (g) { + f = (struct oscar_file_transfer *)g->data; + if (!strncmp(f->cookie, cookie, 8)) + break; + g = g->next; + f = NULL; + } + + return f; +} + static int gaim_parse_auth_resp (aim_session_t *, aim_frame_t *, ...); static int gaim_parse_login (aim_session_t *, aim_frame_t *, ...); static int gaim_handle_redirect (aim_session_t *, aim_frame_t *, ...); @@ -290,6 +371,14 @@ static int gaim_directim_typing (aim_session_t *, aim_frame_t *, ...); static int gaim_update_ui (aim_session_t *, aim_frame_t *, ...); +static int oscar_file_transfer_do(aim_session_t *, aim_frame_t *, ...); +static void oscar_file_transfer_disconnect(aim_session_t *, + aim_conn_t *); +static void oscar_cancel_transfer(struct gaim_connection *, + struct file_transfer *); +static int oscar_sendfile_request(aim_session_t *sess, + struct oscar_file_transfer *oft); + static char *msgerrreason[] = { "Invalid error", "Invalid SNAC", @@ -319,6 +408,26 @@ }; static int msgerrreasonlen = 25; +static void oscar_file_transfer_disconnect(aim_session_t *sess, + aim_conn_t *conn) { + struct gaim_connection *gc = sess->aux_data; + struct oscar_data *od = (struct oscar_data *)gc->proto_data; + struct oscar_file_transfer *oft = find_oft_by_conn(gc, + conn); + + od->file_transfers = g_slist_remove(od->file_transfers, oft); + + if (oft->watcher) { + gaim_input_remove(oft->watcher); + oft->watcher = 0; + } + + aim_conn_kill(sess, &conn); + + g_free(oft->sn); + g_free(oft); +} + static void gaim_directim_disconnect(aim_session_t *sess, aim_conn_t *conn) { struct gaim_connection *gc = sess->aux_data; struct oscar_data *od = (struct oscar_data *)gc->proto_data; @@ -425,6 +534,13 @@ } else if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) { if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) gaim_directim_disconnect(odata->sess, conn); + else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_SENDFILE) { + struct oscar_file_transfer *oft = find_oft_by_conn(gc, conn); + if (oft) { + transfer_abort(oft->xfer, _("Buddy canceled transfer")); + } + oscar_file_transfer_disconnect(odata->sess, conn); + } else { debug_printf("No handler for rendezvous disconnect (%d).\n", source); @@ -463,7 +579,11 @@ aim_conn_t *conn; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -559,6 +679,13 @@ odata->direct_ims = g_slist_remove(odata->direct_ims, n); g_free(n); } + while (odata->file_transfers) { + struct oscar_file_transfer *n = odata->file_transfers->data; + if (n->watcher > 0) + gaim_input_remove(n->watcher); + odata->file_transfers = g_slist_remove(odata->file_transfers, n); + g_free(n); + } while (odata->hasicons) { struct icon_req *n = odata->hasicons->data; g_free(n->user); @@ -603,7 +730,11 @@ aim_conn_t *bosconn; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -623,6 +754,33 @@ set_login_progress(gc, 4, _("Connection established, cookie sent")); } +static void oscar_ask_send_file(struct gaim_connection *gc, char *destsn) { + struct oscar_data *od = (struct oscar_data *)gc->proto_data; + struct oscar_file_transfer *oft = oft_listening; + + /* Kludge: if we try to send a file to a client that doesn't + * support it, the BOS server sends us back an error without + * any information identifying which transfer was aborted. So + * we only allow one sendfile request at a time, to ensure that + * the transfer referenced by an error is unambiguous. It's ugly, + * but what else can we do? -- wtm + */ + if (oft) { + do_error_dialog(_("Sorry, you already have an outgoing transfer pending. Due to limitations of the Oscar protocol, only one outgoing transfer request is permitted at a time."), NULL, GAIM_ERROR); + } + else { + struct oscar_file_transfer *oft = g_new0(struct oscar_file_transfer, + 1); + + oft->type = OFT_SENDFILE_OUT; + oft->sn = g_strdup(destsn); + + od->file_transfers = g_slist_append(od->file_transfers, oft); + + oft->xfer = transfer_out_add(gc, oft->sn); + } +} + static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) { va_list ap; struct aim_authresp_info *info; @@ -770,7 +928,11 @@ int x = 0; unsigned char m[17]; +#ifndef _WIN32 while (read(pos->fd, &in, 1) == 1) { +#else + while (recv(pos->fd, &in, 1, 0) == 1) { +#endif if (in == '\n') x++; else if (in != '\r') @@ -784,18 +946,30 @@ _("You may be disconnected shortly. You may want to use TOC until " "this is fixed. Check " WEBSITE " for updates."), GAIM_WARNING); gaim_input_remove(pos->inpa); +#ifndef _WIN32 close(pos->fd); +#else + closesocket(pos->fd); +#endif g_free(pos); return; } +#ifndef _WIN32 read(pos->fd, m, 16); +#else + recv(pos->fd, m, 16, 0); +#endif m[16] = '\0'; debug_printf("Sending hash: "); for (x = 0; x < 16; x++) debug_printf("%02x ", (unsigned char)m[x]); debug_printf("\n"); gaim_input_remove(pos->inpa); +#ifndef _WIN32 close(pos->fd); +#else + closesocket(pos->fd); +#endif aim_sendmemblock(od->sess, pos->conn, 0, 16, m, AIM_SENDMEMBLOCK_FLAG_ISHASH); g_free(pos); } @@ -817,7 +991,11 @@ g_snprintf(buf, sizeof(buf), "GET " AIMHASHDATA "?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n", pos->offset, pos->len, pos->modname ? pos->modname : ""); +#ifndef _WIN32 write(pos->fd, buf, strlen(buf)); +#else + send(pos->fd, buf, strlen(buf), 0); +#endif if (pos->modname) g_free(pos->modname); pos->inpa = gaim_input_add(pos->fd, GAIM_INPUT_READ, damn_you, pos); @@ -959,7 +1137,11 @@ aim_conn_t *tstconn; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -987,7 +1169,11 @@ aim_conn_t *tstconn; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -1016,7 +1202,11 @@ aim_conn_t *tstconn; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif g_free(ccon->show); g_free(ccon->name); g_free(ccon); @@ -1278,6 +1468,193 @@ oscar_callback, dim->conn); } +static int oscar_sendfile_out_done(aim_session_t *sess, aim_frame_t *fr, ...) { + struct gaim_connection *gc = sess->aux_data; + va_list ap; + aim_conn_t *conn; + const char *cook; + struct oscar_file_transfer *oft; + + va_start(ap, fr); + conn = va_arg(ap, aim_conn_t *); + cook = va_arg(ap, const char *); + va_end(ap); + + oft = find_oft_by_cookie(gc, cook); + if (oft->filesdone == oft->totfiles) + oscar_file_transfer_disconnect(sess, conn); + else + /* Send header for next file */ + oscar_sendfile_request(sess, oft); + + return 0; +} + +/* Called once for each file before sending the raw data. */ +static int oscar_sendfile_request(aim_session_t *sess, + struct oscar_file_transfer *oft) { + char *name; + int size; + + transfer_get_file_info(oft->xfer, &size, &name); + aim_oft_sendfile_request(sess, oft->conn, name, oft->filesdone, + oft->totfiles, size, oft->totsize); + + return 0; +} + +static int oscar_sendfile_accepted(aim_session_t *sess, aim_frame_t *fr, ...) { + struct gaim_connection *gc = sess->aux_data; + struct oscar_data *od = (struct oscar_data *)gc->proto_data; + struct oscar_file_transfer *oft; + va_list ap; + aim_conn_t *conn, *listenerconn; + + alarm(0); /* reset timeout alarm */ + va_start(ap, fr); + conn = va_arg(ap, aim_conn_t *); + listenerconn = va_arg(ap, aim_conn_t *); + va_end(ap); + + oft = find_oft_by_conn(gc, listenerconn); + oft->conn = conn; + /* Stop watching listener conn; watch transfer conn instead */ + gaim_input_remove(oft->watcher); + aim_conn_kill(sess, &listenerconn); + /* We no longer need to block other outgoing transfers. */ + oft_listening = NULL; + + aim_conn_addhandler(od->sess, oft->conn, AIM_CB_FAM_OFT, + AIM_CB_OFT_GETFILEFILESEND, + oscar_file_transfer_do, + 0); + aim_conn_addhandler(sess, conn, + AIM_CB_FAM_OFT, + AIM_CB_OFT_GETFILECOMPLETE, + oscar_sendfile_out_done, + 0); + oft->watcher = gaim_input_add(oft->conn->fd, GAIM_INPUT_READ, + oscar_callback, oft->conn); + + oscar_sendfile_request(sess, oft); + + return 0; +} + +void oscar_sendfile_timeout(int sig) +{ + struct oscar_file_transfer *oft = oft_listening; + + if (oft) { + aim_session_t *sess = aim_conn_getsess(oft->conn); + aim_conn_t *bosconn; + { + /* XXX is this valid? is there a better way? -- wtm */ + struct gaim_connection *gc = sess->aux_data; + struct oscar_data *odata = (struct oscar_data *)gc->proto_data; + bosconn = odata->conn; + } + + oft_listening = NULL; + aim_canceltransfer(sess, bosconn, oft->cookie, + oft->sn, AIM_CAPS_SENDFILE); + + transfer_abort(oft->xfer, _("Transfer timed out")); + oscar_file_transfer_disconnect(sess, oft->conn); + } +} + +/* Called once at the beginning of an outgoing transfer session. */ +static void oscar_start_transfer_out(struct gaim_connection *gc, + struct file_transfer *xfer, const char *name, int totfiles, + int totsize) { + struct oscar_data *od = (struct oscar_data *)gc->proto_data; + struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); + + oft->xfer = xfer; + oft->totsize = totsize; + oft->totfiles = totfiles; + oft->filesdone = 0; + oft_listening = oft; + + oft->conn = aim_sendfile_initiate(od->sess, oft->sn, + name, totfiles, oft->totsize, oft->cookie); + if (!oft->conn) { + do_error_dialog(_("Couldn't open listener to send file"), + _("File transfer aborted"), + GAIM_ERROR); + return; + } + + { + /* XXX is there a good glib-oriented way of doing this? + * -- wtm */ + struct sigaction act; + act.sa_handler = oscar_sendfile_timeout; + act.sa_flags = SA_ONESHOT; + sigemptyset (&act.sa_mask); + sigaction(SIGALRM, &act, NULL); + alarm(OFT_TIMEOUT); + } + + aim_conn_addhandler(od->sess, oft->conn, AIM_CB_FAM_OFT, + AIM_CB_OFT_GETFILEINITIATE, + oscar_sendfile_accepted, + 0); + oft->watcher = gaim_input_add(oft->conn->fd, GAIM_INPUT_READ, + oscar_callback, oft->conn); +} + +static void oscar_transfer_data_chunk(struct gaim_connection *gc, + struct file_transfer *xfer, const char *buf, int len) +{ + struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); + aim_session_t *sess = aim_conn_getsess(oft->conn); + + if (oft->type == OFT_SENDFILE_IN) + aim_update_checksum(sess, oft->conn, buf, len); +} + +static void oscar_start_transfer_in(struct gaim_connection *gc, + struct file_transfer *xfer, int offset) { + struct oscar_data *od = (struct oscar_data *)gc->proto_data; + struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); + + oft->xfer = xfer; + oft->conn = aim_accepttransfer(od->sess, od->conn, oft->sn, + oft->cookie, oft->ip, + oft->port, + AIM_CAPS_SENDFILE); + if (!oft->conn) { + char *buf = g_strdup_printf("Couldn't connect to remote host"); + do_error_dialog(buf, NULL, GAIM_ERROR); + g_free(buf); + return; + } + + aim_conn_addhandler(od->sess, oft->conn, AIM_CB_FAM_OFT, + AIM_CB_OFT_GETFILEFILEREQ, oscar_file_transfer_do, + 0); + + oft->watcher = gaim_input_add(oft->conn->fd, GAIM_INPUT_READ, + oscar_callback, oft->conn); +} + +static void oscar_cancel_transfer(struct gaim_connection *gc, + struct file_transfer *xfer) { + struct oscar_data *od = (struct oscar_data *)gc->proto_data; + struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); + + if (oft->type == OFT_SENDFILE_IN) + aim_denytransfer(od->sess, oft->sn, oft->cookie, + AIM_TRANSFER_DENY_DECLINE); + + od->file_transfers = g_slist_remove(od->file_transfers, oft); + aim_conn_kill(od->sess, &oft->conn); + g_free(oft->sn); + g_free(oft); +} + static int accept_direct_im(gpointer w, struct ask_direct *d) { struct gaim_connection *gc = d->gc; struct oscar_data *od = (struct oscar_data *)gc->proto_data; @@ -1428,8 +1805,26 @@ debug_printf("rendezvous status %d (%s)\n", args->status, userinfo->sn); - if (args->status != AIM_RENDEZVOUS_PROPOSE) + + if (args->status == AIM_RENDEZVOUS_CANCEL) { + struct oscar_file_transfer *oft; + oft = find_oft_by_cookie(gc, args->cookie); + if (oft) { + transfer_abort(oft->xfer, _("Buddy canceled transfer")); + oscar_file_transfer_disconnect(sess, oft->conn); + } + return 0; + } + else if (args->status == AIM_RENDEZVOUS_ACCEPT) { + /* The user accepted our transfer request, but we don't + * really need to do anything yet. + * -- wtm + */ + return 0; + } + else if (args->status != AIM_RENDEZVOUS_PROPOSE) { return 1; + } if (args->reqclass & AIM_CAPS_CHAT) { char *name = extract_name(args->info.chat.roominfo.name); @@ -1446,6 +1841,39 @@ if (name) g_free(name); } else if (args->reqclass & AIM_CAPS_SENDFILE) { + struct oscar_file_transfer *oft; + + if (!args->verifiedip) { + /* It seems that Trillian sends a message + * with no file data during multiple-file + * transfers. + */ + debug_printf("sendfile: didn't get any data\n"); + return -1; + } + + oft = g_new0(struct oscar_file_transfer, 1); + + debug_printf("%s (%s) requests to send a file to %s\n", + userinfo->sn, args->verifiedip, gc->username); + + oft->type = OFT_SENDFILE_IN; + oft->sn = g_strdup(userinfo->sn); + strncpy(oft->ip, args->verifiedip, sizeof(oft->ip)); + oft->port = args->port; + memcpy(oft->cookie, args->cookie, 8); + + { /* XXX ugly... */ + struct gaim_connection *gc = sess->aux_data; + struct oscar_data *od = gc->proto_data; + od->file_transfers = g_slist_append(od->file_transfers, oft); + } + + oft->xfer = transfer_in_add(gc, userinfo->sn, + args->info.sendfile.filename, + args->info.sendfile.totsize, + args->info.sendfile.totfiles, + args->msg); } else if (args->reqclass & AIM_CAPS_GETFILE) { } else if (args->reqclass & AIM_CAPS_VOICE) { } else if (args->reqclass & AIM_CAPS_BUDDYICON) { @@ -1745,6 +2173,34 @@ return g_strdup_printf("Online"); } +static int gaim_parse_clientauto_rend(aim_session_t *sess, + const char *who, int reason, const char *cookie) { + struct gaim_connection *gc = sess->aux_data; + struct oscar_file_transfer *oft; + char *buf; + + switch (reason) { + case 3: /* Decline sendfile. */ + oft = find_oft_by_cookie(gc, cookie); + + if (oft) { + buf = g_strdup_printf(_("%s has declined to receive a file from %s.\n"), + who, gc->username); + alarm(0); /* reset timeout alarm */ + oft_listening = NULL; + transfer_abort(oft->xfer, buf); + g_free(buf); + oscar_file_transfer_disconnect(sess, oft->conn); + } + break; + default: + debug_printf("Received an unknown rendezvous client auto-response from %s. Type 0x%04x\n", who, reason); + + } + + return 0; +} + static int gaim_parse_clientauto(aim_session_t *sess, aim_frame_t *fr, ...) { struct gaim_connection *gc = sess->aux_data; va_list ap; @@ -1756,6 +2212,14 @@ who = va_arg(ap, char *); reason = (fu16_t)va_arg(ap, unsigned int); + if (chan == 2) { + char *cookie = va_arg(ap, char *); + va_end(va); + + return gaim_parse_clientauto_rend(sess, who, reason, + cookie); + } + switch(reason) { case 0x0003: { /* Reply from an ICQ status message request */ int state = (int)va_arg(ap, fu32_t); @@ -1827,12 +2291,27 @@ char *destn; fu16_t reason; char buf[1024]; + struct oscar_file_transfer *oft = oft_listening; va_start(ap, fr); reason = (fu16_t)va_arg(ap, unsigned int); destn = va_arg(ap, char *); va_end(ap); + if (oft) { + /* If we try to send a file but it isn't supported, then + * we get this error without any information identifying + * the failed connection. So we can only have one outgoing + * transfer at a time. Ugh. -- wtm + */ + oft_listening = NULL; + transfer_abort(oft->xfer, + (reason < msgerrreasonlen) ? msgerrreason[reason] : _("No reason was given.")); + + oscar_file_transfer_disconnect(sess, oft->conn); + return 1; + } + snprintf(buf, sizeof(buf), _("Your message to %s did not get sent:"), destn); do_error_dialog(buf, (reason < msgerrreasonlen) ? msgerrreason[reason] : _("No reason was given."), GAIM_ERROR); @@ -2806,7 +3285,12 @@ } else if (len != -1) { /* Trying to send an IM image outside of a direct connection. */ oscar_ask_direct_im(gc, name); +#ifndef _WIN32 return -ENOTCONN; +#else + WSASetLastError( WSAENOTCONN ); + return SOCKET_ERROR; +#endif } if (imflags & IM_FLAG_AWAY) { ret = aim_send_im(odata->sess, name, AIM_IMFLAGS_AWAY, message); @@ -3538,6 +4022,80 @@ return NULL; } +void oscar_transfer_nextfile(struct gaim_connection *gc, + struct file_transfer *xfer) { + struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); + aim_conn_t *conn = oft->conn; + aim_session_t *sess = aim_conn_getsess(conn); + + oft->filesdone++; + oft->watcher = gaim_input_add(conn->fd, GAIM_INPUT_READ, + oscar_callback, conn); + + /* If this is an incoming sendfile transfer, we send an OK + * message to the sender; if this is an outgoing sendfile, we + * will get an OK from the receiver that will be handled in + * oscar_sendfile_out_done(), so we don't need to do anything + * yet. + */ + + if (oft->type == OFT_SENDFILE_IN) + aim_oft_end(sess, conn); +} + +void oscar_transfer_done(struct gaim_connection *gc, + struct file_transfer *xfer) { + struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); + aim_conn_t *conn = oft->conn; + aim_session_t *sess = aim_conn_getsess(conn); + + oft->filesdone++; + if (oft->type == OFT_SENDFILE_IN) { + aim_oft_end(sess, conn); + oscar_file_transfer_disconnect(sess, conn); + } + else if (oft->type == OFT_SENDFILE_OUT) { +#if 0 + /* Wait for response before closing connection. */ + oft->watcher = gaim_input_add(conn->fd, GAIM_INPUT_READ, + oscar_callback, conn); +#else + oscar_file_transfer_disconnect(sess, conn); +#endif + } +} + +static int oscar_file_transfer_do(aim_session_t *sess, aim_frame_t *fr, ...) { + struct gaim_connection *gc = sess->aux_data; + va_list ap; + aim_conn_t *conn; + struct oscar_file_transfer *oft; + + va_start(ap, fr); + conn = va_arg(ap, aim_conn_t *); + + oft = find_oft_by_conn(gc, conn); + + /* Don't use the regular input handler for the raw data. */ + gaim_input_remove(oft->watcher); + oft->watcher = 0; + + if (oft->type == OFT_SENDFILE_IN) { + const char *name = va_arg(ap, const char *); + int size = va_arg(ap, int); + if (transfer_in_do(oft->xfer, conn->fd, name, size)) + oscar_file_transfer_disconnect(sess, oft->conn); + } + else { + int offset = va_arg(ap, int); + if (transfer_out_do(oft->xfer, conn->fd, offset)) + oscar_file_transfer_disconnect(sess, oft->conn); + } + va_end(ap); + + return 0; +} + static int gaim_directim_initiate(aim_session_t *sess, aim_frame_t *fr, ...) { va_list ap; struct gaim_connection *gc = sess->aux_data; @@ -3766,6 +4324,12 @@ pbm->gc = gc; m = g_list_append(m, pbm); } + + pbm = g_new0(struct proto_buddy_menu, 1); + pbm->label = _("Send File"); + pbm->callback = oscar_ask_send_file; + pbm->gc = gc; + m = g_list_append(m, pbm); } pbm = g_new0(struct proto_buddy_menu, 1); @@ -4015,7 +4579,7 @@ static struct prpl *my_protocol = NULL; -void oscar_init(struct prpl *ret) { +G_MODULE_EXPORT void oscar_init(struct prpl *ret) { struct proto_user_opt *puo; ret->protocol = PROTO_OSCAR; ret->options = OPT_PROTO_BUDDY_ICON | OPT_PROTO_IM_IMAGE; @@ -4043,6 +4607,12 @@ ret->add_buddies = oscar_add_buddies; ret->group_buddy = oscar_move_buddy; ret->rename_group = oscar_rename_group; + ret->file_transfer_cancel = oscar_cancel_transfer; + ret->file_transfer_in = oscar_start_transfer_in; + ret->file_transfer_out = oscar_start_transfer_out; + ret->file_transfer_data_chunk = oscar_transfer_data_chunk; + ret->file_transfer_nextfile = oscar_transfer_nextfile; + ret->file_transfer_done = oscar_transfer_done; ret->remove_buddy = oscar_remove_buddy; ret->remove_buddies = oscar_remove_buddies; ret->add_permit = oscar_add_permit; @@ -4077,7 +4647,7 @@ #ifndef STATIC -void *gaim_prpl_init(struct prpl *prpl) +G_MODULE_EXPORT void gaim_prpl_init(struct prpl *prpl) { oscar_init(prpl); prpl->plug->desc.api_version = PLUGIN_API_VERSION; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/oscar/ssi.c --- a/src/protocols/oscar/ssi.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/oscar/ssi.c Fri Oct 11 03:14:01 2002 +0000 @@ -500,7 +500,7 @@ /* Look up the parent group */ if (!(parentgroup = aim_ssi_itemlist_finditem(sess->ssi.items, NULL, gn, AIM_SSI_TYPE_GROUP))) { - aim_ssi_addgroups(sess, conn, &gn, 1); + aim_ssi_addgroups(sess, conn, (const char **)&gn, 1); if (!(parentgroup = aim_ssi_itemlist_finditem(sess->ssi.items, NULL, gn, AIM_SSI_TYPE_GROUP))) return -ENOMEM; } diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/oscar/txqueue.c --- a/src/protocols/oscar/txqueue.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/oscar/txqueue.c Fri Oct 11 03:14:01 2002 +0000 @@ -10,6 +10,8 @@ #ifndef _WIN32 #include +#else +#include "win32dep.h" #endif /* @@ -24,7 +26,7 @@ * chan = channel for FLAP, hdrtype for OFT * */ -faim_internal aim_frame_t *aim_tx_new(aim_session_t *sess, aim_conn_t *conn, fu8_t framing, fu8_t chan, int datalen) +faim_internal aim_frame_t *aim_tx_new(aim_session_t *sess, aim_conn_t *conn, fu8_t framing, fu16_t chan, int datalen) { aim_frame_t *fr; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/toc/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/toc/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,151 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of libtoc +# + +# +# PATHS +# + +INCLUDE_DIR := . +GTK_TOP := ../../../../win32-dev/gtk_2_0 +GAIM_TOP := ../../.. +TOC_ROOT := . +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir + +## +## VARIABLE DEFINITIONS +## + +TARGET = libtoc + +VERSION := $(shell cat $(GAIM_TOP)/VERSION) + +# Compiler Options + +CC = gcc + +CFLAGS = -O2 -Werror -Wall -mno-cygwin -fnative-struct + +DEFINES = -DAIM_BUILDDATE=\"`date +%Y%m%d`\" \ + -DAIM_BUILDTIME=\"`date +%H%M%S`\" \ + -DVERSION=\"$(VERSION)\" \ + -DHAVE_CONFIG_H + +# Static or Plugin... +ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR) +else +ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR)/plugins +endif +endif + + +## +## INCLUDE MAKEFILES +## + + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(TOC_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src + + +## +## SOURCES, OBJECTS +## + +C_SRC = toc.c + + +OBJECTS = $(C_SRC:%.c=%.o) + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 -lglib-2.0 -lgdk-win32-2.0 -lgmodule-2.0 -lgobject-2.0 -lws2_32 -lintl -lgaim + +# -liberty + + +## +## RULES +## + +# How to make a C file + +%.o: %.c + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: $(TARGET).dll + +install: + cp $(TOC_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + + +## +## BUILD Dependencies +## + +$(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + +## +## BUILD DLL +## + +$(TARGET).def: $(OBJECTS) + dlltool --dllname $(TARGET).dll -z $(TARGET).def \ + $(OBJECTS) + +$(TARGET).base: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + gcc -mdll -o junk.tmp -Wl,--base-file,$@ $(OBJECTS) $(LIB_PATHS) $(LIBS) + rm -rf junk.tmp + +$(TARGET).exp: $(TARGET).def $(TARGET).base + dlltool --dllname $(TARGET).dll --base-file $(TARGET).base \ + --output-exp $(TARGET).exp --def $(TARGET).def + rm -rf $(TARGET).base + +$(TARGET).dll: $(OBJECTS) $(TARGET).exp $(GAIM_TOP)/src/gaim.lib + dlltool -D $(TARGET).dll -d $(TARGET).def -l $(TARGET).lib + gcc -mdll -o $(TARGET).dll $(OBJECTS) -Wl,$(TARGET).exp $(LIB_PATHS) $(LIBS) + rm -rf $(TARGET).exp + + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).lib + rm -rf $(TARGET).def diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/toc/toc.c --- a/src/protocols/toc/toc.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/toc/toc.c Fri Oct 11 03:14:01 2002 +0000 @@ -24,17 +24,23 @@ #ifdef HAVE_CONFIG_H #include #endif + +#ifndef _WIN32 #include -#include #include -#include #include #include +#include +#else +#include +#endif + +#include +#include #include #include #include #include -#include #include #include #include "prpl.h" @@ -42,6 +48,10 @@ #include "gaim.h" #include "proxy.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #include "pixmaps/protocols/oscar/admin_icon.xpm" #include "pixmaps/protocols/oscar/aol_icon.xpm" #include "pixmaps/protocols/oscar/away_icon.xpm" @@ -49,6 +59,9 @@ #include "pixmaps/protocols/oscar/free_icon.xpm" #include "pixmaps/protocols/oscar/wireless_icon.xpm" +/* for win32 compatability */ +G_MODULE_IMPORT GSList *connections; + #define REVISION "penguin" #define TYPE_SIGNON 1 @@ -134,6 +147,36 @@ static void toc_callback(gpointer, gint, GaimInputCondition); static void accept_file_dialog(struct ft_request *); +/* The following were added for win32 port - Herman */ + +int toc_write(int fd, const void *buffer, int len) +{ +#ifndef _WIN32 + return write(fd, buffer, len); +#else + return send(fd, buffer, len, 0); +#endif +} + +int toc_read(int fd, void *buffer, int size) +{ +#ifndef _WIN32 + return read(fd, buffer, size); +#else + return recv(fd, buffer, size, 0); +#endif +} + +int toc_soc_close( int fd ) +{ +#ifndef _WIN32 + return close(fd); +#else + return closesocket(fd); +#endif +} + + /* ok. this function used to take username/password, and return 0 on success. * now, it takes username/password, and returns NULL on error or a new gaim_connection * on success. */ @@ -173,7 +216,7 @@ char buf[80]; if (!g_slist_find(connections, data)) { - close(source); + toc_soc_close(source); return; } @@ -190,7 +233,7 @@ tdt->toc_fd = source; debug_printf("* Client sends \"FLAPON\\r\\n\\r\\n\"\n"); - if (write(tdt->toc_fd, FLAPON, strlen(FLAPON)) < 0) { + if (toc_write(tdt->toc_fd, FLAPON, strlen(FLAPON)) < 0) { hide_login_progress(gc, "Disconnected."); signoff(gc); return; @@ -211,7 +254,7 @@ if (gc->inpa > 0) gaim_input_remove(gc->inpa); gc->inpa = 0; - close(((struct toc_data *)gc->proto_data)->toc_fd); + toc_soc_close(((struct toc_data *)gc->proto_data)->toc_fd); g_free(gc->proto_data); } @@ -327,7 +370,7 @@ slen += 1; } - return write(tdt->toc_fd, obuf, slen); + return toc_write(tdt->toc_fd, obuf, slen); } static int wait_reply(struct gaim_connection *gc, char *buffer, size_t buflen) @@ -336,7 +379,7 @@ struct sflap_hdr *hdr; int ret; - if (read(tdt->toc_fd, buffer, sizeof(struct sflap_hdr)) < 0) { + if (toc_read(tdt->toc_fd, buffer, sizeof(struct sflap_hdr)) < 0) { debug_printf("error, couldn't read flap header\n"); return -1; } @@ -354,7 +397,7 @@ ret = 0; do { count += ret; - ret = read(tdt->toc_fd, + ret = toc_read(tdt->toc_fd, buffer + sizeof(struct sflap_hdr) + count, ntohs(hdr->len) - count); } while (count + ret < ntohs(hdr->len) && ret > 0); buffer[sizeof(struct sflap_hdr) + count + ret] = '\0'; @@ -1356,7 +1399,7 @@ static struct prpl *my_protocol = NULL; -void toc_init(struct prpl *ret) +G_MODULE_EXPORT void toc_init(struct prpl *ret) { struct proto_user_opt *puo; ret->protocol = PROTO_TOC; @@ -1413,7 +1456,7 @@ #ifndef STATIC -void *gaim_prpl_init(struct prpl *prpl) +G_MODULE_EXPORT void gaim_prpl_init(struct prpl *prpl) { toc_init(prpl); prpl->plug->desc.api_version = PLUGIN_API_VERSION; @@ -1516,8 +1559,8 @@ char *buf; frombase64(ft->cookie, &buf, NULL); - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); + toc_read(source, ft, 8); + toc_read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); debug_header(ft); ft->hdr.hdrtype = 0x202; @@ -1525,7 +1568,7 @@ g_free(buf); ft->hdr.encrypt = 0; ft->hdr.compress = 0; debug_header(ft); - write(source, ft, 256); + toc_write(source, ft, 256); if (ft->files == 1) { ft->file = fopen(ft->filename, "w"); @@ -1534,7 +1577,7 @@ do_error_dialog(buf, strerror(errno), GAIM_ERROR); g_free(buf); gaim_input_remove(ft->inpa); - close(source); + toc_soc_close(source); g_free(ft->filename); g_free(ft->user); g_free(ft->ip); @@ -1551,7 +1594,7 @@ do_error_dialog(buf, strerror(errno), GAIM_ERROR); g_free(buf); gaim_input_remove(ft->inpa); - close(source); + toc_soc_close(source); g_free(ft->filename); g_free(ft->user); g_free(ft->ip); @@ -1563,11 +1606,11 @@ return; } - rt = read(source, buf, MIN(ntohl(ft->hdr.size) - ft->recvsize, 1024)); + rt = toc_read(source, buf, MIN(ntohl(ft->hdr.size) - ft->recvsize, 1024)); if (rt < 0) { do_error_dialog("File transfer failed; other side probably canceled.", NULL, GAIM_ERROR); gaim_input_remove(ft->inpa); - close(source); + toc_soc_close(source); g_free(ft->user); g_free(ft->ip); g_free(ft->cookie); @@ -1587,13 +1630,13 @@ ft->hdr.recvcsum = ft->hdr.checksum; /* uh... */ ft->hdr.nrecvd = htons(ntohs(ft->hdr.nrecvd) + 1); ft->hdr.flags = 0; - write(source, ft, 256); + toc_write(source, ft, 256); debug_header(ft); ft->recvsize = 0; fclose(ft->file); if (ft->hdr.filesleft == 0) { gaim_input_remove(ft->inpa); - close(source); + toc_soc_close(source); g_free(ft->filename); g_free(ft->user); g_free(ft->ip); @@ -1671,7 +1714,7 @@ int i; for (i = 0; i < remain; i++) fscanf(ft->file, "%c", &buf[i]); - write(source, buf, remain); + toc_write(source, buf, remain); ft->recvsize += remain; if (ft->recvsize == ntohl(ft->hdr.totsize)) { gaim_input_remove(ft->inpa); @@ -1685,8 +1728,8 @@ struct tm *fortime; struct stat st; - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); + toc_read(source, ft, 8); + toc_read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); debug_header(ft); stat(ft->filename, &st); @@ -1695,27 +1738,27 @@ fortime->tm_mon + 1, fortime->tm_mday, fortime->tm_year + 1900, fortime->tm_hour + 1, fortime->tm_min + 1, (long)st.st_size, g_basename(ft->filename)); - write(source, buf, ntohl(ft->hdr.size)); + toc_write(source, buf, ntohl(ft->hdr.size)); return; } if (ft->hdr.hdrtype == htons(0x1209)) { - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); + toc_read(source, ft, 8); + toc_read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); debug_header(ft); return; } if (ft->hdr.hdrtype == htons(0x120b)) { - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); + toc_read(source, ft, 8); + toc_read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); debug_header(ft); if (ft->hdr.hdrtype != htons(0x120c)) { g_snprintf(buf, sizeof(buf), "%s decided to cancel the transfer", ft->user); do_error_dialog(buf, NULL, GAIM_ERROR); gaim_input_remove(ft->inpa); - close(source); + toc_soc_close(source); g_free(ft->filename); g_free(ft->user); g_free(ft->ip); @@ -1729,13 +1772,13 @@ ft->hdr.hdrtype = 0x0101; ft->hdr.totfiles = htons(1); ft->hdr.filesleft = htons(1); ft->hdr.flags = 0x20; - write(source, ft, 256); + toc_write(source, ft, 256); return; } if (ft->hdr.hdrtype == 0x0101) { - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); + toc_read(source, ft, 8); + toc_read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); debug_header(ft); gaim_input_remove(ft->inpa); @@ -1745,12 +1788,12 @@ } if (ft->hdr.hdrtype == 0x0202) { - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); + toc_read(source, ft, 8); + toc_read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); debug_header(ft); gaim_input_remove(ft->inpa); - close(source); + toc_soc_close(source); g_free(ft->filename); g_free(ft->user); g_free(ft->ip); @@ -1798,7 +1841,7 @@ hdr->lnameoffset = 0x1A; hdr->lsizeoffset = 0x10; g_snprintf(hdr->name, 64, "listing.txt"); - if (write(src, hdr, 256) < 0) { + if (toc_write(src, hdr, 256) < 0) { do_error_dialog(_("Could not write file header. The file will not be transferred."), NULL, GAIM_ERROR); fclose(ft->file); g_free(ft->filename); @@ -1889,7 +1932,7 @@ ft->files = fr->files; ft->window = window = gtk_file_selection_new(_("Gaim - Save As...")); - g_snprintf(buf, sizeof(buf), "%s/%s", g_get_home_dir(), fr->filename ? fr->filename : ""); + g_snprintf(buf, sizeof(buf), "%s/%s", gaim_home_dir(), fr->filename ? fr->filename : ""); gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), buf); gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(cancel_callback), ft); diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/yahoo/Makefile.mingw --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/yahoo/Makefile.mingw Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,157 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of libyahoo +# + +# +# PATHS +# + +BUILD_TOOLS = /usr/local/mingw + +INCLUDE_DIR := . + +GTK_TOP := ../../../../win32-dev/gtk_2_0 +GAIM_TOP := ../../.. +YAHOO_ROOT := . +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir + +## +## VARIABLE DEFINITIONS +## + +TARGET = libyahoo + +VERSION := $(shell cat $(GAIM_TOP)/VERSION) + +# Compiler Options + +GCOPTS = -B $(BUILD_TOOLS) + +CC = gcc.exe $(GCOPTS) + +CFLAGS = -O2 -Werror -Wall -mno-cygwin -fnative-struct + +DEFINES = -DAIM_BUILDDATE=\"`date +%Y%m%d`\" \ + -DAIM_BUILDTIME=\"`date +%H%M%S`\" \ + -DVERSION=\"$(VERSION)\" \ + -DHAVE_CONFIG_H + +# Static or Plugin... +ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR) +else +ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR)/plugins +endif +endif + + +## +## INCLUDE MAKEFILES +## + + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(YAHOO_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src + + +## +## SOURCES, OBJECTS +## + +C_SRC = yahoo.c \ + crypt.c + + +OBJECTS = $(C_SRC:%.c=%.o) + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 -lglib-2.0 -lgdk-win32-2.0 -lgmodule-2.0 -lgobject-2.0 -lws2_32 -lintl -lgaim + +# -liberty + + +## +## RULES +## + +# How to make a C file + +%.o: %.c + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: $(TARGET).dll + +install: + cp $(YAHOO_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + + +## +## BUILD Dependencies +## + +$(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + +## +## BUILD DLL +## + +$(TARGET).def: $(OBJECTS) + dlltool --dllname $(TARGET).dll -z $(TARGET).def \ + $(OBJECTS) + +$(TARGET).base: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + gcc -mdll -o junk.tmp -Wl,--base-file,$@ $(OBJECTS) $(LIB_PATHS) $(LIBS) + rm -rf junk.tmp + +$(TARGET).exp: $(TARGET).def $(TARGET).base + dlltool --dllname $(TARGET).dll --base-file $(TARGET).base \ + --output-exp $(TARGET).exp --def $(TARGET).def + rm -rf $(TARGET).base + +$(TARGET).dll: $(OBJECTS) $(TARGET).exp $(GAIM_TOP)/src/gaim.lib + dlltool -D $(TARGET).dll -d $(TARGET).def -l $(TARGET).lib + gcc -mdll -o $(TARGET).dll $(OBJECTS) -Wl,$(TARGET).exp $(LIB_PATHS) $(LIBS) + rm -rf $(TARGET).exp + + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).lib + rm -rf $(TARGET).def diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/yahoo/yahoo.c --- a/src/protocols/yahoo/yahoo.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/yahoo/yahoo.c Fri Oct 11 03:14:01 2002 +0000 @@ -24,17 +24,21 @@ #include "config.h" #endif - +#ifndef _WIN32 #include #include -#include #include #include +#include +#else +#include +#endif + +#include #include #include #include #include -#include #include #include #include "multi.h" @@ -43,8 +47,15 @@ #include "proxy.h" #include "md5.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + extern char *yahoo_crypt(char *, char *); +/* for win32 compatability */ +G_MODULE_IMPORT GSList *connections; + #include "pixmaps/status-away.xpm" #include "pixmaps/status-here.xpm" #include "pixmaps/status-idle.xpm" @@ -354,8 +365,11 @@ yahoo_packet_write(pkt, data + pos); yahoo_packet_dump(data, len); +#ifndef _WIN32 ret = write(yd->fd, data, len); - +#else + ret = send(yd->fd, data, len, 0); +#endif g_free(data); return ret; @@ -877,9 +891,19 @@ char buf[1024]; int len; +#ifndef _WIN32 len = read(yd->fd, buf, sizeof(buf)); +#else + len = recv(yd->fd, buf, sizeof(buf), 0); +#endif if (len <= 0) { +#ifdef _WIN32 + if(len == SOCKET_ERROR) + debug_printf("Error reading socket: %d\n", WSAGetLastError()); + else if( len == 0 ) + debug_printf("Connection was gracefully closed.\n"); +#endif hide_login_progress_error(gc, "Unable to read"); signoff(gc); return; @@ -941,7 +965,11 @@ struct yahoo_packet *pkt; if (!g_slist_find(connections, gc)) { +#ifndef _WIN32 close(source); +#else + closesocket(source); +#endif return; } @@ -1009,7 +1037,11 @@ g_hash_table_foreach_remove(yd->games, yahoo_destroy_hash, NULL); g_hash_table_destroy(yd->games); if (yd->fd >= 0) +#ifndef _WIN32 close(yd->fd); +#else + closesocket(yd->fd); +#endif if (yd->rxqueue) g_free(yd->rxqueue); yd->rxlen = 0; @@ -1410,7 +1442,7 @@ static struct prpl *my_protocol = NULL; -void yahoo_init(struct prpl *ret) { +G_MODULE_EXPORT void yahoo_init(struct prpl *ret) { struct proto_user_opt *puo; ret->protocol = PROTO_YAHOO; ret->options = OPT_PROTO_MAIL_CHECK; @@ -1448,7 +1480,7 @@ #ifndef STATIC -void *gaim_prpl_init(struct prpl *prpl) +G_MODULE_EXPORT void gaim_prpl_init(struct prpl *prpl) { yahoo_init(prpl); prpl->plug->desc.api_version = PLUGIN_API_VERSION; diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/zephyr/ZVariables.c --- a/src/protocols/zephyr/ZVariables.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/zephyr/ZVariables.c Fri Oct 11 03:14:01 2002 +0000 @@ -5,7 +5,7 @@ * Created by: Robert French * * $Source$ - * $Author: warmenhoven $ + * $Author: robflynn $ * * Copyright (c) 1987 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file @@ -118,7 +118,7 @@ char *envptr; struct passwd *pwd; - envptr = getenv("HOME"); + envptr = gaim_home_dir(); if (envptr) (void) strcpy(bfr, envptr); else { diff -r afc5bb164c5a -r 9682c0e022c6 src/protocols/zephyr/zephyr.c --- a/src/protocols/zephyr/zephyr.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/protocols/zephyr/zephyr.c Fri Oct 11 03:14:01 2002 +0000 @@ -86,17 +86,17 @@ /* just for debugging static void handle_unknown(ZNotice_t notice) { - g_print("z_packet: %s\n", notice.z_packet); - g_print("z_version: %s\n", notice.z_version); - g_print("z_kind: %d\n", notice.z_kind); - g_print("z_class: %s\n", notice.z_class); - g_print("z_class_inst: %s\n", notice.z_class_inst); - g_print("z_opcode: %s\n", notice.z_opcode); - g_print("z_sender: %s\n", notice.z_sender); - g_print("z_recipient: %s\n", notice.z_recipient); - g_print("z_message: %s\n", notice.z_message); - g_print("z_message_len: %d\n", notice.z_message_len); - g_print("\n"); + debug_printf("z_packet: %s\n", notice.z_packet); + debug_printf("z_version: %s\n", notice.z_version); + debug_printf("z_kind: %d\n", notice.z_kind); + debug_printf("z_class: %s\n", notice.z_class); + debug_printf("z_class_inst: %s\n", notice.z_class_inst); + debug_printf("z_opcode: %s\n", notice.z_opcode); + debug_printf("z_sender: %s\n", notice.z_sender); + debug_printf("z_recipient: %s\n", notice.z_recipient); + debug_printf("z_message: %s\n", notice.z_message); + debug_printf("z_message_len: %d\n", notice.z_message_len); + debug_printf("\n"); } */ @@ -499,7 +499,7 @@ gchar *fname; gchar buff[BUFSIZ]; - fname = g_strdup_printf("%s/.zephyr.subs", g_getenv("HOME")); + fname = g_strdup_printf("%s/.zephyr.subs", gaim_home_dir()); f = fopen(fname, "r"); if (f) { char **triple; @@ -566,7 +566,7 @@ FILE *fd; gchar buff[BUFSIZ], *filename; - filename = g_strconcat(g_get_home_dir(), "/.anyone", NULL); + filename = g_strconcat(gaim_home_dir(), "/.anyone", NULL); if ((fd = fopen(filename, "r")) != NULL) { while (fgets(buff, BUFSIZ, fd)) { strip_comments(buff); @@ -623,7 +623,7 @@ char *fname; char** triple; - fname = g_strdup_printf("%s/.zephyr.subs", g_get_home_dir()); + fname = g_strdup_printf("%s/.zephyr.subs", gaim_home_dir()); fd = fopen(fname, "w"); if (!fd) { @@ -660,7 +660,7 @@ char *ptr, *fname, *ptr2; FILE *fd; - fname = g_strdup_printf("%s/.anyone", g_get_home_dir()); + fname = g_strdup_printf("%s/.anyone", gaim_home_dir()); fd = fopen(fname, "w"); if (!fd) { g_free(fname); diff -r afc5bb164c5a -r 9682c0e022c6 src/proxy.c --- a/src/proxy.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/proxy.c Fri Oct 11 03:14:01 2002 +0000 @@ -30,16 +30,26 @@ #include #include #include + +#ifndef _WIN32 #include #include #include #include #include +#else +#include +#endif + #include #include #include "gaim.h" #include "proxy.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) @@ -123,11 +133,20 @@ { static struct sockaddr_in sin; +#ifndef _WIN32 if (!inet_aton(host, &sin.sin_addr)) { +#else + if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) { +#endif struct hostent *hp; - if (!(hp = gethostbyname(host))) { + if(!(hp = gethostbyname(host))) { +#ifndef _WIN32 debug_printf("gaim_gethostbyname(\"%s\", %d) failed: %s", host, port, hstrerror(h_errno)); +#else + debug_printf("gaim_gethostbyname(\"%s\", %d) failed: Error %d", + host, port, WSAGetLastError()); +#endif return NULL; } memset(&sin, 0, sizeof(struct sockaddr_in)); @@ -144,8 +163,26 @@ { struct PHB *phb = data; unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + u_long imode; +#else int error = ETIMEDOUT; +#endif debug_printf("Connected\n"); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(source); + gaim_input_remove(phb->inpa); + phb->func(phb->data, -1, GAIM_INPUT_READ); + g_free(phb); + return; + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(source, FIONBIO, &imode); +#else len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); @@ -155,6 +192,7 @@ return; } fcntl(source, F_SETFL, 0); +#endif gaim_input_remove(phb->inpa); phb->func(phb->data, source, GAIM_INPUT_READ); g_free(phb); @@ -175,7 +213,10 @@ { struct sockaddr_in *sin; int fd = -1; - +#ifdef _WIN32 + u_long imode; + int w_errno; +#endif debug_printf("connecting to %s:%d with no proxy\n", host, port); if (!(sin = gaim_gethostbyname(host, port))) { @@ -189,19 +230,50 @@ g_free(phb); return -1; } - +#ifdef _WIN32 + imode=1; + ioctlsocket(fd, FIONBIO, &imode); +#else fcntl(fd, F_SETFL, O_NONBLOCK); +#endif if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { +#ifdef _WIN32 + w_errno = WSAGetLastError(); + if ((w_errno == WSAEINPROGRESS) || (w_errno == WSAEINTR) || (w_errno == WSAEWOULDBLOCK)) { +#else if ((errno == EINPROGRESS) || (errno == EINTR)) { +#endif debug_printf("Connect would have blocked\n"); phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, no_one_calls, phb); } else { +#ifdef _WIN32 + debug_printf("connect failed (errno %d)\n", w_errno); + closesocket(fd); +#else debug_printf("connect failed (errno %d)\n", errno); close(fd); +#endif g_free(phb); return -1; } } else { +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + unsigned int len; + u_long imode; + + debug_printf("Connect didn't block\n"); + len = sizeof(werror); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + debug_printf("getsockopt failed\n"); + closesocket(fd); + g_free(phb); + return -1; + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(fd, FIONBIO, &imode); +#else unsigned int len; int error = ETIMEDOUT; debug_printf("Connect didn't block\n"); @@ -213,6 +285,7 @@ return -1; } fcntl(fd, F_SETFL, 0); +#endif phb->port = fd; /* bleh */ g_timeout_add(50, clean_connect, phb); /* we do this because we never want to call our callback @@ -234,7 +307,11 @@ gaim_input_remove(phb->inpa); +#ifdef _WIN32 + while ((nlc != 2) && (recv(source, &inputline[pos++], 1, 0) == 1)) { +#else while ((nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) { +#endif if (inputline[pos - 1] == '\n') nlc++; else if (inputline[pos - 1] != '\r') @@ -252,7 +329,11 @@ return; } +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -264,24 +345,44 @@ char cmd[384]; struct PHB *phb = data; unsigned int len; +#ifdef _WIN32 + int w_error = WSAETIMEDOUT; + u_long imode = 0; +#else int error = ETIMEDOUT; +#endif debug_printf("Connected\n"); if (phb->inpa > 0) gaim_input_remove(phb->inpa); +#ifdef _WIN32 + len = sizeof(w_error); + if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&w_error, &len) < 0) { + closesocket(source); +#else len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); return; +#ifdef _WIN32 + } else + WSASetLastError( w_error ); + ioctlsocket(source, FIONBIO, &imode); +#else } fcntl(source, F_SETFL, 0); - +#endif g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, phb->host, phb->port); if (send(source, cmd, strlen(cmd), 0) < 0) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -296,7 +397,11 @@ g_snprintf(cmd, sizeof(cmd), "Proxy-Authorization: Basic %s\r\n", t2); g_free(t2); if (send(source, cmd, strlen(cmd), 0) < 0) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -306,7 +411,11 @@ g_snprintf(cmd, sizeof(cmd), "\r\n"); if (send(source, cmd, strlen(cmd), 0) < 0) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -320,6 +429,9 @@ { struct sockaddr_in *sin; int fd = -1; +#ifdef _WIN32 + u_long imode; +#endif debug_printf("connecting to %s:%d via %s:%d using HTTP\n", host, port, proxyhost, proxyport); @@ -336,29 +448,61 @@ phb->host = g_strdup(host); phb->port = port; +#ifdef _WIN32 + imode = 1; + ioctlsocket(fd, FIONBIO, &imode); +#else fcntl(fd, F_SETFL, O_NONBLOCK); +#endif if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { +#ifdef _WIN32 + int w_errno = WSAGetLastError(); + if ((w_errno == WSAEINPROGRESS) || (w_errno == WSAEINTR)) { +#else if ((errno == EINPROGRESS) || (errno == EINTR)) { +#endif debug_printf("Connect would have blocked\n"); phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, http_canwrite, phb); } else { +#ifdef _WIN32 + closesocket(fd); +#else close(fd); +#endif g_free(phb->host); g_free(phb); return -1; } } else { unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + u_long imode; +#else int error = ETIMEDOUT; +#endif debug_printf("Connect didn't block\n"); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(fd); +#else len = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(fd); +#endif g_free(phb->host); g_free(phb); return -1; +#ifdef _WIN32 + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(fd, FIONBIO, &imode); +#else } fcntl(fd, F_SETFL, 0); +#endif http_canwrite(phb, fd, GAIM_INPUT_WRITE); } @@ -373,14 +517,22 @@ gaim_input_remove(phb->inpa); memset(packet, 0, sizeof(packet)); +#ifdef _WIN32 + if (recv(source, packet, 9, 0) >= 4 && packet[1] == 90) { +#else if (read(source, packet, 9) >= 4 && packet[1] == 90) { +#endif phb->func(phb->data, source, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); return; } +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -392,23 +544,44 @@ struct hostent *hp; struct PHB *phb = data; unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + u_long imode; +#else int error = ETIMEDOUT; +#endif debug_printf("Connected\n"); if (phb->inpa > 0) gaim_input_remove(phb->inpa); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(source); +#else len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); return; +#ifdef _WIN32 + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(source, FIONBIO, &imode); +#else } fcntl(source, F_SETFL, 0); - +#endif /* XXX does socks4 not support host name lookups by the proxy? */ if (!(hp = gethostbyname(phb->host))) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -424,8 +597,13 @@ packet[6] = (unsigned char)(hp->h_addr_list[0])[2]; packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; packet[8] = 0; +#ifdef _WIN32 + if (send(source, packet, 9, 0) != 9) { + closesocket(source); +#else if (write(source, packet, 9) != 9) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -439,6 +617,10 @@ { struct sockaddr_in *sin; int fd = -1; +#ifdef _WIN32 + int werrno; + u_long imode; +#endif debug_printf("connecting to %s:%d via %s:%d using SOCKS4\n", host, port, proxyhost, proxyport); @@ -455,29 +637,61 @@ phb->host = g_strdup(host); phb->port = port; +#ifdef _WIN32 + imode=1; + ioctlsocket(fd, FIONBIO, &imode); +#else fcntl(fd, F_SETFL, O_NONBLOCK); +#endif if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { +#ifdef _WIN32 + werrno = WSAGetLastError(); + if ((werrno == WSAEINPROGRESS) || (werrno == WSAEINTR)) { +#else if ((errno == EINPROGRESS) || (errno == EINTR)) { +#endif debug_printf("Connect would have blocked\n"); phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s4_canwrite, phb); } else { +#ifdef _WIN32 + closesocket(fd); +#else close(fd); +#endif g_free(phb->host); g_free(phb); return -1; } } else { unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + u_long imode; +#else int error = ETIMEDOUT; +#endif debug_printf("Connect didn't block\n"); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(fd); +#else len = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(fd); +#endif g_free(phb->host); g_free(phb); return -1; +#ifdef _WIN32 + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(fd, FIONBIO, &imode); +#else } fcntl(fd, F_SETFL, 0); +#endif s4_canwrite(phb, fd, GAIM_INPUT_WRITE); } @@ -492,9 +706,17 @@ gaim_input_remove(phb->inpa); debug_printf("able to read again\n"); +#ifdef _WIN32 + if (recv(source, buf, 10, 0) < 10) { +#else if (read(source, buf, 10) < 10) { +#endif debug_printf("or not...\n"); +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -502,7 +724,11 @@ } if ((buf[0] != 0x05) || (buf[1] != 0x00)) { debug_printf("bad data\n"); +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -530,8 +756,13 @@ buf[5 + strlen(phb->host)] = phb->port >> 8; buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; +#ifdef _WIN32 + if (send(source, buf, (5 + strlen(phb->host) + 2), 0) < (5 + strlen(phb->host) + 2)) { + closesocket(source); +#else if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -549,8 +780,13 @@ gaim_input_remove(phb->inpa); debug_printf("got auth response\n"); +#ifdef _WIN32 + if (recv(source, buf, 2, 0) < 2) { + closesocket(source); +#else if (read(source, buf, 2) < 2) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -558,7 +794,11 @@ } if ((buf[0] != 0x01) || (buf[1] != 0x00)) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -576,8 +816,13 @@ gaim_input_remove(phb->inpa); debug_printf("able to read\n"); +#ifdef _WIN32 + if (recv(source, buf, 2, 0) < 2) { + closesocket(source); +#else if (read(source, buf, 2) < 2) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -585,7 +830,11 @@ } if ((buf[0] != 0x05) || (buf[1] == 0xff)) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -599,8 +848,13 @@ memcpy(buf + 2, proxyuser, i); buf[2 + i] = j; memcpy(buf + 2 + i + 1, proxypass, j); +#ifdef _WIN32 + if (send(source, buf, 3 + i + j, 0) < 3 + i + j) { + closesocket(source); +#else if (write(source, buf, 3 + i + j) < 3 + i + j) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -619,19 +873,37 @@ int i; struct PHB *phb = data; unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + u_long imode; +#else int error = ETIMEDOUT; +#endif debug_printf("Connected\n"); if (phb->inpa > 0) gaim_input_remove(phb->inpa); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(source); +#else len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); return; +#ifdef _WIN32 + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(source, FIONBIO, &imode); +#else } fcntl(source, F_SETFL, 0); +#endif i = 0; buf[0] = 0x05; /* SOCKS version 5 */ @@ -645,10 +917,17 @@ buf[2] = 0x00; i = 3; } - +#ifdef _WIN32 + if (send(source, buf, i, 0) < i) { +#else if (write(source, buf, i) < i) { +#endif debug_printf("unable to write\n"); +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -662,6 +941,10 @@ { struct sockaddr_in *sin; int fd = -1; +#ifdef _WIN32 + u_long imode; + int werrno; +#endif debug_printf("connecting to %s:%d via %s:%d using SOCKS5\n", host, port, proxyhost, proxyport); @@ -678,29 +961,60 @@ phb->host = g_strdup(host); phb->port = port; +#ifdef _WIN32 + imode=1; + ioctlsocket(fd, FIONBIO, &imode); +#else fcntl(fd, F_SETFL, O_NONBLOCK); +#endif if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { +#ifdef _WIN32 + werrno = WSAGetLastError(); + if ((werrno == WSAEINPROGRESS) || (werrno == WSAEINTR)) { +#else if ((errno == EINPROGRESS) || (errno == EINTR)) { +#endif debug_printf("Connect would have blocked\n"); phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s5_canwrite, phb); } else { +#ifdef _WIN32 + closesocket(fd); +#else close(fd); +#endif g_free(phb->host); g_free(phb); return -1; } } else { unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; +#else int error = ETIMEDOUT; +#endif debug_printf("Connect didn't block\n"); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(fd); +#else len = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(fd); +#endif g_free(phb->host); g_free(phb); return -1; +#ifdef _WIN32 + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(fd, FIONBIO, &imode); +#else } fcntl(fd, F_SETFL, 0); +#endif s5_canwrite(phb, fd, GAIM_INPUT_WRITE); } @@ -717,9 +1031,9 @@ g_free(phb); return -1; } - +#ifndef _WIN32 sethostent(1); - +#endif if ((proxytype == PROXY_NONE) || !proxyhost || !proxyhost[0] || !proxyport || (proxyport == -1)) return proxy_connect_none(host, port, phb); else if (proxytype == PROXY_HTTP) @@ -732,3 +1046,4 @@ g_free(phb); return -1; } + diff -r afc5bb164c5a -r 9682c0e022c6 src/proxy.h --- a/src/proxy.h Fri Oct 11 02:10:08 2002 +0000 +++ b/src/proxy.h Fri Oct 11 03:14:01 2002 +0000 @@ -26,10 +26,15 @@ #ifndef _PROXY_H_ #define _PROXY_H_ -#include +#ifndef _WIN32 #include #include #include +#else +#include +#endif + +#include #include #define PROXY_NONE 0 diff -r afc5bb164c5a -r 9682c0e022c6 src/prpl.h --- a/src/prpl.h Fri Oct 11 02:10:08 2002 +0000 +++ b/src/prpl.h Fri Oct 11 03:14:01 2002 +0000 @@ -193,7 +193,7 @@ }; extern GSList *protocols; -extern prpl_accounts[]; +extern int prpl_accounts[]; /* this is mostly just for aim.c, when it initializes the protocols */ extern void static_proto_init(); diff -r afc5bb164c5a -r 9682c0e022c6 src/sound.c --- a/src/sound.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/sound.c Fri Oct 11 03:14:01 2002 +0000 @@ -25,11 +25,18 @@ #include #include #include + +#ifndef _WIN32 #include #include -#include #include #include +#else +#include +#include +#endif + +#include #include #include @@ -80,6 +87,7 @@ SND_CHAT_YOU_SAY, SND_CHAT_SAY, SND_CHAT_NICK, 0 }; +#ifndef _WIN32 static int check_dev(char *dev) { struct stat stat_buf; @@ -410,15 +418,13 @@ } #endif +#endif /* !_WIN32 */ void play_file(char *filename) { +#ifndef _WIN32 int pid; - -#ifdef _WIN32 - return; #endif - if (sound_options & OPT_SOUND_BEEP) { gdk_beep(); return; @@ -427,7 +433,7 @@ else if (sound_options & OPT_SOUND_NORMAL) { debug_printf("attempting to play audio file with internal method -- this is unlikely to work\n"); } - +#ifndef _WIN32 pid = fork(); if (pid < 0) @@ -476,21 +482,23 @@ _exit(0); } +#else /* _WIN32 */ + debug_printf("Playing %s\n", filename); + if (!PlaySound(filename, 0, SND_ASYNC | SND_FILENAME)) + debug_printf("Error playing sound."); +#endif } void play(unsigned char *data, int size) { +#ifndef _WIN32 int pid; - -#ifdef _WIN32 - return; #endif - if (sound_options & OPT_SOUND_BEEP) { gdk_beep(); return; } - +#ifndef _WIN32 else if ((sound_options & OPT_SOUND_CMD) && sound_cmd[0]) { char command[4096]; FILE *child; @@ -556,6 +564,10 @@ _exit(0); } +#else /* _WIN32 */ + if (!PlaySound(data, 0, SND_ASYNC | SND_MEMORY)) + debug_printf("Error playing sound."); +#endif } extern int logins_not_muted; diff -r afc5bb164c5a -r 9682c0e022c6 src/util.c --- a/src/util.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/util.c Fri Oct 11 03:14:01 2002 +0000 @@ -22,15 +22,22 @@ #ifdef HAVE_CONFIG_H #include #endif + +#ifndef _WIN32 #include +#include +#include +#else +#include +#include +#endif + #include #include #include -#include #include #include #include -#include #include #ifdef HAVE_ICONV #include @@ -40,6 +47,16 @@ #include "prpl.h" #include "gtkspell.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +static char home_dir[MAXPATHLEN]; + char *full_date() { char *date; @@ -334,7 +351,9 @@ char log_all_file[256]; struct stat st; FILE *fd; +#ifndef _WIN32 int res; +#endif gchar *gaim_dir; buf = g_malloc(BUF_LONG); @@ -344,6 +363,7 @@ /* Dont log yourself */ strncpy(log_all_file, gaim_dir, 256); +#ifndef _WIN32 stat(log_all_file, &st); if (!S_ISDIR(st.st_mode)) unlink(log_all_file); @@ -358,13 +378,12 @@ do_error_dialog(buf, NULL, GAIM_ERROR); g_free(buf); g_free(buf2); - g_free(gaim_dir); return NULL; } } else fclose(fd); - g_snprintf(log_all_file, 256, "%s/logs", gaim_dir); + g_snprintf(log_all_file, 256, "%s" G_DIR_SEPARATOR_S "logs", gaim_dir); if (stat(log_all_file, &st) < 0) *flag = 1; @@ -380,15 +399,23 @@ do_error_dialog(buf, NULL, GAIM_ERROR); g_free(buf); g_free(buf2); - g_free(gaim_dir); return NULL; } } else fclose(fd); - +#else /* _WIN32 */ + g_snprintf(log_all_file, 256, "%s" G_DIR_SEPARATOR_S "logs", gaim_dir); + if( _mkdir(log_all_file) < 0 && errno != EEXIST ) { + g_snprintf(buf, BUF_LONG, "Unable to make directory %s for logging", log_all_file); + do_error_dialog(buf, NULL, GAIM_ERROR); + g_free(buf); + g_free(buf2); + return NULL; + } +#endif - g_snprintf(log_all_file, 256, "%s/logs/%s", gaim_dir, name); + g_snprintf(log_all_file, 256, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s", gaim_dir, name); if (stat(log_all_file, &st) < 0) *flag = 1; @@ -398,7 +425,6 @@ g_free(buf); g_free(buf2); - g_free(gaim_dir); return fd; } @@ -620,6 +646,7 @@ void clean_pid(void) { +#ifndef _WIN32 int status; pid_t pid, spell_pid; @@ -633,6 +660,7 @@ sprintf(errmsg, "Warning: waitpid() returned %d", pid); perror(errmsg); } +#endif } struct aim_user *find_user(const char *name, int protocol) @@ -879,12 +907,32 @@ } } +gchar *gaim_home_dir() +{ + if(g_get_home_dir()) + return g_get_home_dir(); + else +#ifndef _WIN32 + return NULL; +#else + /* Win9x and WinME don't have a home dir */ + return "C:"; +#endif + +} + /* returns a string of the form ~/.gaim, where ~ is replaced by the user's home - * dir. this string should be freed after it's used. Note that there is no - * trailing slash after .gaim. */ + * dir. Note that there is no trailing slash after .gaim. */ gchar *gaim_user_dir() { - return g_strjoin(G_DIR_SEPARATOR_S, g_get_home_dir(), ".gaim", NULL); + if(gaim_home_dir()) { + strcpy( (char*)&home_dir, gaim_home_dir() ); + strcat( (char*)&home_dir, G_DIR_SEPARATOR_S ".gaim" ); + return (gchar*)&home_dir; + } + else { + return NULL; + } } /* @@ -1243,11 +1291,24 @@ FILE *gaim_mkstemp(gchar **fpath) { const gchar *tmpdir; +#ifndef _WIN32 int fd; +#endif FILE *fp = NULL; - if((tmpdir = g_get_tmp_dir()) != NULL) { - if((*fpath = g_strdup_printf("%s/%s", tmpdir, gaim_mkstemp_templ)) != NULL) { + if((tmpdir = (gchar*)g_get_tmp_dir()) != NULL) { + if((*fpath = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", tmpdir, gaim_mkstemp_templ)) != NULL) { +#ifdef _WIN32 + char* result = _mktemp( *fpath ); + if( result == NULL ) + debug_printf("gaim_mkstemp: Problem creating the template\n"); + else + { + if( (fp = fopen( result, "w+" )) == NULL ) { + debug_printf("Error: Couldn't fopen()in gaim_mkstemp():\n%s\n", result); + } + } +#else if((fd = mkstemp(*fpath)) == -1) { debug_printf("Error: Couldn't make \"%s\", error: %d\n", *fpath, errno); } else { @@ -1256,6 +1317,7 @@ debug_printf("Error: Couldn't fdopen(), error: %d\n", errno); } } +#endif if(!fp) { g_free(*fpath); *fpath = NULL; diff -r afc5bb164c5a -r 9682c0e022c6 src/win32/MinimizeToTray.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/win32/MinimizeToTray.c Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,132 @@ +/* MinimizeToTray + * + * A couple of routines to show how to make it produce a custom caption + * animation to make it look like we are minimizing to and maximizing + * from the system tray + * + * These routines are public domain, but it would be nice if you dropped + * me a line if you use them! + * + * 1.0 29.06.2000 Initial version + * 1.1 01.07.2000 The window retains it's place in the Z-order of windows + * when minimized/hidden. This means that when restored/shown, it doen't + * always appear as the foreground window unless we call SetForegroundWindow + * + * Copyright 2000 Matthew Ellis + */ +#include "stdafx.h" + +#ifndef IDANI_OPEN +#define IDANI_OPEN 1 +#endif +#ifndef IDANI_CLOSE +#define IDANI_CLOSE 2 +#endif +#ifndef IDANI_CAPTION +#define IDANI_CAPTION 3 +#endif + +#define DEFAULT_RECT_WIDTH 150 +#define DEFAULT_RECT_HEIGHT 30 + +static void GetTrayWndRect(LPRECT lpTrayRect) +{ + APPBARDATA appBarData; + HWND hShellTrayWnd=FindWindowEx(NULL,NULL,TEXT("Shell_TrayWnd"),NULL); + + if(hShellTrayWnd) + { + HWND hTrayNotifyWnd=FindWindowEx(hShellTrayWnd,NULL,TEXT("TrayNotifyWnd"),NULL); + if(hTrayNotifyWnd) + { + GetWindowRect(hTrayNotifyWnd,lpTrayRect); + return; + } + } + + appBarData.cbSize=sizeof(appBarData); + if(SHAppBarMessage(ABM_GETTASKBARPOS,&appBarData)) + { + switch(appBarData.uEdge) + { + case ABE_LEFT: + case ABE_RIGHT: + lpTrayRect->top=appBarData.rc.bottom-100; + lpTrayRect->bottom=appBarData.rc.bottom-16; + lpTrayRect->left=appBarData.rc.left; + lpTrayRect->right=appBarData.rc.right; + break; + + case ABE_TOP: + case ABE_BOTTOM: + lpTrayRect->top=appBarData.rc.top; + lpTrayRect->bottom=appBarData.rc.bottom; + lpTrayRect->left=appBarData.rc.right-100; + lpTrayRect->right=appBarData.rc.right-16; + break; + } + + return; + } + + hShellTrayWnd=FindWindowEx(NULL,NULL,TEXT("Shell_TrayWnd"),NULL); + if(hShellTrayWnd) + { + GetWindowRect(hShellTrayWnd,lpTrayRect); + if(lpTrayRect->right-lpTrayRect->left>DEFAULT_RECT_WIDTH) + lpTrayRect->left=lpTrayRect->right-DEFAULT_RECT_WIDTH; + if(lpTrayRect->bottom-lpTrayRect->top>DEFAULT_RECT_HEIGHT) + lpTrayRect->top=lpTrayRect->bottom-DEFAULT_RECT_HEIGHT; + + return; + } + + SystemParametersInfo(SPI_GETWORKAREA,0,lpTrayRect,0); + lpTrayRect->left=lpTrayRect->right-DEFAULT_RECT_WIDTH; + lpTrayRect->top=lpTrayRect->bottom-DEFAULT_RECT_HEIGHT; +} + +static int GetDoAnimateMinimize(void) +{ + ANIMATIONINFO ai; + + ai.cbSize=sizeof(ai); + SystemParametersInfo(SPI_GETANIMATION,sizeof(ai),&ai,0); + + return ai.iMinAnimate?TRUE:FALSE; +} + +void MinimizeWndToTray(HWND hWnd) +{ + if(GetDoAnimateMinimize()) + { + RECT rcFrom,rcTo; + + GetWindowRect(hWnd,&rcFrom); + GetTrayWndRect(&rcTo); + + DrawAnimatedRects(hWnd,IDANI_CAPTION,&rcFrom,&rcTo); + } + + ShowWindow(hWnd,SW_HIDE); +} + +void RestoreWndFromTray(HWND hWnd) +{ + if(GetDoAnimateMinimize()) + { + RECT rcFrom,rcTo; + GetTrayWndRect(&rcFrom); + GetWindowRect(hWnd,&rcTo); + + DrawAnimatedRects(hWnd,IDANI_CAPTION,&rcFrom,&rcTo); + } + + ShowWindow(hWnd,SW_SHOW); + SetActiveWindow(hWnd); + SetForegroundWindow(hWnd); + +} + + + diff -r afc5bb164c5a -r 9682c0e022c6 src/win32/MinimizeToTray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/win32/MinimizeToTray.h Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,7 @@ +#ifndef _MINIMIZE_TO_TRAY_H_ +#define _MINIMIZE_TO_TRAY_H_ + +void MinimizeWndToTray(HWND hWnd); +void RestoreWndFromTray(HWND hWnd); + +#endif /* _MINIMIZE_TO_TRAY_H_ */ diff -r afc5bb164c5a -r 9682c0e022c6 src/win32/StdAfx.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/win32/StdAfx.h Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,24 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) +#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include +#include + + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) diff -r afc5bb164c5a -r 9682c0e022c6 src/win32/resource.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/win32/resource.h Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,1 @@ +#define IDI_ICON2 104 diff -r afc5bb164c5a -r 9682c0e022c6 src/win32/win32dep.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/win32/win32dep.c Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,145 @@ +/* + * win32dep.c + * + * Author: Herman Bloggs + * Date: June, 2002 + * Description: Windows dependant code for Gaim + */ +#include +#include +#include +#include +#include "gaim.h" + +#include "stdafx.h" +#include "resource.h" + +/* + * DEFINES & MACROS + */ +#define WM_TRAYMESSAGE WM_USER +#define GAIM_SYSTRAY_HINT "Gaim Instant Messenger" + +/* + * LOCALS + */ +static char install_dir[MAXPATHLEN]; +static char lib_dir[MAXPATHLEN]; +static char locale_dir[MAXPATHLEN]; +static int bhide_icon; + +/* + * GLOBALS + */ +HINSTANCE g_hInstance = 0; + +/* + * STATIC CODE + */ + +static void ShowNotifyIcon(HWND hWnd,BOOL bAdd) +{ + NOTIFYICONDATA nid; + ZeroMemory(&nid,sizeof(nid)); + nid.cbSize=sizeof(NOTIFYICONDATA); + nid.hWnd=hWnd; + nid.uID=0; + nid.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP; + nid.uCallbackMessage=WM_TRAYMESSAGE; + nid.hIcon=LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON2)); + lstrcpy(nid.szTip,TEXT(GAIM_SYSTRAY_HINT)); + + if(bAdd) + Shell_NotifyIcon(NIM_ADD,&nid); + else + Shell_NotifyIcon(NIM_DELETE,&nid); +} + +static GdkFilterReturn traymsg_filter_func( GdkXEvent *xevent, GdkEvent *event, gpointer data) +{ + MSG *msg = (MSG*)xevent; + + if( msg->lParam == WM_LBUTTONDBLCLK ) { + RestoreWndFromTray(msg->hwnd); + bhide_icon = TRUE; + return GDK_FILTER_REMOVE; + } + + if( msg->lParam == WM_LBUTTONUP ) { + if(bhide_icon) { + ShowNotifyIcon(msg->hwnd,FALSE); + bhide_icon = FALSE; + } + } + return GDK_FILTER_REMOVE; +} + +/* + * PUBLIC CODE + */ + +char* wgaim_install_dir(void) { + HMODULE hmod; + char* buf; + + hmod = GetModuleHandle(NULL); + if( hmod == 0 ) { + buf = g_win32_error_message( GetLastError() ); + debug_printf("GetModuleHandle error: %s\n", buf); + free(buf); + return NULL; + } + if(GetModuleFileName( hmod, (char*)&install_dir, MAXPATHLEN ) == 0) { + buf = g_win32_error_message( GetLastError() ); + debug_printf("GetModuleFileName error: %s\n", buf); + free(buf); + return NULL; + } + buf = g_path_get_dirname( install_dir ); + strcpy( (char*)&install_dir, buf ); + free( buf ); + + return (char*)&install_dir; +} + +char* wgaim_lib_dir(void) { + strcpy(lib_dir, wgaim_install_dir()); + strcat(lib_dir, G_DIR_SEPARATOR_S "plugins"); + return (char*)&lib_dir; +} + +char* wgaim_locale_dir(void) { + strcpy(locale_dir, wgaim_install_dir()); + strcat(locale_dir, G_DIR_SEPARATOR_S "locale"); + return (char*)&locale_dir; +} + +GdkFilterReturn wgaim_window_filter( GdkXEvent *xevent, GdkEvent *event, gpointer data) +{ + MSG *msg = (MSG*)xevent; + + switch( msg->message ) { + case WM_SYSCOMMAND: + if( msg->wParam == SC_MINIMIZE ) { + MinimizeWndToTray(msg->hwnd); + ShowNotifyIcon(msg->hwnd,TRUE); + + SetWindowLong(msg->hwnd,DWL_MSGRESULT,0); + return GDK_FILTER_REMOVE; + } + break; + case WM_CLOSE: + MinimizeWndToTray(msg->hwnd); + ShowNotifyIcon(msg->hwnd,TRUE); + return GDK_FILTER_REMOVE; + } + + return GDK_FILTER_CONTINUE; +} + +void wgaim_init(void) { + /* Filter to catch systray events */ + gdk_add_client_message_filter (GDK_POINTER_TO_ATOM (WM_TRAYMESSAGE), + traymsg_filter_func, + NULL); +} diff -r afc5bb164c5a -r 9682c0e022c6 src/win32/win32dep.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/win32/win32dep.h Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,34 @@ +/* + * win32dep.h + */ + +#ifndef _WIN32DEP_H_ +#define _WIN32DEP_H_ +#include + +extern char* wgaim_install_dir(void); +extern char* wgaim_lib_dir(void); +extern char* wgaim_locale_dir(void); +extern GdkFilterReturn wgaim_window_filter(GdkXEvent *xevent, + GdkEvent *event, + gpointer data); +extern void wgaim_init(void); + +#define unlink _unlink +#define bzero( dest, size ) memset( ## dest ##, 0, ## size ## ) +#define sleep(x) Sleep((x)*1000) +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#define DATADIR wgaim_install_dir() + +/* Needed for accessing global variables outside the current module */ +#ifdef G_MODULE_IMPORT +#undef G_MODULE_IMPORT +#endif +#define G_MODULE_IMPORT __declspec(dllimport) + +#define LIBDIR wgaim_lib_dir() +#define LOCALEDIR wgaim_locale_dir() + +#endif /* _WIN32DEP_H_ */ + diff -r afc5bb164c5a -r 9682c0e022c6 src/win_aim.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/win_aim.c Fri Oct 11 03:14:01 2002 +0000 @@ -0,0 +1,37 @@ +/* + * win_aim.c + * + * Author: Herman Bloggs + * Date: June, 2002 + * Description: Entry point for win32 gaim, and various win32 dependant + * routines. + */ +#include +#include + +/* + * GLOBALS + */ +__declspec(dllimport) HINSTANCE g_hInstance; + +/* + * PROTOTYPES + */ +extern int gaim_main( int, char** ); + +#ifdef __GNUC__ +# ifndef _stdcall +# define _stdcall __attribute__((stdcall)) +# endif +#endif + +int _stdcall +WinMain (struct HINSTANCE__ *hInstance, + struct HINSTANCE__ *hPrevInstance, + char *lpszCmdLine, + int nCmdShow) +{ + g_hInstance = hInstance; + return gaim_main (__argc, __argv); +} +