mcabber/src/jabglue.c
changeset 1384 f762805b3f42
parent 1383 d9606bd03144
child 1385 7ca57f7e313c
equal deleted inserted replaced
1383:d9606bd03144 1384:f762805b3f42
  1994   if ((p = xmlnode_get_attrib(x, "stamp")) != NULL)
  1994   if ((p = xmlnode_get_attrib(x, "stamp")) != NULL)
  1995     return from_iso8601(p, 1);
  1995     return from_iso8601(p, 1);
  1996   return 0;
  1996   return 0;
  1997 }
  1997 }
  1998 
  1998 
       
  1999 //  muc_get_item_info(...)
       
  2000 // Get room member's information from xmlndata.
       
  2001 // The variables must be initialized before calling this function,
       
  2002 // because they are not touched if the relevant information is missing.
       
  2003 static void muc_get_item_info(const char *from, xmlnode xmldata,
       
  2004                               enum imrole *mbrole, enum imaffiliation *mbaffil,
       
  2005                               const char **mbjid, const char **mbnick,
       
  2006                               const char **actorjid, const char **reason)
       
  2007 {
       
  2008   xmlnode y, z;
       
  2009   char *p;
       
  2010 
       
  2011   y = xmlnode_get_tag(xmldata, "item");
       
  2012   if (!y)
       
  2013     return;
       
  2014 
       
  2015   p = xmlnode_get_attrib(y, "affiliation");
       
  2016   if (p) {
       
  2017     if (!strcmp(p, "owner"))        *mbaffil = affil_owner;
       
  2018     else if (!strcmp(p, "admin"))   *mbaffil = affil_admin;
       
  2019     else if (!strcmp(p, "member"))  *mbaffil = affil_member;
       
  2020     else if (!strcmp(p, "outcast")) *mbaffil = affil_outcast;
       
  2021     else if (!strcmp(p, "none"))    *mbaffil = affil_none;
       
  2022     else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown affiliation \"%s\"",
       
  2023                       from, p);
       
  2024   }
       
  2025   p = xmlnode_get_attrib(y, "role");
       
  2026   if (p) {
       
  2027     if (!strcmp(p, "moderator"))        *mbrole = role_moderator;
       
  2028     else if (!strcmp(p, "participant")) *mbrole = role_participant;
       
  2029     else if (!strcmp(p, "visitor"))     *mbrole = role_visitor;
       
  2030     else if (!strcmp(p, "none"))        *mbrole = role_none;
       
  2031     else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"",
       
  2032                       from, p);
       
  2033   }
       
  2034   *mbjid = xmlnode_get_attrib(y, "jid");
       
  2035   *mbnick = xmlnode_get_attrib(y, "nick");
       
  2036   // For kick/ban, there can be actor and reason tags
       
  2037   *reason = xmlnode_get_tag_data(y, "reason");
       
  2038   z = xmlnode_get_tag(y, "actor");
       
  2039   if (z)
       
  2040     *actorjid = xmlnode_get_attrib(z, "jid");
       
  2041 }
       
  2042 
       
  2043 //  muc_handle_join(...)
       
  2044 // Handle a join event in a MUC room.
       
  2045 // This function will return the new_member value TRUE if somebody else joins
       
  2046 // the room (and FALSE if _we_ are joining the room).
       
  2047 static bool muc_handle_join(const GSList *room_elt, const char *rname,
       
  2048                             const char *roomjid, const char *ournick,
       
  2049                             enum room_printstatus printstatus,
       
  2050                             time_t usttime, int log_muc_conf)
       
  2051 {
       
  2052   bool new_member = FALSE; // True if somebody else joins the room (not us)
       
  2053   gchar *mbuf;
       
  2054 
       
  2055   if (!buddy_getinsideroom(room_elt->data)) {
       
  2056     // We weren't inside the room yet.  Now we are.
       
  2057     // However, this could be a presence packet from another room member
       
  2058 
       
  2059     buddy_setinsideroom(room_elt->data, TRUE);
       
  2060     // Set the message flag unless we're already in the room buffer window
       
  2061     scr_setmsgflag_if_needed(roomjid, FALSE);
       
  2062     // Add a message to the tracelog file
       
  2063     mbuf = g_strdup_printf("You have joined %s as \"%s\"", roomjid, ournick);
       
  2064     scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
       
  2065     g_free(mbuf);
       
  2066     mbuf = g_strdup_printf("You have joined as \"%s\"", ournick);
       
  2067 
       
  2068     // The 1st presence message could be for another room member
       
  2069     if (strcmp(ournick, rname)) {
       
  2070       // Display current mbuf and create a new message for the member
       
  2071       // Note: the usttime timestamp is related to the other member,
       
  2072       //       so we use 0 here.
       
  2073       scr_WriteIncomingMessage(roomjid, mbuf, 0,
       
  2074                                HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
       
  2075       if (log_muc_conf)
       
  2076         hlog_write_message(roomjid, 0, -1, mbuf);
       
  2077       g_free(mbuf);
       
  2078       if (printstatus != status_none)
       
  2079         mbuf = g_strdup_printf("%s has joined", rname);
       
  2080       else
       
  2081         mbuf = NULL;
       
  2082       new_member = TRUE;
       
  2083     }
       
  2084   } else {
       
  2085     mbuf = NULL;
       
  2086     if (strcmp(ournick, rname)) {
       
  2087       if (printstatus != status_none)
       
  2088         mbuf = g_strdup_printf("%s has joined", rname);
       
  2089       new_member = TRUE;
       
  2090     }
       
  2091   }
       
  2092 
       
  2093   if (mbuf) {
       
  2094     guint msgflags = HBB_PREFIX_INFO;
       
  2095     if (!settings_opt_get_int("muc_flag_joins"))
       
  2096       msgflags |= HBB_PREFIX_NOFLAG;
       
  2097     scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0);
       
  2098     if (log_muc_conf)
       
  2099       hlog_write_message(roomjid, 0, -1, mbuf);
       
  2100     g_free(mbuf);
       
  2101   }
       
  2102 
       
  2103   return new_member;
       
  2104 }
       
  2105 
  1999 static void handle_presence_muc(const char *from, xmlnode xmldata,
  2106 static void handle_presence_muc(const char *from, xmlnode xmldata,
  2000                                 const char *roomjid, const char *rname,
  2107                                 const char *roomjid, const char *rname,
  2001                                 enum imstatus ust, char *ustmsg,
  2108                                 enum imstatus ust, char *ustmsg,
  2002                                 time_t usttime, char bpprio)
  2109                                 time_t usttime, char bpprio)
  2003 {
  2110 {
  2032     // Make sure this is a room (it can be a conversion user->room)
  2139     // Make sure this is a room (it can be a conversion user->room)
  2033     buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
  2140     buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
  2034   }
  2141   }
  2035 
  2142 
  2036   // Get room member's information
  2143   // Get room member's information
  2037   y = xmlnode_get_tag(xmldata, "item");
  2144   muc_get_item_info(from, xmldata, &mbrole, &mbaffil, &mbjid, &mbnick,
  2038   if (y) {
  2145                     &actorjid, &reason);
  2039     xmlnode z;
       
  2040     p = xmlnode_get_attrib(y, "affiliation");
       
  2041     if (p) {
       
  2042       if (!strcmp(p, "owner"))        mbaffil = affil_owner;
       
  2043       else if (!strcmp(p, "admin"))   mbaffil = affil_admin;
       
  2044       else if (!strcmp(p, "member"))  mbaffil = affil_member;
       
  2045       else if (!strcmp(p, "outcast")) mbaffil = affil_outcast;
       
  2046       else if (!strcmp(p, "none"))    mbaffil = affil_none;
       
  2047       else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown affiliation \"%s\"",
       
  2048                         from, p);
       
  2049     }
       
  2050     p = xmlnode_get_attrib(y, "role");
       
  2051     if (p) {
       
  2052       if (!strcmp(p, "moderator"))        mbrole = role_moderator;
       
  2053       else if (!strcmp(p, "participant")) mbrole = role_participant;
       
  2054       else if (!strcmp(p, "visitor"))     mbrole = role_visitor;
       
  2055       else if (!strcmp(p, "none"))        mbrole = role_none;
       
  2056       else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"",
       
  2057                         from, p);
       
  2058     }
       
  2059     mbjid = xmlnode_get_attrib(y, "jid");
       
  2060     mbnick = xmlnode_get_attrib(y, "nick");
       
  2061     // For kick/ban, there can be actor and reason tags
       
  2062     reason = xmlnode_get_tag_data(y, "reason");
       
  2063     z = xmlnode_get_tag(y, "actor");
       
  2064     if (z)
       
  2065       actorjid = xmlnode_get_attrib(z, "jid");
       
  2066   }
       
  2067 
  2146 
  2068   // Get our room nickname
  2147   // Get our room nickname
  2069   ournick = buddy_getnickname(room_elt->data);
  2148   ournick = buddy_getnickname(room_elt->data);
  2070 
  2149 
  2071   if (!ournick) {
  2150   if (!ournick) {
  2117     nickchange = TRUE;
  2196     nickchange = TRUE;
  2118   }
  2197   }
  2119 
  2198 
  2120   // Check for departure/arrival
  2199   // Check for departure/arrival
  2121   if (!mbnick && ust == offline) {
  2200   if (!mbnick && ust == offline) {
       
  2201     // Somebody is leaving
  2122     enum { leave=0, kick, ban } how = leave;
  2202     enum { leave=0, kick, ban } how = leave;
  2123     bool we_left = FALSE;
  2203     bool we_left = FALSE;
  2124 
  2204 
  2125     if (statuscode == 307)
  2205     if (statuscode == 307)
  2126       how = kick;
  2206       how = kick;
  2206       return;
  2286       return;
  2207     }
  2287     }
  2208     g_free(mbuf);
  2288     g_free(mbuf);
  2209   } else if (buddy_getstatus(room_elt->data, rname) == offline &&
  2289   } else if (buddy_getstatus(room_elt->data, rname) == offline &&
  2210              ust != offline) {
  2290              ust != offline) {
  2211 
  2291     // Somebody is joining
  2212     if (!buddy_getinsideroom(room_elt->data)) {
  2292     new_member = muc_handle_join(room_elt, rname, roomjid, ournick,
  2213       // We weren't inside the room yet.  Now we are.
  2293                                  printstatus, usttime, log_muc_conf);
  2214       // However, this could be a presence packet from another room member
       
  2215 
       
  2216       buddy_setinsideroom(room_elt->data, TRUE);
       
  2217       // Set the message flag unless we're already in the room buffer window
       
  2218       scr_setmsgflag_if_needed(roomjid, FALSE);
       
  2219       // Add a message to the tracelog file
       
  2220       mbuf = g_strdup_printf("You have joined %s as \"%s\"", roomjid, ournick);
       
  2221       scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
       
  2222       g_free(mbuf);
       
  2223       mbuf = g_strdup_printf("You have joined as \"%s\"", ournick);
       
  2224 
       
  2225       // The 1st presence message could be for another room member
       
  2226       if (strcmp(ournick, rname)) {
       
  2227         // Display current mbuf and create a new message for the member
       
  2228         // Note: the usttime timestamp is related to the other member,
       
  2229         //       so we use 0 here.
       
  2230         scr_WriteIncomingMessage(roomjid, mbuf, 0,
       
  2231                                  HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
       
  2232         if (log_muc_conf)
       
  2233           hlog_write_message(roomjid, 0, -1, mbuf);
       
  2234         g_free(mbuf);
       
  2235         if (printstatus != status_none)
       
  2236           mbuf = g_strdup_printf("%s has joined", rname);
       
  2237         else
       
  2238           mbuf = NULL;
       
  2239         new_member = TRUE;
       
  2240       }
       
  2241     } else {
       
  2242       mbuf = NULL;
       
  2243       if (strcmp(ournick, rname)) {
       
  2244         if (printstatus != status_none)
       
  2245           mbuf = g_strdup_printf("%s has joined", rname);
       
  2246         new_member = TRUE;
       
  2247       }
       
  2248     }
       
  2249 
       
  2250     if (mbuf) {
       
  2251       msgflags = HBB_PREFIX_INFO;
       
  2252       if (!settings_opt_get_int("muc_flag_joins"))
       
  2253         msgflags |= HBB_PREFIX_NOFLAG;
       
  2254       scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0);
       
  2255       if (log_muc_conf)
       
  2256         hlog_write_message(roomjid, 0, -1, mbuf);
       
  2257       g_free(mbuf);
       
  2258     }
       
  2259   } else {
  2294   } else {
  2260     // This is a simple member status change
  2295     // This is a simple member status change
  2261 
  2296 
  2262     if (printstatus == status_all && !nickchange) {
  2297     if (printstatus == status_all && !nickchange) {
  2263       mbuf = g_strdup_printf("Member status has changed: %s [%c] %s", rname,
  2298       mbuf = g_strdup_printf("Member status has changed: %s [%c] %s", rname,