Mercurial > ~mikael > mcabber > hg
comparison mcabber/src/jabglue.c @ 469:a926523d2392
Use UTF8 to handle resources and room nicknames
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Sat, 01 Oct 2005 23:17:05 +0200 |
parents | 644b8bf9ca4d |
children | eaa2ad773192 |
comparison
equal
deleted
inserted
replaced
468:644b8bf9ca4d | 469:a926523d2392 |
---|---|
34 #define JABBERPORT 5222 | 34 #define JABBERPORT 5222 |
35 #define JABBERSSLPORT 5223 | 35 #define JABBERSSLPORT 5223 |
36 | 36 |
37 #define JABBER_AGENT_GROUP "Jabber Agents" | 37 #define JABBER_AGENT_GROUP "Jabber Agents" |
38 | 38 |
39 #define to_utf8(s) ((s) ? g_locale_to_utf8((s), -1, NULL,NULL,NULL) : NULL) | |
40 #define from_utf8(s) ((s) ? g_locale_from_utf8((s), -1, NULL,NULL,NULL) : NULL) | |
41 | |
42 jconn jc; | 39 jconn jc; |
43 static time_t LastPingTime; | 40 static time_t LastPingTime; |
44 static unsigned int KeepaliveDelay; | 41 static unsigned int KeepaliveDelay; |
45 static unsigned int prio; | 42 static unsigned int prio; |
46 static int s_id; | 43 static int s_id; |
124 } | 121 } |
125 | 122 |
126 jconn jb_connect(const char *jid, const char *server, unsigned int port, | 123 jconn jb_connect(const char *jid, const char *server, unsigned int port, |
127 int ssl, const char *pass) | 124 int ssl, const char *pass) |
128 { | 125 { |
126 char *utf8_jid; | |
129 if (!port) { | 127 if (!port) { |
130 if (ssl) | 128 if (ssl) |
131 port = JABBERSSLPORT; | 129 port = JABBERSSLPORT; |
132 else | 130 else |
133 port = JABBERPORT; | 131 port = JABBERPORT; |
134 } | 132 } |
135 | 133 |
136 jb_disconnect(); | 134 jb_disconnect(); |
137 | 135 |
136 utf8_jid = to_utf8(jid); | |
137 if (!utf8_jid) return jc; | |
138 | |
138 s_id = 1; | 139 s_id = 1; |
139 jc = jab_new((char*)jid, (char*)pass, (char*)server, port, ssl); | 140 jc = jab_new(utf8_jid, (char*)pass, (char*)server, port, ssl); |
141 g_free(utf8_jid); | |
140 | 142 |
141 /* These 3 functions can deal with a NULL jc, no worry... */ | 143 /* These 3 functions can deal with a NULL jc, no worry... */ |
142 jab_logger(jc, logger); | 144 jab_logger(jc, logger); |
143 jab_packet_handler(jc, &packethandler); | 145 jab_packet_handler(jc, &packethandler); |
144 jab_state_handler(jc, &statehandler); | 146 jab_state_handler(jc, &statehandler); |
468 g_free(name_utf8); | 470 g_free(name_utf8); |
469 g_free(cleanjid); | 471 g_free(cleanjid); |
470 } | 472 } |
471 | 473 |
472 // Join a MUC room | 474 // Join a MUC room |
473 // room syntax: "room@server/nick" | 475 void jb_room_join(const char *room, const char *nickname) |
474 void jb_room_join(const char *room) | |
475 { | 476 { |
476 xmlnode x, y; | 477 xmlnode x, y; |
477 | 478 gchar *roomid, *utf8_nickname; |
478 if (!online) return; | 479 GSList *roster_usr; |
479 if (!room) return; | 480 |
480 | 481 if (!online || !room || !nickname) return; |
482 | |
483 utf8_nickname = to_utf8(nickname); | |
484 roomid = g_strdup_printf("%s/%s", room, utf8_nickname); | |
485 g_free(utf8_nickname); | |
486 if (check_jid_syntax(roomid)) { | |
487 scr_LogPrint(LPRINT_NORMAL, "<%s/%s> is not a valid Jabber room", room, | |
488 nickname); | |
489 g_free(roomid); | |
490 return; | |
491 } | |
492 | |
493 // We need to save the nickname for future use | |
494 roster_usr = roster_add_user(room, NULL, NULL, ROSTER_TYPE_ROOM); | |
495 if (roster_usr) | |
496 buddy_setnickname(roster_usr->data, nickname); | |
497 | |
498 // Send the XML request | |
481 x = jutil_presnew(JPACKET__UNKNOWN, 0, 0); | 499 x = jutil_presnew(JPACKET__UNKNOWN, 0, 0); |
482 xmlnode_put_attrib(x, "from", jid_full(jc->user)); | 500 xmlnode_put_attrib(x, "from", jid_full(jc->user)); |
483 xmlnode_put_attrib(x, "to", room); | 501 xmlnode_put_attrib(x, "to", roomid); |
484 y = xmlnode_insert_tag(x, "x"); | 502 y = xmlnode_insert_tag(x, "x"); |
485 xmlnode_put_attrib(y, "xmlns", "http://jabber.org/protocol/muc"); | 503 xmlnode_put_attrib(y, "xmlns", "http://jabber.org/protocol/muc"); |
486 | 504 |
487 jab_send(jc, x); | 505 jab_send(jc, x); |
488 xmlnode_free(x); | 506 xmlnode_free(x); |
489 jb_reset_keepalive(); | 507 jb_reset_keepalive(); |
508 g_free(roomid); | |
490 } | 509 } |
491 | 510 |
492 // Unlock a MUC room | 511 // Unlock a MUC room |
493 // room syntax: "room@server" | 512 // room syntax: "room@server" |
494 void jb_room_unlock(const char *room) | 513 void jb_room_unlock(const char *room) |
775 char *ns=NULL; | 794 char *ns=NULL; |
776 char *id=NULL; | 795 char *id=NULL; |
777 enum imstatus ust; | 796 enum imstatus ust; |
778 char bpprio; | 797 char bpprio; |
779 | 798 |
780 jb_reset_keepalive(); // reset keepalive delay | 799 jb_reset_keepalive(); // reset keepalive timeout |
781 jpacket_reset(packet); | 800 jpacket_reset(packet); |
782 | 801 |
783 p = xmlnode_get_attrib(packet->x, "from"); if (p) from = p; | |
784 p = xmlnode_get_attrib(packet->x, "type"); if (p) type = p; | 802 p = xmlnode_get_attrib(packet->x, "type"); if (p) type = p; |
803 p = xmlnode_get_attrib(packet->x, "from"); | |
804 if (p) { // Convert from UTF8 | |
805 // We need to be careful because from_utf8() can fail on some chars | |
806 // Thus we only convert the resource part | |
807 from = g_new0(char, strlen(p)+1); | |
808 strcpy(from, p); | |
809 r = strchr(from, '/'); | |
810 m = strchr(p, '/'); | |
811 if (m++) { | |
812 s = from_utf8(m); | |
813 if (s) { | |
814 // The length should be enough because from_utf should only | |
815 // reduce the string length | |
816 strcpy(r+1, s); | |
817 g_free(s); | |
818 } else { | |
819 *(r+1) = 0; | |
820 scr_LogPrint(LPRINT_LOGNORM, "Decoding of message sender has failed"); | |
821 } | |
822 } | |
823 } | |
824 | |
825 if (!from && packet->type != JPACKET_IQ) { | |
826 scr_LogPrint(LPRINT_LOGNORM, "Error in packet (could be UTF8-related)"); | |
827 return; | |
828 } | |
785 | 829 |
786 switch (packet->type) { | 830 switch (packet->type) { |
787 case JPACKET_MESSAGE: | 831 case JPACKET_MESSAGE: |
788 { | 832 { |
789 char *tmp = NULL; | 833 char *tmp = NULL; |
1051 y = xmlnode_get_tag(x, "status"); | 1095 y = xmlnode_get_tag(x, "status"); |
1052 if (y && mbnewnick) { | 1096 if (y && mbnewnick) { |
1053 p = xmlnode_get_attrib(y, "code"); | 1097 p = xmlnode_get_attrib(y, "code"); |
1054 if (p && !strcmp(p, "303")) { | 1098 if (p && !strcmp(p, "303")) { |
1055 gchar *mbuf; | 1099 gchar *mbuf; |
1056 mbuf = g_strdup_printf("%s is now known as %s", rname, mbnewnick); | 1100 gchar *newname_noutf8 = from_utf8(mbnewnick); |
1101 mbuf = g_strdup_printf("%s is now known as %s", rname, | |
1102 (newname_noutf8 ? newname_noutf8 : "(?)")); | |
1057 scr_WriteIncomingMessage(r, mbuf, 0, HBB_PREFIX_INFO); | 1103 scr_WriteIncomingMessage(r, mbuf, 0, HBB_PREFIX_INFO); |
1058 g_free(mbuf); | 1104 g_free(mbuf); |
1059 buddy_resource_setname(room_elt->data, rname, mbnewnick); | 1105 if (newname_noutf8) { |
1106 buddy_resource_setname(room_elt->data, rname, newname_noutf8); | |
1107 g_free(newname_noutf8); | |
1108 } | |
1060 } | 1109 } |
1061 } | 1110 } |
1062 | 1111 |
1063 // Check for departure/arrival | 1112 // Check for departure/arrival |
1064 if (!mbnewnick && mbrole == role_none) { | 1113 if (!mbnewnick && mbrole == role_none) { |
1126 break; | 1175 break; |
1127 | 1176 |
1128 default: | 1177 default: |
1129 break; | 1178 break; |
1130 } | 1179 } |
1131 } | 1180 g_free(from); |
1132 | 1181 } |
1182 |