Mercurial > pidgin
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) |
