comparison mcabber/src/jabglue.c @ 447:03bb57383cea

Initial Multi-User Chat support This patch adds basic MUC support. We now can: - join an existing room; - create and unlock a room using the /rawxml command; - set our nickname; - send/receive chatgroup messages; - see the members of the room; - leave the room. Chatroom logging is currently disabled, as it could do some unexpected things.
author Mikael Berthe <mikael@lilotux.net>
date Sun, 25 Sep 2005 01:01:44 +0200
parents 5927c3bfba13
children e08b0c2d0e54
comparison
equal deleted inserted replaced
446:9f4e9e9aaf08 447:03bb57383cea
331 331
332 hk_mystatuschange(0, mystatus, st, msg); 332 hk_mystatuschange(0, mystatus, st, msg);
333 mystatus = st; 333 mystatus = st;
334 } 334 }
335 335
336 void jb_send_msg(const char *jid, const char *text) 336 void jb_send_msg(const char *jid, const char *text, int type)
337 { 337 {
338 gchar *strtype;
338 gchar *buffer = to_utf8(text); 339 gchar *buffer = to_utf8(text);
339 xmlnode x = jutil_msgnew(TMSG_CHAT, (char*)jid, 0, (char*)buffer); 340
341 if (type == ROSTER_TYPE_ROOM)
342 strtype = TMSG_GROUPCHAT;
343 else
344 strtype = TMSG_CHAT;
345
346 xmlnode x = jutil_msgnew(strtype, (char*)jid, 0, (char*)buffer);
340 jab_send(jc, x); 347 jab_send(jc, x);
341 xmlnode_free(x); 348 xmlnode_free(x);
342 g_free(buffer); 349 g_free(buffer);
343 jb_reset_keepalive(); 350 jb_reset_keepalive();
344 } 351 }
460 xmlnode_free(x); 467 xmlnode_free(x);
461 g_free(name_utf8); 468 g_free(name_utf8);
462 g_free(cleanjid); 469 g_free(cleanjid);
463 } 470 }
464 471
472 // Join a MUC room
473 // room syntax: "room@server/nick"
474 void jb_room_join(const char *room)
475 {
476 xmlnode x, y;
477
478 if (!online) return;
479 if (!room) return;
480
481 x = jutil_presnew(JPACKET__UNKNOWN, 0, 0);
482 xmlnode_put_attrib(x, "from", jid_full(jc->user));
483 xmlnode_put_attrib(x, "to", room);
484 y = xmlnode_insert_tag(x, "x");
485 xmlnode_put_attrib(y, "xmlns", "http://jabber.org/protocol/muc");
486
487 jab_send(jc, x);
488 xmlnode_free(x);
489 jb_reset_keepalive();
490 }
491
465 void postlogin() 492 void postlogin()
466 { 493 {
467 //int i; 494 //int i;
468 495
469 //flogged = TRUE; 496 //flogged = TRUE;
569 596
570 void gotmessage(char *type, const char *from, const char *body, 597 void gotmessage(char *type, const char *from, const char *body,
571 const char *enc, time_t timestamp) 598 const char *enc, time_t timestamp)
572 { 599 {
573 char *jid; 600 char *jid;
601 const char *rname;
574 gchar *buffer = from_utf8(body); 602 gchar *buffer = from_utf8(body);
575 603
576 jid = jidtodisp(from); 604 jid = jidtodisp(from);
577 605
578 if (!buffer && body) { 606 if (!buffer && body) {
583 0, HBB_PREFIX_ERR | HBB_PREFIX_IN); 611 0, HBB_PREFIX_ERR | HBB_PREFIX_IN);
584 g_free(jid); 612 g_free(jid);
585 return; 613 return;
586 } 614 }
587 615
588 /* 616 rname = strchr(from, '/');
589 //char *u, *h, *r; 617 if (rname) rname++;
590 //jidsplit(from, &u, &h, &r); 618 hk_message_in(jid, rname, timestamp, buffer, type);
591 // Maybe we should remember the resource?
592 if (r)
593 scr_LogPrint(LPRINT_NORMAL,
594 "There is an extra part in message (resource?): %s", r);
595 //scr_LogPrint(LPRINT_NORMAL, "Msg from <%s>, type=%s",
596 // jidtodisp(from), type);
597 */
598
599 hk_message_in(jid, timestamp, buffer, type);
600 g_free(jid); 619 g_free(jid);
601 g_free(buffer); 620 g_free(buffer);
602 } 621 }
603 622
604 const char *defaulterrormsg(int code) 623 const char *defaulterrormsg(int code)
725 previous_state = state; 744 previous_state = state;
726 } 745 }
727 746
728 void packethandler(jconn conn, jpacket packet) 747 void packethandler(jconn conn, jpacket packet)
729 { 748 {
730 char *p, *r; 749 char *p, *r, *s;
731 const char *m, *rname; 750 const char *m, *rname;
732 xmlnode x, y; 751 xmlnode x, y;
733 char *from=NULL, *type=NULL, *body=NULL, *enc=NULL; 752 char *from=NULL, *type=NULL, *body=NULL, *enc=NULL;
734 char *ns=NULL; 753 char *ns=NULL;
735 char *id=NULL; 754 char *id=NULL;
904 xmlnode_free(x); 923 xmlnode_free(x);
905 } 924 }
906 925
907 } 926 }
908 } 927 }
928 } else if (!strcmp(type, "get")) {
929 p = xmlnode_get_attrib(packet->x, "id");
930 if (p) {
931 xmlnode z;
932
933 id = p;
934 x = xmlnode_new_tag("iq");
935 xmlnode_put_attrib(x, "type", "result");
936 xmlnode_put_attrib(x, "to", from);
937 xmlnode_put_attrib(x, "id", id);
938 xmlnode_put_attrib(x, "type", "error");
939 y = xmlnode_insert_tag(x, "error");
940 xmlnode_put_attrib(y, "code", "503");
941 xmlnode_put_attrib(y, "type", "cancel");
942 z = xmlnode_insert_tag(y, "feature-not-implemented");
943 xmlnode_put_attrib(z, "xmlns",
944 "urn:ietf:params:xml:ns:xmpp-stanzas");
945 jab_send(conn, x);
946 xmlnode_free(x);
947 }
909 } else if (!strcmp(type, "set")) { 948 } else if (!strcmp(type, "set")) {
949 /* FIXME: send error */
910 } else if (!strcmp(type, "error")) { 950 } else if (!strcmp(type, "error")) {
911 if ((x = xmlnode_get_tag(packet->x, "error")) != NULL) 951 if ((x = xmlnode_get_tag(packet->x, "error")) != NULL)
912 display_server_error(x); 952 display_server_error(x);
913 } 953 }
914 break; 954 break;
938 978
939 if (type && !strcmp(type, "unavailable")) 979 if (type && !strcmp(type, "unavailable"))
940 ust = offline; 980 ust = offline;
941 981
942 if ((x = xmlnode_get_tag(packet->x, "status")) != NULL) 982 if ((x = xmlnode_get_tag(packet->x, "status")) != NULL)
943 p = from_utf8(xmlnode_get_data(x)); 983 s = from_utf8(xmlnode_get_data(x));
944 else 984 else
945 p = NULL; 985 s = NULL;
946 986
947 // Call hk_statuschange() if status has changed or if the 987 // Call hk_statuschange() if status has changed or if the
948 // status message is different 988 // status message is different
949 rname = strchr(from, '/'); 989 rname = strchr(from, '/');
950 if (rname) rname++; 990 if (rname) rname++;
991
992 // Check for MUC presence packet
993 // There can be multiple <x> tags!!
994 x = xmlnode_get_firstchild(packet->x);
995 for ( ; x; x = xmlnode_get_nextsibling(x)) {
996 if ((p = xmlnode_get_name(x)) && !strcmp(p, "x"))
997 if ((p = xmlnode_get_attrib(x, "xmlns")) &&
998 !strncasecmp(p, "http://jabber.org/protocol/muc", 30))
999 break;
1000 }
1001 if (x) { // This is a MUC presence message
1002 roster_add_user(r, NULL, NULL, ROSTER_TYPE_ROOM);
1003
1004 if (rname)
1005 roster_setstatus(r, rname, bpprio, ust, NULL);
1006 else
1007 scr_LogPrint(LPRINT_LOGNORM, "MUC DBG: no rname!"); /* DBG */
1008
1009 buddylist_build();
1010 scr_DrawRoster();
1011 break;
1012 }
1013
1014 // Not a MUC message, so this is a regular buddy...
951 m = roster_getstatusmsg(r, rname); 1015 m = roster_getstatusmsg(r, rname);
952 if ((ust != roster_getstatus(r, rname)) || (p && (!m || strcmp(p, m)))) 1016 if ((ust != roster_getstatus(r, rname)) || (s && (!m || strcmp(s, m))))
953 hk_statuschange(r, rname, bpprio, 0, ust, p); 1017 hk_statuschange(r, rname, bpprio, 0, ust, s);
954 g_free(r); 1018 g_free(r);
955 if (p) g_free(p); 1019 if (s) g_free(s);
956 break; 1020 break;
957 1021
958 case JPACKET_S10N: 1022 case JPACKET_S10N:
959 scr_LogPrint(LPRINT_LOGNORM, "Received (un)subscription packet " 1023 scr_LogPrint(LPRINT_LOGNORM, "Received (un)subscription packet "
960 "(type=%s)", ((type) ? type : "")); 1024 "(type=%s)", ((type) ? type : ""));