Mercurial > pidgin
changeset 3616:9e776fde2fed
[gaim-migrate @ 3730]
IRC file receive support. This may be a little odd at the moment. It is also a little
spammy on the console. I did this so I could make sure things were working until I get
a GUI designed for FT stuff.
I'll try to do that tomorrow night. Could some people test this and let me know what you think.
committer: Tailor Script <tailor@pidgin.im>
author | Rob Flynn <gaim@robflynn.com> |
---|---|
date | Wed, 09 Oct 2002 06:09:10 +0000 |
parents | 220bed0e439c |
children | fcf1fc6c73a0 |
files | ChangeLog src/protocols/irc/irc.c |
diffstat | 2 files changed, 173 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Wed Oct 09 05:59:33 2002 +0000 +++ b/ChangeLog Wed Oct 09 06:09:10 2002 +0000 @@ -81,6 +81,7 @@ (Thanks Mark Doliner) * Improved typing notification support for Jabber and Yahoo! (Thanks Nathan Walp) + * DCC File Receive support for IRC version 0.59 (06/24/2002): * Hungarian translation added (Thanks, Sutto Zoltan)
--- a/src/protocols/irc/irc.c Wed Oct 09 05:59:33 2002 +0000 +++ b/src/protocols/irc/irc.c Wed Oct 09 06:09:10 2002 +0000 @@ -57,6 +57,20 @@ char nick[80]; }; +struct irc_file_transfer { + enum { IFT_SENDFILE_IN, IFT_SENDFILE_OUT } type; + struct file_transfer *xfer; + char *sn; + char *name; + int len; + int watcher; + char ip[12]; + int port; + int fd; + int cur; + struct gaim_connection *gc; +}; + GSList *dcc_chat_list = NULL; struct irc_data { @@ -78,6 +92,7 @@ gboolean in_whois; gboolean in_list; GString *liststr; + GSList *file_transfers; }; struct dcc_chat * @@ -445,6 +460,27 @@ } } +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); + ift->watcher = 0; + } +} + + +void dcc_recv_callback (gpointer data, gint source, GaimInputCondition condition) { + struct irc_file_transfer *ift = data; + + ift->fd = source; + + printf("WELL, we should be doing something then, should we not?\n"); + + irc_file_transfer_do(ift->gc, ift); +} + void dcc_chat_callback (gpointer data, gint source, GaimInputCondition condition) { struct dcc_chat *chat = data; struct conversation *convo = new_conversation (chat->nick); @@ -1009,6 +1045,8 @@ memcpy(chat, data, sizeof(struct dcc_chat)); /* we have to make a new one * because the old one get's freed by * dcc_chat_cancel. */ + + printf("ONE MORE TIME: %s:%d\n", chat->ip_address, chat->port); proxy_connect(chat->ip_address, chat->port, dcc_chat_callback, chat); } @@ -1055,12 +1093,34 @@ struct dcc_chat * dccchat = g_new0(struct dcc_chat, 1); dccchat->gc = gc; g_snprintf(dccchat->ip_address, sizeof(dccchat->ip_address), chat_args[3]); + printf("DCC CHAT DEBUG CRAP: %s\n", dccchat->ip_address); dccchat->port=atoi(chat_args[4]); g_snprintf(dccchat->nick, sizeof(dccchat->nick), nick); g_snprintf(ask, sizeof(ask), _("%s has requested a DCC chat. " "Would you like to establish the direct connection?"), nick); do_ask_dialog(ask, dccchat, dcc_chat_init, dcc_chat_cancel); } + + + if (!g_strncasecmp(msg, "DCC SEND", 8)) { + struct irc_file_transfer *ift = g_new0(struct irc_file_transfer, 1); + char **send_args = g_strsplit(msg, " ", 6); + send_args[5][strlen(send_args[5])-1] = 0; + + ift->type = IFT_SENDFILE_IN; + ift->sn = g_strdup(nick); + ift->gc = gc; + g_snprintf(ift->ip, sizeof(ift->ip), send_args[3]); + ift->port = atoi(send_args[4]); + ift->len = atoi(send_args[5]); + ift->name = g_strdup(send_args[2]); + ift->cur = 0; + + id->file_transfers = g_slist_append(id->file_transfers, ift); + + ift->xfer = transfer_in_add(gc, nick, ift->name, ift->len, 1, NULL); + } + /* XXX should probably write_to_conv or something here */ } @@ -1895,6 +1955,102 @@ dcc_chat_list = g_slist_append (dcc_chat_list, chat); } +static void irc_ask_send_file(struct gaim_connection *gc, char *destsn) { + struct irc_data *id = (struct irc_data *)gc->proto_data; + struct irc_file_transfer *ift = g_new0(struct irc_file_transfer, 1); + + ift->type = IFT_SENDFILE_OUT; + ift->sn = g_strdup(destsn); + ift->gc = gc; + id->file_transfers = g_slist_append(id->file_transfers, ift); + 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) { + + GSList *g = ((struct irc_data *)gc->proto_data)->file_transfers; + struct irc_file_transfer *f = NULL; + + while (g) { + f = (struct irc_file_transfer *)g->data; + if (f->xfer == xfer) + break; + g = g->next; + f = NULL; + } + + return f; +} + +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; + + ift->cur += len; + pos = htonl(ift->cur); + write(ift->fd, (char *)&pos, 4); + + printf("Cheap-O Progress Bar (%s) %d of %d: %2.0f\%\n", ift->name, ift->cur, ift->len, ((float)ift->cur/(float)ift->len) * 100); +} + +static void irc_file_transfer_cancel (struct gaim_connection *gc, struct file_transfer *xfer) { + struct irc_data *id = (struct irc_data *)gc->proto_data; + struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); + + printf("Our shit got canceled, yo!\n"); + + /* Remove the FT from our list of transfers */ + id->file_transfers = g_slist_remove(id->file_transfers, ift); + + gaim_input_remove(ift->watcher); + + /* Close our FT because we're done */ + close(ift->fd); + + g_free(ift->sn); + g_free(ift->name); + + g_free(ift); +} + +static void irc_file_transfer_done(struct gaim_connection *gc, struct file_transfer *xfer) { + struct irc_data *id = (struct irc_data *)gc->proto_data; + struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); + + + printf("Our shit be done, yo.\n"); + + /* Remove the FT from our list of transfers */ + id->file_transfers = g_slist_remove(id->file_transfers, ift); + + gaim_input_remove(ift->watcher); + + /* Close our FT because we're done */ + close(ift->fd); + + g_free(ift->sn); + g_free(ift->name); + + g_free(ift); +} + +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; + printf("You, I should be getting a file or some shit, hehe\n"); + printf("Connecting to: %s %d\n", ift->ip, ift->port); + proxy_connect(ift->ip, ift->port, dcc_recv_callback, ift); +} + static void irc_start_chat(struct gaim_connection *gc, char *who) { struct dcc_chat *chat; int len; @@ -1951,11 +2107,21 @@ pbm->callback = irc_get_info; pbm->gc = gc; m = g_list_append(m, pbm); + pbm = g_new0(struct proto_buddy_menu, 1); pbm->label = _("DCC Chat"); pbm->callback = irc_start_chat; pbm->gc = gc; m = g_list_append(m, pbm); + +/* + pbm = g_new0(struct proto_buddy_menu, 1); + pbm->label = _("DCC Send"); + pbm->callback = irc_ask_send_file; + pbm->gc = gc; + m = g_list_append(m, pbm); +*/ + return m; } @@ -1983,6 +2149,11 @@ ret->buddy_menu = irc_buddy_menu; ret->chat_invite = irc_chat_invite; ret->convo_closed = irc_convo_closed; + ret->file_transfer_out = NULL; /* Implement me */ + ret->file_transfer_in = irc_file_transfer_in; + ret->file_transfer_data_chunk = irc_file_transfer_data_chunk; + ret->file_transfer_done = irc_file_transfer_done; + ret->file_transfer_cancel =irc_file_transfer_cancel; puo = g_new0(struct proto_user_opt, 1); puo->label = g_strdup("Server:"); @@ -1996,7 +2167,7 @@ puo->pos = USEROPT_PORT; ret->user_opts = g_list_append(ret->user_opts, puo); - my_protocol = ret; + my_protocol = ret; } #ifndef STATIC