# HG changeset patch # User Eric Warmenhoven # Date 981026955 0 # Node ID c6f9d0cdaa00a1df440ca2909ec6fff1d742219b # Parent 6650776468b3ef1fcc47bfd1ce6076a325686af9 [gaim-migrate @ 1467] all of toc in one file; rewritten file transfer. no get file yet; just send file. but why would you want to send files to people anyway? ;) committer: Tailor Script diff -r 6650776468b3 -r c6f9d0cdaa00 src/Makefile.am --- a/src/Makefile.am Thu Feb 01 08:37:16 2001 +0000 +++ b/src/Makefile.am Thu Feb 01 11:29:15 2001 +0000 @@ -22,7 +22,6 @@ prefs.c \ proxy.c \ prpl.c \ - rvous.c \ server.c \ sound.c \ ticker.c \ @@ -54,7 +53,6 @@ prefs.c \ proxy.c \ prpl.c \ - rvous.c \ server.c \ sound.c \ ticker.c \ diff -r 6650776468b3 -r c6f9d0cdaa00 src/gaim.h --- a/src/gaim.h Thu Feb 01 08:37:16 2001 +0000 +++ b/src/gaim.h Thu Feb 01 11:29:15 2001 +0000 @@ -354,34 +354,9 @@ gboolean is_chat; }; -struct file_transfer { - GtkWidget *window; - char *cookie; - char *ip; - char *message; - int port; - int size; - int accepted; - char *filename; - char *lfilename; - char *user; - FILE *f; - int fd; - char UID[2048]; - struct gaim_connection *gc; -}; - #define CONVERSATION_TITLE "Gaim - %s" #define LOG_CONVERSATION_TITLE "Gaim - %s (logged)" -#define VOICE_UID "09461341-4C7F-11D1-8222-444553540000" -#define FILE_SEND_UID "09461343-4C7F-11D1-8222-444553540000" -#define IMAGE_UID "09461345-4C7F-11D1-8222-444553540000" -#define B_ICON_UID "09461346-4C7F-11D1-8222-444553540000" -#define STOCKS_UID "09461347-4C7F-11D1-8222-444553540000" -#define FILE_GET_UID "09461348-4C7F-11D1-8222-444553540000" -#define GAMES_UID "0946134a-4C7F-11D1-8222-444553540000" - #define AOL_SRCHSTR "/community/aimcheck.adp/url=" /* These should all be runtime selectable */ @@ -809,9 +784,6 @@ extern void apply_font(GtkWidget *widget, GtkFontSelection *fontsel); extern void set_color_selection(GtkWidget *selection, GdkColor color); -/* 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 *); diff -r 6650776468b3 -r c6f9d0cdaa00 src/prpl.c --- a/src/prpl.c Thu Feb 01 08:37:16 2001 +0000 +++ b/src/prpl.c Thu Feb 01 11:29:15 2001 +0000 @@ -138,7 +138,6 @@ gtk_container_add(GTK_CONTAINER(window), vbox); label = gtk_label_new(text); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); hbox = gtk_hbox_new(FALSE, 5); diff -r 6650776468b3 -r c6f9d0cdaa00 src/rvous.c --- a/src/rvous.c Thu Feb 01 08:37:16 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,742 +0,0 @@ -/* - * gaim - * - * Copyright (C) 1998-1999, Mark Spencer - * - * 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 - * - */ - -#ifdef HAVE_CONFIG_H -#include "../config.h" -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "proxy.h" -#include "gaim.h" - -#define TYPE_DATA 2 /* from toc.c */ - -struct file_header { - char magic[4]; /* 0 */ - short hdrlen; /* 4 */ - short hdrtype; /* 6 */ - char bcookie[8]; /* 8 */ - short encrypt; /* 16 */ - short compress; /* 18 */ - short totfiles; /* 20 */ - short filesleft; /* 22 */ - short totparts; /* 24 */ - short partsleft; /* 26 */ - long totsize; /* 28 */ - long size; /* 32 */ - long modtime; /* 36 */ - long checksum; /* 40 */ - long rfrcsum; /* 44 */ - long rfsize; /* 48 */ - long cretime; /* 52 */ - long rfcsum; /* 56 */ - long nrecvd; /* 60 */ - long recvcsum; /* 64 */ - char idstring[32]; /* 68 */ - char flags; /* 100 */ - char lnameoffset; /* 101 */ - char lsizeoffset; /* 102 */ - char dummy[69]; /* 103 */ - char macfileinfo[16]; /* 172 */ - short nencode; /* 188 */ - short nlanguage; /* 190 */ - char name[64]; /* 192 */ - /* 256 */ -}; - -static void do_send_file(GtkWidget *, struct file_transfer *); -static void do_get_file (GtkWidget *, struct file_transfer *); -extern int sflap_send(struct gaim_connection *, char *, int, int); - -static int snpa = -1; - -static void toggle(GtkWidget *w, int *m) -{ - *m = !(*m); -} - -static void free_ft(struct file_transfer *ft) -{ - if (ft->window) { gtk_widget_destroy(ft->window); ft->window = NULL; } - if (ft->filename) g_free(ft->filename); - if (ft->user) g_free(ft->user); - if (ft->message) g_free(ft->message); - if (ft->ip) g_free(ft->ip); - if (ft->cookie) g_free(ft->cookie); - g_free(ft); -} - -static void warn_callback(GtkWidget *widget, struct file_transfer *ft) -{ - show_warn_dialog(ft->gc, ft->user); -} - -static void info_callback(GtkWidget *widget, struct file_transfer *ft) -{ - serv_get_info(ft->gc, ft->user); -} - -static void cancel_callback(GtkWidget *widget, struct file_transfer *ft) -{ - char buf[MSG_LEN]; - - if (ft->accepted) { - return; - } - - g_snprintf(buf, MSG_LEN, "toc_rvous_cancel %s %s %s", ft->user, ft->cookie, ft->UID); - sflap_send(ft->gc, buf, -1, TYPE_DATA); - - free_ft(ft); -} - -static void accept_callback(GtkWidget *widget, struct file_transfer *ft) -{ - char buf[BUF_LEN]; - char fname[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); -} - -static int read_file_header(int fd, struct file_header *header) { - char buf[257]; - int read_rv = read(fd, buf, 256); - if (read_rv < 0) - return read_rv; - memcpy(&header->magic, buf + 0, 4); - memcpy(&header->hdrlen, buf + 4, 2); - memcpy(&header->hdrtype, buf + 6, 2); - memcpy(&header->bcookie, buf + 8, 8); - memcpy(&header->encrypt, buf + 16, 2); - memcpy(&header->compress, buf + 18, 2); - memcpy(&header->totfiles, buf + 20, 2); - memcpy(&header->filesleft, buf + 22, 2); - memcpy(&header->totparts, buf + 24, 2); - memcpy(&header->partsleft, buf + 26, 2); - memcpy(&header->totsize, buf + 28, 4); - memcpy(&header->size, buf + 32, 4); - memcpy(&header->modtime, buf + 36, 4); - memcpy(&header->checksum, buf + 40, 4); - memcpy(&header->rfrcsum, buf + 44, 4); - memcpy(&header->rfsize, buf + 48, 4); - memcpy(&header->cretime, buf + 52, 4); - memcpy(&header->rfcsum, buf + 56, 4); - memcpy(&header->nrecvd, buf + 60, 4); - memcpy(&header->recvcsum, buf + 64, 4); - memcpy(&header->idstring, buf + 68, 32); - memcpy(&header->flags, buf + 100, 1); - memcpy(&header->lnameoffset, buf + 101, 1); - memcpy(&header->lsizeoffset, buf + 102, 1); - memcpy(&header->dummy, buf + 103, 69); - memcpy(&header->macfileinfo, buf + 172, 16); - memcpy(&header->nencode, buf + 188, 2); - memcpy(&header->nlanguage, buf + 190, 2); - memcpy(&header->name, buf + 192, 64); - return read_rv; -} - -static int write_file_header(int fd, struct file_header *header) { - char buf[257]; - memcpy(buf + 0, &header->magic, 4); - memcpy(buf + 4, &header->hdrlen, 2); - memcpy(buf + 6, &header->hdrtype, 2); - memcpy(buf + 8, &header->bcookie, 8); - memcpy(buf + 16, &header->encrypt, 2); - memcpy(buf + 18, &header->compress, 2); - memcpy(buf + 20, &header->totfiles, 2); - memcpy(buf + 22, &header->filesleft, 2); - memcpy(buf + 24, &header->totparts, 2); - memcpy(buf + 26, &header->partsleft, 2); - memcpy(buf + 28, &header->totsize, 4); - memcpy(buf + 32, &header->size, 4); - memcpy(buf + 36, &header->modtime, 4); - memcpy(buf + 40, &header->checksum, 4); - memcpy(buf + 44, &header->rfrcsum, 4); - memcpy(buf + 48, &header->rfsize, 4); - memcpy(buf + 52, &header->cretime, 4); - memcpy(buf + 56, &header->rfcsum, 4); - memcpy(buf + 60, &header->nrecvd, 4); - memcpy(buf + 64, &header->recvcsum, 4); - memcpy(buf + 68, &header->idstring, 32); - memcpy(buf + 100, &header->flags, 1); - memcpy(buf + 101, &header->lnameoffset, 1); - memcpy(buf + 102, &header->lsizeoffset, 1); - memcpy(buf + 103, &header->dummy, 69); - memcpy(buf + 172, &header->macfileinfo, 16); - memcpy(buf + 188, &header->nencode, 2); - memcpy(buf + 190, &header->nlanguage, 2); - memcpy(buf + 192, &header->name, 64); - return write(fd, buf, 256); -} - -static void do_get_file(GtkWidget *w, struct file_transfer *ft) -{ - char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(ft->window)); - char buf[BUF_LONG]; - char *buf2; - char tmp_buf[MSG_LEN]; - struct file_header header; - int read_rv; - guint32 rcv; - int cont = 1; - GtkWidget *fw = NULL, *fbar = NULL, *label = NULL; - GtkWidget *button = NULL, *pct = NULL; - - if (file_is_dir(file, ft->window)) { - return; - } - - if (!(ft->f = fopen(file,"w"))) { - g_snprintf(buf, BUF_LONG / 2, _("Error writing file %s"), file); - do_error_dialog(buf, _("Error")); - ft->accepted = 0; - accept_callback(NULL, ft); - return; - } - - ft->accepted = 1; - - gtk_widget_destroy(ft->window); - ft->window = NULL; - g_snprintf(tmp_buf, MSG_LEN, "toc_rvous_accept %s %s %s", ft->user, ft->cookie, ft->UID); - sflap_send(ft->gc, tmp_buf, -1, TYPE_DATA); - - - - /* XXX is ft->port in host order or network order? */ - ft->fd = proxy_connect(ft->ip, ft->port, NULL, 0, -1); - - if (ft->fd <= -1) { - fclose(ft->f); - free_ft(ft); - return; - } - - read_rv = read_file_header(ft->fd, &header); - if(read_rv < 0) { - close(ft->fd); - fclose(ft->f); - free_ft(ft); - return; - } - - debug_printf("header length %d\n", header.hdrlen); - - header.hdrtype = 0x202; - - buf2 = frombase64(ft->cookie); - memcpy(header.bcookie, buf2, 8); - snprintf(header.idstring, 32, "Gaim"); - g_free(buf2); - header.encrypt = 0; header.compress = 0; - header.totparts = 1; header.partsleft = 1; - - debug_printf("sending confirmation\n"); - write_file_header(ft->fd, &header); - - rcv = 0; - - fw = gtk_dialog_new(); - snprintf(buf, 2048, _("Receiving %s from %s"), ft->filename, ft->user); - 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); - pct = gtk_label_new("0 %"); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->action_area), pct, 0, 0, 5); - gtk_widget_show(pct); - button = gtk_button_new_with_label(_("Cancel")); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->action_area), button, 0, 0, 5); - gtk_widget_show(button); - if (display_options & OPT_DISP_COOL_LOOK) - gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)toggle, &cont); - gtk_window_set_title(GTK_WINDOW(fw), _("Gaim - File Transfer")); - gtk_widget_realize(fw); - aol_icon(fw->window); - gtk_widget_show(fw); - - debug_printf("Receiving %s from %s (%d bytes)\n", ft->filename, ft->user, ft->size); - - fcntl(ft->fd, F_SETFL, O_NONBLOCK); - - while (rcv != ft->size && cont) { - int i; - float pcnt = ((float)rcv)/((float)ft->size); - int remain = ft->size - rcv > 1024 ? 1024 : ft->size - rcv; - read_rv = read(ft->fd, buf, remain); - if(read_rv < 0) { - if (errno == EWOULDBLOCK) { - while(gtk_events_pending()) - gtk_main_iteration(); - continue; - } - gtk_widget_destroy(fw); - fw = NULL; - fclose(ft->f); - close(ft->fd); - free_ft(ft); - return; - } - rcv += read_rv; - for (i = 0; i < read_rv; i++) - fprintf(ft->f, "%c", buf[i]); - gtk_progress_bar_update(GTK_PROGRESS_BAR(fbar), pcnt); - sprintf(buf, "%d / %d K (%2.0f %%)", rcv/1024, ft->size/1024, 100*pcnt); - gtk_label_set_text(GTK_LABEL(pct), buf); - while(gtk_events_pending()) - gtk_main_iteration(); - } - fclose(ft->f); - gtk_widget_destroy(fw); - fw = NULL; - - if (!cont) { - g_snprintf(tmp_buf, MSG_LEN, "toc_rvous_cancel %s %s %s", ft->user, ft->cookie, ft->UID); - sflap_send(ft->gc, tmp_buf, -1, TYPE_DATA); - close(ft->fd); - free_ft(ft); - return; - } - - debug_printf("Download complete.\n"); - - header.hdrtype = 0x402; - header.totparts = 0; header.partsleft = 0; - header.flags = 0; - header.recvcsum = header.checksum; - header.nrecvd = header.totsize; - write_file_header(ft->fd, &header); - close(ft->fd); - - free_ft(ft); -} - -static void send_file_callback(gpointer data, gint source, - GdkInputCondition condition) { - struct file_transfer *ft = (struct file_transfer *)data; - struct file_header fhdr; - int read_rv; - char buf[2048]; - GtkWidget *fw = NULL, *fbar = NULL, *label = NULL; - GtkWidget *button = NULL, *pct = NULL; - int rcv, cont; - - gdk_input_remove(snpa); - snpa = -1; - - if (condition & GDK_INPUT_EXCEPTION) { - fclose(ft->f); - close(ft->fd); - free_ft(ft); - return; - } - - /* OK, so here's what's going on: we need to send a file. The person - * sends us a file_header, then we send a file_header, then they send - * us a file header, then we send the file, then they send a header, - * and we're done. */ - - /* we can do some neat tricks because the other person sends us back - * all the information we need in the file_header */ - - read_rv = read_file_header(ft->fd, &fhdr); - if (read_rv < 0) { - fclose(ft->f); - close(ft->fd); - free_ft(ft); - return; - } - - if (fhdr.hdrtype != 0xc12) { - debug_printf("%s decided to cancel. (%x)\n", ft->user, fhdr.hdrtype); - fclose(ft->f); - close(ft->fd); - free_ft(ft); - return; - } - - /* now we need to set the hdrtype to a certain value, but I don't know - * what that value is, and I don't happen to have a win computer to do - * my sniffing from :-P */ - fhdr.hdrtype = ntohs(0x101); - fhdr.totfiles = 1; - fhdr.filesleft = 1; - fhdr.flags = 0x20; - write_file_header(ft->fd, &fhdr); - read_file_header(ft->fd, &fhdr); - - fw = gtk_dialog_new(); - snprintf(buf, 2048, _("Sending %s to %s"), fhdr.name, ft->user); - 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); - pct = gtk_label_new("0 %"); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->action_area), pct, 0, 0, 5); - gtk_widget_show(pct); - button = gtk_button_new_with_label(_("Cancel")); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->action_area), button, 0, 0, 5); - gtk_widget_show(button); - if (display_options & OPT_DISP_COOL_LOOK) - gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)toggle, &cont); - gtk_window_set_title(GTK_WINDOW(fw), _("Gaim - File Transfer")); - gtk_widget_realize(fw); - aol_icon(fw->window); - gtk_widget_show(fw); - - debug_printf("Sending %s to %s (%ld bytes)\n", fhdr.name, ft->user, fhdr.totsize); - - rcv = 0; cont = 1; - while (rcv != ntohl(fhdr.totsize) && cont) { - int i; - float pcnt = ((float)rcv)/((float)ntohl(fhdr.totsize)); - int remain = ntohl(fhdr.totsize) - rcv > 1024 ? 1024 : - ntohl(fhdr.totsize) - rcv; - for (i = 0; i < remain; i++) - fscanf(ft->f, "%c", &buf[i]); - read_rv = write(ft->fd, buf, remain); - if (read_rv < 0) { - fclose(ft->f); - gtk_widget_destroy(fw); - fw = NULL; - fclose(ft->f); - close(ft->fd); - free_ft(ft); - return; - } - rcv += read_rv; - gtk_progress_bar_update(GTK_PROGRESS_BAR(fbar), pcnt); - sprintf(buf, "%d / %d K (%2.0f %%)", rcv/1024, - ntohl(fhdr.totsize)/1024, 100*pcnt); - gtk_label_set_text(GTK_LABEL(pct), buf); - while(gtk_events_pending()) - gtk_main_iteration(); - } - fclose(ft->f); - gtk_widget_destroy(fw); - fw = NULL; - - if (!cont) { - char tmp_buf[MSG_LEN]; - g_snprintf(tmp_buf, MSG_LEN, "toc_rvous_cancel %s %s %s", ft->user, ft->cookie, ft->UID); - sflap_send(ft->gc, tmp_buf, -1, TYPE_DATA); - close(ft->fd); - free_ft(ft); - return; - } - - debug_printf("Upload complete.\n"); - - read_file_header(ft->fd, &fhdr); - - close(ft->fd); - free_ft(ft); -} - -static void do_send_file(GtkWidget *w, struct file_transfer *ft) { - char *file = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(ft->window))); - char buf[BUF_LONG]; - char *buf2; - char tmp_buf[MSG_LEN]; - int read_rv; - int at; - struct file_header fhdr; - guint32 rcv = 0; - char *c; - struct stat st; - struct tm *fortime; - - if (file_is_dir (file, ft->window)) { - g_free(file); - return; - } - - stat(file, &st); - if (!(ft->f = fopen(file, "r"))) { - g_snprintf(buf, BUF_LONG / 2, _("Error reading file %s"), file); - do_error_dialog(buf, _("Error")); - ft->accepted = 0; - accept_callback(NULL, ft); - free_ft(ft); - return; - } - - ft->accepted = 1; - ft->filename = file; - - gtk_widget_destroy(ft->window); - ft->window = NULL; - g_snprintf(tmp_buf, MSG_LEN, "toc_rvous_accept %s %s %s", ft->user, ft->cookie, ft->UID); - sflap_send(ft->gc, tmp_buf, -1, TYPE_DATA); - - - /* XXX is ft->port in host order or network order? */ - ft->fd = proxy_connect(ft->ip, ft->port, NULL, 0, -1); - - if (ft->fd <= -1) { - free_ft(ft); - return; - } - - /* here's where we differ from do_get_file */ - /* 1. build/send header - * 2. receive header - * 3. send listing file - * 4. receive header - * - * then we need to wait to actually send the file, if they want. - * - */ - - /* 1. build/send header */ - c = file + strlen(file); - while (*(c - 1) != '/') c--; - buf2 = frombase64(ft->cookie); - debug_printf("Building header to send %s (cookie: %s)\n", file, buf2); - fhdr.magic[0] = 'O'; fhdr.magic[1] = 'F'; - fhdr.magic[2] = 'T'; fhdr.magic[3] = '2'; - fhdr.hdrlen = htons(256); - fhdr.hdrtype = htons(0x1108); - snprintf(fhdr.bcookie, 8, "%s", buf2); - g_free(buf2); - fhdr.encrypt = 0; - fhdr.compress = 0; - fhdr.totfiles = htons(1); - fhdr.filesleft = htons(1); - fhdr.totparts = htons(1); - fhdr.partsleft = htons(1); - fhdr.totsize = htonl((long)st.st_size); /* combined size of all files */ - /* size = strlen("mm/dd/yyyy hh:mm sizesize 'name'\r\n") */ - fhdr.size = htonl(28 + strlen(c)); /* size of listing.txt */ - fhdr.modtime = htonl(time(NULL)); /* time since UNIX epoch */ - fhdr.checksum = htonl(0x89f70000); /* ? i don't think this matters */ - fhdr.rfrcsum = 0; - fhdr.rfsize = 0; - fhdr.cretime = 0; - fhdr.rfcsum = 0; - fhdr.nrecvd = 0; - fhdr.recvcsum = 0; - snprintf(fhdr.idstring, 32, "OFT_Windows ICBMFT V1.1 32"); - fhdr.flags = 0x02; /* don't ask me why */ - fhdr.lnameoffset = 0x1A; /* ? still no clue */ - fhdr.lsizeoffset = 0x10; /* whatever */ - memset(fhdr.dummy, 0, 69); - memset(fhdr.macfileinfo, 0, 16); - fhdr.nencode = 0; - fhdr.nlanguage = 0; - snprintf(fhdr.name, 64, "listing.txt"); - read_rv = write_file_header(ft->fd, &fhdr); - if (read_rv <= -1) { - debug_printf("Couldn't write opening header\n"); - close(ft->fd); - free_ft(ft); - return; - } - - /* 2. receive header */ - debug_printf("Receiving header\n"); - read_rv = read_file_header(ft->fd, &fhdr); - if (read_rv <= -1) { - debug_printf("Couldn't read header\n"); - close(ft->fd); - free_ft(ft); - return; - } - - /* 3. send listing file */ - /* mm/dd/yyyy hh:mm sizesize name.ext\r\n */ - /* creation date ^ */ - debug_printf("Sending file\n"); - fortime = localtime(&st.st_ctime); - at = g_snprintf(buf, ntohl(fhdr.size) + 1, "%2d/%2d/%4d %2d:%2d %8ld ", - fortime->tm_mon + 1, fortime->tm_mday, fortime->tm_year + 1900, - fortime->tm_hour + 1, fortime->tm_min + 1, - (long)st.st_size); - g_snprintf(buf + at, ntohl(fhdr.size) + 1 - at, "%s\r\n", c); - debug_printf("Sending listing.txt (%d bytes) to %s\n", ntohl(fhdr.size) + 1, ft->user); - - read_rv = write(ft->fd, buf, ntohl(fhdr.size)); - if (read_rv <= -1) { - debug_printf("Could not send file, wrote %d\n", rcv); - close(ft->fd); - free_ft(ft); - return; - } - - /* 4. receive header */ - debug_printf("Receiving closing header\n"); - read_rv = read_file_header(ft->fd, &fhdr); - if (read_rv <= -1) { - debug_printf("Couldn't read closing header\n"); - close(ft->fd); - free_ft(ft); - return; - } - - snpa = gdk_input_add(ft->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, - send_file_callback, ft); - -} - -void accept_file_dialog(struct file_transfer *ft) -{ - GtkWidget *accept, *info, *warn, *cancel; - GtkWidget *label; - GtkWidget *vbox, *bbox; - char buf[1024]; - - - ft->window = gtk_window_new(GTK_WINDOW_DIALOG); - gtk_window_set_wmclass(GTK_WINDOW(ft->window), "accept_file", "Gaim"); - - 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); - - if (display_options & OPT_DISP_COOL_LOOK) - { - gtk_button_set_relief(GTK_BUTTON(accept), GTK_RELIEF_NONE); - gtk_button_set_relief(GTK_BUTTON(info), GTK_RELIEF_NONE); - gtk_button_set_relief(GTK_BUTTON(warn), GTK_RELIEF_NONE); - gtk_button_set_relief(GTK_BUTTON(cancel), GTK_RELIEF_NONE); - } - - 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); - } - if (ft->message) - strncat(buf, ft->message, sizeof(buf) - strlen(buf)); - label = gtk_label_new(buf); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 5); - 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); - */ - } -} diff -r 6650776468b3 -r c6f9d0cdaa00 src/toc.c --- a/src/toc.c Thu Feb 01 08:37:16 2001 +0000 +++ b/src/toc.c Thu Feb 01 11:29:15 2001 +0000 @@ -46,7 +46,7 @@ #include "pixmaps/dt_icon.xpm" #include "pixmaps/free_icon.xpm" -#define REVISION "gaim:$Revision: 1445 $" +#define REVISION "gaim:$Revision: 1467 $" #define TYPE_SIGNON 1 #define TYPE_DATA 2 @@ -69,6 +69,27 @@ #define STATE_ONLINE 3 #define STATE_PAUSE 4 +#define VOICE_UID "09461341-4C7F-11D1-8222-444553540000" +#define FILE_SEND_UID "09461343-4C7F-11D1-8222-444553540000" +#define IMAGE_UID "09461345-4C7F-11D1-8222-444553540000" +#define B_ICON_UID "09461346-4C7F-11D1-8222-444553540000" +#define STOCKS_UID "09461347-4C7F-11D1-8222-444553540000" +#define FILE_GET_UID "09461348-4C7F-11D1-8222-444553540000" +#define GAMES_UID "0946134a-4C7F-11D1-8222-444553540000" + +struct ft_request { + struct gaim_connection *gc; + char *user; + char UID[2048]; + char *cookie; + char *ip; + int port; + char *message; + char *filename; + int files; + int size; +}; + struct toc_data { int toc_fd; int seqno; @@ -98,6 +119,7 @@ static void toc_callback(gpointer, gint, GdkInputCondition); static unsigned char *roast_password(char *); +static void accept_file_dialog(struct ft_request *); /* 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 @@ -161,7 +183,7 @@ close(((struct toc_data *)gc->proto_data)->toc_fd); } -int sflap_send(struct gaim_connection *gc, char *buf, int olen, int type) +static int sflap_send(struct gaim_connection *gc, char *buf, int olen, int type) { int len; int slen = 0; @@ -337,8 +359,7 @@ g_snprintf(snd, sizeof snd, "toc_init_done"); sflap_send(gc, snd, -1, TYPE_DATA); - g_snprintf(snd, sizeof snd, "toc_set_caps %s %s", - FILE_SEND_UID, FILE_GET_UID); + g_snprintf(snd, sizeof snd, "toc_set_caps %s", FILE_SEND_UID); sflap_send(gc, snd, -1, TYPE_DATA); return; @@ -561,7 +582,7 @@ int unk[4], i; char *messages[4], *tmp, *name; int subtype, files, totalsize = 0; - struct file_transfer *ft; + struct ft_request *ft; for (i = 0; i < 4; i++) { sscanf(strtok(NULL, ":"), "%d", &unk[i]); @@ -588,7 +609,7 @@ name = tmp + 8; - ft = g_new0(struct file_transfer, 1); + ft = g_new0(struct ft_request, 1); ft->cookie = g_strdup(cookie); ft->ip = g_strdup(pip); ft->port = port; @@ -599,6 +620,7 @@ ft->filename = g_strdup(name); ft->user = g_strdup(user); ft->size = totalsize; + ft->files = files; g_snprintf(ft->UID, sizeof(ft->UID), "%s", FILE_SEND_UID); ft->gc = gc; @@ -606,12 +628,15 @@ for (i--; i >= 0; i--) g_free(messages[i]); + debug_printf("English translation of RVOUS_PROPOSE: %s requests Send File (i.e." + " send a file to you); %s:%d (verified_ip:port), %d files at" + " total size of %ld bytes.\n", user, vip, port, files, totalsize); accept_file_dialog(ft); } else if (!strcmp(uuid, FILE_GET_UID)) { - /* they want us to send a file */ + /* they want us to send a file int unk[4], i; char *messages[4], *tmp; - struct file_transfer *ft; + struct ft_request *ft; for (i = 0; i < 4; i++) { sscanf(strtok(NULL, ":"), "%d", unk + i); @@ -621,7 +646,7 @@ } tmp = frombase64(strtok(NULL, ":")); - ft = g_new0(struct file_transfer, 1); + ft = g_new0(struct ft_request, 1); ft->cookie = g_strdup(cookie); ft->ip = g_strdup(pip); ft->port = port; @@ -638,6 +663,7 @@ g_free(messages[i]); accept_file_dialog(ft); + */ } else if (!strcmp(uuid, VOICE_UID)) { /* oh goody. voice over ip. fun stuff. */ } else if (!strcmp(uuid, B_ICON_UID)) { @@ -1219,3 +1245,284 @@ ret->chat_send = toc_chat_send; ret->keepalive = toc_keepalive; } + +/********* + * RVOUS ACTIONS + ********/ + +struct file_header { + char magic[4]; /* 0 */ + short hdrlen; /* 4 */ + short hdrtype; /* 6 */ + char bcookie[8]; /* 8 */ + short encrypt; /* 16 */ + short compress; /* 18 */ + short totfiles; /* 20 */ + short filesleft; /* 22 */ + short totparts; /* 24 */ + short partsleft; /* 26 */ + long totsize; /* 28 */ + long size; /* 32 */ + long modtime; /* 36 */ + long checksum; /* 40 */ + long rfrcsum; /* 44 */ + long rfsize; /* 48 */ + long cretime; /* 52 */ + long rfcsum; /* 56 */ + long nrecvd; /* 60 */ + long recvcsum; /* 64 */ + char idstring[32]; /* 68 */ + char flags; /* 100 */ + char lnameoffset; /* 101 */ + char lsizeoffset; /* 102 */ + char dummy[69]; /* 103 */ + char macfileinfo[16]; /* 172 */ + short nencode; /* 188 */ + short nlanguage; /* 190 */ + char name[64]; /* 192 */ + /* 256 */ +}; + +struct file_transfer { + struct file_header hdr; + + struct gaim_connection *gc; + + char *user; + char *cookie; + char *ip; + int port; + long size; + + GtkWidget *window; + FILE *file; + int recvsize; + + gint inpa; +}; + +static void toc_get_file(gpointer a, struct file_transfer *ft) { + char *dirname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(ft->window)); + + if (file_is_dir(dirname, ft->window)) + return; + gtk_widget_destroy(ft->window); +} + +static void debug_header(struct file_transfer *ft) { + struct file_header *f = (struct file_header *)ft; + debug_printf("TOC FT HEADER:\n" + "\t%s %d 0x%04x\n" + "\t%s %d %d\n" + "\t%d %d %d %d %ld %ld\n" + "\t%ld %ld %ld %ld %ld %ld %ld %ld\n" + "\t%s\n" + "\t0x%02x, 0x%02x, 0x%02x\n" + "\t%s %s\n" + "\t%d %d\n" + "\t%s\n", + f->magic, ntohs(f->hdrlen), f->hdrtype, + f->bcookie, ntohs(f->encrypt), ntohs(f->compress), + ntohs(f->totfiles), ntohs(f->filesleft), ntohs(f->totparts), + ntohs(f->partsleft), ntohl(f->totsize), ntohl(f->size), + ntohl(f->modtime), ntohl(f->checksum), ntohl(f->rfrcsum), ntohl(f->rfsize), + ntohl(f->cretime), ntohl(f->rfcsum), ntohl(f->nrecvd), + ntohl(f->recvcsum), + f->idstring, + f->flags, f->lnameoffset, f->lsizeoffset, + f->dummy, f->macfileinfo, + ntohs(f->nencode), ntohs(f->nlanguage), + f->name); +} + +static void toc_send_file_callback(gpointer data, gint source, GdkInputCondition cond) { + char buf[BUF_LONG]; + int rt, i; + + struct file_transfer *ft = data; + + if (cond & GDK_INPUT_EXCEPTION) { + gdk_input_remove(ft->inpa); + close(source); + g_free(ft->user); + g_free(ft->ip); + g_free(ft->cookie); + fclose(ft->file); + g_free(ft); + return; + } + + if (ft->hdr.hdrtype != 0x202) { + char *buf = frombase64(ft->cookie); + + read(source, ft, 8); + read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); + debug_header(ft); + + ft->hdr.hdrtype = 0x202; + memcpy(ft->hdr.bcookie, buf, 8); + g_free(buf); + ft->hdr.encrypt = 0; ft->hdr.compress = 0; + debug_header(ft); + write(source, ft, 256); + + return; + } + + rt = read(source, buf, MIN(ntohl(ft->hdr.size) - ft->recvsize, 1024)); + if (rt < 0) { + do_error_dialog("File transfer failed; other side probably canceled.", "Error"); + gdk_input_remove(ft->inpa); + close(source); + g_free(ft->user); + g_free(ft->ip); + g_free(ft->cookie); + fclose(ft->file); + g_free(ft); + return; + } + ft->recvsize += rt; + for (i = 0; i < rt; i++) + fprintf(ft->file, "%c", buf[i]); + + if (ft->recvsize == ntohl(ft->hdr.size)) { + ft->hdr.hdrtype = 0x402; + ft->hdr.filesleft = htons(ntohs(ft->hdr.filesleft) - 1); + ft->hdr.partsleft = htons(ntohs(ft->hdr.partsleft) - 1); + ft->hdr.recvcsum = ft->hdr.checksum; /* uh... */ + ft->hdr.nrecvd = htons(ntohs(ft->hdr.nrecvd) + 1); + ft->hdr.flags = 0; + write(source, ft, 256); + ft->recvsize = 0; + if (ft->hdr.filesleft != 0) { + char *msg = g_strdup_printf("%s tried to send you more than one file, but" + " currently that is not possible.", ft->user); + do_error_dialog(msg, "Error"); + g_free(msg); + } + gdk_input_remove(ft->inpa); + close(source); + g_free(ft->user); + g_free(ft->ip); + g_free(ft->cookie); + fclose(ft->file); + g_free(ft); + } +} + +static void toc_send_file(gpointer a, struct file_transfer *old_ft) { + struct file_transfer *ft; + char *dirname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(old_ft->window)); + int fd; + struct aim_user *user; + char *buf; + + if (file_is_dir(dirname, old_ft->window)) + return; + ft = g_new0(struct file_transfer, 1); + ft->file = fopen(dirname, "w"); + if (!ft->file) { + do_error_dialog(_("Could not open file for writing!"), _("Error")); + g_free(ft); + gtk_widget_destroy(old_ft->window); + return; + } + + ft->cookie = g_strdup(old_ft->cookie); + ft->user = g_strdup(old_ft->user); + ft->ip = g_strdup(old_ft->ip); + ft->port = old_ft->port; + ft->gc = old_ft->gc; + user = ft->gc->user; + gtk_widget_destroy(old_ft->window); + + buf = g_strdup_printf("toc_rvous_accept %s %s %s", ft->user, ft->cookie, FILE_SEND_UID); + sflap_send(ft->gc, buf, -1, TYPE_DATA); + g_free(buf); + + fd = + proxy_connect(ft->ip, ft->port, + user->proto_opt[USEROPT_SOCKSHOST], + atoi(user->proto_opt[USEROPT_SOCKSPORT]), + atoi(user->proto_opt[USEROPT_PROXYTYPE])); + if (fd < 0) { + do_error_dialog(_("Could not connect for transfer!"), _("Error")); + g_free(ft->cookie); + g_free(ft->user); + g_free(ft->ip); + g_free(ft); + return; + } + + ft->inpa = gdk_input_add(fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, toc_send_file_callback, ft); +} + +static void cancel_callback(gpointer a, struct file_transfer *ft) { + gtk_widget_destroy(ft->window); + if (a == ft->window) { + g_free(ft->cookie); + g_free(ft->user); + g_free(ft->ip); + g_free(ft); + } +} + +static void toc_accept_ft(gpointer a, struct ft_request *fr) { + GtkWidget *window; + char buf[BUF_LEN]; + + struct file_transfer *ft = g_new0(struct file_transfer, 1); + ft->gc = fr->gc; + ft->user = g_strdup(fr->user); + ft->cookie = g_strdup(fr->cookie); + ft->ip = g_strdup(fr->ip); + ft->port = fr->port; + + 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 : ""); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), buf); + gtk_signal_connect(GTK_OBJECT(window), "destroy", + GTK_SIGNAL_FUNC(cancel_callback), ft); + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(ft->window)->cancel_button), "clicked", + GTK_SIGNAL_FUNC(cancel_callback), ft); + + if (!strcmp(fr->UID, FILE_SEND_UID)) + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked", + GTK_SIGNAL_FUNC(toc_send_file), ft); + else + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked", + GTK_SIGNAL_FUNC(toc_get_file), ft); + + gtk_widget_show(window); +} + +static void toc_reject_ft(gpointer a, struct ft_request *ft) { + g_free(ft->user); + g_free(ft->filename); + g_free(ft->ip); + g_free(ft->cookie); + if (ft->message) + g_free(ft->message); + g_free(ft); +} + +static void accept_file_dialog(struct ft_request *ft) { + char buf[BUF_LONG]; + if (!strcmp(ft->UID, FILE_SEND_UID)) { + /* holy crap. who the fuck would transfer gigabytes through AIM?! */ + static char *sizes[4] = { "bytes", "KB", "MB", "GB" }; + float size = ft->size; + int index = 0; + while ((index < 4) && (size > 1024)) { + size /= 1024; + index++; + } + g_snprintf(buf, sizeof(buf), _("%s requests %s to accept %d file%s: %s (%.2f %s)%s%s"), + ft->user, ft->gc->username, ft->files, (ft->files == 1) ? "" : "s", + ft->filename, size, sizes[index], (ft->message) ? "\n" : "", + (ft->message) ? ft->message : ""); + } else { + g_snprintf(buf, sizeof(buf), _("%s requests you to send them a file"), ft->user); + } + do_ask_dialog(buf, ft, toc_accept_ft, toc_reject_ft); +}