Changeset ffa5b70 for protocols/msn/ns.c


Ignore:
Timestamp:
2015-03-15T14:41:47Z (10 years ago)
Author:
dequis <dx@…>
Children:
6e74911
Parents:
3752019
git-author:
dequis <dx@…> (09-03-15 08:35:50)
git-committer:
dequis <dx@…> (15-03-15 14:41:47)
Message:

msn: removed switchboards, implemented SDG message

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/ns.c

    r3752019 rffa5b70  
    3535static gboolean msn_ns_connected(gpointer data, gint source, b_input_condition cond);
    3636static gboolean msn_ns_callback(gpointer data, gint source, b_input_condition cond);
    37 static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_parts);
    38 static int msn_ns_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts);
    3937
    4038static void msn_ns_send_adl_start(struct im_connection *ic);
     
    5452
    5553        if (fd < 0) {
    56                 fd = md->ns->fd;
     54                fd = md->fd;
    5755        }
    5856
     
    7371}
    7472
    75 gboolean msn_ns_connect(struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port)
    76 {
     73gboolean msn_ns_connect(struct im_connection *ic, const char *host, int port)
     74{
     75        struct msn_data *handler = ic->proto_data;
     76
    7777        if (handler->fd >= 0) {
    7878                closesocket(handler->fd);
    7979        }
    8080
    81         handler->exec_command = msn_ns_command;
    82         handler->exec_message = msn_ns_message;
    83         handler->data = ic;
    8481        handler->fd = proxy_connect(host, port, msn_ns_connected, handler);
    8582        if (handler->fd < 0) {
     
    9491static gboolean msn_ns_connected(gpointer data, gint source, b_input_condition cond)
    9592{
    96         struct msn_handler_data *handler = data;
    97         struct im_connection *ic = handler->data;
    98         struct msn_data *md;
    99 
    100         if (!g_slist_find(msn_connections, ic)) {
    101                 return FALSE;
    102         }
    103 
    104         md = ic->proto_data;
     93        struct msn_data *md = data;
     94        struct msn_data *handler = md;
     95        struct im_connection *ic = md->ic;
    10596
    10697        if (source == -1) {
     
    137128}
    138129
    139 void msn_ns_close(struct msn_handler_data *handler)
     130void msn_ns_close(struct msn_data *handler)
    140131{
    141132        if (handler->fd >= 0) {
     
    155146static gboolean msn_ns_callback(gpointer data, gint source, b_input_condition cond)
    156147{
    157         struct msn_handler_data *handler = data;
    158         struct im_connection *ic = handler->data;
     148        struct msn_data *handler = data;
     149        struct im_connection *ic = handler->ic;
    159150
    160151        if (msn_handler(handler) == -1) {  /* Don't do this on ret == 0, it's already done then. */
     
    168159}
    169160
    170 static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_parts)
    171 {
    172         struct im_connection *ic = handler->data;
    173         struct msn_data *md = ic->proto_data;
     161int msn_ns_command(struct msn_data *handler, char **cmd, int num_parts)
     162{
     163        struct im_connection *ic = handler->ic;
     164        struct msn_data *md = handler;
    174165
    175166        if (num_parts == 0) {
     
    209200
    210201                        imcb_log(ic, "Transferring to other server");
    211                         return msn_ns_connect(ic, handler, server, port);
    212                 } else if (num_parts >= 6 && strcmp(cmd[2], "SB") == 0) {
    213                         struct msn_switchboard *sb;
    214 
    215                         server = strchr(cmd[3], ':');
    216                         if (!server) {
    217                                 imcb_error(ic, "Syntax error");
    218                                 imc_logout(ic, TRUE);
    219                                 return(0);
    220                         }
    221                         *server = 0;
    222                         port = atoi(server + 1);
    223                         server = cmd[3];
    224 
    225                         if (strcmp(cmd[4], "CKI") != 0) {
    226                                 imcb_error(ic, "Unknown authentication method for switchboard");
    227                                 imc_logout(ic, TRUE);
    228                                 return(0);
    229                         }
    230 
    231                         debug("Connecting to a new switchboard with key %s", cmd[5]);
    232 
    233                         if ((sb = msn_sb_create(ic, server, port, cmd[5], MSN_SB_NEW)) == NULL) {
    234                                 /* Although this isn't strictly fatal for the NS connection, it's
    235                                    definitely something serious (we ran out of file descriptors?). */
    236                                 imcb_error(ic, "Could not create new switchboard");
    237                                 imc_logout(ic, TRUE);
    238                                 return(0);
    239                         }
    240 
    241                         if (md->msgq) {
    242                                 struct msn_message *m = md->msgq->data;
    243                                 GSList *l;
    244 
    245                                 sb->who = g_strdup(m->who);
    246 
    247                                 /* Move all the messages to the first user in the message
    248                                    queue to the switchboard message queue. */
    249                                 l = md->msgq;
    250                                 while (l) {
    251                                         m = l->data;
    252                                         l = l->next;
    253                                         if (strcmp(m->who, sb->who) == 0) {
    254                                                 sb->msgq = g_slist_append(sb->msgq, m);
    255                                                 md->msgq = g_slist_remove(md->msgq, m);
    256                                         }
    257                                 }
    258                         }
     202                        return msn_ns_connect(ic, server, port);
    259203                } else {
    260204                        imcb_error(ic, "Syntax error");
     
    361305                                  st->name, NULL);
    362306
    363                 msn_sb_stop_keepalives(msn_sb_by_handle(ic, handle));
    364307        } else if (strcmp(cmd[0], "FLN") == 0) {
    365308                const char *handle;
     
    371314                handle = msn_normalize_handle(cmd[1]);
    372315                imcb_buddy_status(ic, handle, 0, NULL, NULL);
    373                 msn_sb_start_keepalives(msn_sb_by_handle(ic, handle), TRUE);
    374         } else if (strcmp(cmd[0], "RNG") == 0) {
    375                 struct msn_switchboard *sb;
    376                 char *server;
    377                 int session, port;
    378 
    379                 if (num_parts < 7) {
    380                         imcb_error(ic, "Syntax error");
    381                         imc_logout(ic, TRUE);
    382                         return(0);
    383                 }
    384 
    385                 session = atoi(cmd[1]);
    386 
    387                 server = strchr(cmd[2], ':');
    388                 if (!server) {
    389                         imcb_error(ic, "Syntax error");
    390                         imc_logout(ic, TRUE);
    391                         return(0);
    392                 }
    393                 *server = 0;
    394                 port = atoi(server + 1);
    395                 server = cmd[2];
    396 
    397                 if (strcmp(cmd[3], "CKI") != 0) {
    398                         imcb_error(ic, "Unknown authentication method for switchboard");
    399                         imc_logout(ic, TRUE);
    400                         return(0);
    401                 }
    402 
    403                 debug("Got a call from %s (session %d). Key = %s", cmd[5], session, cmd[4]);
    404 
    405                 if ((sb = msn_sb_create(ic, server, port, cmd[4], session)) == NULL) {
    406                         /* Although this isn't strictly fatal for the NS connection, it's
    407                            definitely something serious (we ran out of file descriptors?). */
    408                         imcb_error(ic, "Could not create new switchboard");
    409                         imc_logout(ic, TRUE);
    410                         return(0);
    411                 } else {
    412                         sb->who = g_strdup(msn_normalize_handle(cmd[5]));
    413                 }
    414316        } else if (strcmp(cmd[0], "OUT") == 0) {
    415317                int allow_reconnect = TRUE;
     
    494396                        handler->msglen = atoi(cmd[1]);
    495397                }
    496         } else if (strcmp(cmd[0], "NFY") == 0) {
     398        } else if ((strcmp(cmd[0], "NFY") == 0) || (strcmp(cmd[0], "SDG") == 0)) {
    497399                if (num_parts >= 3) {
    498400                        handler->msglen = atoi(cmd[2]);
     
    526428}
    527429
    528 static int msn_ns_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts)
    529 {
    530         struct im_connection *ic = handler->data;
     430int msn_ns_message(struct msn_data *handler, char *msg, int msglen, char **cmd, int num_parts)
     431{
     432        struct im_connection *ic = handler->ic;
    531433        char *body;
    532434        int blen = 0;
     
    717619                        }
    718620                }
    719         } else if (strcmp(cmd[0], "UBM") == 0) {
    720                 /* This one will give us msgs from federated networks. Technically
    721                    it should also get us offline messages, but I don't know how
    722                    I can signal MSN servers to use it. */
    723                 char *ct, *handle;
    724 
    725                 if (strcmp(cmd[1], ic->acc->user) == 0) {
    726                         /* With MPOP, you'll get copies of your own msgs from other
    727                            sessions. Discard those at least for now. */
    728                         return 1;
    729                 }
    730 
    731                 ct = get_rfc822_header(msg, "Content-Type", msglen);
    732                 if (strncmp(ct, "text/plain", 10) != 0) {
    733                         /* Typing notification or something? */
    734                         g_free(ct);
    735                         return 1;
    736                 }
    737                 if (strcmp(cmd[2], "1") != 0) {
    738                         handle = g_strdup_printf("%s:%s", cmd[2], cmd[1]);
    739                 } else {
    740                         handle = g_strdup(cmd[1]);
    741                 }
    742 
    743                 imcb_buddy_msg(ic, handle, body, 0, 0);
    744                 g_free(handle);
     621        } else if (strcmp(cmd[0], "SDG") == 0) {
     622                char **parts = g_strsplit(msg, "\r\n\r\n", 4);
     623                char *from = NULL;
     624                char *mt = NULL;
     625                char *who = NULL;
     626                char *s = NULL;
     627
     628                if ((from = get_rfc822_header(parts[0], "From", 0)) &&
     629                    (mt = get_rfc822_header(parts[2], "Message-Type", 0)) &&
     630                    (s = strchr(from, ';'))) {
     631
     632                        who = g_strndup(from + 2, s - from - 2);
     633
     634                        if (strcmp(mt, "Control/Typing") == 0) {
     635                                imcb_buddy_typing(ic, who, OPT_TYPING);
     636                        } else if (strcmp(mt, "Text") == 0) {
     637                                imcb_buddy_msg(ic, who, parts[3], 0, 0);
     638                        }
     639                }
     640                g_free(from);
     641                g_free(mt);
     642                g_free(who);
     643                return 1;
    745644        }
    746645
     
    893792}
    894793
     794// TODO: typing notifications, nudges lol, etc
    895795int msn_ns_sendmessage(struct im_connection *ic, bee_user_t *bu, const char *text)
    896796{
    897797        struct msn_data *md = ic->proto_data;
    898         int type = 0;
    899         char *buf, *handle;
     798        int retval = 0;
     799        char *buf;
    900800
    901801        if (strncmp(text, "\r\r\r", 3) == 0) {
     
    905805        }
    906806
    907         /* This might be a federated contact. Get its network number,
    908            prefixed to bu->handle with a colon. Default is 1. */
    909         for (handle = bu->handle; g_ascii_isdigit(*handle); handle++) {
    910                 type = type * 10 + *handle - '0';
    911         }
    912         if (*handle == ':') {
    913                 handle++;
    914         } else {
    915                 type = 1;
    916         }
    917 
    918         buf = g_strdup_printf("%s%s", MSN_MESSAGE_HEADERS, text);
    919 
    920         if (msn_ns_write(ic, -1, "UUM %d %s %d %d %zd\r\n%s",
    921                          ++md->trId, handle, type,
    922                          1,          /* type == IM (not nudge/typing) */
    923                          strlen(buf), buf)) {
    924                 return 1;
    925         } else {
    926                 return 0;
    927         }
     807        buf = g_strdup_printf(MSN_MESSAGE_HEADERS, bu->handle, ic->acc->user, md->uuid, strlen(text), text);
     808        retval = msn_ns_write(ic, -1, "SDG %d %zd\r\n%s", ++md->trId, strlen(buf), buf);
     809        g_free(buf);
     810        return retval;
    928811}
    929812
Note: See TracChangeset for help on using the changeset viewer.