comparison mcabber/src/jabglue.c @ 1128:ac9c89f6cb51

Support for invitations to muc rooms According to section "7.5" ("Inviting Another User to a Room") of the xep 0045 (about multi user chat), someone can invite you to a room. But it seems mcabber ignore this, so I have coded the missing support. [Patch slightly modified by Mikael]
author misc@mandriva.org
date Sat, 20 Jan 2007 18:41:13 +0100
parents 382972712208
children 1650056b96fc
comparison
equal deleted inserted replaced
1127:fddf2fef7b83 1128:ac9c89f6cb51
54 static gchar *mystatusmsg; 54 static gchar *mystatusmsg;
55 static unsigned char online; 55 static unsigned char online;
56 56
57 static void statehandler(jconn, int); 57 static void statehandler(jconn, int);
58 static void packethandler(jconn, jpacket); 58 static void packethandler(jconn, jpacket);
59 void handle_state_events(char* from, xmlnode xmldata); 59 static void handle_state_events(char* from, xmlnode xmldata);
60
61 static void evscallback_invitation(eviqs *evp, guint evcontext);
60 62
61 static void logger(jconn j, int io, const char *buf) 63 static void logger(jconn j, int io, const char *buf)
62 { 64 {
63 scr_LogPrint(LPRINT_DEBUG, "%03s: %s", ((io == 0) ? "OUT" : "IN"), buf); 65 scr_LogPrint(LPRINT_DEBUG, "%03s: %s", ((io == 0) ? "OUT" : "IN"), buf);
64 } 66 }
2148 ustmsg = ""; // Some clients omit the <status/> element :-( 2150 ustmsg = ""; // Some clients omit the <status/> element :-(
2149 check_signature(r, rname, xml_get_xmlns(xmldata, NS_SIGNED), ustmsg); 2151 check_signature(r, rname, xml_get_xmlns(xmldata, NS_SIGNED), ustmsg);
2150 } 2152 }
2151 2153
2152 g_free(r); 2154 g_free(r);
2155 }
2156
2157 static void got_invite(char* from, char *to, char* reason, char* passwd)
2158 {
2159 eviqs *evn;
2160 event_muc_invitation *invitation;
2161 GString *sbuf;
2162
2163 sbuf = g_string_new("");
2164 if (reason) {
2165 g_string_printf(sbuf,
2166 "Received an invitation to <%s>, from <%s>, reason: %s",
2167 to, from, reason);
2168 } else {
2169 g_string_printf(sbuf, "Received an invitation to <%s>, from <%s>",
2170 to, from);
2171 }
2172 scr_WriteIncomingMessage(from, sbuf->str, 0, HBB_PREFIX_INFO);
2173 scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
2174
2175 evn = evs_new(EVS_TYPE_INVITATION, EVS_MAX_TIMEOUT);
2176 if (evn) {
2177 evn->callback = &evscallback_invitation;
2178 invitation = g_new(event_muc_invitation, 1);
2179 invitation->to = g_strdup(to);
2180 invitation->from = g_strdup(from);
2181 invitation->passwd = g_strdup(passwd);
2182 invitation->reason = g_strdup(reason);
2183 evn->data = invitation;
2184 evn->desc = g_strdup_printf("<%s> invites you to %s ", from, to);
2185 g_string_printf(sbuf, "Please use /event %s accept|reject", evn->id);
2186 } else {
2187 g_string_printf(sbuf, "Unable to create a new event!");
2188 }
2189 scr_WriteIncomingMessage(from, sbuf->str, 0, HBB_PREFIX_INFO);
2190 scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
2191 g_string_free(sbuf, TRUE);
2192 }
2193
2194 // Specific MUC message handling (for example invitation processing)
2195 static void got_muc_message(char *from, xmlnode x)
2196 {
2197 xmlnode invite = xmlnode_get_tag(x, "invite");
2198 if (invite)
2199 {
2200 char* invite_from;
2201 char *reason = NULL;
2202 char *password = NULL;
2203 xmlnode r;
2204
2205 invite_from = xmlnode_get_attrib(invite, "from");
2206 r = xmlnode_get_tag(invite, "reason");
2207 if (r)
2208 reason = xmlnode_get_tag_data(r, NULL);
2209 r = xmlnode_get_tag(invite, "password");
2210 if (r)
2211 password = xmlnode_get_tag_data(r, NULL);
2212 if (invite_from)
2213 got_invite(invite_from, from, reason, password);
2214 }
2215 // TODO
2216 // handle status code = 100 ( not anonymous )
2217 // handle status code = 170 ( changement de config )
2218 // 10.2.1 Notification of Configuration Changes
2219 // declined invitation
2153 } 2220 }
2154 2221
2155 static void handle_packet_message(jconn conn, char *type, char *from, 2222 static void handle_packet_message(jconn conn, char *type, char *from,
2156 xmlnode xmldata) 2223 xmlnode xmldata)
2157 { 2224 {
2225 #endif 2292 #endif
2226 } 2293 }
2227 if (from && body) 2294 if (from && body)
2228 gotmessage(type, from, body, enc, timestamp, 2295 gotmessage(type, from, body, enc, timestamp,
2229 xml_get_xmlns(xmldata, NS_SIGNED)); 2296 xml_get_xmlns(xmldata, NS_SIGNED));
2297
2298 if (from) {
2299 x = xml_get_xmlns(xmldata, "http://jabber.org/protocol/muc#user");
2300 if (x && !strcmp(xmlnode_get_name(x), "x"))
2301 got_muc_message(from, x);
2302 }
2230 g_free(tmp); 2303 g_free(tmp);
2231 } 2304 }
2232 2305
2233 void handle_state_events(char *from, xmlnode xmldata) 2306 static void handle_state_events(char *from, xmlnode xmldata)
2234 { 2307 {
2235 #if defined JEP0022 || defined JEP0085 2308 #if defined JEP0022 || defined JEP0085
2236 xmlnode state_ns = NULL; 2309 xmlnode state_ns = NULL;
2237 const char *body; 2310 const char *body;
2238 char *rname, *bjid; 2311 char *rname, *bjid;
2389 } 2462 }
2390 } 2463 }
2391 scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO); 2464 scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO);
2392 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); 2465 scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
2393 g_free(buf); 2466 g_free(buf);
2467 }
2468
2469 static void decline_invitation(event_muc_invitation *invitation, char *reason)
2470 {
2471 // cut and paste from jb_room_invite
2472 xmlnode x,y,z;
2473
2474 if (!invitation) return;
2475 if (!invitation->to || !invitation->from) return;
2476
2477 x = jutil_msgnew(NULL, (char*)invitation->to, NULL, NULL);
2478
2479 y = xmlnode_insert_tag(x, "x");
2480 xmlnode_put_attrib(y, "xmlns", "http://jabber.org/protocol/muc#user");
2481
2482 z = xmlnode_insert_tag(y, "decline");
2483 xmlnode_put_attrib(z, "to", invitation->from);
2484
2485 if (reason) {
2486 y = xmlnode_insert_tag(z, "reason");
2487 xmlnode_insert_cdata(y, reason, (unsigned) -1);
2488 }
2489
2490 jab_send(jc, x);
2491 xmlnode_free(x);
2492 jb_reset_keepalive();
2493 }
2494
2495 static void evscallback_invitation(eviqs *evp, guint evcontext)
2496 {
2497 event_muc_invitation *invitation = evp->data;
2498
2499 // Sanity check
2500 if (!invitation) {
2501 // Shouldn't happen.
2502 scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback.");
2503 return;
2504 }
2505
2506 if (evcontext == EVS_CONTEXT_TIMEOUT) {
2507 scr_LogPrint(LPRINT_LOGNORM, "Event %s timed out, cancelled.", evp->id);
2508 goto evscallback_invitation_free;
2509 }
2510 if (evcontext == EVS_CONTEXT_CANCEL) {
2511 scr_LogPrint(LPRINT_LOGNORM, "Event %s cancelled.", evp->id);
2512 goto evscallback_invitation_free;
2513 }
2514 if (!(evcontext & EVS_CONTEXT_USER))
2515 goto evscallback_invitation_free;
2516 // Ok, let's work now.
2517 // evcontext: 0, 1 == reject, accept
2518
2519 if (evcontext & ~EVS_CONTEXT_USER) {
2520 char *nickname = default_muc_nickname();
2521 jb_room_join(invitation->to, nickname, invitation->passwd);
2522 g_free(nickname);
2523 } else {
2524 scr_LogPrint(LPRINT_LOGNORM, "Invitation to %s refused.", invitation->to);
2525 decline_invitation(invitation, NULL);
2526 }
2527
2528 evscallback_invitation_free:
2529 g_free(invitation->to);
2530 g_free(invitation->from);
2531 g_free(invitation->passwd);
2532 g_free(invitation->reason);
2533 g_free(invitation);
2534 evp->data = NULL;
2394 } 2535 }
2395 2536
2396 static void handle_packet_s10n(jconn conn, char *type, char *from, 2537 static void handle_packet_s10n(jconn conn, char *type, char *from,
2397 xmlnode xmldata) 2538 xmlnode xmldata)
2398 { 2539 {