comparison src/protocols/irc/irc.c @ 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 1066e65b1a18
children 6b12659dfd70
comparison
equal deleted inserted replaced
3615:220bed0e439c 3616:9e776fde2fed
55 int fd; 55 int fd;
56 int inpa; 56 int inpa;
57 char nick[80]; 57 char nick[80];
58 }; 58 };
59 59
60 struct irc_file_transfer {
61 enum { IFT_SENDFILE_IN, IFT_SENDFILE_OUT } type;
62 struct file_transfer *xfer;
63 char *sn;
64 char *name;
65 int len;
66 int watcher;
67 char ip[12];
68 int port;
69 int fd;
70 int cur;
71 struct gaim_connection *gc;
72 };
73
60 GSList *dcc_chat_list = NULL; 74 GSList *dcc_chat_list = NULL;
61 75
62 struct irc_data { 76 struct irc_data {
63 int fd; 77 int fd;
64 gboolean online; 78 gboolean online;
76 gboolean six_modes; 90 gboolean six_modes;
77 91
78 gboolean in_whois; 92 gboolean in_whois;
79 gboolean in_list; 93 gboolean in_list;
80 GString *liststr; 94 GString *liststr;
95 GSList *file_transfers;
81 }; 96 };
82 97
83 struct dcc_chat * 98 struct dcc_chat *
84 find_dcc_chat (struct gaim_connection *gc, char *nick) 99 find_dcc_chat (struct gaim_connection *gc, char *nick)
85 { 100 {
443 time ((time_t) NULL), -1); 458 time ((time_t) NULL), -1);
444 dcc_chat_cancel (NULL,chat); 459 dcc_chat_cancel (NULL,chat);
445 } 460 }
446 } 461 }
447 462
463 static void irc_file_transfer_do(struct gaim_connection *gc, struct irc_file_transfer *ift) {
464 struct irc_data *id = (struct irc_data *)gc->proto_data;
465
466 /* Ok, we better be receiving some crap here boyeee */
467 if (transfer_in_do(ift->xfer, ift->fd, ift->name, ift->len)) {
468 gaim_input_remove(ift->watcher);
469 ift->watcher = 0;
470 }
471 }
472
473
474 void dcc_recv_callback (gpointer data, gint source, GaimInputCondition condition) {
475 struct irc_file_transfer *ift = data;
476
477 ift->fd = source;
478
479 printf("WELL, we should be doing something then, should we not?\n");
480
481 irc_file_transfer_do(ift->gc, ift);
482 }
483
448 void dcc_chat_callback (gpointer data, gint source, GaimInputCondition condition) { 484 void dcc_chat_callback (gpointer data, gint source, GaimInputCondition condition) {
449 struct dcc_chat *chat = data; 485 struct dcc_chat *chat = data;
450 struct conversation *convo = new_conversation (chat->nick); 486 struct conversation *convo = new_conversation (chat->nick);
451 char buf[IRC_BUF_LEN]; 487 char buf[IRC_BUF_LEN];
452 chat->fd = source; 488 chat->fd = source;
1007 struct dcc_chat * chat = g_new0(struct dcc_chat, 1); 1043 struct dcc_chat * chat = g_new0(struct dcc_chat, 1);
1008 1044
1009 memcpy(chat, data, sizeof(struct dcc_chat)); /* we have to make a new one 1045 memcpy(chat, data, sizeof(struct dcc_chat)); /* we have to make a new one
1010 * because the old one get's freed by 1046 * because the old one get's freed by
1011 * dcc_chat_cancel. */ 1047 * dcc_chat_cancel. */
1048
1049 printf("ONE MORE TIME: %s:%d\n", chat->ip_address, chat->port);
1012 proxy_connect(chat->ip_address, chat->port, dcc_chat_callback, chat); 1050 proxy_connect(chat->ip_address, chat->port, dcc_chat_callback, chat);
1013 } 1051 }
1014 1052
1015 static void dcc_chat_cancel(gpointer obj, struct dcc_chat *data){ 1053 static void dcc_chat_cancel(gpointer obj, struct dcc_chat *data){
1016 if (find_dcc_chat(data->gc, data->nick)) { 1054 if (find_dcc_chat(data->gc, data->nick)) {
1053 char **chat_args = g_strsplit(msg, " ", 5); 1091 char **chat_args = g_strsplit(msg, " ", 5);
1054 char ask[1024]; 1092 char ask[1024];
1055 struct dcc_chat * dccchat = g_new0(struct dcc_chat, 1); 1093 struct dcc_chat * dccchat = g_new0(struct dcc_chat, 1);
1056 dccchat->gc = gc; 1094 dccchat->gc = gc;
1057 g_snprintf(dccchat->ip_address, sizeof(dccchat->ip_address), chat_args[3]); 1095 g_snprintf(dccchat->ip_address, sizeof(dccchat->ip_address), chat_args[3]);
1096 printf("DCC CHAT DEBUG CRAP: %s\n", dccchat->ip_address);
1058 dccchat->port=atoi(chat_args[4]); 1097 dccchat->port=atoi(chat_args[4]);
1059 g_snprintf(dccchat->nick, sizeof(dccchat->nick), nick); 1098 g_snprintf(dccchat->nick, sizeof(dccchat->nick), nick);
1060 g_snprintf(ask, sizeof(ask), _("%s has requested a DCC chat. " 1099 g_snprintf(ask, sizeof(ask), _("%s has requested a DCC chat. "
1061 "Would you like to establish the direct connection?"), nick); 1100 "Would you like to establish the direct connection?"), nick);
1062 do_ask_dialog(ask, dccchat, dcc_chat_init, dcc_chat_cancel); 1101 do_ask_dialog(ask, dccchat, dcc_chat_init, dcc_chat_cancel);
1063 } 1102 }
1103
1104
1105 if (!g_strncasecmp(msg, "DCC SEND", 8)) {
1106 struct irc_file_transfer *ift = g_new0(struct irc_file_transfer, 1);
1107 char **send_args = g_strsplit(msg, " ", 6);
1108 send_args[5][strlen(send_args[5])-1] = 0;
1109
1110 ift->type = IFT_SENDFILE_IN;
1111 ift->sn = g_strdup(nick);
1112 ift->gc = gc;
1113 g_snprintf(ift->ip, sizeof(ift->ip), send_args[3]);
1114 ift->port = atoi(send_args[4]);
1115 ift->len = atoi(send_args[5]);
1116 ift->name = g_strdup(send_args[2]);
1117 ift->cur = 0;
1118
1119 id->file_transfers = g_slist_append(id->file_transfers, ift);
1120
1121 ift->xfer = transfer_in_add(gc, nick, ift->name, ift->len, 1, NULL);
1122 }
1123
1064 /* XXX should probably write_to_conv or something here */ 1124 /* XXX should probably write_to_conv or something here */
1065 } 1125 }
1066 1126
1067 static gboolean irc_parse(struct gaim_connection *gc, char *buf) 1127 static gboolean irc_parse(struct gaim_connection *gc, char *buf)
1068 { 1128 {
1893 write_to_conv (convo, buf, WFLAG_SYSTEM, NULL, time ((time_t) NULL), -1); 1953 write_to_conv (convo, buf, WFLAG_SYSTEM, NULL, time ((time_t) NULL), -1);
1894 debug_printf ("Chat with %s established\n", chat->nick); 1954 debug_printf ("Chat with %s established\n", chat->nick);
1895 dcc_chat_list = g_slist_append (dcc_chat_list, chat); 1955 dcc_chat_list = g_slist_append (dcc_chat_list, chat);
1896 } 1956 }
1897 1957
1958 static void irc_ask_send_file(struct gaim_connection *gc, char *destsn) {
1959 struct irc_data *id = (struct irc_data *)gc->proto_data;
1960 struct irc_file_transfer *ift = g_new0(struct irc_file_transfer, 1);
1961
1962 ift->type = IFT_SENDFILE_OUT;
1963 ift->sn = g_strdup(destsn);
1964 ift->gc = gc;
1965 id->file_transfers = g_slist_append(id->file_transfers, ift);
1966 ift->xfer = transfer_out_add(gc, ift->sn);
1967 }
1968
1969
1970 static struct irc_file_transfer *find_ift_by_xfer(struct gaim_connection *gc,
1971 struct file_transfer *xfer) {
1972
1973 GSList *g = ((struct irc_data *)gc->proto_data)->file_transfers;
1974 struct irc_file_transfer *f = NULL;
1975
1976 while (g) {
1977 f = (struct irc_file_transfer *)g->data;
1978 if (f->xfer == xfer)
1979 break;
1980 g = g->next;
1981 f = NULL;
1982 }
1983
1984 return f;
1985 }
1986
1987 static void irc_file_transfer_data_chunk(struct gaim_connection *gc, struct file_transfer *xfer, const char *data, int len) {
1988 struct irc_data *id = (struct irc_data *)gc->proto_data;
1989 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer);
1990 guint32 pos;
1991
1992 ift->cur += len;
1993 pos = htonl(ift->cur);
1994 write(ift->fd, (char *)&pos, 4);
1995
1996 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);
1997 }
1998
1999 static void irc_file_transfer_cancel (struct gaim_connection *gc, struct file_transfer *xfer) {
2000 struct irc_data *id = (struct irc_data *)gc->proto_data;
2001 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer);
2002
2003 printf("Our shit got canceled, yo!\n");
2004
2005 /* Remove the FT from our list of transfers */
2006 id->file_transfers = g_slist_remove(id->file_transfers, ift);
2007
2008 gaim_input_remove(ift->watcher);
2009
2010 /* Close our FT because we're done */
2011 close(ift->fd);
2012
2013 g_free(ift->sn);
2014 g_free(ift->name);
2015
2016 g_free(ift);
2017 }
2018
2019 static void irc_file_transfer_done(struct gaim_connection *gc, struct file_transfer *xfer) {
2020 struct irc_data *id = (struct irc_data *)gc->proto_data;
2021 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer);
2022
2023
2024 printf("Our shit be done, yo.\n");
2025
2026 /* Remove the FT from our list of transfers */
2027 id->file_transfers = g_slist_remove(id->file_transfers, ift);
2028
2029 gaim_input_remove(ift->watcher);
2030
2031 /* Close our FT because we're done */
2032 close(ift->fd);
2033
2034 g_free(ift->sn);
2035 g_free(ift->name);
2036
2037 g_free(ift);
2038 }
2039
2040 static void irc_file_transfer_in(struct gaim_connection *gc,
2041 struct file_transfer *xfer, int offset) {
2042
2043 struct irc_data *id = (struct irc_data *)gc->proto_data;
2044 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer);
2045 struct sockaddr_in addr;
2046 char *ip = (char *)malloc(32);
2047
2048 ift->xfer = xfer;
2049 printf("You, I should be getting a file or some shit, hehe\n");
2050 printf("Connecting to: %s %d\n", ift->ip, ift->port);
2051 proxy_connect(ift->ip, ift->port, dcc_recv_callback, ift);
2052 }
2053
1898 static void irc_start_chat(struct gaim_connection *gc, char *who) { 2054 static void irc_start_chat(struct gaim_connection *gc, char *who) {
1899 struct dcc_chat *chat; 2055 struct dcc_chat *chat;
1900 int len; 2056 int len;
1901 struct sockaddr_in addr; 2057 struct sockaddr_in addr;
1902 char buf[200]; 2058 char buf[200];
1949 pbm = g_new0(struct proto_buddy_menu, 1); 2105 pbm = g_new0(struct proto_buddy_menu, 1);
1950 pbm->label = _("Get Info"); 2106 pbm->label = _("Get Info");
1951 pbm->callback = irc_get_info; 2107 pbm->callback = irc_get_info;
1952 pbm->gc = gc; 2108 pbm->gc = gc;
1953 m = g_list_append(m, pbm); 2109 m = g_list_append(m, pbm);
2110
1954 pbm = g_new0(struct proto_buddy_menu, 1); 2111 pbm = g_new0(struct proto_buddy_menu, 1);
1955 pbm->label = _("DCC Chat"); 2112 pbm->label = _("DCC Chat");
1956 pbm->callback = irc_start_chat; 2113 pbm->callback = irc_start_chat;
1957 pbm->gc = gc; 2114 pbm->gc = gc;
1958 m = g_list_append(m, pbm); 2115 m = g_list_append(m, pbm);
2116
2117 /*
2118 pbm = g_new0(struct proto_buddy_menu, 1);
2119 pbm->label = _("DCC Send");
2120 pbm->callback = irc_ask_send_file;
2121 pbm->gc = gc;
2122 m = g_list_append(m, pbm);
2123 */
2124
1959 return m; 2125 return m;
1960 } 2126 }
1961 2127
1962 static struct prpl *my_protocol = NULL; 2128 static struct prpl *my_protocol = NULL;
1963 2129
1981 ret->set_away = irc_set_away; 2147 ret->set_away = irc_set_away;
1982 ret->get_info = irc_get_info; 2148 ret->get_info = irc_get_info;
1983 ret->buddy_menu = irc_buddy_menu; 2149 ret->buddy_menu = irc_buddy_menu;
1984 ret->chat_invite = irc_chat_invite; 2150 ret->chat_invite = irc_chat_invite;
1985 ret->convo_closed = irc_convo_closed; 2151 ret->convo_closed = irc_convo_closed;
2152 ret->file_transfer_out = NULL; /* Implement me */
2153 ret->file_transfer_in = irc_file_transfer_in;
2154 ret->file_transfer_data_chunk = irc_file_transfer_data_chunk;
2155 ret->file_transfer_done = irc_file_transfer_done;
2156 ret->file_transfer_cancel =irc_file_transfer_cancel;
1986 2157
1987 puo = g_new0(struct proto_user_opt, 1); 2158 puo = g_new0(struct proto_user_opt, 1);
1988 puo->label = g_strdup("Server:"); 2159 puo->label = g_strdup("Server:");
1989 puo->def = g_strdup("irc.openprojects.net"); 2160 puo->def = g_strdup("irc.openprojects.net");
1990 puo->pos = USEROPT_SERV; 2161 puo->pos = USEROPT_SERV;
1994 puo->label = g_strdup("Port:"); 2165 puo->label = g_strdup("Port:");
1995 puo->def = g_strdup("6667"); 2166 puo->def = g_strdup("6667");
1996 puo->pos = USEROPT_PORT; 2167 puo->pos = USEROPT_PORT;
1997 ret->user_opts = g_list_append(ret->user_opts, puo); 2168 ret->user_opts = g_list_append(ret->user_opts, puo);
1998 2169
1999 my_protocol = ret; 2170 my_protocol = ret;
2000 } 2171 }
2001 2172
2002 #ifndef STATIC 2173 #ifndef STATIC
2003 2174
2004 void *gaim_prpl_init(struct prpl* prpl) 2175 void *gaim_prpl_init(struct prpl* prpl)