Changeset 65418c59 for protocols/msn


Ignore:
Timestamp:
2015-03-19T10:48:48Z (10 years ago)
Author:
dequis <dx@…>
Children:
ac4999a
Parents:
75e49de
Message:

msn: handle NFY PUT (presence notifications), refactor a bit

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/ns.c

    r75e49de r65418c59  
    3838static void msn_ns_send_adl_start(struct im_connection *ic);
    3939static void msn_ns_send_adl(struct im_connection *ic);
     40static void msn_ns_structured_message(struct msn_data *handler, char *msg, int msglen, char **cmd);
     41static void msn_ns_sdg(struct msn_data *handler, char *who, char **parts, char *action);
     42static void msn_ns_nfy(struct msn_data *handler, char *who, char **parts, char *action, gboolean is_put);
    4043
    4144int msn_ns_write(struct im_connection *ic, int fd, const char *fmt, ...)
     
    485488                        }
    486489                }
    487         } else if (strcmp(cmd[0], "SDG") == 0) {
    488                 char **parts = g_strsplit(msg, "\r\n\r\n", 4);
    489                 char *from = NULL;
    490                 char *mt = NULL;
    491                 char *who = NULL;
    492                 char *s = NULL;
    493 
    494                 if ((from = get_rfc822_header(parts[0], "From", 0)) &&
    495                     (mt = get_rfc822_header(parts[2], "Message-Type", 0)) &&
    496                     (s = strchr(from, ';'))) {
    497 
    498                         who = g_strndup(from + 2, s - from - 2);
    499 
    500                         if (strcmp(mt, "Control/Typing") == 0) {
    501                                 imcb_buddy_typing(ic, who, OPT_TYPING);
    502                         } else if (strcmp(mt, "Text") == 0) {
    503                                 imcb_buddy_msg(ic, who, parts[3], 0, 0);
    504                         }
    505                 }
    506                 g_free(from);
    507                 g_free(mt);
    508                 g_free(who);
    509                 return 1;
     490        } else if ((strcmp(cmd[0], "SDG") == 0) || (strcmp(cmd[0], "NFY") == 0)) {
     491                msn_ns_structured_message(handler, msg, msglen, cmd);
    510492        }
    511493
    512494        return 1;
     495}
     496
     497static void msn_ns_structured_message(struct msn_data *handler, char *msg, int msglen, char **cmd)
     498{
     499        char **parts = NULL;
     500        char *semicolon = NULL;
     501        char *action = NULL;
     502        char *from = NULL;
     503        char *who = NULL;
     504
     505        parts = g_strsplit(msg, "\r\n\r\n", 4);
     506
     507        if (!(from = get_rfc822_header(parts[0], "From", 0))) {
     508                goto cleanup;
     509        }
     510
     511        /* either the semicolon or the end of the string */
     512        semicolon = strchr(from, ';') ? : (from + strlen(from));
     513
     514        who = g_strndup(from + 2, semicolon - from - 2);
     515
     516        if ((strcmp(cmd[0], "SDG") == 0) && (action = get_rfc822_header(parts[2], "Message-Type", 0))) {
     517                msn_ns_sdg(handler, who, parts, action);
     518
     519        } else if ((strcmp(cmd[0], "NFY") == 0) && (action = get_rfc822_header(parts[2], "Uri", 0))) {
     520                gboolean is_put = (strcmp(cmd[1], "PUT") == 0);
     521                msn_ns_nfy(handler, who, parts, action, is_put);
     522        }
     523
     524cleanup:
     525        g_strfreev(parts);
     526        g_free(action);
     527        g_free(from);
     528        g_free(who);
     529}
     530
     531static void msn_ns_sdg(struct msn_data *handler, char *who, char **parts, char *action)
     532{
     533        struct im_connection *ic = handler->ic;
     534
     535        if (strcmp(action, "Control/Typing") == 0) {
     536                imcb_buddy_typing(ic, who, OPT_TYPING);
     537        } else if (strcmp(action, "Text") == 0) {
     538                imcb_buddy_msg(ic, who, parts[3], 0, 0);
     539        }
     540}
     541
     542static void msn_ns_nfy(struct msn_data *handler, char *who, char **parts, char *action, gboolean is_put)
     543{
     544        struct im_connection *ic = handler->ic;
     545        struct xt_node *body = NULL;
     546        struct xt_node *s = NULL;
     547        const char *state = NULL;
     548        char *nick = NULL;
     549        char *psm = NULL;
     550        int flags = OPT_LOGGED_IN;
     551
     552        if (strcmp(action, "/user") != 0) {
     553                return;
     554        }
     555
     556        if (!(body = xt_from_string(parts[3], 0))) {
     557                goto cleanup;
     558        }
     559
     560        s = body->children;
     561        while ((s = xt_find_node(s, "s"))) {
     562                struct xt_node *s2;
     563                char *n = xt_find_attr(s, "n");  /* service name: IM, PE, etc */
     564
     565                if (strcmp(n, "IM") == 0) {
     566                        /* IM has basic presence information */
     567                        if (!is_put) {
     568                                /* NFY DEL with a <s> usually means log out from the last endpoint */
     569                                flags &= ~OPT_LOGGED_IN;
     570                                break;
     571                        }
     572
     573                        s2 = xt_find_node(s->children, "Status");
     574                        if (s2 && s2->text_len) {
     575                                const struct msn_away_state *msn_state = msn_away_state_by_code(s2->text);
     576                                state = msn_state->name;
     577                                if (msn_state != msn_away_state_list) {
     578                                        flags |= OPT_AWAY;
     579                                }
     580                        }
     581                } else if (strcmp(n, "PE") == 0) {
     582                        if ((s2 = xt_find_node(s->children, "PSM")) && s2->text_len) {
     583                                psm = s2->text;
     584                        }
     585                        if ((s2 = xt_find_node(s->children, "FriendlyName")) && s2->text_len) {
     586                                nick = s2->text;
     587                        }
     588                }
     589                s = s->next;
     590        }
     591
     592        imcb_buddy_status(ic, who, flags, state, psm);
     593
     594        if (nick) {
     595                imcb_rename_buddy(ic, who, nick);
     596        }
     597
     598cleanup:
     599        xt_free_node(body);
    513600}
    514601
Note: See TracChangeset for help on using the changeset viewer.