changeset 3630:9682c0e022c6

[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 <tailor@pidgin.im>
author Rob Flynn <gaim@robflynn.com>
date Fri, 11 Oct 2002 03:14:01 +0000
parents afc5bb164c5a
children 29ef47dafb48
files ChangeLog.win32 Makefile.mingw PROGRAMMING_NOTES README.mingw VERSION gaim-installer.nsi pixmaps/gaim-install.ico pixmaps/gaim.ico plugins/Makefile.mingw plugins/autorecon.c plugins/chatlist.c plugins/iconaway.c plugins/spellchk.c plugins/ticker/Makefile.mingw plugins/ticker/ticker.c po/Makefile.mingw sounds/BuddyArrive.wav sounds/BuddyLeave.wav sounds/Makefile.mingw sounds/Receive.wav sounds/RedAlert.wav sounds/Send.wav src/about.c src/aim.c src/browser.c src/buddy.c src/conversation.c src/core.c src/dialogs.c src/ft.c src/gaim.h src/gaimrc.c src/gtkimhtml.c src/gtkspell.c src/html.c src/list.c src/module.c src/multi.c src/perl.c src/prefs.c src/protocols/gg/Makefile.mingw src/protocols/gg/common.c src/protocols/gg/gg.c src/protocols/gg/libgg.c src/protocols/irc/Makefile.mingw src/protocols/irc/irc.c src/protocols/jabber/Makefile.mingw src/protocols/jabber/jabber.c src/protocols/jabber/jabber.h src/protocols/jabber/lib.h src/protocols/jabber/libxode.h src/protocols/jabber/socket.c src/protocols/jabber/win32/posix.uname.c src/protocols/jabber/win32/utsname.h src/protocols/msn/Makefile.mingw src/protocols/msn/msn.c src/protocols/napster/Makefile.mingw src/protocols/napster/napster.c src/protocols/oscar/Makefile.mingw src/protocols/oscar/aim.h src/protocols/oscar/aim_internal.h src/protocols/oscar/conn.c src/protocols/oscar/ft.c src/protocols/oscar/im.c src/protocols/oscar/meta.c src/protocols/oscar/oscar.c src/protocols/oscar/ssi.c src/protocols/oscar/txqueue.c src/protocols/toc/Makefile.mingw src/protocols/toc/toc.c src/protocols/yahoo/Makefile.mingw src/protocols/yahoo/yahoo.c src/protocols/zephyr/ZVariables.c src/protocols/zephyr/zephyr.c src/proxy.c src/proxy.h src/prpl.h src/sound.c src/util.c src/win32/MinimizeToTray.c src/win32/MinimizeToTray.h src/win32/StdAfx.h src/win32/resource.h src/win32/win32dep.c src/win32/win32dep.h src/win_aim.c
diffstat 86 files changed, 5746 insertions(+), 642 deletions(-) [+]
line wrap: on
line diff
--- /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
--- /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
--- /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)
--- /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 .. <all zip files>
+  
+  $ 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 <hermanator12002@yahoo.com>
+  
+
+
+
+  
+  
--- /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
--- /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
+
Binary file pixmaps/gaim-install.ico has changed
Binary file pixmaps/gaim.ico has changed
--- /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
--- 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);
--- 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 <stdlib.h>
 #include <string.h>
+#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.";
--- 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 <gtk/gtk.h>
 
+#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.";
 }
--- 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 <sys/types.h>
 #include <unistd.h>
 #include <fcntl.h>
+#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 &lt;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 &lt;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;
--- /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
--- 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);
--- /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
Binary file sounds/BuddyArrive.wav has changed
Binary file sounds/BuddyLeave.wav has changed
--- /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
Binary file sounds/Receive.wav has changed
Binary file sounds/RedAlert.wav has changed
Binary file sounds/Send.wav has changed
--- 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 */
 
--- 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 <config.h>
 #endif
 #ifdef GAIM_PLUGINS
+#ifndef _WIN32
 #include <dlfcn.h>
+#endif
 #endif /* GAIM_PLUGINS */
 #include <gtk/gtk.h>
+#ifdef _WIN32
+#include <winsock.h>
+#else
 #include <gdk/gdkx.h>
-#include <gdk/gdk.h>
 #include <unistd.h>
-#include <sys/types.h>
 #include <sys/socket.h>
-#include <sys/stat.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <errno.h>
 #include <sys/un.h>
 #include <sys/wait.h>
+#endif /* _WIN32 */
+#include <gdk/gdk.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
@@ -51,6 +57,9 @@
 #include "locale.h"
 #include "gtkspell.h"
 #include <getopt.h>
+#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 */
 
--- 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 <config.h>
 #endif
+#ifdef _WIN32
+#include <gdk/gdkwin32.h>
+#else
+#include <unistd.h>
+#include <gdk/gdkx.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
 
 
@@ -40,7 +45,6 @@
 
 #include <gtk/gtk.h>
 #include <gdk/gdkprivate.h>
-#include <gdk/gdkx.h>
 #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);
 }
 
 
--- 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 <config.h>
 #endif
 #ifdef GAIM_PLUGINS
+#ifndef _WIN32
 #include <dlfcn.h>
+#endif
 #endif /* GAIM_PLUGINS */
 #include <string.h>
 #include <stdio.h>
@@ -31,13 +33,24 @@
 #include <ctype.h>
 #include <math.h>
 #include <time.h>
+#include <ctype.h>
+
+#ifdef _WIN32
+#include <gdk/gdkwin32.h>
+#else
 #include <unistd.h>
-#include <ctype.h>
+#include <gdk/gdkx.h>
+#endif
 
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
 #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()
--- 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 <config.h>
 #endif
 #include <string.h>
+#ifndef _WIN32
 #include <sys/time.h>
+#include <unistd.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+#else
+#ifdef small
+#undef small
+#endif
+#endif /*_WIN32*/
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <ctype.h>
-#include <gdk/gdkx.h>
-#include <X11/Xlib.h>
 #include <gtk/gtk.h>
 #include "gtkimhtml.h"
 #include <gdk/gdkkeysyms.h>
@@ -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;
--- 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 <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
+
+#ifdef _WIN32
+#include <winsock.h>
+#include <io.h>
+#else
 #include <sys/socket.h>
-#include <sys/stat.h>
 #include <sys/un.h>
 #include <unistd.h>
+#endif
+
+#include <sys/stat.h>
 #include <errno.h>
 #include <signal.h>
 #include <getopt.h>
@@ -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
 }
--- 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 <string.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <ctype.h>
+
+#ifdef _WIN32
+#include <winsock.h>
+#else
 #include <sys/socket.h>
+#include <time.h>
 #include <netdb.h>
 #include <netinet/in.h>
 #include <unistd.h>
-#include <netinet/in.h>
 #include <arpa/inet.h>
+#endif
+
 #include <errno.h>
 #include <math.h>
 
@@ -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);
 	}
--- 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;
--- 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);
--- 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 <config.h>
 #endif
 #include <string.h>
+
+#ifndef _WIN32
 #include <sys/time.h>
+#include <unistd.h>
+#endif
 
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #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");
 }
 
 
--- 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 <config.h>
 #endif
 #include "gtkimhtml.h"
+
+#ifndef _WIN32
 #include <X11/Xlib.h>
+#include <gdk/gdkx.h>
+#else
+#include <gdk/gdkwin32.h>
+#endif
+
 #include <stdlib.h>
-#include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 #include <string.h>
 #include <ctype.h>
@@ -36,6 +42,12 @@
 #include <locale.h>
 #endif
 
+#ifdef _WIN32
+/* GDK_SELECTION_PRIMARY is ignored win32 GTK */
+#undef GDK_SELECTION_PRIMARY
+#define GDK_SELECTION_PRIMARY GDK_SELECTION_CLIPBOARD
+#endif
+
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gdk-pixbuf/gdk-pixbuf-loader.h>
 
@@ -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;
--- 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 <gtk/gtk.h>
 
 #include <sys/types.h>
+
+#ifndef _WIN32
 #include <sys/wait.h>
 #include <sys/time.h>
-#include <unistd.h>   
+#include <unistd.h>
+#else
+#include <io.h>
+#endif   
+
 #include <stdio.h>    
 #include <signal.h>
 #include <ctype.h>
@@ -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;
 }
 
--- 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 <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+
+#ifndef _WIN32
 #include <sys/time.h>
 #include <unistd.h>
-#include "gaim.h"
-#include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
 #include <netinet/in.h>
+#else
+#include <winsock.h>
+#include <io.h>
+#endif
+
+#include <sys/types.h>
 #include <fcntl.h>
 #include <errno.h>
+#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);
--- 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 <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifndef _WIN32
 #include <unistd.h>
+#else
+#include <direct.h>
+#include <io.h>
+#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)
--- 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 <stdio.h>
 #include <stdlib.h>
 
+#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) {
--- 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);
 	}
 
--- 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 <EXTERN.h>
 #ifndef _SEM_SEMUN_UNDEFINED
 #define HAS_UNION_SEMUN
 #endif
 #include <perl.h>
 #include <XSUB.h>
+#ifndef _WIN32
 #include <sys/mman.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #undef PACKAGE
 #include <stdio.h>
+#ifndef _WIN32
 #include <dirent.h>
+#else
+/* We're using perl's win32 port of this */
+#define dirent direct
+#endif
 #include <string.h>
 
 #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 {
--- 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), _("<span size=\"larger\">%s %s</span>\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), _("<span size=\"larger\">%s %s</span>\n\n"
-				       "<span weight=\"bold\">Written by:</span>\t%s\n"
-				       "<span weight=\"bold\">URL:</span>\t%s\n"
-				       "<span weight=\"bold\">File name:</span>\t %s"),
+	g_snprintf(buf, sizeof(buf), 
+#ifndef _WIN32
+		   _("<span size=\"larger\">%s %s</span>\n\n"
+		     "<span weight=\"bold\">Written by:</span>\t%s\n"
+		     "<span weight=\"bold\">URL:</span>\t%s\n"
+		     "<span weight=\"bold\">File name:</span>\t%s"),
+#else
+		   _("<span size=\"larger\">%s %s</span>\n\n"
+		     "<span weight=\"bold\">Written by:</span>  %s\n"
+		     "<span weight=\"bold\">URL:</span>  %s\n"
+		     "<span weight=\"bold\">File name:</span>  %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));
--- /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
--- 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 <wojtekka@irc.pl>,
@@ -20,21 +20,24 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#ifndef _WIN32
 #include <unistd.h>
-#include <stdio.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <netdb.h>
 #include <sys/ioctl.h>
+#include <pwd.h>
 #include <sys/wait.h>
+#else
+#include <winsock.h>
+#endif
 #include <sys/time.h>
-#include <netdb.h>
 #include <errno.h>
 #ifndef _AIX
 #  include <string.h>
 #endif
 #include <stdarg.h>
-#include <pwd.h>
 #include <time.h>
 #ifdef sun
   #include <sys/filio.h>
@@ -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++;
--- 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 <misiek@pld.ORG.PL>
  * 
@@ -24,17 +24,22 @@
 #include <config.h>
 #endif
 
+#ifndef _WIN32
 #include <netdb.h>
 #include <unistd.h>
-#include <errno.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sys/socket.h>
+#else
+#include <winsock.h>
+#endif
+
+#include <errno.h>
 #include <fcntl.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
-#include <sys/socket.h>
 #include <sys/stat.h>
 #include <ctype.h>
 #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;
--- 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 <wojtekka@irc.pl>,
@@ -18,23 +18,29 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
+#ifndef _WIN32
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/ioctl.h>
 #include <sys/wait.h>
+#include <netdb.h>
+#include <pwd.h>
+#else
+#include <winsock.h>
+#include <fcntl.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
 #include <sys/time.h>
-#include <netdb.h>
 #include <errno.h>
 #ifndef _AIX
 #  include <string.h>
 #endif
 #include <stdarg.h>
-#include <pwd.h>
 #include <time.h>
 #ifdef sun
   #include <sys/filio.h>
@@ -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;
--- /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
--- 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 <config.h>
 
+#ifndef _WIN32
+#include <unistd.h>
+#else
+#include <winsock.h>
+#endif
+
 #include <fcntl.h>
-#include <unistd.h>
 #include <errno.h>
 #include <string.h>
 #include <stdlib.h>
@@ -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;
--- /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
--- 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 <config.h>
 #endif
 
-
+#ifndef _WIN32
 #include <netdb.h>
-#include <unistd.h>
-#include <errno.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#else
+#include <winsock.h>
+#include "utsname.h"
+#endif
+
+#include <errno.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
-#include <sys/socket.h>
-#include <sys/utsname.h>
 #include <sys/stat.h>
 #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, "</stream:stream>");
 	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;
--- 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 <syslog.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <strings.h>
+#include <unistd.h>
+#else
+#include <winsock.h>
+#include "win32dep.h"
+#endif
 
 #include <string.h>
 #include <stdlib.h>
@@ -27,13 +39,6 @@
 #include <errno.h>
 #include <signal.h>
 #include <stdarg.h>
-#include <syslog.h>
-#include <strings.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
 #include <sys/time.h>
 #include <time.h>
 #include <ctype.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 <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifndef _WIN32
+#include <syslog.h>
+#include <strings.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#else
+#include <winsock.h>
+#include <stdlib.h>
+#include "win32dep.h"
+#endif
 
 #include <string.h>
 #include <stdlib.h>
@@ -8,14 +26,6 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <signal.h>
-#include <syslog.h>
-#include <strings.h>
-#include <unistd.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
 #include <sys/time.h>
 #include <stdarg.h>
 #include <ctype.h>
@@ -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
 
 
 /* --------------------------------------------------------- */
--- 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 <syslog.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <strings.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <unistd.h>
+#else
+
+#endif
+
 #include <string.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -7,15 +21,6 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <signal.h>
-#include <syslog.h>
-#include <strings.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
 #include <sys/time.h>
 #include <time.h>
 
@@ -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
 
 
 /* --------------------------------------------------------- */
--- 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
 
--- /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 <earnie_boyd@yahoo.com>
+ */
+
+#include "utsname.h"
+#include <string.h>
+#include <stdio.h>
+
+/* 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 <windows.h>
+#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;
+}
+
--- /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
--- /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
--- 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 <unistd.h>
+#else
+#include <winsock.h>
+#include <io.h>
+#endif
+
+
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <ctype.h>
 #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, "<html>\n");
-		fprintf(fd, "<head>\n");
-		fprintf(fd, "<noscript>\n");
-		fprintf(fd, "<meta http-equiv=Refresh content=\"0; url=http://www.hotmail.com\">\n");
-		fprintf(fd, "</noscript>\n");
-		fprintf(fd, "</head>\n\n");
+		if( (fd = gaim_mkstemp(&(md->passport))) == NULL ) {
+		  debug_printf("Error opening temp file\n"); 
+		}
+		else {
+		        fprintf(fd, "<html>\n");
+		        fprintf(fd, "<head>\n");
+		        fprintf(fd, "<noscript>\n");
+		        fprintf(fd, "<meta http-equiv=Refresh content=\"0; url=http://www.hotmail.com\">\n");
+		        fprintf(fd, "</noscript>\n");
+		        fprintf(fd, "</head>\n\n");
 		
-		fprintf(fd, "<body onload=\"document.pform.submit(); \">\n");
-		fprintf(fd, "<form name=\"pform\" action=\"%s\" method=\"POST\">\n\n", passport);
-		fprintf(fd, "<input type=\"hidden\" name=\"mode\" value=\"ttl\">\n");
-		fprintf(fd, "<input type=\"hidden\" name=\"login\" value=\"%s\">\n", gc->username);
-		fprintf(fd, "<input type=\"hidden\" name=\"username\" value=\"%s\">\n", gc->username);
-		fprintf(fd, "<input type=\"hidden\" name=\"sid\" value=\"%s\">\n", md->sid);
-		fprintf(fd, "<input type=\"hidden\" name=\"kv\" value=\"%s\">\n", md->kv);
-		fprintf(fd, "<input type=\"hidden\" name=\"id\" value=\"2\">\n");
-		fprintf(fd, "<input type=\"hidden\" name=\"sl\" value=\"%ld\">\n", time(NULL) - md->sl);
-		fprintf(fd, "<input type=\"hidden\" name=\"rru\" value=\"%s\">\n", rru);
-		fprintf(fd, "<input type=\"hidden\" name=\"auth\" value=\"%s\">\n", md->mspauth);
-		fprintf(fd, "<input type=\"hidden\" name=\"creds\" value=\"%s\">\n", sendbuf); // Digest me
-		fprintf(fd, "<input type=\"hidden\" name=\"svc\" value=\"mail\">\n");
-		fprintf(fd, "<input type=\"hidden\" name=\"js\" value=\"yes\">\n");
-		fprintf(fd, "</form></body>\n");
-		fprintf(fd, "</html>\n");
-		fclose(fd);
-
+		        fprintf(fd, "<body onload=\"document.pform.submit(); \">\n");
+		        fprintf(fd, "<form name=\"pform\" action=\"%s\" method=\"POST\">\n\n", passport);
+		        fprintf(fd, "<input type=\"hidden\" name=\"mode\" value=\"ttl\">\n");
+		        fprintf(fd, "<input type=\"hidden\" name=\"login\" value=\"%s\">\n", gc->username);
+		        fprintf(fd, "<input type=\"hidden\" name=\"username\" value=\"%s\">\n", gc->username);
+			fprintf(fd, "<input type=\"hidden\" name=\"sid\" value=\"%s\">\n", md->sid);
+			fprintf(fd, "<input type=\"hidden\" name=\"kv\" value=\"%s\">\n", md->kv);
+			fprintf(fd, "<input type=\"hidden\" name=\"id\" value=\"2\">\n");
+			fprintf(fd, "<input type=\"hidden\" name=\"sl\" value=\"%ld\">\n", time(NULL) - md->sl);
+			fprintf(fd, "<input type=\"hidden\" name=\"rru\" value=\"%s\">\n", rru);
+			fprintf(fd, "<input type=\"hidden\" name=\"auth\" value=\"%s\">\n", md->mspauth);
+			fprintf(fd, "<input type=\"hidden\" name=\"creds\" value=\"%s\">\n", sendbuf); // Digest me
+			fprintf(fd, "<input type=\"hidden\" name=\"svc\" value=\"mail\">\n");
+			fprintf(fd, "<input type=\"hidden\" name=\"js\" value=\"yes\">\n");
+			fprintf(fd, "</form></body>\n");
+			fprintf(fd, "</html>\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");
 }
--- /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
--- 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 <config.h>
 
+#ifndef _WIN32
 #include <netdb.h>
 #include <unistd.h>
-#include <errno.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sys/socket.h>
+#else
+#include <winsock.h>
+#endif
+
+#include <errno.h>
 #include <time.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
-#include <sys/socket.h>
 #include <sys/stat.h>
 #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;
--- /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
--- 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 <errno.h>
 #include <time.h>
 
-#ifdef _WIN32
-#include <windows.h>
-#include <io.h>
-#else
+#ifndef _WIN32
 #include <sys/time.h>
 #include <unistd.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
+#else
+#include <winsock.h>
 #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);
--- 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 *);
--- 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 <netdb.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#else
+#include <winsock.h>
 #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)))
--- 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 <sys/socket.h>
 #include <netinet/in.h>
 #include <sys/utsname.h> /* for aim_directim_initiate */
+#include <arpa/inet.h> /* for inet_ntoa */
+#else
+#include "win32dep.h"
+#endif
 
-#include <arpa/inet.h> /* 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<bufferlen;i++){
+        oldcheck = check;
+        if(i&1){
+            val = buffer[i];
+        } else {
+            val = buffer[i] << 8;
+        }
+        check -= val;
+        /*  The follownig appears to be necessary....  It happens every once in a while and the checksum doesn't fail. */
+        if(check > 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 */
 }
 
--- 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 <aim.h>
 
+#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;
--- 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 <aim.h>
 
+#ifdef _WIN32
+#include "win32dep.h"
+#endif
+
 faim_export char *aim_getbuilddate(void)
 {
 	return AIM_BUILDDATE;
--- 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 <config.h>
 #endif
 
-
+#ifndef _WIN32
 #include <netdb.h>
-#include <unistd.h>
-#include <errno.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#else
+#include <winsock.h>
+#endif
+
+#include <errno.h>
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
-#include <sys/socket.h>
 #include <sys/stat.h>
+#include <signal.h>
+
 #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;
--- 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;
 	}
--- 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 <sys/socket.h>
+#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;
 
--- /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
--- 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 <config.h>
 #endif
+
+#ifndef _WIN32
 #include <netdb.h>
-#include <gtk/gtk.h>
 #include <unistd.h>
-#include <errno.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sys/socket.h>
+#else
+#include <winsock.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <errno.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
-#include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #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);
--- /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
--- 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 <netdb.h>
 #include <unistd.h>
-#include <errno.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sys/socket.h>
+#else
+#include <winsock.h>
+#endif
+
+#include <errno.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
-#include <sys/socket.h>
 #include <sys/stat.h>
 #include <ctype.h>
 #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;
--- 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 {
--- 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);
--- 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 <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
+
+#ifndef _WIN32
 #include <sys/socket.h>
 #include <netdb.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <unistd.h>
+#else
+#include <winsock.h>
+#endif
+
 #include <fcntl.h>
 #include <errno.h>
 #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;
 }
+
--- 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 <sys/types.h>
+#ifndef _WIN32
 #include <sys/socket.h>
 #include <netdb.h>
 #include <netinet/in.h>
+#else
+#include <winsock.h>
+#endif
+
+#include <sys/types.h>
 #include <glib.h>
 
 #define PROXY_NONE 0
--- 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();
--- 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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
+#ifndef _WIN32
 #include <sys/time.h>
 #include <unistd.h>
-#include <fcntl.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#else
+#include <windows.h>
+#include <mmsystem.h>
+#endif
+
+#include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -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;
--- 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 <config.h>
 #endif
+
+#ifndef _WIN32
 #include <unistd.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#else
+#include <direct.h>
+#include <io.h>
+#endif
+
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <sys/time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <string.h>
-#include <sys/wait.h>
 #include <ctype.h>
 #ifdef HAVE_ICONV
 #include <iconv.h>
@@ -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;
--- /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 <m.t.ellis@bigfoot.com>
+ */
+#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);
+
+}
+
+
+
--- /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_ */
--- /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 <windows.h>
+#include <shellapi.h>
+
+
+// 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_)
--- /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
--- /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 <hermanator12002@yahoo.com>
+ *  Date: June, 2002
+ *  Description: Windows dependant code for Gaim
+ */
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#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);
+}
--- /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 <gdk/gdkevents.h>
+
+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_ */
+
--- /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 <hermanator12002@yahoo.com>
+ *  Date: June, 2002
+ *  Description: Entry point for win32 gaim, and various win32 dependant
+ *  routines.
+ */
+#include <windows.h>
+#include <stdlib.h>
+
+/*
+ *  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);
+}
+