Mercurial > pidgin.yaz
view src/rvous.c @ 199:be5fbefdb195
[gaim-migrate @ 209]
This may or may not fix the bug where sending a message in buddy chat doesn't
make you non-idle.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Sun, 30 Apr 2000 10:42:46 +0000 |
parents | 73e9a0bfff62 |
children | bc117fbcf527 |
line wrap: on
line source
/* * 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); */ } }