Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/msn.c

    r3058c30 r5ebff60  
    3030int msn_chat_id;
    3131GSList *msn_connections;
     32GSList *msn_switchboards;
    3233
    3334static char *set_eval_display_name(set_t *set, char *value);
     
    4041        s->flags |= SET_NOSAVE | ACC_SET_ONLINE_ONLY;
    4142
    42         s = set_add(&acc->set, "server", NULL, set_eval_account, acc);
     43        s = set_add(&acc->set, "server", MSN_NS_HOST, set_eval_account, acc);
    4344        s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
    4445
     
    4748
    4849        set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc);
     50        set_add(&acc->set, "switchboard_keepalives", "false", set_eval_bool, acc);
    4951
    5052        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE |
     
    5658        struct im_connection *ic = imcb_new(acc);
    5759        struct msn_data *md = g_new0(struct msn_data, 1);
    58         char *server = set_getstr(&ic->acc->set, "server");
    5960
    6061        ic->proto_data = md;
    6162        ic->flags |= OPT_PONGS | OPT_PONGED;
    62 
    63         if (!server) {
    64                 server = "geo.gateway.messenger.live.com";
    65         }
    6663
    6764        if (strchr(acc->user, '@') == NULL) {
     
    7471        md->away_state = msn_away_state_list;
    7572        md->domaintree = g_tree_new(msn_domaintree_cmp);
    76         md->fd = -1;
    77         md->is_http = TRUE;
     73        md->ns->fd = -1;
    7874
    7975        msn_connections = g_slist_prepend(msn_connections, ic);
    8076
    8177        imcb_log(ic, "Connecting");
    82         msn_ns_connect(ic, server,
     78        msn_ns_connect(ic, md->ns,
     79                       set_getstr(&ic->acc->set, "server"),
    8380                       set_getint(&ic->acc->set, "port"));
    8481}
     
    9188
    9289        if (md) {
    93                 msn_ns_close(md);
    94 
     90                /** Disabling MSN ft support for now.
     91                while( md->filetransfers ) {
     92                        imcb_file_canceled( md->filetransfers->data, "Closing connection" );
     93                }
     94                */
     95
     96                msn_ns_close(md->ns);
     97
     98                while (md->switchboards) {
     99                        msn_sb_destroy(md->switchboards->data);
     100                }
     101
     102                msn_msgq_purge(ic, &md->msgq);
    95103                msn_soapq_flush(ic, FALSE);
    96104
     
    104112                while (md->groups) {
    105113                        struct msn_group *mg = md->groups->data;
    106                         md->groups = g_slist_remove(md->groups, mg);
    107114                        g_free(mg->id);
    108115                        g_free(mg->name);
    109116                        g_free(mg);
     117                        md->groups = g_slist_remove(md->groups, mg);
    110118                }
    111119
     
    119127                while (md->grpq) {
    120128                        struct msn_groupadd *ga = md->grpq->data;
    121                         md->grpq = g_slist_remove(md->grpq, ga);
    122129                        g_free(ga->group);
    123130                        g_free(ga->who);
    124131                        g_free(ga);
     132                        md->grpq = g_slist_remove(md->grpq, ga);
    125133                }
    126134
     
    144152{
    145153        struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who);
     154        struct msn_buddy_data *bd = bu ? bu->data : NULL;
     155        struct msn_switchboard *sb;
    146156
    147157#ifdef DEBUG
    148158        if (strcmp(who, "raw") == 0) {
    149159                msn_ns_write(ic, -1, "%s\r\n", message);
    150                 return 0;
    151         }
     160        } else
    152161#endif
    153 
    154         msn_ns_sendmessage(ic, bu, message);
     162        if (bd && bd->flags & MSN_BUDDY_FED) {
     163                msn_ns_sendmessage(ic, bu, message);
     164        } else if ((sb = msn_sb_by_handle(ic, who))) {
     165                return(msn_sb_sendmessage(sb, message));
     166        } else {
     167                struct msn_message *m;
     168
     169                /* Create a message. We have to arrange a usable switchboard, and send the message later. */
     170                m = g_new0(struct msn_message, 1);
     171                m->who = g_strdup(who);
     172                m->text = g_strdup(message);
     173
     174                return msn_sb_write_msg(ic, m);
     175        }
     176
    155177        return(0);
    156178}
     
    174196static void msn_set_away(struct im_connection *ic, char *state, char *message)
    175197{
     198        char *uux;
    176199        struct msn_data *md = ic->proto_data;
    177         char *nick, *psm, *idle, *statecode, *body, *buf;
    178200
    179201        if (state == NULL) {
     
    183205        }
    184206
    185         statecode = (char *) md->away_state->code;
    186         nick = set_getstr(&ic->acc->set, "display_name");
    187         psm = message ? message : "";
    188         idle = (strcmp(statecode, "IDL") == 0) ? "false" : "true";
    189 
    190         body = g_markup_printf_escaped(MSN_PUT_USER_BODY,
    191                 nick, psm, psm, md->uuid, statecode, md->uuid, idle, statecode,
    192                 MSN_CAP1, MSN_CAP2, MSN_CAP1, MSN_CAP2
    193         );
    194 
    195         buf = g_strdup_printf(MSN_PUT_HEADERS, ic->acc->user, ic->acc->user, md->uuid,
    196                 "/user", "application/user+xml",
    197                 strlen(body), body);
    198         msn_ns_write(ic, -1, "PUT %d %zd\r\n%s", ++md->trId, strlen(buf), buf);
    199 
    200         g_free(buf);
    201         g_free(body);
     207        if (!msn_ns_write(ic, -1, "CHG %d %s %d:%02d\r\n", ++md->trId, md->away_state->code, MSN_CAP1, MSN_CAP2)) {
     208                return;
     209        }
     210
     211        uux = g_markup_printf_escaped("<EndpointData><Capabilities>%d:%02d"
     212                                      "</Capabilities></EndpointData>",
     213                                      MSN_CAP1, MSN_CAP2);
     214        msn_ns_write(ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen(uux), uux);
     215        g_free(uux);
     216
     217        uux = g_markup_printf_escaped("<PrivateEndpointData><EpName>%s</EpName>"
     218                                      "<Idle>%s</Idle><ClientType>%d</ClientType>"
     219                                      "<State>%s</State></PrivateEndpointData>",
     220                                      md->uuid,
     221                                      strcmp(md->away_state->code, "IDL") ? "false" : "true",
     222                                      1,  /* ? */
     223                                      md->away_state->code);
     224        msn_ns_write(ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen(uux), uux);
     225        g_free(uux);
     226
     227        uux = g_markup_printf_escaped("<Data><DDP></DDP><PSM>%s</PSM>"
     228                                      "<CurrentMedia></CurrentMedia>"
     229                                      "<MachineGuid>%s</MachineGuid></Data>",
     230                                      message ? message : "", md->uuid);
     231        msn_ns_write(ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen(uux), uux);
     232        g_free(uux);
    202233}
    203234
     
    225256static void msn_chat_msg(struct groupchat *c, char *message, int flags)
    226257{
    227         /* TODO: groupchats*/
     258        struct msn_switchboard *sb = msn_sb_by_chat(c);
     259
     260        if (sb) {
     261                msn_sb_sendmessage(sb, message);
     262        }
     263        /* FIXME: Error handling (although this can't happen unless something's
     264           already severely broken) disappeared here! */
    228265}
    229266
    230267static void msn_chat_invite(struct groupchat *c, char *who, char *message)
    231268{
    232         /* TODO: groupchats*/
     269        struct msn_switchboard *sb = msn_sb_by_chat(c);
     270
     271        if (sb) {
     272                msn_sb_write(sb, "CAL %d %s\r\n", ++sb->trId, who);
     273        }
    233274}
    234275
    235276static void msn_chat_leave(struct groupchat *c)
    236277{
    237         /* TODO: groupchats*/
     278        struct msn_switchboard *sb = msn_sb_by_chat(c);
     279
     280        if (sb) {
     281                msn_sb_write(sb, "OUT\r\n");
     282        }
    238283}
    239284
    240285static struct groupchat *msn_chat_with(struct im_connection *ic, char *who)
    241286{
    242         /* TODO: groupchats*/
     287        struct msn_switchboard *sb;
    243288        struct groupchat *c = imcb_chat_new(ic, who);
    244         return c;
     289
     290        if ((sb = msn_sb_by_handle(ic, who))) {
     291                debug("Converting existing switchboard to %s to a groupchat", who);
     292                return msn_sb_to_chat(sb);
     293        } else {
     294                struct msn_message *m;
     295
     296                /* Create a magic message. This is quite hackish, but who cares? :-P */
     297                m = g_new0(struct msn_message, 1);
     298                m->who = g_strdup(who);
     299                m->text = g_strdup(GROUPCHAT_SWITCHBOARD_MESSAGE);
     300
     301                msn_sb_write_msg(ic, m);
     302
     303                return c;
     304        }
    245305}
    246306
     
    262322static void msn_add_deny(struct im_connection *ic, char *who)
    263323{
     324        struct msn_switchboard *sb;
     325
    264326        msn_buddy_list_add(ic, MSN_BUDDY_BL, who, who, NULL);
     327
     328        /* If there's still a conversation with this person, close it. */
     329        if ((sb = msn_sb_by_handle(ic, who))) {
     330                msn_sb_destroy(sb);
     331        }
    265332}
    266333
     
    395462        ret->buddy_action = msn_buddy_action;
    396463
     464        //ret->transfer_request = msn_ftp_transfer_request;
     465
    397466        register_protocol(ret);
    398467}
Note: See TracChangeset for help on using the changeset viewer.