Mercurial > pidgin
comparison src/protocols/irc/irc.c @ 3751:e25577506dec
[gaim-migrate @ 3889]
from Jonas Birme' (birme):
* CTCP PING now calculates with usec.
* Some minor code cleanup.
from Ethan Blanton (eblanton):
This adds another option to IRC on a per-account basis
that specifies the encoding one wishes to use for
non-ASCII text. Like most of my recent patches,
send-path is not well tested but receive path appears
correct.
With this patch, accented chars/etc. should work
properly again over IRC. In addition, even IRC users
in different locales should be able to communicate
using non-ASCII character sets. :-)
committer: Tailor Script <tailor@pidgin.im>
| author | Luke Schierer <lschiere@pidgin.im> |
|---|---|
| date | Sat, 19 Oct 2002 05:04:58 +0000 |
| parents | 242e52b37a78 |
| children | fb519383a058 |
comparison
equal
deleted
inserted
replaced
| 3750:ddd9e50e547a | 3751:e25577506dec |
|---|---|
| 53 #define IRC_BUF_LEN 4096 | 53 #define IRC_BUF_LEN 4096 |
| 54 #define PDIWORDS 32 | 54 #define PDIWORDS 32 |
| 55 | 55 |
| 56 #define USEROPT_SERV 0 | 56 #define USEROPT_SERV 0 |
| 57 #define USEROPT_PORT 1 | 57 #define USEROPT_PORT 1 |
| 58 #define USEROPT_CHARSET 2 | |
| 58 | 59 |
| 59 /* for win32 compatability */ | 60 /* for win32 compatability */ |
| 60 G_MODULE_IMPORT GSList *connections; | 61 G_MODULE_IMPORT GSList *connections; |
| 61 | 62 |
| 62 | 63 |
| 63 static void irc_start_chat(struct gaim_connection *gc, char *who); | 64 /* Datastructs */ |
| 64 static void irc_ctcp_clientinfo(struct gaim_connection *gc, char *who); | |
| 65 static void irc_ctcp_userinfo(struct gaim_connection *gc, char *who); | |
| 66 static void irc_ctcp_version(struct gaim_connection *gc, char *who); | |
| 67 static void irc_ctcp_ping(struct gaim_connection *gc, char *who); | |
| 68 | |
| 69 static void irc_send_privmsg(struct gaim_connection *gc, char *who, char *what); | |
| 70 static void irc_send_notice(struct gaim_connection *gc, char *who, char *what); | |
| 71 | |
| 72 struct dcc_chat | 65 struct dcc_chat |
| 73 { | 66 { |
| 74 struct gaim_connection *gc; | 67 struct gaim_connection *gc; |
| 75 char ip_address[12]; | 68 char ip_address[12]; |
| 76 int port; | 69 int port; |
| 92 int fd; | 85 int fd; |
| 93 int cur; | 86 int cur; |
| 94 struct gaim_connection *gc; | 87 struct gaim_connection *gc; |
| 95 }; | 88 }; |
| 96 | 89 |
| 97 GSList *dcc_chat_list = NULL; | |
| 98 | |
| 99 struct irc_data { | 90 struct irc_data { |
| 100 int fd; | 91 int fd; |
| 101 gboolean online; | 92 gboolean online; |
| 102 guint32 timer; | 93 guint32 timer; |
| 103 | 94 |
| 115 gboolean in_whois; | 106 gboolean in_whois; |
| 116 gboolean in_list; | 107 gboolean in_list; |
| 117 GString *liststr; | 108 GString *liststr; |
| 118 GSList *file_transfers; | 109 GSList *file_transfers; |
| 119 }; | 110 }; |
| 111 | |
| 112 /* Prototypes */ | |
| 113 static void irc_start_chat(struct gaim_connection *gc, char *who); | |
| 114 static void irc_ctcp_clientinfo(struct gaim_connection *gc, char *who); | |
| 115 static void irc_ctcp_userinfo(struct gaim_connection *gc, char *who); | |
| 116 static void irc_ctcp_version(struct gaim_connection *gc, char *who); | |
| 117 static void irc_ctcp_ping(struct gaim_connection *gc, char *who); | |
| 118 | |
| 119 static void irc_send_privmsg(struct gaim_connection *gc, char *who, char *what, gboolean fragment); | |
| 120 static void irc_send_notice(struct gaim_connection *gc, char *who, char *what); | |
| 121 | |
| 122 static char *irc_send_convert(struct gaim_connection *gc, char *string, int maxlen, int *done); | |
| 123 static char *irc_recv_convert(struct gaim_connection *gc, char *string); | |
| 124 static void irc_parse_notice(struct gaim_connection *gc, char *nick, char *ex, | |
| 125 char *word[], char *word_eol[]); | |
| 126 static void irc_parse_join(struct gaim_connection *gc, char *nick, | |
| 127 char *word[], char *word_eol[]); | |
| 128 static gboolean irc_parse_part(struct gaim_connection *gc, char *nick, char *cmd, | |
| 129 char *word[], char *word_eol[]); | |
| 130 static void irc_parse_topic(struct gaim_connection *gc, char *nick, | |
| 131 char *word[], char *word_eol[]); | |
| 132 | |
| 133 static void dcc_chat_cancel(struct dcc_chat *); | |
| 134 | |
| 135 /* Global variables */ | |
| 136 GSList *dcc_chat_list = NULL; | |
| 120 | 137 |
| 121 struct dcc_chat * | 138 struct dcc_chat * |
| 122 find_dcc_chat (struct gaim_connection *gc, char *nick) | 139 find_dcc_chat (struct gaim_connection *gc, char *nick) |
| 123 { | 140 { |
| 124 GSList *tmp; | 141 GSList *tmp; |
| 137 tmp = tmp->next; | 154 tmp = tmp->next; |
| 138 } | 155 } |
| 139 return NULL; | 156 return NULL; |
| 140 } | 157 } |
| 141 | 158 |
| 142 static int irc_write(int fd, char *data, int len) | 159 static int |
| 160 irc_write(int fd, char *data, int len) | |
| 143 { | 161 { |
| 144 debug_printf("IRC C: %s", data); | 162 debug_printf("IRC C: %s", data); |
| 145 return write(fd, data, len); | 163 return write(fd, data, len); |
| 146 } | 164 } |
| 147 | 165 |
| 148 static struct conversation *irc_find_chat(struct gaim_connection *gc, char *name) | 166 static char * |
| 167 irc_send_convert(struct gaim_connection *gc, char *string, int maxlen, int *done) | |
| 168 { | |
| 169 char *converted = g_malloc(maxlen + 1); | |
| 170 gchar *inptr = string, *outptr = converted; | |
| 171 int inleft = strlen(string), outleft = maxlen; | |
| 172 GIConv conv; | |
| 173 | |
| 174 conv = g_iconv_open(gc->user->proto_opt[USEROPT_CHARSET], "UTF-8"); | |
| 175 if (g_iconv(conv, &inptr, &inleft, &outptr, &outleft) == -1) { | |
| 176 debug_printf("IRC charset conversion error\n"); | |
| 177 debug_printf("Sending as UTF-8 (this is a hack!)\n"); | |
| 178 g_free(converted); | |
| 179 *done = maxlen; | |
| 180 return(g_strndup(string, maxlen)); | |
| 181 } | |
| 182 | |
| 183 *done = strlen(string) - inleft; | |
| 184 *outptr = '\0'; | |
| 185 return(converted); | |
| 186 } | |
| 187 | |
| 188 static char * | |
| 189 irc_recv_convert(struct gaim_connection *gc, char *string) | |
| 190 { | |
| 191 char *utf8; | |
| 192 GError *err = NULL; | |
| 193 | |
| 194 utf8 = g_convert(string, strlen(string), "UTF-8", | |
| 195 gc->user->proto_opt[USEROPT_CHARSET], NULL, NULL, &err); | |
| 196 if (err) { | |
| 197 debug_printf("IRC recv conversion error: %s\n", err->message); | |
| 198 utf8 = g_strdup(_("(There was an error converting this message. Check the 'Encoding' option in the Account Editor)")); | |
| 199 } | |
| 200 | |
| 201 return (utf8); | |
| 202 } | |
| 203 | |
| 204 static struct conversation * | |
| 205 irc_find_chat(struct gaim_connection *gc, char *name) | |
| 149 { | 206 { |
| 150 GSList *bcs = gc->buddy_chats; | 207 GSList *bcs = gc->buddy_chats; |
| 151 | 208 |
| 152 while (bcs) { | 209 while (bcs) { |
| 153 struct conversation *b = bcs->data; | 210 struct conversation *b = bcs->data; |
| 156 bcs = bcs->next; | 213 bcs = bcs->next; |
| 157 } | 214 } |
| 158 return NULL; | 215 return NULL; |
| 159 } | 216 } |
| 160 | 217 |
| 161 static struct conversation *irc_find_chat_by_id(struct gaim_connection *gc, int id) | 218 static struct conversation * |
| 219 irc_find_chat_by_id(struct gaim_connection *gc, int id) | |
| 162 { | 220 { |
| 163 GSList *bcs = gc->buddy_chats; | 221 GSList *bcs = gc->buddy_chats; |
| 164 | 222 |
| 165 while (bcs) { | 223 while (bcs) { |
| 166 struct conversation *b = bcs->data; | 224 struct conversation *b = bcs->data; |
| 169 bcs = bcs->next; | 227 bcs = bcs->next; |
| 170 } | 228 } |
| 171 return NULL; | 229 return NULL; |
| 172 } | 230 } |
| 173 | 231 |
| 174 static void process_data_init(char *buf, char *cmd, char *word[], char *eol[], gboolean quotes) | 232 static void |
| 233 process_data_init(char *buf, char *cmd, char *word[], char *eol[], gboolean quotes) | |
| 175 { | 234 { |
| 176 int wordcount = 2; | 235 int wordcount = 2; |
| 177 gboolean space = FALSE; | 236 gboolean space = FALSE; |
| 178 gboolean quote = FALSE; | 237 gboolean quote = FALSE; |
| 179 int j = 0; | 238 int j = 0; |
| 221 } | 280 } |
| 222 cmd++; | 281 cmd++; |
| 223 } | 282 } |
| 224 } | 283 } |
| 225 | 284 |
| 226 static void handle_005(struct gaim_connection *gc, char *word[], char *word_eol[]) | 285 static void |
| 286 handle_005(struct gaim_connection *gc, char *word[], char *word_eol[]) | |
| 227 { | 287 { |
| 228 int w = 4; | 288 int w = 4; |
| 229 struct irc_data *id = gc->proto_data; | 289 struct irc_data *id = gc->proto_data; |
| 230 | 290 |
| 231 while (w < PDIWORDS && *word[w]) { | 291 while (w < PDIWORDS && *word[w]) { |
| 248 } | 308 } |
| 249 w++; | 309 w++; |
| 250 } | 310 } |
| 251 } | 311 } |
| 252 | 312 |
| 253 static char *int_to_col(int c) | 313 static char * |
| 314 int_to_col(int c) | |
| 254 { | 315 { |
| 255 switch(c) { | 316 switch(c) { |
| 256 case 1: | 317 case 1: |
| 257 return "#ffffff"; | 318 return "#ffffff"; |
| 258 case 2: | 319 case 2: |
| 286 default: | 347 default: |
| 287 return "#000000"; | 348 return "#000000"; |
| 288 } | 349 } |
| 289 } | 350 } |
| 290 | 351 |
| 291 static GString *encode_html(char *msg) | 352 static GString * |
| 353 encode_html(char *msg) | |
| 292 { | 354 { |
| 293 GString *str = g_string_new(""); | 355 GString *str = g_string_new(""); |
| 294 char *cur = msg, *end = msg; | 356 char *cur = msg, *end = msg; |
| 295 gboolean bold = FALSE, underline = FALSE, italics = FALSE; | 357 gboolean bold = FALSE, underline = FALSE, italics = FALSE; |
| 296 | 358 |
| 341 } | 403 } |
| 342 str = g_string_append(str, cur); | 404 str = g_string_append(str, cur); |
| 343 return str; | 405 return str; |
| 344 } | 406 } |
| 345 | 407 |
| 346 static GString *decode_html(char *msg) | 408 static GString * |
| 409 decode_html(char *msg) | |
| 347 { | 410 { |
| 348 GString /* oo la la */ *str = g_string_new(""); | 411 GString /* oo la la */ *str = g_string_new(""); |
| 349 char *cur = msg, *end = msg; | 412 char *cur = msg, *end = msg; |
| 350 gboolean bold = FALSE, underline = FALSE, fg = FALSE, bg = FALSE; | 413 gboolean bold = FALSE, underline = FALSE, fg = FALSE, bg = FALSE; |
| 351 int fore, back; | 414 int fore, back; |
| 438 if (*cur) | 501 if (*cur) |
| 439 str = g_string_append(str, cur); | 502 str = g_string_append(str, cur); |
| 440 return str; | 503 return str; |
| 441 } | 504 } |
| 442 | 505 |
| 443 static void irc_got_im(struct gaim_connection *gc, char *who, char *what, int flags, time_t t) | 506 static void |
| 444 { | 507 irc_got_im(struct gaim_connection *gc, char *who, char *what, int flags, time_t t) |
| 445 GString *str = decode_html(what); | 508 { |
| 509 char *utf8 = irc_recv_convert(gc, what); | |
| 510 GString *str = decode_html(utf8); | |
| 446 serv_got_im(gc, who, str->str, flags, t, -1); | 511 serv_got_im(gc, who, str->str, flags, t, -1); |
| 447 g_string_free(str, TRUE); | 512 g_string_free(str, TRUE); |
| 448 } | 513 g_free(utf8); |
| 449 | 514 } |
| 450 static void dcc_chat_cancel(struct dcc_chat *); | 515 |
| 516 static void | |
| 517 dcc_chat_cancel(struct dcc_chat *); | |
| 451 | 518 |
| 452 void | 519 void |
| 453 dcc_chat_in (gpointer data, gint source, GaimInputCondition condition) | 520 dcc_chat_in (gpointer data, gint source, GaimInputCondition condition) |
| 454 { | 521 { |
| 455 struct dcc_chat *chat = data; | 522 struct dcc_chat *chat = data; |
| 479 time ((time_t) NULL), -1); | 546 time ((time_t) NULL), -1); |
| 480 dcc_chat_cancel (chat); | 547 dcc_chat_cancel (chat); |
| 481 } | 548 } |
| 482 } | 549 } |
| 483 | 550 |
| 484 static void irc_file_transfer_do(struct gaim_connection *gc, struct irc_file_transfer *ift) { | 551 static void |
| 552 irc_file_transfer_do(struct gaim_connection *gc, struct irc_file_transfer *ift) { | |
| 485 /* Ok, we better be receiving some crap here boyeee */ | 553 /* Ok, we better be receiving some crap here boyeee */ |
| 486 if (transfer_in_do(ift->xfer, ift->fd, ift->name, ift->len)) { | 554 if (transfer_in_do(ift->xfer, ift->fd, ift->name, ift->len)) { |
| 487 gaim_input_remove(ift->watcher); | 555 gaim_input_remove(ift->watcher); |
| 488 ift->watcher = 0; | 556 ift->watcher = 0; |
| 489 } | 557 } |
| 490 } | 558 } |
| 491 | 559 |
| 492 | 560 |
| 493 void irc_read_dcc_ack (gpointer data, gint source, GaimInputCondition condition) { | 561 void |
| 562 irc_read_dcc_ack (gpointer data, gint source, GaimInputCondition condition) { | |
| 494 /* Read ACK Here */ | 563 /* Read ACK Here */ |
| 495 | 564 |
| 496 } | 565 } |
| 497 | 566 |
| 498 void dcc_send_callback (gpointer data, gint source, GaimInputCondition condition) { | 567 void |
| 568 dcc_send_callback (gpointer data, gint source, GaimInputCondition condition) { | |
| 499 struct irc_file_transfer *ift = data; | 569 struct irc_file_transfer *ift = data; |
| 500 struct sockaddr_in addr; | 570 struct sockaddr_in addr; |
| 501 int len = sizeof(addr); | 571 int len = sizeof(addr); |
| 502 | 572 |
| 503 addr.sin_family = AF_INET; | 573 addr.sin_family = AF_INET; |
| 517 gaim_input_remove(ift->watcher); | 587 gaim_input_remove(ift->watcher); |
| 518 ift->watcher = 0; | 588 ift->watcher = 0; |
| 519 } | 589 } |
| 520 } | 590 } |
| 521 | 591 |
| 522 void dcc_recv_callback (gpointer data, gint source, GaimInputCondition condition) { | 592 void |
| 593 dcc_recv_callback (gpointer data, gint source, GaimInputCondition condition) { | |
| 523 struct irc_file_transfer *ift = data; | 594 struct irc_file_transfer *ift = data; |
| 524 | 595 |
| 525 ift->fd = source; | 596 ift->fd = source; |
| 526 irc_file_transfer_do(ift->gc, ift); | 597 irc_file_transfer_do(ift->gc, ift); |
| 527 } | 598 } |
| 528 | 599 |
| 529 void dcc_chat_callback (gpointer data, gint source, GaimInputCondition condition) { | 600 void |
| 601 dcc_chat_callback (gpointer data, gint source, GaimInputCondition condition) { | |
| 530 struct dcc_chat *chat = data; | 602 struct dcc_chat *chat = data; |
| 531 struct conversation *convo = new_conversation (chat->nick); | 603 struct conversation *convo = new_conversation (chat->nick); |
| 532 char buf[IRC_BUF_LEN]; | 604 char buf[IRC_BUF_LEN]; |
| 533 chat->fd = source; | 605 chat->fd = source; |
| 534 g_snprintf (buf, sizeof buf, | 606 g_snprintf (buf, sizeof buf, |
| 540 dcc_chat_list = g_slist_append (dcc_chat_list, chat); | 612 dcc_chat_list = g_slist_append (dcc_chat_list, chat); |
| 541 gaim_input_remove(chat->inpa); | 613 gaim_input_remove(chat->inpa); |
| 542 chat->inpa = gaim_input_add(source, GAIM_INPUT_READ, dcc_chat_in, chat); | 614 chat->inpa = gaim_input_add(source, GAIM_INPUT_READ, dcc_chat_in, chat); |
| 543 } | 615 } |
| 544 | 616 |
| 545 static void irc_got_chat_in(struct gaim_connection *gc, int id, char *who, int whisper, char *msg, time_t t) | 617 static void |
| 546 { | 618 irc_got_chat_in(struct gaim_connection *gc, int id, char *who, int whisper, char *msg, time_t t) |
| 547 GString *str = decode_html(msg); | 619 { |
| 620 char *utf8 = irc_recv_convert(gc, msg); | |
| 621 GString *str = decode_html(utf8); | |
| 548 serv_got_chat_in(gc, id, who, whisper, str->str, t); | 622 serv_got_chat_in(gc, id, who, whisper, str->str, t); |
| 549 g_string_free(str, TRUE); | 623 g_string_free(str, TRUE); |
| 550 } | 624 g_free(utf8); |
| 551 | 625 } |
| 552 static void handle_list(struct gaim_connection *gc, char *list) | 626 |
| 627 static void | |
| 628 handle_list(struct gaim_connection *gc, char *list) | |
| 553 { | 629 { |
| 554 struct irc_data *id = gc->proto_data; | 630 struct irc_data *id = gc->proto_data; |
| 555 GSList *gr; | 631 GSList *gr; |
| 556 | 632 |
| 557 id->str = g_string_append_c(id->str, ' '); | 633 id->str = g_string_append_c(id->str, ' '); |
| 584 } | 660 } |
| 585 g_string_free(id->str, TRUE); | 661 g_string_free(id->str, TRUE); |
| 586 id->str = g_string_new(""); | 662 id->str = g_string_new(""); |
| 587 } | 663 } |
| 588 | 664 |
| 589 static gboolean irc_request_buddy_update(gpointer data) | 665 static gboolean |
| 666 irc_request_buddy_update(gpointer data) | |
| 590 { | 667 { |
| 591 struct gaim_connection *gc = data; | 668 struct gaim_connection *gc = data; |
| 592 struct irc_data *id = gc->proto_data; | 669 struct irc_data *id = gc->proto_data; |
| 593 char buf[500]; | 670 char buf[500]; |
| 594 int n = g_snprintf(buf, sizeof(buf), "ISON"); | 671 int n = g_snprintf(buf, sizeof(buf), "ISON"); |
| 617 irc_write(id->fd, buf, strlen(buf)); | 694 irc_write(id->fd, buf, strlen(buf)); |
| 618 id->bc++; | 695 id->bc++; |
| 619 return TRUE; | 696 return TRUE; |
| 620 } | 697 } |
| 621 | 698 |
| 622 static void handle_names(struct gaim_connection *gc, char *chan, char *names) | 699 static void |
| 700 handle_names(struct gaim_connection *gc, char *chan, char *names) | |
| 623 { | 701 { |
| 624 struct conversation *c = irc_find_chat(gc, chan); | 702 struct conversation *c = irc_find_chat(gc, chan); |
| 625 char **buf, **tmp; | 703 char **buf, **tmp; |
| 626 if (!c) return; | 704 if (!c) return; |
| 627 if (*names == ':') names++; | 705 if (*names == ':') names++; |
| 629 for (tmp = buf; *tmp; tmp++) | 707 for (tmp = buf; *tmp; tmp++) |
| 630 add_chat_buddy(c, *tmp, NULL); | 708 add_chat_buddy(c, *tmp, NULL); |
| 631 g_strfreev(buf); | 709 g_strfreev(buf); |
| 632 } | 710 } |
| 633 | 711 |
| 634 static void handle_notopic(struct gaim_connection *gc, char *text) | 712 static void |
| 713 handle_notopic(struct gaim_connection *gc, char *text) | |
| 635 { | 714 { |
| 636 struct conversation *c; | 715 struct conversation *c; |
| 637 if ((c = irc_find_chat(gc, text))) { | 716 if ((c = irc_find_chat(gc, text))) { |
| 638 char buf[IRC_BUF_LEN]; | 717 char buf[IRC_BUF_LEN]; |
| 639 g_snprintf(buf, sizeof(buf), _("No topic is set")); | 718 g_snprintf(buf, sizeof(buf), _("No topic is set")); |
| 640 chat_set_topic(c, NULL, buf); | 719 chat_set_topic(c, NULL, buf); |
| 641 } | 720 } |
| 642 } | 721 } |
| 643 | 722 |
| 644 static void handle_topic(struct gaim_connection *gc, char *text) | 723 static void |
| 724 handle_topic(struct gaim_connection *gc, char *text) | |
| 645 { | 725 { |
| 646 struct conversation *c; | 726 struct conversation *c; |
| 647 char *po = strchr(text, ' '); | 727 char *po = strchr(text, ' '); |
| 648 | 728 |
| 649 if (!po) | 729 if (!po) |
| 659 text, po); | 739 text, po); |
| 660 write_to_conv(c, buf, WFLAG_SYSTEM, NULL, time(NULL), -1); | 740 write_to_conv(c, buf, WFLAG_SYSTEM, NULL, time(NULL), -1); |
| 661 } | 741 } |
| 662 } | 742 } |
| 663 | 743 |
| 664 static gboolean mode_has_arg(struct gaim_connection *gc, char sign, char mode) | 744 static gboolean |
| 745 mode_has_arg(struct gaim_connection *gc, char sign, char mode) | |
| 665 { | 746 { |
| 666 struct irc_data *id = gc->proto_data; | 747 struct irc_data *id = gc->proto_data; |
| 667 char *cm = id->chanmodes; | 748 char *cm = id->chanmodes; |
| 668 int type = 0; | 749 int type = 0; |
| 669 | 750 |
| 689 } | 770 } |
| 690 | 771 |
| 691 return FALSE; | 772 return FALSE; |
| 692 } | 773 } |
| 693 | 774 |
| 694 static void irc_chan_mode(struct gaim_connection *gc, char *room, char sign, char mode, char *argstr, char *who) | 775 static void |
| 776 irc_chan_mode(struct gaim_connection *gc, char *room, char sign, char mode, char *argstr, char *who) | |
| 695 { | 777 { |
| 696 struct conversation *c = irc_find_chat(gc, room); | 778 struct conversation *c = irc_find_chat(gc, room); |
| 697 char buf[IRC_BUF_LEN]; | 779 char buf[IRC_BUF_LEN]; |
| 698 char *nick = g_strndup(who, strchr(who, '!') - who); | 780 char *nick = g_strndup(who, strchr(who, '!') - who); |
| 699 | 781 |
| 702 nick); | 784 nick); |
| 703 g_free(nick); | 785 g_free(nick); |
| 704 write_to_conv(c, buf, WFLAG_SYSTEM, NULL, time((time_t)NULL), -1); | 786 write_to_conv(c, buf, WFLAG_SYSTEM, NULL, time((time_t)NULL), -1); |
| 705 } | 787 } |
| 706 | 788 |
| 707 static void irc_user_mode(struct gaim_connection *gc, char *room, char sign, char mode, char *nick) | 789 static void |
| 790 irc_user_mode(struct gaim_connection *gc, char *room, char sign, char mode, char *nick) | |
| 708 { | 791 { |
| 709 struct conversation *c = irc_find_chat(gc, room); | 792 struct conversation *c = irc_find_chat(gc, room); |
| 710 GList *r; | 793 GList *r; |
| 711 | 794 |
| 712 if (mode != 'o' && mode != 'v') | 795 if (mode != 'o' && mode != 'v') |
| 750 } | 833 } |
| 751 r = r->next; | 834 r = r->next; |
| 752 } | 835 } |
| 753 } | 836 } |
| 754 | 837 |
| 755 static void handle_mode(struct gaim_connection *gc, char *word[], char *word_eol[], gboolean n324) | 838 static void |
| 839 handle_mode(struct gaim_connection *gc, char *word[], char *word_eol[], gboolean n324) | |
| 756 { | 840 { |
| 757 struct irc_data *id = gc->proto_data; | 841 struct irc_data *id = gc->proto_data; |
| 758 int offset = n324 ? 4 : 3; | 842 int offset = n324 ? 4 : 3; |
| 759 char *chan = word[offset]; | 843 char *chan = word[offset]; |
| 760 struct conversation *c = irc_find_chat(gc, chan); | 844 struct conversation *c = irc_find_chat(gc, chan); |
| 791 } | 875 } |
| 792 modes++; | 876 modes++; |
| 793 } | 877 } |
| 794 } | 878 } |
| 795 | 879 |
| 796 static void handle_version(struct gaim_connection *gc, char *word[], char *word_eol[], int num) | 880 static void |
| 881 handle_version(struct gaim_connection *gc, char *word[], char *word_eol[], int num) | |
| 797 { | 882 { |
| 798 struct irc_data *id = gc->proto_data; | 883 struct irc_data *id = gc->proto_data; |
| 799 GString *str; | 884 GString *str; |
| 800 | 885 |
| 801 id->liststr = g_string_new(""); | 886 id->liststr = g_string_new(""); |
| 808 g_string_free(str, TRUE); | 893 g_string_free(str, TRUE); |
| 809 g_string_free(id->liststr, TRUE); | 894 g_string_free(id->liststr, TRUE); |
| 810 id->liststr = NULL; | 895 id->liststr = NULL; |
| 811 } | 896 } |
| 812 | 897 |
| 813 static void handle_who(struct gaim_connection *gc, char *word[], char *word_eol[], int num) | 898 static void |
| 899 handle_who(struct gaim_connection *gc, char *word[], char *word_eol[], int num) | |
| 814 { | 900 { |
| 815 struct irc_data *id = gc->proto_data; | 901 struct irc_data *id = gc->proto_data; |
| 816 char buf[IRC_BUF_LEN]; | 902 char buf[IRC_BUF_LEN]; |
| 817 | 903 |
| 818 if (!id->in_whois) { | 904 if (!id->in_whois) { |
| 831 | 917 |
| 832 /* Handle our whois stuff here. You know what, I have a sore throat. You know | 918 /* Handle our whois stuff here. You know what, I have a sore throat. You know |
| 833 * what I think about that? I'm not too pleased with it. Perhaps I should take | 919 * what I think about that? I'm not too pleased with it. Perhaps I should take |
| 834 * some medicine, or perhaps I should go to bed? Blah!! */ | 920 * some medicine, or perhaps I should go to bed? Blah!! */ |
| 835 | 921 |
| 836 static void handle_whois(struct gaim_connection *gc, char *word[], char *word_eol[], int num) | 922 static void |
| 923 handle_whois(struct gaim_connection *gc, char *word[], char *word_eol[], int num) | |
| 837 { | 924 { |
| 838 struct irc_data *id = gc->proto_data; | 925 struct irc_data *id = gc->proto_data; |
| 839 char tmp[1024]; | 926 char tmp[1024]; |
| 840 | 927 |
| 841 if (!id->in_whois) { | 928 if (!id->in_whois) { |
| 887 } | 974 } |
| 888 else | 975 else |
| 889 id->liststr = g_string_append(id->liststr, word_eol[5]); | 976 id->liststr = g_string_append(id->liststr, word_eol[5]); |
| 890 } | 977 } |
| 891 | 978 |
| 892 static void handle_roomlist(struct gaim_connection *gc, char *word[], char *word_eol[]) | 979 static void |
| 980 handle_roomlist(struct gaim_connection *gc, char *word[], char *word_eol[]) | |
| 893 { | 981 { |
| 894 struct irc_data *id = gc->proto_data; | 982 struct irc_data *id = gc->proto_data; |
| 895 | 983 |
| 896 if (!id->in_list) { | 984 if (!id->in_list) { |
| 897 id->in_list = TRUE; | 985 id->in_list = TRUE; |
| 902 } | 990 } |
| 903 | 991 |
| 904 id->liststr = g_string_append(id->liststr, word_eol[4]); | 992 id->liststr = g_string_append(id->liststr, word_eol[4]); |
| 905 } | 993 } |
| 906 | 994 |
| 907 static void irc_change_nick(void *a, char *b) { | 995 static void |
| 996 irc_change_nick(void *a, char *b) { | |
| 908 struct gaim_connection *gc = a; | 997 struct gaim_connection *gc = a; |
| 909 struct irc_data *id = gc->proto_data; | 998 struct irc_data *id = gc->proto_data; |
| 910 char buf[IRC_BUF_LEN]; | 999 char buf[IRC_BUF_LEN]; |
| 911 g_snprintf(buf, sizeof(buf), "NICK %s\r\n", b); | 1000 g_snprintf(buf, sizeof(buf), "NICK %s\r\n", b); |
| 912 irc_write(id->fd, buf, strlen(buf)); | 1001 irc_write(id->fd, buf, strlen(buf)); |
| 913 } | 1002 } |
| 914 | 1003 |
| 915 static void process_numeric(struct gaim_connection *gc, char *word[], char *word_eol[]) | 1004 static void |
| 1005 process_numeric(struct gaim_connection *gc, char *word[], char *word_eol[]) | |
| 916 { | 1006 { |
| 917 struct irc_data *id = gc->proto_data; | 1007 struct irc_data *id = gc->proto_data; |
| 918 char *text = word_eol[3]; | 1008 char *text = word_eol[3]; |
| 919 int n = atoi(word[2]); | 1009 int n = atoi(word[2]); |
| 920 | 1010 |
| 1022 } | 1112 } |
| 1023 break; | 1113 break; |
| 1024 } | 1114 } |
| 1025 } | 1115 } |
| 1026 | 1116 |
| 1027 static gboolean is_channel(struct gaim_connection *gc, char *name) | 1117 static gboolean |
| 1118 is_channel(struct gaim_connection *gc, char *name) | |
| 1028 { | 1119 { |
| 1029 struct irc_data *id = gc->proto_data; | 1120 struct irc_data *id = gc->proto_data; |
| 1030 if (strchr(id->chantypes, *name)) | 1121 if (strchr(id->chantypes, *name)) |
| 1031 return TRUE; | 1122 return TRUE; |
| 1032 return FALSE; | 1123 return FALSE; |
| 1033 } | 1124 } |
| 1034 | 1125 |
| 1035 static void irc_rem_chat_bud(struct gaim_connection *gc, char *nick, char *reason) | 1126 static void |
| 1127 irc_rem_chat_bud(struct gaim_connection *gc, char *nick, char *reason) | |
| 1036 { | 1128 { |
| 1037 GSList *bcs = gc->buddy_chats; | 1129 GSList *bcs = gc->buddy_chats; |
| 1038 | 1130 |
| 1039 while (bcs) { | 1131 while (bcs) { |
| 1040 struct conversation *b = bcs->data; | 1132 struct conversation *b = bcs->data; |
| 1056 } | 1148 } |
| 1057 bcs = bcs->next; | 1149 bcs = bcs->next; |
| 1058 } | 1150 } |
| 1059 } | 1151 } |
| 1060 | 1152 |
| 1061 static void irc_change_name(struct gaim_connection *gc, char *old, char *new) | 1153 static void |
| 1154 irc_change_name(struct gaim_connection *gc, char *old, char *new) | |
| 1062 { | 1155 { |
| 1063 GSList *bcs = gc->buddy_chats; | 1156 GSList *bcs = gc->buddy_chats; |
| 1064 char buf[IRC_BUF_LEN]; | 1157 char buf[IRC_BUF_LEN]; |
| 1065 | 1158 |
| 1066 while (bcs) { | 1159 while (bcs) { |
| 1086 } | 1179 } |
| 1087 bcs = bcs->next; | 1180 bcs = bcs->next; |
| 1088 } | 1181 } |
| 1089 } | 1182 } |
| 1090 | 1183 |
| 1091 static void handle_privmsg(struct gaim_connection *gc, char *to, char *nick, char *msg) | 1184 static void |
| 1185 handle_privmsg(struct gaim_connection *gc, char *to, char *nick, char *msg) | |
| 1092 { | 1186 { |
| 1093 if (is_channel(gc, to)) { | 1187 if (is_channel(gc, to)) { |
| 1094 struct conversation *c = irc_find_chat(gc, to); | 1188 struct conversation *c = irc_find_chat(gc, to); |
| 1095 if (!c) | 1189 if (!c) |
| 1096 return; | 1190 return; |
| 1109 } | 1203 } |
| 1110 g_free(tmp); | 1204 g_free(tmp); |
| 1111 } | 1205 } |
| 1112 } | 1206 } |
| 1113 | 1207 |
| 1114 static void dcc_chat_init(struct dcc_chat *data) { | 1208 static void |
| 1209 dcc_chat_init(struct dcc_chat *data) { | |
| 1115 proxy_connect(data->ip_address, data->port, dcc_chat_callback, data); | 1210 proxy_connect(data->ip_address, data->port, dcc_chat_callback, data); |
| 1116 } | 1211 } |
| 1117 | 1212 |
| 1118 static void dcc_chat_cancel(struct dcc_chat *data){ | 1213 static void |
| 1214 dcc_chat_cancel(struct dcc_chat *data){ | |
| 1119 if (find_dcc_chat(data->gc, data->nick)) { | 1215 if (find_dcc_chat(data->gc, data->nick)) { |
| 1120 dcc_chat_list = g_slist_remove(dcc_chat_list, data); | 1216 dcc_chat_list = g_slist_remove(dcc_chat_list, data); |
| 1121 gaim_input_remove (data->inpa); | 1217 gaim_input_remove (data->inpa); |
| 1122 close (data->fd); | 1218 close (data->fd); |
| 1123 } | 1219 } |
| 1124 g_free(data); | 1220 g_free(data); |
| 1125 } | 1221 } |
| 1126 | 1222 |
| 1127 static void irc_convo_closed(struct gaim_connection *gc, char *who) | 1223 static void |
| 1224 irc_convo_closed(struct gaim_connection *gc, char *who) | |
| 1128 { | 1225 { |
| 1129 struct dcc_chat *dchat = find_dcc_chat(gc, who); | 1226 struct dcc_chat *dchat = find_dcc_chat(gc, who); |
| 1130 if (!dchat) | 1227 if (!dchat) |
| 1131 return; | 1228 return; |
| 1132 | 1229 |
| 1133 dcc_chat_cancel(dchat); | 1230 dcc_chat_cancel(dchat); |
| 1134 } | 1231 } |
| 1135 | 1232 |
| 1136 static void handle_ctcp(struct gaim_connection *gc, char *to, char *nick, | 1233 static void |
| 1234 handle_ctcp(struct gaim_connection *gc, char *to, char *nick, | |
| 1137 char *msg, char *word[], char *word_eol[]) | 1235 char *msg, char *word[], char *word_eol[]) |
| 1138 { | 1236 { |
| 1139 struct irc_data *id = gc->proto_data; | 1237 struct irc_data *id = gc->proto_data; |
| 1140 char buf[IRC_BUF_LEN]; | 1238 char buf[IRC_BUF_LEN]; |
| 1141 char out[IRC_BUF_LEN]; | 1239 char out[IRC_BUF_LEN]; |
| 1207 } | 1305 } |
| 1208 | 1306 |
| 1209 /*write_to_conv(c, out, WFLAG_SYSTEM, NULL, time(NULL), -1);*/ | 1307 /*write_to_conv(c, out, WFLAG_SYSTEM, NULL, time(NULL), -1);*/ |
| 1210 } | 1308 } |
| 1211 | 1309 |
| 1212 static gboolean irc_parse(struct gaim_connection *gc, char *buf) | 1310 static gboolean |
| 1311 irc_parse(struct gaim_connection *gc, char *buf) | |
| 1213 { | 1312 { |
| 1214 struct irc_data *idata = gc->proto_data; | 1313 struct irc_data *idata = gc->proto_data; |
| 1215 gchar outbuf[IRC_BUF_LEN]; | 1314 gchar outbuf[IRC_BUF_LEN]; |
| 1216 char *word[PDIWORDS], *word_eol[PDIWORDS]; | 1315 char *word[PDIWORDS], *word_eol[PDIWORDS]; |
| 1217 char pdibuf[522]; | 1316 char pdibuf[522]; |
| 1279 | 1378 |
| 1280 if (!strcmp(cmd, "INVITE")) { | 1379 if (!strcmp(cmd, "INVITE")) { |
| 1281 char *chan = g_strdup(word[4]); | 1380 char *chan = g_strdup(word[4]); |
| 1282 serv_got_chat_invite(gc, chan + 1, nick, NULL, g_list_append(NULL, chan)); | 1381 serv_got_chat_invite(gc, chan + 1, nick, NULL, g_list_append(NULL, chan)); |
| 1283 } else if (!strcmp(cmd, "JOIN")) { | 1382 } else if (!strcmp(cmd, "JOIN")) { |
| 1284 char *chan = *word[3] == ':' ? word[3] + 1 : word[3]; | 1383 irc_parse_join(gc, nick, word, word_eol); |
| 1285 if (!g_strcasecmp(gc->displayname, nick)) { | |
| 1286 static int id = 1; | |
| 1287 serv_got_joined_chat(gc, id++, chan); | |
| 1288 } else { | |
| 1289 struct conversation *c = irc_find_chat(gc, chan); | |
| 1290 if (c) { | |
| 1291 char *hostmask = g_strdup(word[1]); | |
| 1292 char *p = strchr(hostmask, '!'); | |
| 1293 if (p) { | |
| 1294 char *pend = strchr(p, ' '); | |
| 1295 if (pend) { | |
| 1296 *pend = 0; | |
| 1297 } | |
| 1298 add_chat_buddy(c, nick, p+1); | |
| 1299 g_free(hostmask); | |
| 1300 } | |
| 1301 } | |
| 1302 } | |
| 1303 | |
| 1304 } else if (!strcmp(cmd, "KICK")) { | 1384 } else if (!strcmp(cmd, "KICK")) { |
| 1305 if (!strcmp(gc->displayname, word[4])) { | 1385 if (!strcmp(gc->displayname, word[4])) { |
| 1306 struct conversation *c = irc_find_chat(gc, word[3]); | 1386 struct conversation *c = irc_find_chat(gc, word[3]); |
| 1307 if (!c) | 1387 if (!c) |
| 1308 return FALSE; | 1388 return FALSE; |
| 1324 char *new = *word_eol[3] == ':' ? word_eol[3] + 1 : word_eol[3]; | 1404 char *new = *word_eol[3] == ':' ? word_eol[3] + 1 : word_eol[3]; |
| 1325 if (!strcmp(gc->displayname, nick)) | 1405 if (!strcmp(gc->displayname, nick)) |
| 1326 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", new); | 1406 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", new); |
| 1327 irc_change_name(gc, nick, new); | 1407 irc_change_name(gc, nick, new); |
| 1328 } else if (!strcmp(cmd, "NOTICE")) { | 1408 } else if (!strcmp(cmd, "NOTICE")) { |
| 1329 char buf[IRC_BUF_LEN]; | 1409 irc_parse_notice(gc, nick, ex, word, word_eol); |
| 1330 if (!g_strcasecmp(word[4], ":\001CLIENTINFO")) { | |
| 1331 char *p = strrchr(word_eol[5], '\001'); | |
| 1332 *p = 0; | |
| 1333 g_snprintf(buf, sizeof(buf), "CTCP Answer: %s", | |
| 1334 word_eol[5]); | |
| 1335 do_error_dialog(buf, _("CTCP ClientInfo"), GAIM_INFO); | |
| 1336 } else if (!g_strcasecmp(word[4], ":\001USERINFO")) { | |
| 1337 char *p = strrchr(word_eol[5], '\001'); | |
| 1338 *p = 0; | |
| 1339 g_snprintf(buf, sizeof(buf), "CTCP Answer: %s", | |
| 1340 word_eol[5]); | |
| 1341 do_error_dialog(buf, _("CTCP UserInfo"), GAIM_INFO); | |
| 1342 } else if (!g_strcasecmp(word[4], ":\001VERSION")) { | |
| 1343 char *p = strrchr(word_eol[5], '\001'); | |
| 1344 *p = 0; | |
| 1345 g_snprintf(buf, sizeof(buf), "CTCP Answer: %s", | |
| 1346 word_eol[5]); | |
| 1347 do_error_dialog(buf, _("CTCP Version"), GAIM_INFO); | |
| 1348 } else if (!g_strcasecmp(word[4], ":\001PING")) { | |
| 1349 char *p = strrchr(word_eol[5], '\001'); | |
| 1350 time_t ping_time; | |
| 1351 if (p) | |
| 1352 *p = 0; | |
| 1353 ping_time = time(NULL) - atol(word_eol[5]); | |
| 1354 g_snprintf(buf, sizeof(buf), "CTCP Ping reply from %s; %d seconds", | |
| 1355 word[3], ping_time); | |
| 1356 do_error_dialog(buf, _("CTCP Ping"), GAIM_INFO); | |
| 1357 } else { | |
| 1358 if (*word_eol[4] == ':') word_eol[4]++; | |
| 1359 if (ex) | |
| 1360 irc_got_im(gc, nick, word_eol[4], 0, | |
| 1361 time(NULL)); | |
| 1362 } | |
| 1363 } else if (!strcmp(cmd, "PART")) { | 1410 } else if (!strcmp(cmd, "PART")) { |
| 1364 char *chan = cmd + 5; | 1411 if (!irc_parse_part(gc, nick, cmd, word, word_eol)) |
| 1365 struct conversation *c; | |
| 1366 char *reason = word_eol[4]; | |
| 1367 GList *r; | |
| 1368 if (*chan == ':') | |
| 1369 chan++; | |
| 1370 if (*reason == ':') | |
| 1371 reason++; | |
| 1372 if (!(c = irc_find_chat(gc, chan))) | |
| 1373 return FALSE; | 1412 return FALSE; |
| 1374 if (!strcmp(nick, gc->displayname)) { | |
| 1375 serv_got_chat_left(gc, c->id); | |
| 1376 return FALSE; | |
| 1377 } | |
| 1378 r = c->in_room; | |
| 1379 while (r) { | |
| 1380 char *who = r->data; | |
| 1381 if (*who == '@') | |
| 1382 who++; | |
| 1383 if (*who == '+') | |
| 1384 who++; | |
| 1385 if (!g_strcasecmp(who, nick)) { | |
| 1386 char *tmp = g_strdup(r->data); | |
| 1387 remove_chat_buddy(c, tmp, reason); | |
| 1388 g_free(tmp); | |
| 1389 break; | |
| 1390 } | |
| 1391 r = r->next; | |
| 1392 } | |
| 1393 } else if (!strcmp(cmd, "PRIVMSG")) { | 1413 } else if (!strcmp(cmd, "PRIVMSG")) { |
| 1394 char *to, *msg; | 1414 char *to, *msg; |
| 1395 if (!*word[3]) | 1415 if (!*word[3]) |
| 1396 return FALSE; | 1416 return FALSE; |
| 1397 to = word[3]; | 1417 to = word[3]; |
| 1405 } | 1425 } |
| 1406 } else if (!strcmp(cmd, "PONG")) { /* */ | 1426 } else if (!strcmp(cmd, "PONG")) { /* */ |
| 1407 } else if (!strcmp(cmd, "QUIT")) { | 1427 } else if (!strcmp(cmd, "QUIT")) { |
| 1408 irc_rem_chat_bud(gc, nick, *word_eol[3] == ':' ? word_eol[3] + 1 : word_eol[3]); | 1428 irc_rem_chat_bud(gc, nick, *word_eol[3] == ':' ? word_eol[3] + 1 : word_eol[3]); |
| 1409 } else if (!strcmp(cmd, "TOPIC")) { | 1429 } else if (!strcmp(cmd, "TOPIC")) { |
| 1410 struct conversation *c = irc_find_chat(gc, word[3]); | 1430 irc_parse_topic(gc, nick, word, word_eol); |
| 1411 char *topic = *word_eol[4] == ':' ? word_eol[4] + 1 : word_eol[4]; | |
| 1412 if (c) { | |
| 1413 char buf[IRC_BUF_LEN]; | |
| 1414 chat_set_topic(c, nick, topic); | |
| 1415 g_snprintf(buf, sizeof(buf), _("<B>%s has changed the topic to: %s</B>"), | |
| 1416 nick, topic); | |
| 1417 write_to_conv(c, buf, WFLAG_SYSTEM, NULL, time(NULL), -1); | |
| 1418 } | |
| 1419 } else if (!strcmp(cmd, "WALLOPS")) { /* Don't know if a dialog box is the right way? */ | 1431 } else if (!strcmp(cmd, "WALLOPS")) { /* Don't know if a dialog box is the right way? */ |
| 1420 char *msg = strrchr(word_eol[0], ':'); | 1432 char *msg = strrchr(word_eol[0], ':'); |
| 1421 if (msg) | 1433 if (msg) |
| 1422 do_error_dialog(msg+1, _("IRC Operator"), GAIM_ERROR); | 1434 do_error_dialog(msg+1, _("IRC Operator"), GAIM_ERROR); |
| 1423 } | 1435 } |
| 1424 | 1436 |
| 1425 return FALSE; | 1437 return FALSE; |
| 1426 } | 1438 } |
| 1427 | 1439 |
| 1428 static void irc_callback(gpointer data, gint source, GaimInputCondition condition) | 1440 /* CTCP by jonas@birme.se */ |
| 1441 static void | |
| 1442 irc_parse_notice(struct gaim_connection *gc, char *nick, char *ex, | |
| 1443 char *word[], char *word_eol[]) | |
| 1444 { | |
| 1445 char buf[IRC_BUF_LEN]; | |
| 1446 | |
| 1447 if (!g_strcasecmp(word[4], ":\001CLIENTINFO")) { | |
| 1448 char *p = g_strrstr(word_eol[5], "\001"); | |
| 1449 *p = 0; | |
| 1450 g_snprintf(buf, sizeof(buf), "CTCP Answer: %s", | |
| 1451 word_eol[5]); | |
| 1452 do_error_dialog(buf, _("CTCP ClientInfo"), GAIM_INFO); | |
| 1453 } else if (!g_strcasecmp(word[4], ":\001USERINFO")) { | |
| 1454 char *p = g_strrstr(word_eol[5], "\001"); | |
| 1455 *p = 0; | |
| 1456 g_snprintf(buf, sizeof(buf), "CTCP Answer: %s", | |
| 1457 word_eol[5]); | |
| 1458 do_error_dialog(buf, _("CTCP UserInfo"), GAIM_INFO); | |
| 1459 } else if (!g_strcasecmp(word[4], ":\001VERSION")) { | |
| 1460 char *p = g_strrstr(word_eol[5], "\001"); | |
| 1461 *p = 0; | |
| 1462 g_snprintf(buf, sizeof(buf), "CTCP Answer: %s", | |
| 1463 word_eol[5]); | |
| 1464 do_error_dialog(buf, _("CTCP Version"), GAIM_INFO); | |
| 1465 } else if (!g_strcasecmp(word[4], ":\001PING")) { | |
| 1466 char *p = g_strrstr(word_eol[5], "\001"); | |
| 1467 struct timeval ping_time; | |
| 1468 struct timeval now; | |
| 1469 gchar **vector; | |
| 1470 if (p) | |
| 1471 *p = 0; | |
| 1472 vector = g_strsplit(word_eol[5], " ", 2); | |
| 1473 if (gettimeofday(&now, NULL) == 0 && vector != NULL) { | |
| 1474 if (now.tv_usec - atol(vector[1]) < 0) { | |
| 1475 ping_time.tv_sec = now.tv_sec - atol(vector[0]) - 1; | |
| 1476 ping_time.tv_usec = now.tv_usec - atol(vector[1]) + 1000000; | |
| 1477 } else { | |
| 1478 ping_time.tv_sec = now.tv_sec - atol(vector[0]); | |
| 1479 ping_time.tv_usec = now.tv_usec - atol(vector[1]); | |
| 1480 } | |
| 1481 g_snprintf(buf, sizeof(buf), | |
| 1482 "CTCP Ping reply from %s: %lu.%.03lu seconds", | |
| 1483 nick, ping_time.tv_sec, (ping_time.tv_usec/1000)); | |
| 1484 do_error_dialog(buf, _("CTCP Ping"), GAIM_INFO); | |
| 1485 g_strfreev(vector); | |
| 1486 } | |
| 1487 } else { | |
| 1488 if (*word_eol[4] == ':') word_eol[4]++; | |
| 1489 if (ex) | |
| 1490 irc_got_im(gc, nick, word_eol[4], 0, | |
| 1491 time(NULL)); | |
| 1492 } | |
| 1493 | |
| 1494 } | |
| 1495 | |
| 1496 static void | |
| 1497 irc_parse_join(struct gaim_connection *gc, char *nick, | |
| 1498 char *word[], char *word_eol[]) | |
| 1499 { | |
| 1500 char *chan = *word[3] == ':' ? word[3] + 1 : word[3]; | |
| 1501 static int id = 1; | |
| 1502 struct conversation *c; | |
| 1503 char *hostmask, *p; | |
| 1504 | |
| 1505 if (!g_strcasecmp(gc->displayname, nick)) { | |
| 1506 serv_got_joined_chat(gc, id++, chan); | |
| 1507 } else { | |
| 1508 c = irc_find_chat(gc, chan); | |
| 1509 if (c) { | |
| 1510 hostmask = g_strdup(word[1]); | |
| 1511 p = strchr(hostmask, '!'); | |
| 1512 if (p) { | |
| 1513 char *pend = strchr(p, ' '); | |
| 1514 if (pend) { | |
| 1515 *pend = 0; | |
| 1516 } | |
| 1517 add_chat_buddy(c, nick, p+1); | |
| 1518 g_free(hostmask); | |
| 1519 } | |
| 1520 } | |
| 1521 } | |
| 1522 } | |
| 1523 | |
| 1524 static void | |
| 1525 irc_parse_topic(struct gaim_connection *gc, char *nick, | |
| 1526 char *word[], char *word_eol[]) | |
| 1527 { | |
| 1528 struct conversation *c = irc_find_chat(gc, word[3]); | |
| 1529 char *topic = *word_eol[4] == ':' ? word_eol[4] + 1 : word_eol[4]; | |
| 1530 char buf[IRC_BUF_LEN]; | |
| 1531 | |
| 1532 if (c) { | |
| 1533 chat_set_topic(c, nick, topic); | |
| 1534 g_snprintf(buf, sizeof(buf), _("<B>%s has changed the topic to: %s</B>"), | |
| 1535 nick, topic); | |
| 1536 write_to_conv(c, buf, WFLAG_SYSTEM, NULL, time(NULL), -1); | |
| 1537 } | |
| 1538 } | |
| 1539 | |
| 1540 static gboolean | |
| 1541 irc_parse_part(struct gaim_connection *gc, char *nick, char *cmd, | |
| 1542 char *word[], char *word_eol[]) | |
| 1543 { | |
| 1544 char *chan = cmd + 5; | |
| 1545 struct conversation *c; | |
| 1546 char *reason = word_eol[4]; | |
| 1547 GList *r; | |
| 1548 | |
| 1549 if (*chan == ':') | |
| 1550 chan++; | |
| 1551 if (*reason == ':') | |
| 1552 reason++; | |
| 1553 if (!(c = irc_find_chat(gc, chan))) | |
| 1554 return FALSE; | |
| 1555 if (!strcmp(nick, gc->displayname)) { | |
| 1556 serv_got_chat_left(gc, c->id); | |
| 1557 return FALSE; | |
| 1558 } | |
| 1559 r = c->in_room; | |
| 1560 while (r) { | |
| 1561 char *who = r->data; | |
| 1562 if (*who == '@') | |
| 1563 who++; | |
| 1564 if (*who == '+') | |
| 1565 who++; | |
| 1566 if (!g_strcasecmp(who, nick)) { | |
| 1567 char *tmp = g_strdup(r->data); | |
| 1568 remove_chat_buddy(c, tmp, reason); | |
| 1569 g_free(tmp); | |
| 1570 break; | |
| 1571 } | |
| 1572 r = r->next; | |
| 1573 } | |
| 1574 } | |
| 1575 | |
| 1576 static void | |
| 1577 irc_callback(gpointer data, gint source, | |
| 1578 GaimInputCondition condition) | |
| 1429 { | 1579 { |
| 1430 struct gaim_connection *gc = data; | 1580 struct gaim_connection *gc = data; |
| 1431 struct irc_data *idata = gc->proto_data; | 1581 struct irc_data *idata = gc->proto_data; |
| 1432 int i = 0; | 1582 int i = 0; |
| 1433 gchar buf[1024]; | 1583 gchar buf[1024]; |
| 1456 d = g_strndup(idata->rxqueue, len); | 1606 d = g_strndup(idata->rxqueue, len); |
| 1457 g_strchomp(d); | 1607 g_strchomp(d); |
| 1458 debug_printf("IRC S: %s\n", d); | 1608 debug_printf("IRC S: %s\n", d); |
| 1459 | 1609 |
| 1460 /* REMOVE ME BEFORE SUBMIT! */ | 1610 /* REMOVE ME BEFORE SUBMIT! */ |
| 1461 /* fprintf(stderr, "IRC S: %s\n", d); */ | 1611 /*fprintf(stderr, "IRC S: %s\n", d);*/ |
| 1462 | 1612 |
| 1463 idata->rxlen -= len; | 1613 idata->rxlen -= len; |
| 1464 if (idata->rxlen) { | 1614 if (idata->rxlen) { |
| 1465 char *tmp = g_strdup(e + 1); | 1615 char *tmp = g_strdup(e + 1); |
| 1466 g_free(idata->rxqueue); | 1616 g_free(idata->rxqueue); |
| 1477 if (off) | 1627 if (off) |
| 1478 return; | 1628 return; |
| 1479 } | 1629 } |
| 1480 } | 1630 } |
| 1481 | 1631 |
| 1482 static void irc_login_callback(gpointer data, gint source, GaimInputCondition condition) | 1632 static void |
| 1633 irc_login_callback(gpointer data, gint source, GaimInputCondition condition) | |
| 1483 { | 1634 { |
| 1484 struct gaim_connection *gc = data; | 1635 struct gaim_connection *gc = data; |
| 1485 struct irc_data *idata; | 1636 struct irc_data *idata; |
| 1486 char hostname[256]; | 1637 char hostname[256]; |
| 1487 char buf[IRC_BUF_LEN]; | 1638 char buf[IRC_BUF_LEN]; |
| 1488 | 1639 char *test; |
| 1640 GError *err = NULL; | |
| 1641 | |
| 1489 if (!g_slist_find(connections, gc)) { | 1642 if (!g_slist_find(connections, gc)) { |
| 1490 close(source); | 1643 close(source); |
| 1491 return; | 1644 return; |
| 1492 } | 1645 } |
| 1493 | 1646 |
| 1497 hide_login_progress(gc, "Write error"); | 1650 hide_login_progress(gc, "Write error"); |
| 1498 signoff(gc); | 1651 signoff(gc); |
| 1499 return; | 1652 return; |
| 1500 } | 1653 } |
| 1501 | 1654 |
| 1655 | |
| 1656 /* Try a quick conversion to see if the specified encoding is OK */ | |
| 1657 test = g_convert("test", strlen("test"), gc->user->proto_opt[USEROPT_CHARSET], | |
| 1658 "UTF-8", NULL, NULL, &err); | |
| 1659 if (err) { | |
| 1660 debug_printf("Couldn't initialize %s for IRC charset conversion, using ISO-8859-1\n", | |
| 1661 gc->user->proto_opt[USEROPT_CHARSET]); | |
| 1662 strcpy(gc->user->proto_opt[USEROPT_CHARSET], "ISO-8859-1"); | |
| 1663 } | |
| 1664 | |
| 1502 if (idata->fd != source) | 1665 if (idata->fd != source) |
| 1503 idata->fd = source; | 1666 idata->fd = source; |
| 1504 | 1667 |
| 1505 gethostname(hostname, sizeof(hostname) - 1); | 1668 gethostname(hostname, sizeof(hostname) - 1); |
| 1506 hostname[sizeof(hostname) - 1] = 0; | 1669 hostname[sizeof(hostname) - 1] = 0; |
| 1524 } | 1687 } |
| 1525 | 1688 |
| 1526 gc->inpa = gaim_input_add(idata->fd, GAIM_INPUT_READ, irc_callback, gc); | 1689 gc->inpa = gaim_input_add(idata->fd, GAIM_INPUT_READ, irc_callback, gc); |
| 1527 } | 1690 } |
| 1528 | 1691 |
| 1529 static void irc_login(struct aim_user *user) | 1692 static void |
| 1693 irc_login(struct aim_user *user) | |
| 1530 { | 1694 { |
| 1531 char buf[IRC_BUF_LEN]; | 1695 char buf[IRC_BUF_LEN]; |
| 1532 | 1696 |
| 1533 struct gaim_connection *gc = new_gaim_conn(user); | 1697 struct gaim_connection *gc = new_gaim_conn(user); |
| 1534 struct irc_data *idata = gc->proto_data = g_new0(struct irc_data, 1); | 1698 struct irc_data *idata = gc->proto_data = g_new0(struct irc_data, 1); |
| 1552 signoff(gc); | 1716 signoff(gc); |
| 1553 return; | 1717 return; |
| 1554 } | 1718 } |
| 1555 } | 1719 } |
| 1556 | 1720 |
| 1557 static void irc_close(struct gaim_connection *gc) | 1721 static void |
| 1722 irc_close(struct gaim_connection *gc) | |
| 1558 { | 1723 { |
| 1559 struct irc_data *idata = (struct irc_data *)gc->proto_data; | 1724 struct irc_data *idata = (struct irc_data *)gc->proto_data; |
| 1560 | 1725 |
| 1561 gchar buf[IRC_BUF_LEN]; | 1726 gchar buf[IRC_BUF_LEN]; |
| 1562 | 1727 |
| 1605 | 1770 |
| 1606 close(idata->fd); | 1771 close(idata->fd); |
| 1607 g_free(gc->proto_data); | 1772 g_free(gc->proto_data); |
| 1608 } | 1773 } |
| 1609 | 1774 |
| 1610 static void set_mode_3(struct gaim_connection *gc, char *who, int sign, int mode, | 1775 static void |
| 1776 set_mode_3(struct gaim_connection *gc, char *who, int sign, int mode, | |
| 1611 int start, int end, char *word[]) | 1777 int start, int end, char *word[]) |
| 1612 { | 1778 { |
| 1613 struct irc_data *id = gc->proto_data; | 1779 struct irc_data *id = gc->proto_data; |
| 1614 char buf[IRC_BUF_LEN]; | 1780 char buf[IRC_BUF_LEN]; |
| 1615 int left; | 1781 int left; |
| 1641 if (left < 3) | 1807 if (left < 3) |
| 1642 return; | 1808 return; |
| 1643 } | 1809 } |
| 1644 } | 1810 } |
| 1645 | 1811 |
| 1646 static void set_mode_6(struct gaim_connection *gc, char *who, int sign, int mode, | 1812 static void |
| 1813 set_mode_6(struct gaim_connection *gc, char *who, int sign, int mode, | |
| 1647 int start, int end, char *word[]) | 1814 int start, int end, char *word[]) |
| 1648 { | 1815 { |
| 1649 struct irc_data *id = gc->proto_data; | 1816 struct irc_data *id = gc->proto_data; |
| 1650 char buf[IRC_BUF_LEN]; | 1817 char buf[IRC_BUF_LEN]; |
| 1651 int left; | 1818 int left; |
| 1697 if (left < 6) | 1864 if (left < 6) |
| 1698 return; | 1865 return; |
| 1699 } | 1866 } |
| 1700 } | 1867 } |
| 1701 | 1868 |
| 1702 static void set_mode(struct gaim_connection *gc, char *who, int sign, int mode, char *word[]) | 1869 static void |
| 1870 set_mode(struct gaim_connection *gc, char *who, int sign, int mode, char *word[]) | |
| 1703 { | 1871 { |
| 1704 struct irc_data *id = gc->proto_data; | 1872 struct irc_data *id = gc->proto_data; |
| 1705 int i = 2; | 1873 int i = 2; |
| 1706 | 1874 |
| 1707 while (1) { | 1875 while (1) { |
| 1716 } | 1884 } |
| 1717 i++; | 1885 i++; |
| 1718 } | 1886 } |
| 1719 } | 1887 } |
| 1720 | 1888 |
| 1721 static void set_chan_mode(struct gaim_connection *gc, char *chan, char *mode_str) | 1889 static void |
| 1890 set_chan_mode(struct gaim_connection *gc, char *chan, char *mode_str) | |
| 1722 { | 1891 { |
| 1723 struct irc_data *id = gc->proto_data; | 1892 struct irc_data *id = gc->proto_data; |
| 1724 char buf[IRC_BUF_LEN]; | 1893 char buf[IRC_BUF_LEN]; |
| 1725 | 1894 |
| 1726 if ((mode_str[0] == '-') || (mode_str[0] == '+')) { | 1895 if ((mode_str[0] == '-') || (mode_str[0] == '+')) { |
| 1727 g_snprintf(buf, sizeof(buf), "MODE %s %s\r\n", chan, mode_str); | 1896 g_snprintf(buf, sizeof(buf), "MODE %s %s\r\n", chan, mode_str); |
| 1728 irc_write(id->fd, buf, strlen(buf)); | 1897 irc_write(id->fd, buf, strlen(buf)); |
| 1729 } | 1898 } |
| 1730 } | 1899 } |
| 1731 | 1900 |
| 1732 static int handle_command(struct gaim_connection *gc, char *who, char *what) | 1901 static int |
| 1902 handle_command(struct gaim_connection *gc, char *who, char *what) | |
| 1733 { | 1903 { |
| 1734 char buf[IRC_BUF_LEN]; | 1904 char buf[IRC_BUF_LEN]; |
| 1735 char pdibuf[IRC_BUF_LEN]; | 1905 char pdibuf[IRC_BUF_LEN]; |
| 1736 char *word[PDIWORDS], *word_eol[PDIWORDS]; | 1906 char *word[PDIWORDS], *word_eol[PDIWORDS]; |
| 1737 char *tmp = g_strdup(what); | 1907 char *tmp = g_strdup(what); |
| 1738 GString *str = encode_html(tmp); | 1908 GString *str = encode_html(tmp); |
| 1909 char *intl; | |
| 1910 int len; | |
| 1739 struct dcc_chat *dccchat = find_dcc_chat(gc, who); | 1911 struct dcc_chat *dccchat = find_dcc_chat(gc, who); |
| 1740 struct irc_data *id = gc->proto_data; | 1912 struct irc_data *id = gc->proto_data; |
| 1741 g_free(tmp); | 1913 g_free(tmp); |
| 1742 what = str->str; | 1914 what = str->str; |
| 1743 if (*what != '/') { | 1915 if (*what != '/') { |
| 1744 unsigned int max = 440 - strlen(who); | |
| 1745 char t; | |
| 1746 while (strlen(what) > max) { | |
| 1747 t = what[max]; | |
| 1748 what[max] = 0; | |
| 1749 if (dccchat) { | |
| 1750 g_snprintf(buf, sizeof(buf), "%s\r\n", what); | |
| 1751 irc_write(dccchat->fd, buf, strlen(buf)); | |
| 1752 g_string_free(str, TRUE); | |
| 1753 return 1; | |
| 1754 } | |
| 1755 /*g_snprintf(buf, sizeof(buf), "PRIVMSG %s :%s\r\n", who, what); | |
| 1756 irc_write(id->fd, buf, strlen(buf));*/ | |
| 1757 irc_send_privmsg (gc, who, what); | |
| 1758 what[max] = t; | |
| 1759 what = what + max; | |
| 1760 } | |
| 1761 if (dccchat) { | 1916 if (dccchat) { |
| 1762 g_snprintf(buf, sizeof(buf), "%s\r\n", what); | 1917 intl = irc_send_convert(gc, what, sizeof(buf), &len); |
| 1918 g_snprintf(buf, sizeof(buf), "%s\r\n", intl); | |
| 1919 g_free(intl); | |
| 1763 irc_write(dccchat->fd, buf, strlen(buf)); | 1920 irc_write(dccchat->fd, buf, strlen(buf)); |
| 1764 g_string_free(str, TRUE); | 1921 g_string_free(str, TRUE); |
| 1765 return 1; | 1922 return 1; |
| 1766 } | 1923 } |
| 1767 /* | 1924 irc_send_privmsg (gc, who, what, TRUE); |
| 1768 g_snprintf(buf, sizeof(buf), "PRIVMSG %s :%s\r\n", who, what); | |
| 1769 irc_write(id->fd, buf, strlen(buf));*/ | |
| 1770 irc_send_privmsg (gc, who, what); | |
| 1771 g_string_free(str, TRUE); | 1925 g_string_free(str, TRUE); |
| 1772 return 1; | 1926 return 1; |
| 1773 } | 1927 } |
| 1774 | 1928 |
| 1775 process_data_init(pdibuf, what + 1, word, word_eol, TRUE); | 1929 process_data_init(pdibuf, what + 1, word, word_eol, TRUE); |
| 1776 g_string_free(str, FALSE); | 1930 g_string_free(str, FALSE); |
| 1777 if (!g_strcasecmp(pdibuf, "ME")) { | 1931 if (!g_strcasecmp(pdibuf, "ME")) { |
| 1778 if (dccchat) { | 1932 if (dccchat) { |
| 1779 g_snprintf(buf, sizeof(buf), "\001ACTION %s\001\r\n", word_eol[2]); | 1933 intl = irc_send_convert(gc, word_eol[2], sizeof(buf), &len); |
| 1934 g_snprintf(buf, sizeof(buf), "\001ACTION %s\001\r\n", intl); | |
| 1935 g_free(intl); | |
| 1780 irc_write(dccchat->fd, buf, strlen(buf)); | 1936 irc_write(dccchat->fd, buf, strlen(buf)); |
| 1781 g_free(what); | 1937 g_free(what); |
| 1782 return 1; | 1938 return 1; |
| 1783 } | 1939 } |
| 1784 /* | |
| 1785 g_snprintf(buf, sizeof(buf), "PRIVMSG %s :\001ACTION %s\001\r\n", who, word_eol[2]); | |
| 1786 irc_write(id->fd, buf, strlen(buf));*/ | |
| 1787 g_snprintf(buf, sizeof(buf), "\001ACTION %s\001", word_eol[2]); | 1940 g_snprintf(buf, sizeof(buf), "\001ACTION %s\001", word_eol[2]); |
| 1788 irc_send_privmsg (gc, who, buf); | 1941 irc_send_privmsg (gc, who, buf, FALSE); |
| 1789 g_free(what); | 1942 g_free(what); |
| 1790 return 1; | 1943 return 1; |
| 1791 } else if (!g_strcasecmp(pdibuf, "INVITE")) { | 1944 } else if (!g_strcasecmp(pdibuf, "INVITE")) { |
| 1792 char buf[IRC_BUF_LEN]; | 1945 char buf[IRC_BUF_LEN]; |
| 1793 g_snprintf(buf, sizeof(buf), "INVITE %s\r\n", word_eol[2]); | 1946 g_snprintf(buf, sizeof(buf), "INVITE %s\r\n", word_eol[2]); |
| 1797 struct conversation *c; | 1950 struct conversation *c; |
| 1798 c = irc_find_chat(gc, who); | 1951 c = irc_find_chat(gc, who); |
| 1799 g_snprintf(buf, sizeof(buf), _("Topic for %s is %s"), who, c->topic ? c->topic : "(no topic set)"); | 1952 g_snprintf(buf, sizeof(buf), _("Topic for %s is %s"), who, c->topic ? c->topic : "(no topic set)"); |
| 1800 write_to_conv(c, buf, WFLAG_SYSTEM | WFLAG_NOLOG, NULL, time(NULL), -1); | 1953 write_to_conv(c, buf, WFLAG_SYSTEM | WFLAG_NOLOG, NULL, time(NULL), -1); |
| 1801 } else { | 1954 } else { |
| 1802 g_snprintf(buf, sizeof(buf), "TOPIC %s :%s\r\n", who, word_eol[2]); | 1955 /* This could be too long */ |
| 1956 intl = irc_send_convert(gc, word_eol[2], sizeof(buf), &len); | |
| 1957 g_snprintf(buf, sizeof(buf), "TOPIC %s :%s\r\n", who, intl); | |
| 1958 g_free(intl); | |
| 1803 irc_write(id->fd, buf, strlen(buf)); | 1959 irc_write(id->fd, buf, strlen(buf)); |
| 1804 } | 1960 } |
| 1805 } else if (!g_strcasecmp(pdibuf, "NICK")) { | 1961 } else if (!g_strcasecmp(pdibuf, "NICK")) { |
| 1806 if (!*word_eol[2]) { | 1962 if (!*word_eol[2]) { |
| 1807 g_free(what); | 1963 g_free(what); |
| 1830 } else if (!g_strcasecmp(pdibuf, "SAY")) { | 1986 } else if (!g_strcasecmp(pdibuf, "SAY")) { |
| 1831 if (!*word_eol[2]) { | 1987 if (!*word_eol[2]) { |
| 1832 g_free(what); | 1988 g_free(what); |
| 1833 return -EINVAL; | 1989 return -EINVAL; |
| 1834 } | 1990 } |
| 1835 /*g_snprintf(buf, sizeof(buf), "PRIVMSG %s :%s\r\n", who, word_eol[2]); | 1991 irc_send_privmsg (gc, who, word_eol[2], TRUE); |
| 1836 irc_write(id->fd, buf, strlen(buf));*/ | |
| 1837 irc_send_privmsg (gc, who, word_eol[2]); | |
| 1838 return 1; | 1992 return 1; |
| 1839 } else if (!g_strcasecmp(pdibuf, "MSG")) { | 1993 } else if (!g_strcasecmp(pdibuf, "MSG")) { |
| 1840 if (!*word[2]) { | 1994 if (!*word[2]) { |
| 1841 g_free(what); | 1995 g_free(what); |
| 1842 return -EINVAL; | 1996 return -EINVAL; |
| 1843 } | 1997 } |
| 1844 if (!*word_eol[3]) { | 1998 if (!*word_eol[3]) { |
| 1845 g_free(what); | 1999 g_free(what); |
| 1846 return -EINVAL; | 2000 return -EINVAL; |
| 1847 } | 2001 } |
| 1848 /* | 2002 irc_send_privmsg (gc, word[2], word_eol[3], TRUE); |
| 1849 g_snprintf(buf, sizeof(buf), "PRIVMSG %s :%s\r\n", word[2], word_eol[3]); | |
| 1850 irc_write(id->fd, buf, strlen(buf));*/ | |
| 1851 irc_send_privmsg (gc, word[2], word_eol[3]); | |
| 1852 } else if (!g_strcasecmp(pdibuf, "KICK")) { | 2003 } else if (!g_strcasecmp(pdibuf, "KICK")) { |
| 1853 if (!*word[2]) { | 2004 if (!*word[2]) { |
| 1854 g_free(what); | 2005 g_free(what); |
| 1855 return -EINVAL; | 2006 return -EINVAL; |
| 1856 } | 2007 } |
| 1857 if (*word_eol[3]) | 2008 if (*word_eol[3]) { |
| 1858 g_snprintf(buf, sizeof(buf), "KICK %s %s :%s\r\n", who, word[2], word_eol[3]); | 2009 intl = irc_send_convert(gc, word_eol[3], sizeof(buf), &len); |
| 1859 else | 2010 g_snprintf(buf, sizeof(buf), "KICK %s %s :%s\r\n", who, word[2], intl); |
| 2011 g_free(intl); | |
| 2012 } else | |
| 1860 g_snprintf(buf, sizeof(buf), "KICK %s %s\r\n", who, word[2]); | 2013 g_snprintf(buf, sizeof(buf), "KICK %s %s\r\n", who, word[2]); |
| 1861 irc_write(id->fd, buf, strlen(buf)); | 2014 irc_write(id->fd, buf, strlen(buf)); |
| 1862 } else if (!g_strcasecmp(pdibuf, "JOIN") || !g_strcasecmp(pdibuf, "J")) { | 2015 } else if (!g_strcasecmp(pdibuf, "JOIN") || !g_strcasecmp(pdibuf, "J")) { |
| 1863 if (!*word[2]) { | 2016 if (!*word[2]) { |
| 1864 g_free(what); | 2017 g_free(what); |
| 1876 if (!is_channel(gc, chan)) { | 2029 if (!is_channel(gc, chan)) { |
| 1877 g_free(what); | 2030 g_free(what); |
| 1878 return -EINVAL; | 2031 return -EINVAL; |
| 1879 } | 2032 } |
| 1880 c = irc_find_chat(gc, chan); | 2033 c = irc_find_chat(gc, chan); |
| 1881 g_snprintf(buf, sizeof(buf), "PART %s%s%s\r\n", chan, | 2034 if (*reason) { |
| 1882 *reason ? " :" : "", | 2035 intl = irc_send_convert(gc, reason, sizeof(buf), &len); |
| 1883 *reason ? reason : ""); | 2036 g_snprintf(buf, sizeof(buf), "PART %s :%s\r\n", chan, intl); |
| 2037 g_free(intl); | |
| 2038 } else | |
| 2039 g_snprintf(buf, sizeof(buf), "PART %s\r\n", chan); | |
| 1884 irc_write(id->fd, buf, strlen(buf)); | 2040 irc_write(id->fd, buf, strlen(buf)); |
| 1885 if (c) { | 2041 if (c) { |
| 1886 gc->buddy_chats = g_slist_remove(gc->buddy_chats, c); | 2042 gc->buddy_chats = g_slist_remove(gc->buddy_chats, c); |
| 1887 c->gc = NULL; | 2043 c->gc = NULL; |
| 1888 g_snprintf(buf, sizeof(buf), _("You have left %s"), chan); | 2044 g_snprintf(buf, sizeof(buf), _("You have left %s"), chan); |
| 1998 } | 2154 } |
| 1999 g_free(what); | 2155 g_free(what); |
| 2000 return 0; | 2156 return 0; |
| 2001 } | 2157 } |
| 2002 | 2158 |
| 2003 static int send_msg(struct gaim_connection *gc, char *who, char *what) | 2159 static int |
| 2160 send_msg(struct gaim_connection *gc, char *who, char *what) | |
| 2004 { | 2161 { |
| 2005 char *cr = strchr(what, '\n'); | 2162 char *cr = strchr(what, '\n'); |
| 2006 if (cr) { | 2163 if (cr) { |
| 2007 int ret = 0; | 2164 int ret = 0; |
| 2008 while (TRUE) { | 2165 while (TRUE) { |
| 2020 return ret; | 2177 return ret; |
| 2021 } else | 2178 } else |
| 2022 return handle_command(gc, who, what); | 2179 return handle_command(gc, who, what); |
| 2023 } | 2180 } |
| 2024 | 2181 |
| 2025 static void irc_chat_invite(struct gaim_connection *gc, int idn, const char *message, const char *name) { | 2182 static void |
| 2183 irc_chat_invite(struct gaim_connection *gc, int idn, const char *message, const char *name) { | |
| 2026 char buf[IRC_BUF_LEN]; | 2184 char buf[IRC_BUF_LEN]; |
| 2027 struct irc_data *id = gc->proto_data; | 2185 struct irc_data *id = gc->proto_data; |
| 2028 struct conversation *c = irc_find_chat_by_id(gc, idn); | 2186 struct conversation *c = irc_find_chat_by_id(gc, idn); |
| 2029 g_snprintf(buf, sizeof(buf), "INVITE %s %s\r\n", name, c->name); | 2187 g_snprintf(buf, sizeof(buf), "INVITE %s %s\r\n", name, c->name); |
| 2030 irc_write(id->fd, buf, strlen(buf)); | 2188 irc_write(id->fd, buf, strlen(buf)); |
| 2031 } | 2189 } |
| 2032 | 2190 |
| 2033 static int irc_send_im(struct gaim_connection *gc, char *who, char *what, int len, int flags) | 2191 static int |
| 2192 irc_send_im(struct gaim_connection *gc, char *who, char *what, int len, int flags) | |
| 2034 { | 2193 { |
| 2035 if (*who == '@' || *who == '+') | 2194 if (*who == '@' || *who == '+') |
| 2036 return send_msg(gc, who + 1, what); | 2195 return send_msg(gc, who + 1, what); |
| 2037 return send_msg(gc, who, what); | 2196 return send_msg(gc, who, what); |
| 2038 } | 2197 } |
| 2039 | 2198 |
| 2040 /* IRC doesn't have a buddy list, but we can still figure out who's online with ISON */ | 2199 /* IRC doesn't have a buddy list, but we can still figure out who's online with ISON */ |
| 2041 static void irc_add_buddy(struct gaim_connection *gc, const char *who) {} | 2200 static void |
| 2042 static void irc_remove_buddy(struct gaim_connection *gc, char *who, char *group) {} | 2201 irc_add_buddy(struct gaim_connection *gc, const char *who) {} |
| 2043 | 2202 static void |
| 2044 static GList *irc_chat_info(struct gaim_connection *gc) | 2203 irc_remove_buddy(struct gaim_connection *gc, char *who, char *group) {} |
| 2204 | |
| 2205 static GList * | |
| 2206 irc_chat_info(struct gaim_connection *gc) | |
| 2045 { | 2207 { |
| 2046 GList *m = NULL; | 2208 GList *m = NULL; |
| 2047 struct proto_chat_entry *pce; | 2209 struct proto_chat_entry *pce; |
| 2048 | 2210 |
| 2049 pce = g_new0(struct proto_chat_entry, 1); | 2211 pce = g_new0(struct proto_chat_entry, 1); |
| 2055 m = g_list_append(m, pce); | 2217 m = g_list_append(m, pce); |
| 2056 | 2218 |
| 2057 return m; | 2219 return m; |
| 2058 } | 2220 } |
| 2059 | 2221 |
| 2060 static void irc_join_chat(struct gaim_connection *gc, GList *data) | 2222 static void |
| 2223 irc_join_chat(struct gaim_connection *gc, GList *data) | |
| 2061 { | 2224 { |
| 2062 struct irc_data *id = gc->proto_data; | 2225 struct irc_data *id = gc->proto_data; |
| 2063 char buf[IRC_BUF_LEN]; | 2226 char buf[IRC_BUF_LEN]; |
| 2064 char *name, *pass; | 2227 char *name, *pass; |
| 2065 | 2228 |
| 2072 } else | 2235 } else |
| 2073 g_snprintf(buf, sizeof(buf), "JOIN %s\r\n", name); | 2236 g_snprintf(buf, sizeof(buf), "JOIN %s\r\n", name); |
| 2074 irc_write(id->fd, buf, strlen(buf)); | 2237 irc_write(id->fd, buf, strlen(buf)); |
| 2075 } | 2238 } |
| 2076 | 2239 |
| 2077 static void irc_chat_leave(struct gaim_connection *gc, int id) | 2240 static void |
| 2241 irc_chat_leave(struct gaim_connection *gc, int id) | |
| 2078 { | 2242 { |
| 2079 struct irc_data *idata = gc->proto_data; | 2243 struct irc_data *idata = gc->proto_data; |
| 2080 struct conversation *c = irc_find_chat_by_id(gc, id); | 2244 struct conversation *c = irc_find_chat_by_id(gc, id); |
| 2081 char buf[IRC_BUF_LEN]; | 2245 char buf[IRC_BUF_LEN]; |
| 2082 | 2246 |
| 2084 | 2248 |
| 2085 g_snprintf(buf, sizeof(buf), "PART %s\r\n", c->name); | 2249 g_snprintf(buf, sizeof(buf), "PART %s\r\n", c->name); |
| 2086 irc_write(idata->fd, buf, strlen(buf)); | 2250 irc_write(idata->fd, buf, strlen(buf)); |
| 2087 } | 2251 } |
| 2088 | 2252 |
| 2089 static int irc_chat_send(struct gaim_connection *gc, int id, char *what) | 2253 static int |
| 2254 irc_chat_send(struct gaim_connection *gc, int id, char *what) | |
| 2090 { | 2255 { |
| 2091 struct conversation *c = irc_find_chat_by_id(gc, id); | 2256 struct conversation *c = irc_find_chat_by_id(gc, id); |
| 2092 if (!c) | 2257 if (!c) |
| 2093 return -EINVAL; | 2258 return -EINVAL; |
| 2094 if (send_msg(gc, c->name, what) > 0) | 2259 if (send_msg(gc, c->name, what) > 0) |
| 2095 serv_got_chat_in(gc, c->id, gc->displayname, 0, what, time(NULL)); | 2260 serv_got_chat_in(gc, c->id, gc->displayname, 0, what, time(NULL)); |
| 2096 return 0; | 2261 return 0; |
| 2097 } | 2262 } |
| 2098 | 2263 |
| 2099 static GList *irc_away_states(struct gaim_connection *gc) | 2264 static GList * |
| 2265 irc_away_states(struct gaim_connection *gc) | |
| 2100 { | 2266 { |
| 2101 return g_list_append(NULL, GAIM_AWAY_CUSTOM); | 2267 return g_list_append(NULL, GAIM_AWAY_CUSTOM); |
| 2102 } | 2268 } |
| 2103 | 2269 |
| 2104 static void irc_set_away(struct gaim_connection *gc, char *state, char *msg) | 2270 static void |
| 2271 irc_set_away(struct gaim_connection *gc, char *state, char *msg) | |
| 2105 { | 2272 { |
| 2106 struct irc_data *idata = gc->proto_data; | 2273 struct irc_data *idata = gc->proto_data; |
| 2107 char buf[IRC_BUF_LEN]; | 2274 char buf[IRC_BUF_LEN]; |
| 2108 | 2275 |
| 2109 if (gc->away) | 2276 if (gc->away) |
| 2115 } else | 2282 } else |
| 2116 g_snprintf(buf, sizeof(buf), "AWAY\r\n"); | 2283 g_snprintf(buf, sizeof(buf), "AWAY\r\n"); |
| 2117 irc_write(idata->fd, buf, strlen(buf)); | 2284 irc_write(idata->fd, buf, strlen(buf)); |
| 2118 } | 2285 } |
| 2119 | 2286 |
| 2120 static char **irc_list_icon(int uc) | 2287 static char ** |
| 2288 irc_list_icon(int uc) | |
| 2121 { | 2289 { |
| 2122 return irc_icon_xpm; | 2290 return irc_icon_xpm; |
| 2123 } | 2291 } |
| 2124 | 2292 |
| 2125 static int getlocalip(char *ip) /* Thanks, libfaim */ | 2293 static int |
| 2294 getlocalip(char *ip) /* Thanks, libfaim */ | |
| 2126 { | 2295 { |
| 2127 struct hostent *hptr; | 2296 struct hostent *hptr; |
| 2128 char localhost[129]; | 2297 char localhost[129]; |
| 2129 long unsigned add; | 2298 long unsigned add; |
| 2130 | 2299 |
| 2142 g_snprintf(ip, 11, "%lu", add); | 2311 g_snprintf(ip, 11, "%lu", add); |
| 2143 | 2312 |
| 2144 return 0; | 2313 return 0; |
| 2145 } | 2314 } |
| 2146 | 2315 |
| 2147 static void dcc_chat_connected(gpointer data, gint source, GdkInputCondition condition) | 2316 static void |
| 2317 dcc_chat_connected(gpointer data, gint source, GdkInputCondition condition) | |
| 2148 { | 2318 { |
| 2149 struct dcc_chat *chat = data; | 2319 struct dcc_chat *chat = data; |
| 2150 struct conversation *convo; | 2320 struct conversation *convo; |
| 2151 char buf[128]; | 2321 char buf[128]; |
| 2152 struct sockaddr_in addr; | 2322 struct sockaddr_in addr; |
| 2172 write_to_conv (convo, buf, WFLAG_SYSTEM, NULL, time ((time_t) NULL), -1); | 2342 write_to_conv (convo, buf, WFLAG_SYSTEM, NULL, time ((time_t) NULL), -1); |
| 2173 debug_printf ("Chat with %s established\n", chat->nick); | 2343 debug_printf ("Chat with %s established\n", chat->nick); |
| 2174 dcc_chat_list = g_slist_append (dcc_chat_list, chat); | 2344 dcc_chat_list = g_slist_append (dcc_chat_list, chat); |
| 2175 } | 2345 } |
| 2176 #if 0 | 2346 #if 0 |
| 2177 static void irc_ask_send_file(struct gaim_connection *gc, char *destsn) { | 2347 static void |
| 2348 irc_ask_send_file(struct gaim_connection *gc, char *destsn) { | |
| 2178 struct irc_data *id = (struct irc_data *)gc->proto_data; | 2349 struct irc_data *id = (struct irc_data *)gc->proto_data; |
| 2179 struct irc_file_transfer *ift = g_new0(struct irc_file_transfer, 1); | 2350 struct irc_file_transfer *ift = g_new0(struct irc_file_transfer, 1); |
| 2180 char *localip = (char *)malloc(12); | 2351 char *localip = (char *)malloc(12); |
| 2181 | 2352 |
| 2182 if (getlocalip(localip) == -1) { | 2353 if (getlocalip(localip) == -1) { |
| 2191 id->file_transfers = g_slist_append(id->file_transfers, ift); | 2362 id->file_transfers = g_slist_append(id->file_transfers, ift); |
| 2192 | 2363 |
| 2193 ift->xfer = transfer_out_add(gc, ift->sn); | 2364 ift->xfer = transfer_out_add(gc, ift->sn); |
| 2194 } | 2365 } |
| 2195 #endif | 2366 #endif |
| 2196 static struct irc_file_transfer *find_ift_by_xfer(struct gaim_connection *gc, | 2367 static struct |
| 2368 irc_file_transfer *find_ift_by_xfer(struct gaim_connection *gc, | |
| 2197 struct file_transfer *xfer) { | 2369 struct file_transfer *xfer) { |
| 2198 | 2370 |
| 2199 GSList *g = ((struct irc_data *)gc->proto_data)->file_transfers; | 2371 GSList *g = ((struct irc_data *)gc->proto_data)->file_transfers; |
| 2200 struct irc_file_transfer *f = NULL; | 2372 struct irc_file_transfer *f = NULL; |
| 2201 | 2373 |
| 2208 } | 2380 } |
| 2209 | 2381 |
| 2210 return f; | 2382 return f; |
| 2211 } | 2383 } |
| 2212 | 2384 |
| 2213 static void irc_file_transfer_data_chunk(struct gaim_connection *gc, struct file_transfer *xfer, const char *data, int len) { | 2385 static void |
| 2386 irc_file_transfer_data_chunk(struct gaim_connection *gc, struct file_transfer *xfer, const char *data, int len) { | |
| 2214 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); | 2387 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); |
| 2215 guint32 pos; | 2388 guint32 pos; |
| 2216 | 2389 |
| 2217 ift->cur += len; | 2390 ift->cur += len; |
| 2218 pos = htonl(ift->cur); | 2391 pos = htonl(ift->cur); |
| 2220 | 2393 |
| 2221 // FIXME: You should check to verify that they received the data when | 2394 // FIXME: You should check to verify that they received the data when |
| 2222 // you are sending a file ... | 2395 // you are sending a file ... |
| 2223 } | 2396 } |
| 2224 | 2397 |
| 2225 static void irc_file_transfer_cancel (struct gaim_connection *gc, struct file_transfer *xfer) { | 2398 static void |
| 2399 irc_file_transfer_cancel (struct gaim_connection *gc, struct file_transfer *xfer) { | |
| 2226 struct irc_data *id = (struct irc_data *)gc->proto_data; | 2400 struct irc_data *id = (struct irc_data *)gc->proto_data; |
| 2227 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); | 2401 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); |
| 2228 | 2402 |
| 2229 printf("Our shit got canceled, yo!\n"); | 2403 printf("Our shit got canceled, yo!\n"); |
| 2230 | 2404 |
| 2240 g_free(ift->name); | 2414 g_free(ift->name); |
| 2241 | 2415 |
| 2242 g_free(ift); | 2416 g_free(ift); |
| 2243 } | 2417 } |
| 2244 | 2418 |
| 2245 static void irc_file_transfer_done(struct gaim_connection *gc, struct file_transfer *xfer) { | 2419 static void |
| 2420 irc_file_transfer_done(struct gaim_connection *gc, struct file_transfer *xfer) { | |
| 2246 struct irc_data *id = (struct irc_data *)gc->proto_data; | 2421 struct irc_data *id = (struct irc_data *)gc->proto_data; |
| 2247 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); | 2422 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); |
| 2248 | 2423 |
| 2249 | 2424 |
| 2250 printf("Our shit be done, yo.\n"); | 2425 printf("Our shit be done, yo.\n"); |
| 2261 g_free(ift->name); | 2436 g_free(ift->name); |
| 2262 | 2437 |
| 2263 g_free(ift); | 2438 g_free(ift); |
| 2264 } | 2439 } |
| 2265 | 2440 |
| 2266 static void irc_file_transfer_out (struct gaim_connection *gc, struct file_transfer *xfer, const char *name, int totfiles, int totsize) { | 2441 static void |
| 2442 irc_file_transfer_out (struct gaim_connection *gc, struct file_transfer *xfer, const char *name, int totfiles, int totsize) { | |
| 2267 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); | 2443 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); |
| 2268 struct sockaddr_in addr; | 2444 struct sockaddr_in addr; |
| 2269 char buf[IRC_BUF_LEN]; | 2445 char buf[IRC_BUF_LEN]; |
| 2270 int len; | 2446 int len; |
| 2271 | 2447 |
| 2288 snprintf(buf, sizeof(buf), "\001DCC SEND %s %s %d %d\001\n", name, ift->ip, ift->port, totsize); | 2464 snprintf(buf, sizeof(buf), "\001DCC SEND %s %s %d %d\001\n", name, ift->ip, ift->port, totsize); |
| 2289 printf("Trying: %s\n", buf); | 2465 printf("Trying: %s\n", buf); |
| 2290 irc_send_im (gc, ift->sn, buf, -1, 0); | 2466 irc_send_im (gc, ift->sn, buf, -1, 0); |
| 2291 } | 2467 } |
| 2292 | 2468 |
| 2293 static void irc_file_transfer_in(struct gaim_connection *gc, | 2469 static void |
| 2470 irc_file_transfer_in(struct gaim_connection *gc, | |
| 2294 struct file_transfer *xfer, int offset) { | 2471 struct file_transfer *xfer, int offset) { |
| 2295 | 2472 |
| 2296 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); | 2473 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); |
| 2297 | 2474 |
| 2298 ift->xfer = xfer; | 2475 ift->xfer = xfer; |
| 2299 proxy_connect(ift->ip, ift->port, dcc_recv_callback, ift); | 2476 proxy_connect(ift->ip, ift->port, dcc_recv_callback, ift); |
| 2300 } | 2477 } |
| 2301 | 2478 |
| 2302 static void irc_ctcp_clientinfo(struct gaim_connection *gc, char *who) | 2479 static void |
| 2480 irc_ctcp_clientinfo(struct gaim_connection *gc, char *who) | |
| 2303 { | 2481 { |
| 2304 char buf[IRC_BUF_LEN]; | 2482 char buf[IRC_BUF_LEN]; |
| 2305 | 2483 |
| 2306 snprintf (buf, sizeof buf, "\001CLIENTINFO\001\n"); | 2484 snprintf (buf, sizeof buf, "\001CLIENTINFO\001"); |
| 2307 irc_send_privmsg(gc, who, buf); | 2485 irc_send_privmsg(gc, who, buf, FALSE); |
| 2308 } | 2486 } |
| 2309 | 2487 |
| 2310 static void irc_ctcp_userinfo(struct gaim_connection *gc, char *who) | 2488 static void |
| 2489 irc_ctcp_userinfo(struct gaim_connection *gc, char *who) | |
| 2311 { | 2490 { |
| 2312 char buf[IRC_BUF_LEN]; | 2491 char buf[IRC_BUF_LEN]; |
| 2313 | 2492 |
| 2314 snprintf (buf, sizeof buf, "\001USERINFO\001\n"); | 2493 snprintf (buf, sizeof buf, "\001USERINFO\001"); |
| 2315 irc_send_privmsg(gc, who, buf); | 2494 irc_send_privmsg(gc, who, buf, FALSE); |
| 2316 } | 2495 } |
| 2317 | 2496 |
| 2318 static void irc_ctcp_version(struct gaim_connection *gc, char *who) | 2497 static void |
| 2498 irc_ctcp_version(struct gaim_connection *gc, char *who) | |
| 2319 { | 2499 { |
| 2320 char buf[IRC_BUF_LEN]; | 2500 char buf[IRC_BUF_LEN]; |
| 2321 | 2501 |
| 2322 snprintf (buf, sizeof buf, "\001VERSION\001\n"); | 2502 snprintf (buf, sizeof buf, "\001VERSION\001"); |
| 2323 irc_send_privmsg(gc, who, buf); | 2503 irc_send_privmsg(gc, who, buf, FALSE); |
| 2324 } | 2504 } |
| 2325 | 2505 |
| 2326 static void irc_ctcp_ping(struct gaim_connection *gc, char *who) | 2506 static void |
| 2507 irc_ctcp_ping(struct gaim_connection *gc, char *who) | |
| 2327 { | 2508 { |
| 2328 char buf[IRC_BUF_LEN]; | 2509 char buf[IRC_BUF_LEN]; |
| 2329 | 2510 |
| 2330 g_snprintf (buf, sizeof(buf), "\001PING %ul\001\n", time(NULL)); | 2511 g_snprintf (buf, sizeof(buf), "\001PING %ul\001", time(NULL)); |
| 2331 irc_send_privmsg(gc, who, buf); | 2512 irc_send_privmsg(gc, who, buf, FALSE); |
| 2332 } | 2513 } |
| 2333 | 2514 |
| 2334 static void irc_send_notice(struct gaim_connection *gc, char *who, char *what) | 2515 static void |
| 2335 { | 2516 irc_send_notice(struct gaim_connection *gc, char *who, char *what) |
| 2336 char buf[IRC_BUF_LEN]; | 2517 { |
| 2518 char buf[IRC_BUF_LEN], *intl; | |
| 2337 struct irc_data *id = gc->proto_data; | 2519 struct irc_data *id = gc->proto_data; |
| 2338 | 2520 int len; |
| 2339 g_snprintf(buf, sizeof(buf), "NOTICE %s :%s\r\n", who, what); | 2521 |
| 2522 intl = irc_send_convert(gc, what, 501, &len); | |
| 2523 g_snprintf(buf, sizeof(buf), "NOTICE %s :%s\r\n", who, intl); | |
| 2524 g_free(intl); | |
| 2340 irc_write(id->fd, buf, strlen(buf)); | 2525 irc_write(id->fd, buf, strlen(buf)); |
| 2341 } | 2526 } |
| 2342 | 2527 |
| 2343 static void irc_send_privmsg(struct gaim_connection *gc, char *who, char *what) | 2528 /* Don't call this guy with fragment = 1 for anything but straight |
| 2344 { | 2529 * up privmsgs. (no CTCP/whatever) It's still dangerous for CTCPs |
| 2345 char buf[IRC_BUF_LEN]; | 2530 * (it might not include the trailing \001), but I think this behavior |
| 2531 * is generally better than not fragmenting at all on lots of our | |
| 2532 * packets. */ | |
| 2533 /* From RFC2812: | |
| 2534 * IRC messages are always lines of characters terminated with a CR-LF | |
| 2535 * (Carriage Return - Line Feed) pair, and these messages SHALL NOT | |
| 2536 * exceed 512 characters in length, counting all characters including | |
| 2537 * the trailing CR-LF. Thus, there are 510 characters maximum allowed | |
| 2538 * for the command and its parameters. */ | |
| 2539 /* So apparently that includes all the inter-server crap, which is up | |
| 2540 * to NINETY-THREE chars on dancer, which seems to be a pretty liberal | |
| 2541 * ircd. My rough calculation for now is ":<nick>!~<user>@<host> ", | |
| 2542 * where <host> is a max of an (uncalculated) 63 chars. Thanks to | |
| 2543 * trelane and #freenode for giving a hand here. */ | |
| 2544 static void | |
| 2545 irc_send_privmsg(struct gaim_connection *gc, char *who, char *what, gboolean fragment) | |
| 2546 { | |
| 2547 char buf[IRC_BUF_LEN], *intl; | |
| 2346 struct irc_data *id = gc->proto_data; | 2548 struct irc_data *id = gc->proto_data; |
| 2347 | 2549 /* 512 - 12 (for PRIVMSG" "" :""\r\n") - namelen - nicklen - 68 */ |
| 2348 g_snprintf(buf, sizeof(buf), "PRIVMSG %s :%s\r\n", who, what); | 2550 int nicklen = (gc->user->alias && strlen(gc->user->alias)) ? strlen(gc->user->alias) : 4; |
| 2349 irc_write(id->fd, buf, strlen(buf)); | 2551 int max = 444 - strlen(who) - strlen(g_get_user_name()) - nicklen; |
| 2350 } | 2552 |
| 2351 | 2553 int len; |
| 2352 static void irc_start_chat(struct gaim_connection *gc, char *who) { | 2554 |
| 2555 do { | |
| 2556 /* the \001 on CTCPs may cause a problem here for some | |
| 2557 * charsets, but probably not ones people use for IRC. */ | |
| 2558 intl = irc_send_convert(gc, what, max, &len); | |
| 2559 g_snprintf(buf, sizeof(buf), "PRIVMSG %s :%s\r\n", who, intl); | |
| 2560 g_free(intl); | |
| 2561 irc_write(id->fd, buf, strlen(buf)); | |
| 2562 what += len; | |
| 2563 } while (fragment && strlen(what)); | |
| 2564 } | |
| 2565 | |
| 2566 static void | |
| 2567 irc_start_chat(struct gaim_connection *gc, char *who) { | |
| 2353 struct dcc_chat *chat; | 2568 struct dcc_chat *chat; |
| 2354 int len; | 2569 int len; |
| 2355 struct sockaddr_in addr; | 2570 struct sockaddr_in addr; |
| 2356 char buf[IRC_BUF_LEN]; | 2571 char buf[IRC_BUF_LEN]; |
| 2357 | 2572 |
| 2379 g_snprintf (buf, sizeof buf, "\001DCC CHAT chat %s %d\001\n", | 2594 g_snprintf (buf, sizeof buf, "\001DCC CHAT chat %s %d\001\n", |
| 2380 chat->ip_address, chat->port); | 2595 chat->ip_address, chat->port); |
| 2381 irc_send_im (gc, who, buf, -1, 0); | 2596 irc_send_im (gc, who, buf, -1, 0); |
| 2382 } | 2597 } |
| 2383 | 2598 |
| 2384 static void irc_get_info(struct gaim_connection *gc, char *who) | 2599 static void |
| 2600 irc_get_info(struct gaim_connection *gc, char *who) | |
| 2385 { | 2601 { |
| 2386 struct irc_data *idata = gc->proto_data; | 2602 struct irc_data *idata = gc->proto_data; |
| 2387 char buf[IRC_BUF_LEN]; | 2603 char buf[IRC_BUF_LEN]; |
| 2388 | 2604 |
| 2389 if (*who == '@') | 2605 if (*who == '@') |
| 2393 | 2609 |
| 2394 g_snprintf(buf, sizeof(buf), "WHOIS %s\r\n", who); | 2610 g_snprintf(buf, sizeof(buf), "WHOIS %s\r\n", who); |
| 2395 irc_write(idata->fd, buf, strlen(buf)); | 2611 irc_write(idata->fd, buf, strlen(buf)); |
| 2396 } | 2612 } |
| 2397 | 2613 |
| 2398 static GList *irc_buddy_menu(struct gaim_connection *gc, char *who) | 2614 static GList * |
| 2615 irc_buddy_menu(struct gaim_connection *gc, char *who) | |
| 2399 { | 2616 { |
| 2400 GList *m = NULL; | 2617 GList *m = NULL; |
| 2401 struct proto_buddy_menu *pbm; | 2618 struct proto_buddy_menu *pbm; |
| 2402 | 2619 |
| 2403 pbm = g_new0(struct proto_buddy_menu, 1); | 2620 pbm = g_new0(struct proto_buddy_menu, 1); |
| 2446 return m; | 2663 return m; |
| 2447 } | 2664 } |
| 2448 | 2665 |
| 2449 static struct prpl *my_protocol = NULL; | 2666 static struct prpl *my_protocol = NULL; |
| 2450 | 2667 |
| 2451 G_MODULE_EXPORT void irc_init(struct prpl *ret) | 2668 G_MODULE_EXPORT void |
| 2669 irc_init(struct prpl *ret) | |
| 2452 { | 2670 { |
| 2453 struct proto_user_opt *puo; | 2671 struct proto_user_opt *puo; |
| 2454 ret->protocol = PROTO_IRC; | 2672 ret->protocol = PROTO_IRC; |
| 2455 ret->options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD; | 2673 ret->options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD; |
| 2456 ret->name = g_strdup("IRC"); | 2674 ret->name = g_strdup("IRC"); |
| 2486 puo->label = g_strdup("Port:"); | 2704 puo->label = g_strdup("Port:"); |
| 2487 puo->def = g_strdup("6667"); | 2705 puo->def = g_strdup("6667"); |
| 2488 puo->pos = USEROPT_PORT; | 2706 puo->pos = USEROPT_PORT; |
| 2489 ret->user_opts = g_list_append(ret->user_opts, puo); | 2707 ret->user_opts = g_list_append(ret->user_opts, puo); |
| 2490 | 2708 |
| 2709 puo = g_new0(struct proto_user_opt, 1); | |
| 2710 puo->label = g_strdup("Encoding:"); | |
| 2711 puo->def = g_strdup("ISO-8859-1"); | |
| 2712 puo->pos = USEROPT_CHARSET; | |
| 2713 ret->user_opts = g_list_append(ret->user_opts, puo); | |
| 2714 | |
| 2491 my_protocol = ret; | 2715 my_protocol = ret; |
| 2492 } | 2716 } |
| 2493 | 2717 |
| 2494 #ifndef STATIC | 2718 #ifndef STATIC |
| 2495 G_MODULE_EXPORT void gaim_prpl_init(struct prpl* prpl) | 2719 G_MODULE_EXPORT void |
| 2720 gaim_prpl_init(struct prpl* prpl) | |
| 2496 { | 2721 { |
| 2497 irc_init(prpl); | 2722 irc_init(prpl); |
| 2498 prpl->plug->desc.api_version = PLUGIN_API_VERSION; | 2723 prpl->plug->desc.api_version = PLUGIN_API_VERSION; |
| 2499 } | 2724 } |
| 2500 | 2725 |
