changeset 198:73e9a0bfff62

[gaim-migrate @ 208] Moved all the RVOUS stuff into rvous.c (mostly to reduce the size of dialogs.c). Started trying to implement FILE_GET_UID, without much luck. I'm going to do some dumps of the win client tomorrow to see if I can figure out what's going on a little better. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sun, 30 Apr 2000 10:39:35 +0000
parents 24f0fef56a73
children be5fbefdb195
files src/Makefile.am src/dialogs.c src/gaim.h src/rvous.c src/toc.c
diffstat 5 files changed, 670 insertions(+), 401 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Sun Apr 30 00:52:53 2000 +0000
+++ b/src/Makefile.am	Sun Apr 30 10:39:35 2000 +0000
@@ -2,14 +2,14 @@
 bin_PROGRAMS = gaim_applet
 gaim_applet_SOURCES = about.c aim.c away.c browser.c buddy.c buddy_chat.c \
 	conversation.c dialogs.c gaimrc.c gnome_applet_mgr.c gtkhtml.c \
-	html.c idle.c network.c oscar.c plugins.c prefs.c proxy.c server.c \
-	sound.c toc.c util.c
+	html.c idle.c network.c oscar.c plugins.c prefs.c proxy.c rvous.c \
+	server.c sound.c toc.c util.c
 else
 bin_PROGRAMS = gaim
 gaim_SOURCES = about.c aim.c away.c browser.c buddy.c buddy_chat.c \
 	conversation.c dialogs.c gaimrc.c gnome_applet_mgr.c gtkhtml.c \
-	html.c idle.c network.c oscar.c plugins.c prefs.c proxy.c server.c \
-	sound.c toc.c util.c
+	html.c idle.c network.c oscar.c plugins.c prefs.c proxy.c rvous.c \
+	server.c sound.c toc.c util.c
 endif
 
 
--- a/src/dialogs.c	Sun Apr 30 00:52:53 2000 +0000
+++ b/src/dialogs.c	Sun Apr 30 10:39:35 2000 +0000
@@ -41,8 +41,6 @@
 static GList *dialogwindows = NULL;
 static GtkWidget *linkdialog, *colordialog, *exportdialog, *importdialog, *logdialog;
 
-static void accept_callback(GtkWidget *widget, struct file_transfer *t);
-
 struct create_away {
         GtkWidget *window;
         GtkWidget *entry;
@@ -2192,385 +2190,3 @@
 
 
 }
-
-/*------------------------------------------------------------------------*/
-/*  The dialog for file requests                                          */
-/*------------------------------------------------------------------------*/
-
-
-static void cancel_callback(GtkWidget *widget, struct file_transfer *ft)
-{
-	char *send = g_malloc(256);
-
-	if (ft->accepted) {
-		g_free(send);
-		return;
-	}
-	
-	g_snprintf(send, 255, "toc_rvous_cancel %s %s %s", ft->user, ft->cookie, FILE_SEND_UID);
-	sflap_send(send, strlen(send), TYPE_DATA);
-	g_free(send);
-	destroy_dialog(NULL, ft->window);
-	g_free(ft->user);
-	if (ft->message)
-		g_free(ft->message);
-	g_free(ft->filename);
-	g_free(ft->cookie);
-	g_free(ft->ip);
-        g_free(ft);
-}
-
-
-static void warn_callback(GtkWidget *widget, struct file_transfer *ft)
-{
-        show_warn_dialog(ft->user);
-}
-
-static void info_callback(GtkWidget *widget, struct file_transfer *ft)
-{
-        serv_get_info(ft->user);
-}
-
-static char *put_16_int(gint i) {
-        static char tmp[2];
-        g_snprintf(tmp, 2, "%c%c", i >> 8,  i & 0xff);
-        return tmp;
-}
-
-static char *put_32_int(gint i) {
-        static char tmp[4];
-        g_snprintf(tmp, 4, "%c%c%c%c", (i >> 24) & 0xff, (i >> 16) & 0xff, (i >> 8) & 0xff, i & 0xff);
-        return tmp;
-}
-
-
-static int get_16_int(char *text)
-{
-        int tmp = 0;
-	tmp = ((*text << 8) & 0xff00);
-	text++;
-	tmp |= (*text & 0xff);
-        text++;
-        return tmp;
-}
-
-static int get_32_int(char *text)
-{
-        int tmp = 0;
-	tmp = ((*text << 24) & 0xff000000);
-	text++;
-	tmp |= ((*text << 16) & 0xff0000);
-	text++;
-	tmp |= ((*text << 8) & 0xff00);
-	text++;
-	tmp |= (*text & 0xff);
-        text++;
-        return tmp;
-}
-	
-static void do_accept(GtkWidget *w, struct file_transfer *ft)
-{
-	char *send = g_malloc(256);
-	char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(ft->window));
-	char *buf;
-	char *header;
-	short hdrlen;
-	int read_rv;
-	char bmagic[7];
-	struct sockaddr_in sin;
-	guint32 rcv;
-	guint32 size;
-        char *c;
-	GtkWidget *fw = NULL, *fbar = NULL, *label;
-        
-	if (!(ft->f = fopen(file,"w"))) {
-		buf = g_malloc(BUF_LONG);
-                g_snprintf(buf, BUF_LONG / 2, "Error writing file %s", file);
-		do_error_dialog(buf, "Error");
-		g_free(buf);
-		ft->accepted = 0;
-		accept_callback(NULL, ft);
-		return;
-	}
-
-	ft->accepted = 1;
-	
-	destroy_dialog(NULL, ft->window);
-	g_snprintf(send, 255, "toc_rvous_accept %s %s %s", ft->user, ft->cookie, FILE_SEND_UID);
-	sflap_send(send, strlen(send), TYPE_DATA);
-	g_free(send);
-
-	
-
-        sin.sin_addr.s_addr = inet_addr(ft->ip);
-        sin.sin_family = AF_INET;
-	sin.sin_port = htons(ft->port);
-	
-	ft->fd = socket(AF_INET, SOCK_STREAM, 0);
-	
-	if (ft->fd <= -1 || connect(ft->fd, (struct sockaddr_in *)&sin, sizeof(sin))) {
-		return;
-	}
-
-	rcv = 0;
-	header = g_malloc(6);
-	while (rcv != 6) {
-		read_rv = read(ft->fd, header + rcv, 6 - rcv);
-		if(read_rv < 0) {
-			close(ft->fd);
-			g_free(header);
-			return;
-		}
-		rcv += read_rv;
-		while(gtk_events_pending())
-			gtk_main_iteration();
-	}
-
-	strncpy(bmagic, header, 6);
-        bmagic[6] = 0;
-
-	hdrlen = get_16_int(&header[4]);
-	hdrlen -= 6;
-	sprintf(debug_buff, "my header is %d\n", hdrlen);
-	debug_print(debug_buff);
-
-	hdrlen = 0;
-	hdrlen = header[4];
-	hdrlen <<= 8;
-	hdrlen |= header[5];
-	hdrlen -= 6;
-
-	sprintf(debug_buff, "header length %d\n", hdrlen);
-	debug_print(debug_buff);
-
-	g_free(header);
-	header = g_malloc(hdrlen);
-
-	rcv = 0;
-
-	while (rcv != hdrlen) {
-		read_rv = read(ft->fd, header + rcv, hdrlen - rcv);
-		if(read_rv < 0) {
-			close(ft->fd);
-			g_free(header);
-			return;
-		}
-		rcv += read_rv;
-		while(gtk_events_pending())
-			gtk_main_iteration();
-	}
-
-        c = header;
-
-	header[0] = 2; header[1] = 2;
-	memcpy(header + 2, ft->cookie, 8);
-	memset(header + 62, 0, 32); strcpy(header + 62, "Gaim");
-	memset(header + 10, 0, 4);
-	header[18] = 1; header[19] = 0;
-	header[20] = 1; header[21] = 0;
-
-	sprintf(debug_buff, "sending confirmation\n");
-	debug_print(debug_buff);
-	write(ft->fd, bmagic, 6);
-	write(ft->fd, header, hdrlen);
-
-	buf = g_malloc(1024);
-	rcv = 0;
-	
-	fw = gtk_dialog_new();
-	buf = g_malloc(2048);
-	snprintf(buf, 2048, "Receiving %s from %s (%d bytes)", ft->filename,
-			ft->user, ft->size);
-	label = gtk_label_new(buf);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->vbox), label, 0, 0, 5);
-	gtk_widget_show(label);
-	fbar = gtk_progress_bar_new();
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->action_area), fbar, 0, 0, 5);
-	gtk_widget_show(fbar);
-	gtk_window_set_title(GTK_WINDOW(fw), "File Transfer");
-	gtk_widget_realize(fw);
-	aol_icon(fw->window);
-	gtk_widget_show(fw);
-
-	size = get_32_int(header + 22);
-	sprintf(debug_buff, "Receiving %s from %s (%d bytes)\n", ft->filename,
-			ft->user, ft->size);
-	debug_print(debug_buff);
-
-	while (rcv != ft->size) {
-		int i;
-		int remain = size - rcv > 1024 ? 1024 : size - rcv;
-		read_rv = read(ft->fd, buf, remain);
-		if(read_rv < 0) {
-			fclose(ft->f);
-			close(ft->fd);
-			g_free(buf);
-			g_free(header);
-			return;
-		}
-		rcv += read_rv;
-		for (i = 0; i < read_rv; i++)
-			fprintf(ft->f, "%c", buf[i]);
-		snprintf(buf, 2048, "Receiving %s from %s (%d / %d bytes)",
-				header + 186, ft->user, rcv, ft->size);
-		gtk_label_set_text(GTK_LABEL(label), buf);
-		gtk_progress_bar_update(GTK_PROGRESS_BAR(fbar),
-					(float)(rcv)/(float)(ft->size));
-		while(gtk_events_pending())
-			gtk_main_iteration();
-	}
-
-	fclose(ft->f);
-	memset(header + 18, 0, 4);
-	header[94] = 0;
-	header[1] = 0x04;
-	memcpy(header+58, header+34, 4);
-	memcpy(header+54, header+22, 4);
-	write(ft->fd, bmagic, 6);
-	write(ft->fd, header, hdrlen);
-	close(ft->fd);
-
-	g_free(buf);
-	g_free(header);
-	gtk_widget_destroy(fw);
-}
-
-
-static void accept_callback(GtkWidget *widget, struct file_transfer *ft)
-{
-	char *buf = g_malloc(BUF_LEN);
-	char *fname = g_malloc(BUF_LEN);
-	char *c;
-
-	c = ft->filename + strlen(ft->filename);
-
-	while (c != ft->filename) {
-		if (*c == '/' || *c == '\\') {
-			strcpy(fname, c+1);
-			break;
-		}
-		c--;
-	}
-
-	if (c == ft->filename)
-                strcpy(fname, ft->filename);
-
-	
-	destroy_dialog(NULL, ft->window);
-	
-	ft->window = gtk_file_selection_new("Gaim - Save As...");
-
-	gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(ft->window));
-
-	g_snprintf(buf, BUF_LEN - 1, "%s/%s", getenv("HOME"), fname);
-
-	gtk_file_selection_set_filename(GTK_FILE_SELECTION(ft->window), buf);
-	gtk_signal_connect(GTK_OBJECT(ft->window), "destroy",
-			   GTK_SIGNAL_FUNC(cancel_callback), ft);
-                
-	gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(ft->window)->ok_button),
-			   "clicked", GTK_SIGNAL_FUNC(do_accept), ft);
-	gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(ft->window)->cancel_button),
-			   "clicked", GTK_SIGNAL_FUNC(cancel_callback), ft);
-
-        dialogwindows = g_list_prepend(dialogwindows, ft->window);
-
-	gtk_widget_show(ft->window);
-	
-	g_free(buf);
-	g_free(fname);
-
-}
-
-
-
-
-void accept_file_dialog(struct file_transfer *ft)
-{
-        GtkWidget *accept, *info, *warn, *cancel;
-        GtkWidget *text = NULL, *sw;
-        GtkWidget *label;
-        GtkWidget *vbox, *bbox;
-        char buf[1024];
-
-        
-        ft->window = gtk_window_new(GTK_WINDOW_DIALOG);
-        dialogwindows = g_list_prepend(dialogwindows, ft->window);
-
-        accept = gtk_button_new_with_label("Accept");
-        info = gtk_button_new_with_label("Info");
-        warn = gtk_button_new_with_label("Warn");
-        cancel = gtk_button_new_with_label("Cancel");
-
-        bbox = gtk_hbox_new(TRUE, 10);
-        vbox = gtk_vbox_new(FALSE, 5);
-
-        gtk_widget_show(accept);
-        gtk_widget_show(info);
-        gtk_widget_show(warn);
-        gtk_widget_show(cancel);
-
-        gtk_box_pack_start(GTK_BOX(bbox), accept, TRUE, TRUE, 10);
-        gtk_box_pack_start(GTK_BOX(bbox), info, TRUE, TRUE, 10);
-        gtk_box_pack_start(GTK_BOX(bbox), warn, TRUE, TRUE, 10);
-        gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 10);
-
-        g_snprintf(buf, sizeof(buf), "%s requests you to accept the file: %s (%d bytes)",
-                   ft->user, ft->filename, ft->size);
-        label = gtk_label_new(buf);
-        gtk_widget_show(label);
-        gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 5);
-        
-        if (ft->message) {
-		/* we'll do this later
-                text = gaim_new_layout();
-                sw = gtk_scrolled_window_new (NULL, NULL);
-                gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
-                                                GTK_POLICY_NEVER,
-                                                GTK_POLICY_AUTOMATIC);
-                gtk_widget_show(sw);
-                gtk_container_add(GTK_CONTAINER(sw), text);
-                gtk_widget_show(text);
-
-                gtk_layout_set_size(GTK_LAYOUT(text), 250, 100);
-                GTK_LAYOUT (text)->vadjustment->step_increment = 10.0;
-                gtk_widget_set_usize(sw, 250, 100);
-
-                gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 10);
-		*/
-        }
-        gtk_box_pack_start(GTK_BOX(vbox), bbox, TRUE, TRUE, 5);
-
-        gtk_window_set_title(GTK_WINDOW(ft->window), "Gaim - Accept File?");
-        gtk_window_set_focus(GTK_WINDOW(ft->window), accept);
-        gtk_container_add(GTK_CONTAINER(ft->window), vbox);
-        gtk_container_border_width(GTK_CONTAINER(ft->window), 10);
-        gtk_widget_show(vbox);
-        gtk_widget_show(bbox);
-        gtk_widget_realize(ft->window);
-        aol_icon(ft->window->window);
-
-        gtk_widget_show(ft->window);
-
-
-	gtk_signal_connect(GTK_OBJECT(accept), "clicked",
-			   GTK_SIGNAL_FUNC(accept_callback), ft);
-	gtk_signal_connect(GTK_OBJECT(cancel), "clicked",
-			   GTK_SIGNAL_FUNC(cancel_callback), ft);
-	gtk_signal_connect(GTK_OBJECT(warn), "clicked",
-			   GTK_SIGNAL_FUNC(warn_callback), ft);
-	gtk_signal_connect(GTK_OBJECT(info), "clicked",
-			   GTK_SIGNAL_FUNC(info_callback), ft);
-
-
-	if (ft->message) {
-		/* we'll do this later
-		while(gtk_events_pending())
-			gtk_main_iteration();
-		html_print(text, ft->message);
-		*/
-	}
-
-
-
-}
--- a/src/gaim.h	Sun Apr 30 00:52:53 2000 +0000
+++ b/src/gaim.h	Sun Apr 30 10:39:35 2000 +0000
@@ -234,6 +234,37 @@
         time_t sent_away;
 };
 
+struct file_header {
+	short hdrtype;		/* 0 */
+	char  bcookie[8];	/* 2 */
+	short encrypt;		/* 10 */
+	short compress;		/* 12 */
+	short totfiles;		/* 14 */
+	short filesleft;	/* 16 */
+	short totparts;		/* 18 */
+	short partsleft;	/* 20 */
+	long  totsize;		/* 22 */
+	long  size;		/* 26 */
+	long  modtime;		/* 30 */
+	long  checksum;		/* 34 */
+	long  rfrcsum;		/* 38 */
+	long  rfsize;		/* 42 */
+	long  cretime;		/* 46 */
+	long  rfcsum;		/* 50 */
+	long  nrecvd;		/* 54 */
+	long  recvcsum;		/* 58 */
+	char  idstring[32];	/* 62 */
+	char  flags;		/* 94 */
+	char  lnameoffset;	/* 95 */
+	char  lsizeoffset;	/* 96 */
+	char  dummy[69];	/* 97 */
+	char  macfileinfo[16];	/* 166 */
+	short nencode;		/* 182 */
+	short nlanguage;	/* 184 */
+	char  name[64];		/* 186 */
+				/* 250 */
+};
+
 struct file_transfer {
         GtkWidget *window;
         char *cookie;
@@ -247,6 +278,7 @@
         char *user;
         FILE *f;
         int fd;
+	char UID[2048];
 };
 
 struct sflap_hdr {
@@ -300,7 +332,7 @@
 #define TYPE_SIGNOFF   4
 #define TYPE_KEEPALIVE 5
 
-#define REVISION "gaim:$Revision: 207 $"
+#define REVISION "gaim:$Revision: 208 $"
 #define FLAPON "FLAPON\r\n\r\n"
 
 #define ROAST "Tic/Toc"
@@ -613,12 +645,14 @@
 extern void show_set_info();
 extern void show_set_dir();
 extern void show_color_dialog(GtkWidget *entrye, GtkWidget *color);
-extern void accept_file_dialog(struct file_transfer *);
 extern void create_away_mess(GtkWidget *, void *);
 extern void show_ee_dialog(int);
 extern void show_add_link(GtkWidget *, GtkWidget *);
 extern void show_change_passwd();
 
+/* Functions in rvous.c */
+extern void accept_file_dialog(struct file_transfer *);
+
 /* Functions in browser.c */
 extern void open_url(GtkWidget *, char *);
 extern void open_url_nw(GtkWidget *, char *);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/rvous.c	Sun Apr 30 10:39:35 2000 +0000
@@ -0,0 +1,610 @@
+/*
+ * gaim
+ *
+ * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h> 
+#include <unistd.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <gtk/gtk.h>
+#include "gaim.h"
+
+static void do_send_file(GtkWidget *, struct file_transfer *);
+static void do_get_file (GtkWidget *, struct file_transfer *);
+
+static void warn_callback(GtkWidget *widget, struct file_transfer *ft)
+{
+        show_warn_dialog(ft->user);
+}
+
+static void info_callback(GtkWidget *widget, struct file_transfer *ft)
+{
+        serv_get_info(ft->user);
+}
+
+static void cancel_callback(GtkWidget *widget, struct file_transfer *ft)
+{
+	char *send = g_malloc(256);
+
+	if (ft->accepted) {
+		g_free(send);
+		return;
+	}
+	
+	g_snprintf(send, 255, "toc_rvous_cancel %s %s %s", normalize(ft->user),
+			ft->cookie, ft->UID);
+	sflap_send(send, strlen(send), TYPE_DATA);
+	g_free(send);
+	gtk_widget_destroy(ft->window);
+	ft->window = NULL;
+	g_free(ft->user);
+	if (ft->message)
+		g_free(ft->message);
+	g_free(ft->filename);
+	if (ft->cookie) g_free(ft->cookie);
+	g_free(ft->ip);
+        g_free(ft);
+}
+
+static void accept_callback(GtkWidget *widget, struct file_transfer *ft)
+{
+	char *buf = g_malloc(BUF_LEN);
+	char *fname = g_malloc(BUF_LEN);
+	char *c;
+
+	if (!strcmp(ft->UID, FILE_SEND_UID)) {
+		c = ft->filename + strlen(ft->filename);
+
+		while (c != ft->filename) {
+			if (*c == '/' || *c == '\\') {
+				strcpy(fname, c+1);
+				break;
+			}
+			c--;
+		}
+
+		if (c == ft->filename)
+	                strcpy(fname, ft->filename);
+	}
+	
+	gtk_widget_destroy(ft->window);
+	ft->window = NULL;
+	
+	ft->window = gtk_file_selection_new("Gaim - Save As...");
+
+	gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(ft->window));
+
+	if (!strcmp(ft->UID, FILE_SEND_UID))
+		g_snprintf(buf, BUF_LEN - 1, "%s/%s", getenv("HOME"), fname);
+	else
+		g_snprintf(buf, BUF_LEN - 1, "%s/", getenv("HOME"));
+	gtk_file_selection_set_filename(GTK_FILE_SELECTION(ft->window), buf);
+
+	gtk_signal_connect(GTK_OBJECT(ft->window), "destroy",
+			   GTK_SIGNAL_FUNC(cancel_callback), ft);
+                
+	if (!strcmp(ft->UID, FILE_SEND_UID)) {
+		gtk_signal_connect(GTK_OBJECT(
+				GTK_FILE_SELECTION(ft->window)->ok_button),
+			        "clicked", GTK_SIGNAL_FUNC(do_get_file), ft);
+	} else {
+		gtk_signal_connect(GTK_OBJECT(
+				GTK_FILE_SELECTION(ft->window)->ok_button),
+				"clicked", GTK_SIGNAL_FUNC(do_send_file), ft);
+	}
+	gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(ft->window)->cancel_button),
+			   "clicked", GTK_SIGNAL_FUNC(cancel_callback), ft);
+
+	gtk_widget_show(ft->window);
+	
+	g_free(buf);
+	g_free(fname);
+}
+
+static void do_get_file(GtkWidget *w, struct file_transfer *ft)
+{
+	char *send = g_malloc(256);
+	char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(ft->window));
+	char *buf;
+	char *header;
+	short hdrlen;
+	int read_rv;
+	char bmagic[7];
+	struct sockaddr_in sin;
+	guint32 rcv;
+        char *c;
+	GtkWidget *fw = NULL, *fbar = NULL, *label;
+        
+	if (!(ft->f = fopen(file,"w"))) {
+		buf = g_malloc(BUF_LONG);
+                g_snprintf(buf, BUF_LONG / 2, "Error writing file %s", file);
+		do_error_dialog(buf, "Error");
+		g_free(buf);
+		ft->accepted = 0;
+		accept_callback(NULL, ft);
+		return;
+	}
+
+	ft->accepted = 1;
+	
+	gtk_widget_destroy(ft->window);
+	ft->window = NULL;
+	g_snprintf(send, 255, "toc_rvous_accept %s %s %s", normalize(ft->user),
+			ft->cookie, ft->UID);
+	sflap_send(send, strlen(send), TYPE_DATA);
+	g_free(send);
+
+	
+
+        sin.sin_addr.s_addr = inet_addr(ft->ip);
+        sin.sin_family = AF_INET;
+	sin.sin_port = htons(ft->port);
+	
+	ft->fd = socket(AF_INET, SOCK_STREAM, 0);
+	
+	if (ft->fd <= -1 || connect(ft->fd, (struct sockaddr_in *)&sin, sizeof(sin))) {
+		return;
+	}
+
+	rcv = 0;
+	header = g_malloc(6);
+	while (rcv != 6) {
+		read_rv = read(ft->fd, header + rcv, 6 - rcv);
+		if(read_rv < 0) {
+			close(ft->fd);
+			g_free(header);
+			return;
+		}
+		rcv += read_rv;
+		while(gtk_events_pending())
+			gtk_main_iteration();
+	}
+
+	strncpy(bmagic, header, 6);
+        bmagic[6] = 0;
+
+	hdrlen = 0;
+	hdrlen |= (header[4] << 8) & 0xff00;
+	hdrlen |= (header[5] << 0) & 0x00ff;
+	hdrlen -= 6;
+
+	sprintf(debug_buff, "header length %d\n", hdrlen);
+	debug_print(debug_buff);
+
+	g_free(header);
+	header = g_malloc(hdrlen);
+
+	rcv = 0;
+
+	while (rcv != hdrlen) {
+		read_rv = read(ft->fd, header + rcv, hdrlen - rcv);
+		if(read_rv < 0) {
+			close(ft->fd);
+			g_free(header);
+			return;
+		}
+		rcv += read_rv;
+		while(gtk_events_pending())
+			gtk_main_iteration();
+	}
+
+	c = header;
+
+	header[0] = 2; header[1] = 2;
+	
+	buf = frombase64(ft->cookie);
+	memcpy(header + 2, buf, 8);
+	g_free(buf);
+	memset(header + 62, 0, 32); strcpy(header + 62, "Gaim");
+	memset(header + 10, 0, 4);
+	header[18] = 1; header[19] = 0;
+	header[20] = 1; header[21] = 0;
+
+	sprintf(debug_buff, "sending confirmation\n");
+	debug_print(debug_buff);
+	write(ft->fd, bmagic, 6);
+	write(ft->fd, header, hdrlen);
+
+	buf = g_malloc(1024);
+	rcv = 0;
+	
+	fw = gtk_dialog_new();
+	buf = g_malloc(2048);
+	snprintf(buf, 2048, "Receiving %s from %s (%d bytes)", ft->filename,
+			ft->user, ft->size);
+	label = gtk_label_new(buf);
+	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->vbox), label, 0, 0, 5);
+	gtk_widget_show(label);
+	fbar = gtk_progress_bar_new();
+	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->action_area), fbar, 0, 0, 5);
+	gtk_widget_show(fbar);
+	gtk_window_set_title(GTK_WINDOW(fw), "File Transfer");
+	gtk_widget_realize(fw);
+	aol_icon(fw->window);
+	gtk_widget_show(fw);
+
+	sprintf(debug_buff, "Receiving %s from %s (%d bytes)\n", ft->filename,
+			ft->user, ft->size);
+	debug_print(debug_buff);
+
+	while (rcv != ft->size) {
+		int i;
+		int remain = ft->size - rcv > 1024 ? 1024 : ft->size - rcv;
+		read_rv = read(ft->fd, buf, remain);
+		if(read_rv < 0) {
+			fclose(ft->f);
+			close(ft->fd);
+			g_free(buf);
+			g_free(header);
+			return;
+		}
+		rcv += read_rv;
+		for (i = 0; i < read_rv; i++)
+			fprintf(ft->f, "%c", buf[i]);
+		snprintf(buf, 2048, "Receiving %s from %s (%d / %d bytes)",
+				header + 186, ft->user, rcv, ft->size);
+		gtk_label_set_text(GTK_LABEL(label), buf);
+		gtk_progress_bar_update(GTK_PROGRESS_BAR(fbar),
+					(float)(rcv)/(float)(ft->size));
+		while(gtk_events_pending())
+			gtk_main_iteration();
+	}
+
+	fclose(ft->f);
+	memset(header + 18, 0, 4);
+	header[94] = 0;
+	header[1] = 0x04;
+	memcpy(header+58, header+34, 4);
+	memcpy(header+54, header+22, 4);
+	write(ft->fd, bmagic, 6);
+	write(ft->fd, header, hdrlen);
+	close(ft->fd);
+
+	g_free(buf);
+	g_free(header);
+	gtk_widget_destroy(fw);
+	g_free(ft->cookie);
+	g_free(ft->ip);
+	if (ft->message)
+		g_free(ft->message);
+	g_free(ft->filename);
+	g_free(ft->user);
+	g_free(ft);
+}
+
+static void do_send_file(GtkWidget *w, struct file_transfer *ft) {
+	char *send = g_malloc(256);
+	char *file = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(ft->window)));
+	char *buf;
+	char *header;
+	short hdrlen;
+	int read_rv;
+	char bmagic[7];
+	struct file_header *fhdr = g_new0(struct file_header, 1);
+	struct sockaddr_in sin;
+	guint32 rcv;
+	char *c;
+	GtkWidget *fw = NULL, *fbar = NULL, *label;
+	struct stat st;
+
+	stat(file, &st);
+	if (!(ft->f = fopen(file, "r"))) {
+		buf = g_malloc(BUF_LONG);
+		g_snprintf(buf, BUF_LONG / 2, "Error reading file %s", file);
+		do_error_dialog(buf, "Error");
+		g_free(buf);
+		ft->accepted = 0;
+		accept_callback(NULL, ft);
+		return;
+	}
+
+	ft->accepted = 1;
+
+	gtk_widget_destroy(ft->window);
+	ft->window = NULL;
+	g_snprintf(send, 255, "toc_rvous_accept %s %s %s", normalize(ft->user),
+			ft->cookie, ft->UID);
+	sflap_send(send, strlen(send), TYPE_DATA);
+	g_free(send);
+
+
+
+	sin.sin_addr.s_addr = inet_addr(ft->ip);
+	sin.sin_family = AF_INET;
+	sin.sin_port = htons(ft->port);
+
+	ft->fd = socket(AF_INET, SOCK_STREAM, 0);
+
+	if (ft->fd <= -1 || connect(ft->fd, (struct sockaddr_in *)&sin, sizeof(sin))) {
+		return;
+	}
+
+	/* here's where we differ from do_get_file */
+	/* 1. build/send header
+	 * 2. receive header
+	 * 3. send header again
+	 * 4. send file
+	 * 5. receive header
+	 */
+
+	/* 1. build/send header */
+	buf = frombase64(ft->cookie);
+	sprintf(debug_buff, "Building header to send %s\n", file);
+	debug_print(debug_buff);
+	fhdr->hdrtype = 0x101;
+	snprintf(fhdr->bcookie, 9, "%s", buf);
+	g_free(buf);
+	fhdr->encrypt = htons(0);
+	fhdr->compress = htons(0);
+	fhdr->totfiles = htons(1);
+	fhdr->filesleft = htons(1);
+	fhdr->totparts = htons(1);
+	fhdr->partsleft = htons(1);
+	fhdr->totsize = htonl((long)(st.st_size));
+	fhdr->size = htonl((long)(st.st_size));
+	fhdr->modtime = htonl(0);
+	fhdr->checksum = htonl(0); /* FIXME? */
+	fhdr->rfrcsum = htonl(0);
+	fhdr->rfsize = htonl(0);
+	fhdr->cretime = htonl(0);
+	fhdr->rfcsum = htonl(0);
+	fhdr->nrecvd = htonl(0);
+	fhdr->recvcsum = htonl(0);
+	snprintf(fhdr->idstring, 32, "Gaim");
+	fhdr->flags = 0x20; /* don't ask me why */
+	fhdr->lnameoffset = htonl(0);
+	fhdr->lsizeoffset = htonl(0);
+	snprintf(fhdr->dummy, 69, "");
+	snprintf(fhdr->macfileinfo, 16, "");
+	fhdr->nencode = htons(0);
+	fhdr->nlanguage = htons(0);
+	c = &file[strlen(file) - 1];
+	while (*(c - 1) != '/') c--;
+	snprintf(fhdr->name, 64, "%s", c);
+	snprintf(bmagic, 7, "GAIM\001\000");
+	read_rv = write(ft->fd, bmagic, 6);
+	if (read_rv <= -1) {
+		sprintf(debug_buff, "Couldn't write opening header \n");
+		debug_print(debug_buff);
+		close(ft->fd);
+		return;
+	}
+	read_rv = write(ft->fd, fhdr, 250);
+	if (read_rv <= -1) {
+		sprintf(debug_buff, "Couldn't write opening header 2\n");
+		debug_print(debug_buff);
+		close(ft->fd);
+		return;
+	}
+
+	/* 2. receive header */
+	sprintf(debug_buff, "Receiving header\n");
+	debug_print(debug_buff);
+	read_rv = read(ft->fd, bmagic, 6);
+	if (read_rv <= -1) {
+		sprintf(debug_buff, "Couldn't read header\n");
+		debug_print(debug_buff);
+		close(ft->fd);
+		return;
+	}
+	read_rv = read(ft->fd, fhdr, *(short *)&bmagic[4]);
+	if (read_rv <= -1) {
+		sprintf(debug_buff, "Couldn't read header 2\n");
+		debug_print(debug_buff);
+		close(ft->fd);
+		return;
+	}
+
+	/* 3. send header again */
+	fhdr->hdrtype = 0x303;
+	fhdr->encrypt = htons(0);
+	fhdr->compress = htons(0);
+	snprintf(fhdr->idstring, 32, "Gaim");
+	read_rv = write(ft->fd, bmagic, 6);
+	if (read_rv <= -1) {
+		sprintf(debug_buff, "Couldn't write ack header\n");
+		debug_print(debug_buff);
+		close(ft->fd);
+		return;
+	}
+	read_rv = write(ft->fd, fhdr, 250);
+	if (read_rv <= -1) {
+		sprintf(debug_buff, "Couldn't write ack header 2\n");
+		debug_print(debug_buff);
+		close(ft->fd);
+		return;
+	}
+
+	/* 4. send file */
+	sprintf(debug_buff, "Sending file\n");
+	debug_print(debug_buff);
+	rcv = 0;
+	buf = g_malloc(2048);
+	fw = gtk_dialog_new();
+	snprintf(buf, 2048, "Sendin %s to %s (%d bytes)", fhdr->name,
+			ft->user, fhdr->size);
+	label = gtk_label_new(buf);
+	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->vbox), label, 0, 0, 5);
+	gtk_widget_show(label);
+	fbar = gtk_progress_bar_new();
+	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->action_area), fbar, 0, 0, 5);
+	gtk_widget_show(fbar);
+	gtk_window_set_title(GTK_WINDOW(fw), "File Transfer");
+	gtk_widget_realize(fw);
+	aol_icon(fw->window);
+	gtk_widget_show(fw);
+
+	sprintf(debug_buff, "Sending %s to %s (%d bytes)\n", fhdr->name,
+			ft->user, ntohl(fhdr->size));
+	debug_print(debug_buff);
+
+	while (rcv != st.st_size) {
+		int i;
+		int remain = st.st_size - rcv > 1024 ? 1024 : st.st_size - rcv;
+		for (i = 0; i < remain; i++)
+			fscanf(ft->f, "%c", &buf[i]);
+		read_rv = write(ft->fd, buf, remain);
+		if (read_rv <= -1) {
+			sprintf(debug_buff, "Could not send file, wrote %d\n", rcv);
+			debug_print(debug_buff);
+			close(ft->fd);
+			gtk_widget_destroy(fw);
+			return;
+		}
+		rcv += read_rv;
+		snprintf(buf, 2048, "Sending %s to %s (%d / %d bytes)",
+				fhdr->name, ft->user, rcv, st.st_size);
+		gtk_label_set_text(GTK_LABEL(label), buf);
+		gtk_progress_bar_update(GTK_PROGRESS_BAR(fbar),
+				(float)(rcv)/(float)(ft->size));
+		while(gtk_events_pending())
+			gtk_main_iteration();
+	}
+	gtk_widget_destroy(fw);
+
+	/* 5. receive header */
+	sprintf(debug_buff, "Receiving closing header\n");
+	debug_print(debug_buff);
+	read_rv = read(ft->fd, bmagic, 6);
+	if (read_rv <= -1) {
+		sprintf(debug_buff, "Couldn't read closing header\n");
+		debug_print(debug_buff);
+		close(ft->fd);
+		return;
+	}
+	read_rv = read(ft->fd, fhdr, *(short *)&bmagic[4]);
+	if (read_rv <= -1) {
+		sprintf(debug_buff, "Couldn't read closing header 2\n");
+		debug_print(debug_buff);
+		close(ft->fd);
+		return;
+	}
+
+	fclose(ft->f);
+	close(ft->fd);
+	g_free(fhdr);
+	g_free(ft->cookie);
+	g_free(ft->ip);
+	if (ft->message)
+		g_free(ft->message);
+	g_free(ft->user);
+	g_free(ft);
+}
+
+void accept_file_dialog(struct file_transfer *ft)
+{
+        GtkWidget *accept, *info, *warn, *cancel;
+        GtkWidget *text = NULL, *sw;
+        GtkWidget *label;
+        GtkWidget *vbox, *bbox;
+        char buf[1024];
+
+        
+        ft->window = gtk_window_new(GTK_WINDOW_DIALOG);
+
+        accept = gtk_button_new_with_label("Accept");
+        info = gtk_button_new_with_label("Info");
+        warn = gtk_button_new_with_label("Warn");
+        cancel = gtk_button_new_with_label("Cancel");
+
+        bbox = gtk_hbox_new(TRUE, 10);
+        vbox = gtk_vbox_new(FALSE, 5);
+
+        gtk_widget_show(accept);
+        gtk_widget_show(info);
+        gtk_widget_show(warn);
+        gtk_widget_show(cancel);
+
+        gtk_box_pack_start(GTK_BOX(bbox), accept, TRUE, TRUE, 10);
+        gtk_box_pack_start(GTK_BOX(bbox), info, TRUE, TRUE, 10);
+        gtk_box_pack_start(GTK_BOX(bbox), warn, TRUE, TRUE, 10);
+        gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 10);
+
+	if (!strcmp(ft->UID, FILE_SEND_UID)) {
+	        g_snprintf(buf, sizeof(buf), "%s requests you to accept the file: %s (%d bytes)",
+				ft->user, ft->filename, ft->size);
+	} else {
+		g_snprintf(buf, sizeof(buf), "%s requests you to send them a file",
+				ft->user);
+	}
+        label = gtk_label_new(buf);
+        gtk_widget_show(label);
+        gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 5);
+        
+        if (ft->message) {
+		/* we'll do this later
+                text = gaim_new_layout();
+                sw = gtk_scrolled_window_new (NULL, NULL);
+                gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+                                                GTK_POLICY_NEVER,
+                                                GTK_POLICY_AUTOMATIC);
+                gtk_widget_show(sw);
+                gtk_container_add(GTK_CONTAINER(sw), text);
+                gtk_widget_show(text);
+
+                gtk_layout_set_size(GTK_LAYOUT(text), 250, 100);
+                GTK_LAYOUT (text)->vadjustment->step_increment = 10.0;
+                gtk_widget_set_usize(sw, 250, 100);
+
+                gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 10);
+		*/
+        }
+        gtk_box_pack_start(GTK_BOX(vbox), bbox, TRUE, TRUE, 5);
+
+        gtk_window_set_title(GTK_WINDOW(ft->window), "Gaim - File Transfer?");
+        gtk_window_set_focus(GTK_WINDOW(ft->window), accept);
+        gtk_container_add(GTK_CONTAINER(ft->window), vbox);
+        gtk_container_border_width(GTK_CONTAINER(ft->window), 10);
+        gtk_widget_show(vbox);
+        gtk_widget_show(bbox);
+        gtk_widget_realize(ft->window);
+        aol_icon(ft->window->window);
+
+        gtk_widget_show(ft->window);
+
+
+	gtk_signal_connect(GTK_OBJECT(accept), "clicked",
+			   GTK_SIGNAL_FUNC(accept_callback), ft);
+	gtk_signal_connect(GTK_OBJECT(cancel), "clicked",
+			   GTK_SIGNAL_FUNC(cancel_callback), ft);
+	gtk_signal_connect(GTK_OBJECT(warn), "clicked",
+			   GTK_SIGNAL_FUNC(warn_callback), ft);
+	gtk_signal_connect(GTK_OBJECT(info), "clicked",
+			   GTK_SIGNAL_FUNC(info_callback), ft);
+
+
+	if (ft->message) {
+		/* we'll do this later
+		while(gtk_events_pending())
+			gtk_main_iteration();
+		html_print(text, ft->message);
+		*/
+	}
+}
--- a/src/toc.c	Sun Apr 30 00:52:53 2000 +0000
+++ b/src/toc.c	Sun Apr 30 10:39:35 2000 +0000
@@ -628,7 +628,7 @@
 
 	                ft = g_new0(struct file_transfer, 1);
 
-	                ft->cookie = frombase64(cookie);
+	                ft->cookie = g_strdup(cookie);
 	                ft->ip = g_strdup(pip);
 	                ft->port = port;
 	                if (i)
@@ -638,6 +638,7 @@
 	                ft->filename = g_strdup(name);
 	                ft->user = g_strdup(user);
 	                ft->size = totalsize;
+			sprintf(ft->UID, "%s", FILE_SEND_UID);
                 
 	                g_free(tmp);
 
@@ -647,16 +648,24 @@
 	                accept_file_dialog(ft);
 		} else if (!strcmp(uuid, FILE_GET_UID)) {
 			/* we're sending a file */
-			/* FIXME */
-			/* here's what needs to happen:
-			 * 1. dialog to accept/reject transfer
-			 * 2. if cancel, toc_rvous_cancel
-			 * 3. if accept, first open a socket, then accept
-			 *    a. on connect, send header
-			 *    b. wait for header
-			 *    c. send file
-			 *    d. wait for info
-			 */
+			ft = g_new0(struct file_transfer, 1);
+
+			ft->cookie = g_strdup(cookie);
+			ft->ip = g_strdup(pip);
+			ft->port = port;
+			if (i)
+				ft->message = g_strdup(messages[0]);
+			else
+				ft->message = NULL;
+			ft->user = g_strdup(user);
+			sprintf(ft->UID, "%s", FILE_GET_UID);
+
+			g_free(tmp);
+
+			for (i--; i >= 0; i--)
+				g_free(messages[i]);
+
+			accept_file_dialog(ft);
 		/*
 		} else if (!strcmp(uuid, VOICE_UID)) {
 		} else if (!strcmp(uuid, B_ICON_UID)) {