> <iq*><session*/></iq>
> <presence/>
+ > <iq*><query*/></iq>
+ > <iq*><query*/></iq>
> <presence*><*/></presence>
< <presence id="join" from="test@localhost/andy"/>
< <presence id="join" from="test@localhost/bob"/>
> <session xmlns='*:xmpp-session'/>
> </iq>
> <presence/>
+ > <iq id='roster' type='get'>
+ > <query xmlns='jabber:iq:roster'/>
+ > </iq>
+ > <iq id='rooms' type='get' to='conf.local'>
+ > <query xmlns='http://jabber.org/protocol/disco#items'/>
+ > </iq>
> <presence id='join' from='andy@localhost/lamechat' to='*'>
> <x xmlns='http://jabber.org/protocol/muc'/>
> </presence>
> <iq*><session*/></iq>
> <presence/>
+ > <iq*><query*/></iq>
+ > <iq*><query*/></iq>
> <presence*><*/></presence>
< <presence from="chan1@conf.serv1/alice1"/>
< <presence from="other1@conf.serv1/bob1"/>
> <iq*><session*/></iq>
> <presence/>
+ > <iq*><query*/></iq>
+ > <iq*><query*/></iq>
> <presence*><*/></presence>
< <presence from="chan2@conf.serv2/alice2"/>
< <presence from="other2@conf.serv2/bob2"/>
XMPP_RECV_JID,
XMPP_SEND_SESSION,
XMPP_SEND_PRESENCE,
+ XMPP_SEND_ROSTER,
+ XMPP_SEND_ROOMS,
XMPP_SEND_JOIN,
XMPP_READY,
XMPP_IN_IQ,
XMPP_IN_VCARD,
+ XMPP_IN_ROSTER,
+ XMPP_IN_ROOMS,
XMPP_IN_MESSAGE,
XMPP_IN_PRESENCE,
} xmpp_state_t;
const char *type;
int muc;
- const char *room;
+ char *room;
+ char *name;
int join;
} xmpp_channel_t;
}
if (srv->state == XMPP_SEND_PRESENCE) {
if (net_print(&srv->net, "<presence/>")) {
- debug("xmpp: presence -> join");
+ debug("xmpp: presence -> roster");
+ srv->state = XMPP_SEND_ROSTER;
+ }
+ }
+ if (srv->state == XMPP_SEND_ROSTER) {
+ if (net_print(&srv->net,
+ "<iq id='roster' type='get'>"
+ "<query xmlns='jabber:iq:roster'/>"
+ "</iq>")) {
+ debug("xmpp: roster -> rooms");
+ srv->state = XMPP_SEND_ROOMS;
+ }
+ }
+ if (srv->state == XMPP_SEND_ROOMS) {
+ if (net_print(&srv->net,
+ "<iq id='rooms' type='get' to='%s'>"
+ "<query xmlns='http://jabber.org/protocol/disco#items'/>"
+ "</iq>",
+ srv->muc)) {
+ debug("xmpp: rooms -> join");
srv->state = XMPP_SEND_JOIN;
}
}
}
}
+ /* Rosters */
+ if (srv->state == XMPP_IN_IQ) {
+ if (match(srv->msg_id, "roster"))
+ srv->state = XMPP_IN_ROSTER;
+ }
+ if (srv->state == XMPP_IN_ROSTER) {
+ if (match(start, "item")) {
+ // Todo: cleanup name setting
+ const char *jid = find_attr(attrs, "jid");
+ const char *fname = find_attr(attrs, "name");
+ xmpp_user_t *usr = find_user(srv, jid, 0);
+ xmpp_channel_t *chan = find_channel(srv, jid, 0);
+ if (usr) {
+ strset(&usr->full_name, fname);
+ strset(&usr->user.name, fname);
+ }
+ if (chan) {
+ strset(&chan->channel.name, fname);
+ }
+ }
+ }
+ if (srv->state == XMPP_IN_ROSTER) {
+ if (match(end, "iq"))
+ srv->state = XMPP_IN_IQ;
+ }
+
+ /* Rooms */
+ if (srv->state == XMPP_IN_IQ) {
+ if (match(srv->msg_id, "rooms"))
+ srv->state = XMPP_IN_ROOMS;
+ }
+ if (srv->state == XMPP_IN_ROOMS) {
+ if (match(start, "item")) {
+ const char *jid = find_attr(attrs, "jid");
+ xmpp_channel_t *chan = find_channel(srv, jid, 1);
+ if (jid && chan) {
+ strset(&chan->room,
+ find_attr(attrs, "name"));
+ strset(&chan->name,
+ find_attr(attrs, "name"));
+ }
+ }
+ }
+ if (srv->state == XMPP_IN_ROOMS) {
+ if (match(end, "iq"))
+ srv->state = XMPP_IN_IQ;
+ }
+
/* Messages */
if (srv->state == XMPP_IN_MESSAGE) {
if (match(start, "delay")) {