Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/yahoo/libyahoo2.c

    r9034ba0 r9fca0657  
    33 *
    44 * Some code copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
    5  * YMSG16 code copyright (C) 2009,
    6  *              Siddhesh Poyarekar <siddhesh dot poyarekar at gmail dot com>
    75 *
    86 * Yahoo Search copyright (C) 2003, Konstantin Klyagin <konst AT konst.org.ua>
     
    2927 *     <hiro-y@kcn.ne.jp>
    3028 *
    31  * YMSG16 authentication code based mostly on write-up at:
    32  *      http://www.carbonize.co.uk/ymsg16.html
    3329 *
    3430 * This program is free software; you can redistribute it and/or modify
     
    9692
    9793#ifdef USE_STRUCT_CALLBACKS
    98 struct yahoo_callbacks *yc = NULL;
    99 
    100 void yahoo_register_callbacks(struct yahoo_callbacks *tyc)
     94struct yahoo_callbacks *yc=NULL;
     95
     96void yahoo_register_callbacks(struct yahoo_callbacks * tyc)
    10197{
    10298        yc = tyc;
     
    108104#endif
    109105
    110 static int yahoo_send_data(void *fd, void *data, int len);
    111 static void _yahoo_http_connected(int id, void *fd, int error, void *data);
    112 static void yahoo_connected(void *fd, int error, void *data);
    113 
    114 int yahoo_log_message(char *fmt, ...)
     106static int yahoo_send_data(int fd, void *data, int len);
     107
     108int yahoo_log_message(char * fmt, ...)
    115109{
    116110        char out[1024];
     
    119113        vsnprintf(out, sizeof(out), fmt, ap);
    120114        va_end(ap);
    121         return YAHOO_CALLBACK(ext_yahoo_log) ("%s", out);
    122 }
    123 
    124 int yahoo_connect(char *host, int port)
    125 {
    126         return YAHOO_CALLBACK(ext_yahoo_connect) (host, port);
     115        return YAHOO_CALLBACK(ext_yahoo_log)("%s", out);
     116}
     117
     118int yahoo_connect(char * host, int port)
     119{
     120        return YAHOO_CALLBACK(ext_yahoo_connect)(host, port);
    127121}
    128122
     
    142136
    143137/* default values for servers */
    144 static char *default_pager_hosts[] = {  "scs.msg.yahoo.com",
    145                                         "scsa.msg.yahoo.com",
    146                                         "scsb.msg.yahoo.com",
    147                                         "scsc.msg.yahoo.com",
    148                                         NULL};
    149 
     138static char pager_host[] = "scs.msg.yahoo.com";
    150139static int pager_port = 5050;
    151 static int fallback_ports[] = { 23, 25, 80, 20, 119, 8001, 8002, 5050, 0 };
    152 
    153 static char filetransfer_host[] = "filetransfer.msg.yahoo.com";
    154 static int filetransfer_port = 80;
    155 static char webcam_host[] = "webcam.yahoo.com";
    156 static int webcam_port = 5100;
    157 static char webcam_description[] = "";
    158 static char local_host[] = "";
    159 static int conn_type = Y_WCM_DSL;
     140static int fallback_ports[]={23, 25, 80, 20, 119, 8001, 8002, 5050, 0};
     141static char filetransfer_host[]="filetransfer.msg.yahoo.com";
     142static int filetransfer_port=80;
     143static char webcam_host[]="webcam.yahoo.com";
     144static int webcam_port=5100;
     145static char webcam_description[]="";
     146static char local_host[]="";
     147static int conn_type=Y_WCM_DSL;
    160148
    161149static char profile_url[] = "http://profiles.yahoo.com/";
    162150
    163 struct connect_callback_data {
    164         struct yahoo_data *yd;
    165         int tag;
    166         int i;
    167         int server_i;
     151enum yahoo_service { /* these are easier to see in hex */
     152        YAHOO_SERVICE_LOGON = 1,
     153        YAHOO_SERVICE_LOGOFF,
     154        YAHOO_SERVICE_ISAWAY,
     155        YAHOO_SERVICE_ISBACK,
     156        YAHOO_SERVICE_IDLE, /* 5 (placemarker) */
     157        YAHOO_SERVICE_MESSAGE,
     158        YAHOO_SERVICE_IDACT,
     159        YAHOO_SERVICE_IDDEACT,
     160        YAHOO_SERVICE_MAILSTAT,
     161        YAHOO_SERVICE_USERSTAT, /* 0xa */
     162        YAHOO_SERVICE_NEWMAIL,
     163        YAHOO_SERVICE_CHATINVITE,
     164        YAHOO_SERVICE_CALENDAR,
     165        YAHOO_SERVICE_NEWPERSONALMAIL,
     166        YAHOO_SERVICE_NEWCONTACT,
     167        YAHOO_SERVICE_ADDIDENT, /* 0x10 */
     168        YAHOO_SERVICE_ADDIGNORE,
     169        YAHOO_SERVICE_PING,
     170        YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */
     171        YAHOO_SERVICE_SYSMESSAGE = 0x14,
     172        YAHOO_SERVICE_SKINNAME = 0x15,
     173        YAHOO_SERVICE_PASSTHROUGH2 = 0x16,
     174        YAHOO_SERVICE_CONFINVITE = 0x18,
     175        YAHOO_SERVICE_CONFLOGON,
     176        YAHOO_SERVICE_CONFDECLINE,
     177        YAHOO_SERVICE_CONFLOGOFF,
     178        YAHOO_SERVICE_CONFADDINVITE,
     179        YAHOO_SERVICE_CONFMSG,
     180        YAHOO_SERVICE_CHATLOGON,
     181        YAHOO_SERVICE_CHATLOGOFF,
     182        YAHOO_SERVICE_CHATMSG = 0x20,
     183        YAHOO_SERVICE_GAMELOGON = 0x28,
     184        YAHOO_SERVICE_GAMELOGOFF,
     185        YAHOO_SERVICE_GAMEMSG = 0x2a,
     186        YAHOO_SERVICE_FILETRANSFER = 0x46,
     187        YAHOO_SERVICE_VOICECHAT = 0x4A,
     188        YAHOO_SERVICE_NOTIFY,
     189        YAHOO_SERVICE_VERIFY,
     190        YAHOO_SERVICE_P2PFILEXFER,
     191        YAHOO_SERVICE_PEERTOPEER = 0x4F,        /* Checks if P2P possible */
     192        YAHOO_SERVICE_WEBCAM,
     193        YAHOO_SERVICE_AUTHRESP = 0x54,
     194        YAHOO_SERVICE_LIST,
     195        YAHOO_SERVICE_AUTH = 0x57,
     196        YAHOO_SERVICE_AUTHBUDDY = 0x6d,
     197        YAHOO_SERVICE_ADDBUDDY = 0x83,
     198        YAHOO_SERVICE_REMBUDDY,
     199        YAHOO_SERVICE_IGNORECONTACT,    /* > 1, 7, 13 < 1, 66, 13, 0*/
     200        YAHOO_SERVICE_REJECTCONTACT,
     201        YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */
     202        YAHOO_SERVICE_Y7_PING = 0x8A, /* 0 - id and that's it?? */
     203        YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/
     204        YAHOO_SERVICE_CHATGOTO,
     205        YAHOO_SERVICE_CHATJOIN, /* > 1 104-room 129-1600326591 62-2 */
     206        YAHOO_SERVICE_CHATLEAVE,
     207        YAHOO_SERVICE_CHATEXIT = 0x9b,
     208        YAHOO_SERVICE_CHATADDINVITE = 0x9d,
     209        YAHOO_SERVICE_CHATLOGOUT = 0xa0,
     210        YAHOO_SERVICE_CHATPING,
     211        YAHOO_SERVICE_COMMENT = 0xa8,
     212        YAHOO_SERVICE_STEALTH = 0xb9,
     213        YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd,
     214        YAHOO_SERVICE_PICTURE = 0xbe,
     215        YAHOO_SERVICE_PICTURE_UPDATE = 0xc1,
     216        YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2,
     217        YAHOO_SERVICE_Y6_VISIBILITY=0xc5,
     218        YAHOO_SERVICE_Y6_STATUS_UPDATE=0xc6,
     219        YAHOO_PHOTOSHARE_INIT=0xd2,     
     220        YAHOO_SERVICE_CONTACT_YMSG13=0xd6,
     221        YAHOO_PHOTOSHARE_PREV=0xd7,
     222        YAHOO_PHOTOSHARE_KEY=0xd8,
     223        YAHOO_PHOTOSHARE_TRANS=0xda,
     224        YAHOO_FILE_TRANSFER_INIT_YMSG13=0xdc,
     225        YAHOO_FILE_TRANSFER_GET_YMSG13=0xdd,
     226        YAHOO_FILE_TRANSFER_PUT_YMSG13=0xde,
     227        YAHOO_SERVICE_YMSG15_STATUS=0xf0,
     228        YAHOO_SERVICE_YMSG15_BUDDY_LIST=0xf1,
    168229};
    169230
     
    181242
    182243struct yahoo_search_state {
    183         int lsearch_type;
    184         char *lsearch_text;
    185         int lsearch_gender;
    186         int lsearch_agerange;
    187         int lsearch_photo;
    188         int lsearch_yahoo_only;
    189         int lsearch_nstart;
    190         int lsearch_nfound;
    191         int lsearch_ntotal;
     244        int   lsearch_type;
     245        char  *lsearch_text;
     246        int   lsearch_gender;
     247        int   lsearch_agerange;
     248        int   lsearch_photo;
     249        int   lsearch_yahoo_only;
     250        int   lsearch_nstart;
     251        int   lsearch_nfound;
     252        int   lsearch_ntotal;
    192253};
    193254
     
    203264        struct yahoo_search_state *ys;
    204265
    205         void *fd;
     266        int   fd;
    206267        enum yahoo_connection_type type;
    207 
    208         unsigned char *rxqueue;
    209         int rxlen;
    210         int read_tag;
     268       
     269        unsigned char   *rxqueue;
     270        int   rxlen;
     271        int   read_tag;
    211272
    212273        YList *txqueues;
    213         int write_tag;
     274        int   write_tag;
    214275};
    215276
    216277struct yahoo_server_settings {
    217278        char *pager_host;
    218         int pager_port;
     279        int   pager_port;
    219280        char *filetransfer_host;
    220         int filetransfer_port;
     281        int   filetransfer_port;
    221282        char *webcam_host;
    222         int webcam_port;
     283        int   webcam_port;
    223284        char *webcam_description;
    224285        char *local_host;
    225         int conn_type;
    226         char **pager_host_list;
     286        int   conn_type;
    227287};
    228288
    229 static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over);
    230 
    231 static void yahoo_process_filetransfer(struct yahoo_input_data *yid,
    232         struct yahoo_packet *pkt);
    233 static void yahoo_process_filetransferinfo(struct yahoo_input_data *yid,
    234         struct yahoo_packet *pkt);
    235 static void yahoo_process_filetransferaccept(struct yahoo_input_data *yid,
    236         struct yahoo_packet *pkt);
    237 
    238 static void yahoo_https_auth(struct yahoo_input_data *yid, const char *seed, const char *sn);
    239 
    240 static void *_yahoo_default_server_settings()
    241 {
    242         struct yahoo_server_settings *yss =
    243                 y_new0(struct yahoo_server_settings, 1);
    244 
    245         /* Give preference to the default host list
    246          * Make sure that only one of the two is set at any time
    247          */
    248         yss->pager_host = NULL;
    249         yss->pager_host_list = default_pager_hosts;
    250 
     289static void * _yahoo_default_server_settings()
     290{
     291        struct yahoo_server_settings *yss = y_new0(struct yahoo_server_settings, 1);
     292
     293        yss->pager_host = strdup(pager_host);
    251294        yss->pager_port = pager_port;
    252295        yss->filetransfer_host = strdup(filetransfer_host);
     
    261304}
    262305
    263 static void *_yahoo_assign_server_settings(va_list ap)
     306static void * _yahoo_assign_server_settings(va_list ap)
    264307{
    265308        struct yahoo_server_settings *yss = _yahoo_default_server_settings();
    266309        char *key;
    267310        char *svalue;
    268         int nvalue;
    269         char **pvalue;
    270 
    271         while (1) {
     311        int   nvalue;
     312
     313        while(1) {
    272314                key = va_arg(ap, char *);
    273                 if (key == NULL)
    274                         break;
    275 
    276                 if (!strcmp(key, "pager_host")) {
     315                if(key == NULL)
     316                        break;
     317
     318                if(!strcmp(key, "pager_host")) {
    277319                        svalue = va_arg(ap, char *);
    278320                        free(yss->pager_host);
    279321                        yss->pager_host = strdup(svalue);
    280                         yss->pager_host_list = NULL;
    281                 } else if (!strcmp(key, "pager_host_list")) {
    282                         pvalue = va_arg(ap, char **);
    283                         yss->pager_host_list = pvalue;
    284                         free(yss->pager_host);
    285                         yss->pager_host = NULL;
    286                 } else if (!strcmp(key, "pager_port")) {
     322                } else if(!strcmp(key, "pager_port")) {
    287323                        nvalue = va_arg(ap, int);
    288324                        yss->pager_port = nvalue;
    289                 } else if (!strcmp(key, "filetransfer_host")) {
     325                } else if(!strcmp(key, "filetransfer_host")) {
    290326                        svalue = va_arg(ap, char *);
    291327                        free(yss->filetransfer_host);
    292328                        yss->filetransfer_host = strdup(svalue);
    293                 } else if (!strcmp(key, "filetransfer_port")) {
     329                } else if(!strcmp(key, "filetransfer_port")) {
    294330                        nvalue = va_arg(ap, int);
    295331                        yss->filetransfer_port = nvalue;
    296                 } else if (!strcmp(key, "webcam_host")) {
     332                } else if(!strcmp(key, "webcam_host")) {
    297333                        svalue = va_arg(ap, char *);
    298334                        free(yss->webcam_host);
    299335                        yss->webcam_host = strdup(svalue);
    300                 } else if (!strcmp(key, "webcam_port")) {
     336                } else if(!strcmp(key, "webcam_port")) {
    301337                        nvalue = va_arg(ap, int);
    302338                        yss->webcam_port = nvalue;
    303                 } else if (!strcmp(key, "webcam_description")) {
     339                } else if(!strcmp(key, "webcam_description")) {
    304340                        svalue = va_arg(ap, char *);
    305341                        free(yss->webcam_description);
    306342                        yss->webcam_description = strdup(svalue);
    307                 } else if (!strcmp(key, "local_host")) {
     343                } else if(!strcmp(key, "local_host")) {
    308344                        svalue = va_arg(ap, char *);
    309345                        free(yss->local_host);
    310346                        yss->local_host = strdup(svalue);
    311                 } else if (!strcmp(key, "conn_type")) {
     347                } else if(!strcmp(key, "conn_type")) {
    312348                        nvalue = va_arg(ap, int);
    313349                        yss->conn_type = nvalue;
    314350                } else {
    315351                        WARNING(("Unknown key passed to yahoo_init, "
    316                                         "perhaps you didn't terminate the list "
    317                                         "with NULL"));
     352                                "perhaps you didn't terminate the list "
     353                                "with NULL"));
    318354                }
    319355        }
     
    324360static void yahoo_free_server_settings(struct yahoo_server_settings *yss)
    325361{
    326         if (!yss)
     362        if(!yss)
    327363                return;
    328364
     
    336372}
    337373
    338 static YList *conns = NULL;
    339 static YList *inputs = NULL;
    340 static int last_id = 0;
     374static YList *conns=NULL;
     375static YList *inputs=NULL;
     376static int last_id=0;
    341377
    342378static void add_to_list(struct yahoo_data *yd)
     
    344380        conns = y_list_prepend(conns, yd);
    345381}
    346 
    347 static struct yahoo_data *find_conn_by_id(int id)
     382static struct yahoo_data * find_conn_by_id(int id)
    348383{
    349384        YList *l;
    350         for (l = conns; l; l = y_list_next(l)) {
     385        for(l = conns; l; l = y_list_next(l)) {
    351386                struct yahoo_data *yd = l->data;
    352                 if (yd->client_id == id)
     387                if(yd->client_id == id)
    353388                        return yd;
    354389        }
    355390        return NULL;
    356391}
    357 
    358392static void del_from_list(struct yahoo_data *yd)
    359393{
     
    362396
    363397/* call repeatedly to get the next one */
    364 /*
    365398static struct yahoo_input_data * find_input_by_id(int id)
    366399{
     
    373406        return NULL;
    374407}
    375 */
    376 
    377 static struct yahoo_input_data *find_input_by_id_and_webcam_user(int id,
    378         const char *who)
     408
     409static struct yahoo_input_data * find_input_by_id_and_webcam_user(int id, const char * who)
    379410{
    380411        YList *l;
    381412        LOG(("find_input_by_id_and_webcam_user"));
    382         for (l = inputs; l; l = y_list_next(l)) {
     413        for(l = inputs; l; l = y_list_next(l)) {
    383414                struct yahoo_input_data *yid = l->data;
    384                 if (yid->type == YAHOO_CONNECTION_WEBCAM
    385                         && yid->yd->client_id == id && yid->wcm && ((who
    386                                         && yid->wcm->user
    387                                         && !strcmp(who, yid->wcm->user))
    388                                 || !(yid->wcm->user && !who)))
     415                if(yid->type == YAHOO_CONNECTION_WEBCAM && yid->yd->client_id == id
     416                                && yid->wcm &&
     417                                ((who && yid->wcm->user && !strcmp(who, yid->wcm->user)) ||
     418                                 !(yid->wcm->user && !who)))
    389419                        return yid;
    390420        }
     
    392422}
    393423
    394 static struct yahoo_input_data *find_input_by_id_and_type(int id,
    395         enum yahoo_connection_type type)
     424static struct yahoo_input_data * find_input_by_id_and_type(int id, enum yahoo_connection_type type)
    396425{
    397426        YList *l;
    398427        LOG(("find_input_by_id_and_type"));
    399         for (l = inputs; l; l = y_list_next(l)) {
     428        for(l = inputs; l; l = y_list_next(l)) {
    400429                struct yahoo_input_data *yid = l->data;
    401                 if (yid->type == type && yid->yd->client_id == id)
     430                if(yid->type == type && yid->yd->client_id == id)
    402431                        return yid;
    403432        }
     
    405434}
    406435
    407 static struct yahoo_input_data *find_input_by_id_and_fd(int id, void *fd)
     436static struct yahoo_input_data * find_input_by_id_and_fd(int id, int fd)
    408437{
    409438        YList *l;
    410439        LOG(("find_input_by_id_and_fd"));
    411         for (l = inputs; l; l = y_list_next(l)) {
     440        for(l = inputs; l; l = y_list_next(l)) {
    412441                struct yahoo_input_data *yid = l->data;
    413                 if (yid->fd == fd && yid->yd->client_id == id)
     442                if(yid->fd == fd && yid->yd->client_id == id)
    414443                        return yid;
    415444        }
     
    419448static int count_inputs_with_id(int id)
    420449{
    421         int c = 0;
     450        int c=0;
    422451        YList *l;
    423452        LOG(("counting %d", id));
    424         for (l = inputs; l; l = y_list_next(l)) {
     453        for(l = inputs; l; l = y_list_next(l)) {
    425454                struct yahoo_input_data *yid = l->data;
    426                 if (yid->yd->client_id == id)
     455                if(yid->yd->client_id == id)
    427456                        c++;
    428457        }
     
    431460}
    432461
     462
    433463extern char *yahoo_crypt(char *, char *);
    434464
    435465/* Free a buddy list */
    436 static void yahoo_free_buddies(YList *list)
     466static void yahoo_free_buddies(YList * list)
    437467{
    438468        YList *l;
    439469
    440         for (l = list; l; l = l->next) {
     470        for(l = list; l; l = l->next)
     471        {
    441472                struct yahoo_buddy *bud = l->data;
    442                 if (!bud)
     473                if(!bud)
    443474                        continue;
    444475
     
    446477                FREE(bud->id);
    447478                FREE(bud->real_name);
    448                 if (bud->yab_entry) {
     479                if(bud->yab_entry) {
    449480                        FREE(bud->yab_entry->fname);
    450481                        FREE(bud->yab_entry->lname);
     
    465496
    466497/* Free an identities list */
    467 static void yahoo_free_identities(YList *list)
     498static void yahoo_free_identities(YList * list)
    468499{
    469500        while (list) {
     
    494525        FREE(yd->cookie_y);
    495526        FREE(yd->cookie_t);
    496         FREE(yd->cookie_b);
    497527        FREE(yd->cookie_c);
    498528        FREE(yd->login_cookie);
     
    510540#define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4)
    511541
    512 static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service,
    513         enum ypacket_status status, int id)
     542static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, 
     543                enum yahoo_status status, int id)
    514544{
    515545        struct yahoo_packet *pkt = y_new0(struct yahoo_packet, 1);
     
    522552}
    523553
    524 static void yahoo_packet_hash(struct yahoo_packet *pkt, int key,
    525         const char *value)
     554static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value)
    526555{
    527556        struct yahoo_pair *pair = y_new0(struct yahoo_pair, 1);
     
    568597                         (((*((buf)+3))&0xff)))
    569598
    570 static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data,
    571         int len)
     599static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data, int len)
    572600{
    573601        int pos = 0;
     
    622650                        FREE(value);
    623651                        pkt->hash = y_list_append(pkt->hash, pair);
    624                         DEBUG_MSG(("Key: %d  \tValue: %s", pair->key,
    625                                         pair->value));
     652                        DEBUG_MSG(("Key: %d  \tValue: %s", pair->key, pair->value));
    626653                } else {
    627654                        FREE(pair);
     
    663690}
    664691
     692
    665693static void yahoo_packet_dump(unsigned char *data, int len)
    666694{
    667         if (yahoo_get_log_level() >= YAHOO_LOG_DEBUG) {
     695        if(yahoo_get_log_level() >= YAHOO_LOG_DEBUG) {
    668696                int i;
    669697                for (i = 0; i < len; i++) {
    670698                        if ((i % 8 == 0) && i)
    671                                 YAHOO_CALLBACK(ext_yahoo_log) (" ");
     699                                YAHOO_CALLBACK(ext_yahoo_log)(" ");
    672700                        if ((i % 16 == 0) && i)
    673                                 YAHOO_CALLBACK(ext_yahoo_log) ("\n");
    674                         YAHOO_CALLBACK(ext_yahoo_log) ("%02x ", data[i]);
    675                 }
    676                 YAHOO_CALLBACK(ext_yahoo_log) ("\n");
     701                                YAHOO_CALLBACK(ext_yahoo_log)("\n");
     702                        YAHOO_CALLBACK(ext_yahoo_log)("%02x ", data[i]);
     703                }
     704                YAHOO_CALLBACK(ext_yahoo_log)("\n");
    677705                for (i = 0; i < len; i++) {
    678706                        if ((i % 8 == 0) && i)
    679                                 YAHOO_CALLBACK(ext_yahoo_log) (" ");
     707                                YAHOO_CALLBACK(ext_yahoo_log)(" ");
    680708                        if ((i % 16 == 0) && i)
    681                                 YAHOO_CALLBACK(ext_yahoo_log) ("\n");
     709                                YAHOO_CALLBACK(ext_yahoo_log)("\n");
    682710                        if (isprint(data[i]))
    683                                 YAHOO_CALLBACK(ext_yahoo_log) (" %c ", data[i]);
     711                                YAHOO_CALLBACK(ext_yahoo_log)(" %c ", data[i]);
    684712                        else
    685                                 YAHOO_CALLBACK(ext_yahoo_log) (" . ");
    686                 }
    687                 YAHOO_CALLBACK(ext_yahoo_log) ("\n");
     713                                YAHOO_CALLBACK(ext_yahoo_log)(" . ");
     714                }
     715                YAHOO_CALLBACK(ext_yahoo_log)("\n");
    688716        }
    689717}
     
    695723}
    696724
    697 static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data,
    698         int length)
     725static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data, int length)
    699726{
    700727        struct data_queue *tx = y_new0(struct data_queue, 1);
     
    705732        yid->txqueues = y_list_append(yid->txqueues, tx);
    706733
    707         if (!yid->write_tag)
    708                 yid->write_tag =
    709                         YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->
    710                         client_id, yid->fd, YAHOO_INPUT_WRITE, yid);
    711 }
    712 
    713 static void yahoo_send_packet(struct yahoo_input_data *yid,
    714         struct yahoo_packet *pkt, int extra_pad)
     734        if(!yid->write_tag)
     735                yid->write_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_WRITE, yid);
     736}
     737
     738static void yahoo_send_packet(struct yahoo_input_data *yid, struct yahoo_packet *pkt, int extra_pad)
    715739{
    716740        int pktlen = yahoo_packet_length(pkt);
    717741        int len = YAHOO_PACKET_HDRLEN + pktlen;
     742
    718743        unsigned char *data;
    719744        int pos = 0;
     
    724749        data = y_new0(unsigned char, len + 1);
    725750
    726         memcpy(data + pos, "YMSG", 4);
    727         pos += 4;
    728         pos += yahoo_put16(data + pos, YAHOO_PROTO_VER);        /* version [latest 12 0x000c] */
    729         pos += yahoo_put16(data + pos, 0x0000); /* HIWORD pkt length??? */
    730         pos += yahoo_put16(data + pos, pktlen + extra_pad);     /* LOWORD pkt length? */
    731         pos += yahoo_put16(data + pos, pkt->service);   /* service */
    732         pos += yahoo_put32(data + pos, pkt->status);    /* status [4bytes] */
    733         pos += yahoo_put32(data + pos, pkt->id);        /* session [4bytes] */
     751        memcpy(data + pos, "YMSG", 4); pos += 4;
     752        pos += yahoo_put16(data + pos, YAHOO_PROTO_VER);
     753        pos += yahoo_put16(data + pos, 0x0000);
     754        pos += yahoo_put16(data + pos, pktlen + extra_pad);
     755        pos += yahoo_put16(data + pos, pkt->service);
     756        pos += yahoo_put32(data + pos, pkt->status);
     757        pos += yahoo_put32(data + pos, pkt->id);
    734758
    735759        yahoo_packet_write(pkt, data + pos);
    736760
    737761        yahoo_packet_dump(data, len);
    738 
    739         if (yid->type == YAHOO_CONNECTION_FT)
     762       
     763        if( yid->type == YAHOO_CONNECTION_FT )
    740764                yahoo_send_data(yid->fd, data, len);
    741765        else
     
    758782}
    759783
    760 static int yahoo_send_data(void *fd, void *data, int len)
     784static int yahoo_send_data(int fd, void *data, int len)
    761785{
    762786        int ret;
    763787        int e;
    764788
    765         if (fd == NULL)
     789        if (fd < 0)
    766790                return -1;
    767791
     
    769793
    770794        do {
    771                 ret = YAHOO_CALLBACK(ext_yahoo_write) (fd, data, len);
    772         } while (ret == -1 && errno == EINTR);
    773         e = errno;
    774 
    775         if (ret == -1) {
     795                ret = write(fd, data, len);
     796        } while(ret == -1 && errno==EINTR);
     797        e=errno;
     798
     799        if (ret == -1)  {
    776800                LOG(("wrote data: ERR %s", strerror(errno)));
    777801        } else {
     
    779803        }
    780804
    781         errno = e;
     805        errno=e;
    782806        return ret;
    783807}
    784808
    785 void yahoo_close(int id)
     809void yahoo_close(int id) 
    786810{
    787811        struct yahoo_data *yd = find_conn_by_id(id);
    788         if (!yd)
     812       
     813        if(!yd)
    789814                return;
    790815
     
    792817
    793818        yahoo_free_data(yd);
    794         if (id == last_id)
     819        if(id == last_id)
    795820                last_id--;
    796821}
    797822
    798 static void yahoo_input_close(struct yahoo_input_data *yid)
     823static void yahoo_input_close(struct yahoo_input_data *yid) 
    799824{
    800825        inputs = y_list_remove(inputs, yid);
    801826
    802         LOG(("yahoo_input_close(read)"));
    803         YAHOO_CALLBACK(ext_yahoo_remove_handler) (yid->yd->client_id,
    804                 yid->read_tag);
    805         LOG(("yahoo_input_close(write)"));
    806         YAHOO_CALLBACK(ext_yahoo_remove_handler) (yid->yd->client_id,
    807                 yid->write_tag);
     827        LOG(("yahoo_input_close(read)"));
     828        YAHOO_CALLBACK(ext_yahoo_remove_handler)(yid->yd->client_id, yid->read_tag);
     829        LOG(("yahoo_input_close(write)"));
     830        YAHOO_CALLBACK(ext_yahoo_remove_handler)(yid->yd->client_id, yid->write_tag);
    808831        yid->read_tag = yid->write_tag = 0;
    809         if (yid->fd)
    810                 YAHOO_CALLBACK(ext_yahoo_close) (yid->fd);
     832        if(yid->fd)
     833                close(yid->fd);
    811834        yid->fd = 0;
    812835        FREE(yid->rxqueue);
    813         if (count_inputs_with_id(yid->yd->client_id) == 0) {
     836        if(count_inputs_with_id(yid->yd->client_id) == 0) {
    814837                LOG(("closing %d", yid->yd->client_id));
    815838                yahoo_close(yid->yd->client_id);
    816839        }
    817840        yahoo_free_webcam(yid->wcm);
    818         if (yid->wcd)
     841        if(yid->wcd)
    819842                FREE(yid->wcd);
    820         if (yid->ys) {
     843        if(yid->ys) {
    821844                FREE(yid->ys->lsearch_text);
    822845                FREE(yid->ys);
     
    825848}
    826849
    827 static int is_same_bud(const void *a, const void *b)
    828 {
     850static int is_same_bud(const void * a, const void * b) {
    829851        const struct yahoo_buddy *subject = a;
    830852        const struct yahoo_buddy *object = b;
     
    833855}
    834856
    835 static char *getcookie(char *rawcookie)
    836 {
    837         char *cookie = NULL;
    838         char *tmpcookie;
    839         char *cookieend;
    840 
    841         if (strlen(rawcookie) < 2)
     857static char * getcookie(char *rawcookie)
     858{
     859        char * cookie=NULL;
     860        char * tmpcookie;
     861        char * cookieend;
     862
     863        if (strlen(rawcookie) < 2) 
    842864                return NULL;
    843865
    844         tmpcookie = strdup(rawcookie + 2);
     866        tmpcookie = strdup(rawcookie+2);
    845867        cookieend = strchr(tmpcookie, ';');
    846868
    847         if (cookieend)
     869        if(cookieend)
    848870                *cookieend = '\0';
    849871
     
    855877}
    856878
    857 static char *getlcookie(char *cookie)
     879static char * getlcookie(char *cookie)
    858880{
    859881        char *tmp;
     
    862884
    863885        tmpend = strstr(cookie, "n=");
    864         if (tmpend) {
    865                 tmp = strdup(tmpend + 2);
     886        if(tmpend) {
     887                tmp = strdup(tmpend+2);
    866888                tmpend = strchr(tmp, '&');
    867                 if (tmpend)
    868                         *tmpend = '\0';
     889                if(tmpend)
     890                        *tmpend='\0';
    869891                login_cookie = strdup(tmp);
    870892                FREE(tmp);
     
    874896}
    875897
    876 static void yahoo_process_notify(struct yahoo_input_data *yid,
    877         struct yahoo_packet *pkt)
     898static void yahoo_process_notify(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    878899{
    879900        struct yahoo_data *yd = yid->yd;
     
    906927        if (!msg)
    907928                return;
    908 
    909         if (!strncasecmp(msg, "TYPING", strlen("TYPING")))
    910                 YAHOO_CALLBACK(ext_yahoo_typing_notify) (yd->client_id, to,
    911                         from, stat);
    912         else if (!strncasecmp(msg, "GAME", strlen("GAME")))
    913                 YAHOO_CALLBACK(ext_yahoo_game_notify) (yd->client_id, to, from,
    914                         stat, ind);
    915         else if (!strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE"))) {
     929       
     930        if (!strncasecmp(msg, "TYPING", strlen("TYPING")))
     931                YAHOO_CALLBACK(ext_yahoo_typing_notify)(yd->client_id, to, from, stat);
     932        else if (!strncasecmp(msg, "GAME", strlen("GAME")))
     933                YAHOO_CALLBACK(ext_yahoo_game_notify)(yd->client_id, to, from, stat);
     934        else if (!strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE")))
     935        {
    916936                if (!strcmp(ind, " ")) {
    917                         YAHOO_CALLBACK(ext_yahoo_webcam_invite) (yd->client_id,
    918                                 to, from);
     937                        YAHOO_CALLBACK(ext_yahoo_webcam_invite)(yd->client_id, to, from);
    919938                } else {
    920939                        accept = atoi(ind);
     
    922941                        if (accept < 0)
    923942                                accept = 0;
    924                         YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply) (yd->
    925                                 client_id, to, from, accept);
    926                 }
    927         } else
     943                        YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply)(yd->client_id, to, from, accept);
     944                }
     945        }
     946        else
    928947                LOG(("Got unknown notification: %s", msg));
    929948}
    930949
    931 static void yahoo_process_conference(struct yahoo_input_data *yid,
    932         struct yahoo_packet *pkt)
     950static void yahoo_process_filetransfer(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     951{
     952        struct yahoo_data *yd = yid->yd;
     953        char *from=NULL;
     954        char *to=NULL;
     955        char *msg=NULL;
     956        char *url=NULL;
     957        long expires=0;
     958
     959        char *service=NULL;
     960
     961        char *filename=NULL;
     962        unsigned long filesize=0L;
     963
     964        YList *l;
     965        for (l = pkt->hash; l; l = l->next) {
     966                struct yahoo_pair *pair = l->data;
     967                if (pair->key == 4)
     968                        from = pair->value;
     969                if (pair->key == 5)
     970                        to = pair->value;
     971                if (pair->key == 14)
     972                        msg = pair->value;
     973                if (pair->key == 20)
     974                        url = pair->value;
     975                if (pair->key == 38)
     976                        expires = atol(pair->value);
     977
     978                if (pair->key == 27)
     979                        filename = pair->value;
     980                if (pair->key == 28)
     981                        filesize = atol(pair->value);
     982
     983                if (pair->key == 49)
     984                        service = pair->value;
     985        }
     986
     987        if(pkt->service == YAHOO_SERVICE_P2PFILEXFER) {
     988                if(strcmp("FILEXFER", service) != 0) {
     989                        WARNING(("unhandled service 0x%02x", pkt->service));
     990                        yahoo_dump_unhandled(pkt);
     991                        return;
     992                }
     993        }
     994
     995        if(msg) {
     996                char *tmp;
     997                tmp = strchr(msg, '\006');
     998                if(tmp)
     999                        *tmp = '\0';
     1000        }
     1001        if(url && from)
     1002                YAHOO_CALLBACK(ext_yahoo_got_file)(yd->client_id, to, from, url, expires, msg, filename, filesize);
     1003
     1004}
     1005
     1006static void yahoo_process_conference(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    9331007{
    9341008        struct yahoo_data *yd = yid->yd;
     
    9381012        char *room = NULL;
    9391013        char *id = NULL;
    940         int utf8 = 0;
     1014        int  utf8 = 0;
    9411015        YList *members = NULL;
    9421016        YList *l;
    943 
     1017       
    9441018        for (l = pkt->hash; l; l = l->next) {
    9451019                struct yahoo_pair *pair = l->data;
    9461020                if (pair->key == 50)
    9471021                        host = pair->value;
    948 
    949                 if (pair->key == 52) {  /* invite */
     1022               
     1023                if (pair->key == 52) {          /* invite */
    9501024                        members = y_list_append(members, strdup(pair->value));
    9511025                }
    952                 if (pair->key == 53)    /* logon */
     1026                if (pair->key == 53)            /* logon */
    9531027                        who = pair->value;
    954                 if (pair->key == 54)    /* decline */
     1028                if (pair->key == 54)            /* decline */
    9551029                        who = pair->value;
    956                 if (pair->key == 55)    /* unavailable (status == 2) */
     1030                if (pair->key == 55)            /* unavailable (status == 2) */
    9571031                        who = pair->value;
    958                 if (pair->key == 56)    /* logoff */
     1032                if (pair->key == 56)            /* logoff */
    9591033                        who = pair->value;
    9601034
     
    9621036                        room = pair->value;
    9631037
    964                 if (pair->key == 58)    /* join message */
     1038                if (pair->key == 58)            /* join message */
    9651039                        msg = pair->value;
    966                 if (pair->key == 14)    /* decline/conf message */
     1040                if (pair->key == 14)            /* decline/conf message */
    9671041                        msg = pair->value;
    9681042
    969                 if (pair->key == 13) ;
    970                 if (pair->key == 16)    /* error */
     1043                if (pair->key == 13)
     1044                        ;
     1045                if (pair->key == 16)            /* error */
    9711046                        msg = pair->value;
    9721047
    973                 if (pair->key == 1)     /* my id */
     1048                if (pair->key == 1)             /* my id */
    9741049                        id = pair->value;
    975                 if (pair->key == 3)     /* message sender */
     1050                if (pair->key == 3)             /* message sender */
    9761051                        who = pair->value;
    9771052
     
    9801055        }
    9811056
    982         if (!room)
    983                 return;
    984 
    985         if (host) {
    986                 for (l = members; l; l = l->next) {
    987                         char *w = l->data;
    988                         if (!strcmp(w, host))
     1057        if(!room)
     1058                return;
     1059
     1060        if(host) {
     1061                for(l = members; l; l = l->next) {
     1062                        char * w = l->data;
     1063                        if(!strcmp(w, host))
    9891064                                break;
    9901065                }
    991                 if (!l)
     1066                if(!l)
    9921067                        members = y_list_append(members, strdup(host));
    9931068        }
    9941069        /* invite, decline, join, left, message -> status == 1 */
    9951070
    996         switch (pkt->service) {
     1071        switch(pkt->service) {
    9971072        case YAHOO_SERVICE_CONFINVITE:
    998                 if (pkt->status == 2) ;
    999                 else if (members)
    1000                         YAHOO_CALLBACK(ext_yahoo_got_conf_invite) (yd->
    1001                                 client_id, id, host, room, msg, members);
    1002                 else if (msg)
    1003                         YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id, msg, 0,
    1004                                 E_CONFNOTAVAIL);
     1073                if(pkt->status == 2)
     1074                        ;
     1075                else if(members)
     1076                        YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members);
     1077                else if(msg)
     1078                        YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, msg, 0, E_CONFNOTAVAIL);
    10051079                break;
    10061080        case YAHOO_SERVICE_CONFADDINVITE:
    1007                 if (pkt->status == 1)
    1008                         YAHOO_CALLBACK(ext_yahoo_got_conf_invite) (yd->
    1009                                 client_id, id, host, room, msg, members);
     1081                if(pkt->status == 2)
     1082                        ;
     1083                else
     1084                        YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members);
    10101085                break;
    10111086        case YAHOO_SERVICE_CONFDECLINE:
    1012                 if (who)
    1013                         YAHOO_CALLBACK(ext_yahoo_conf_userdecline) (yd->
    1014                                 client_id, id, who, room, msg);
     1087                if(who)
     1088                        YAHOO_CALLBACK(ext_yahoo_conf_userdecline)(yd->client_id, id, who, room, msg);
    10151089                break;
    10161090        case YAHOO_SERVICE_CONFLOGON:
    1017                 if (who)
    1018                         YAHOO_CALLBACK(ext_yahoo_conf_userjoin) (yd->client_id,
    1019                                 id, who, room);
     1091                if(who)
     1092                        YAHOO_CALLBACK(ext_yahoo_conf_userjoin)(yd->client_id, id, who, room);
    10201093                break;
    10211094        case YAHOO_SERVICE_CONFLOGOFF:
    1022                 if (who)
    1023                         YAHOO_CALLBACK(ext_yahoo_conf_userleave) (yd->client_id,
    1024                                 id, who, room);
     1095                if(who)
     1096                        YAHOO_CALLBACK(ext_yahoo_conf_userleave)(yd->client_id, id, who, room);
    10251097                break;
    10261098        case YAHOO_SERVICE_CONFMSG:
    1027                 if (who)
    1028                         YAHOO_CALLBACK(ext_yahoo_conf_message) (yd->client_id,
    1029                                 id, who, room, msg, utf8);
     1099                if(who)
     1100                        YAHOO_CALLBACK(ext_yahoo_conf_message)(yd->client_id, id, who, room, msg, utf8);
    10301101                break;
    10311102        }
    10321103}
    10331104
    1034 static void yahoo_process_chat(struct yahoo_input_data *yid,
    1035         struct yahoo_packet *pkt)
     1105static void yahoo_process_chat(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    10361106{
    10371107        char *msg = NULL;
     
    10421112        YList *members = NULL;
    10431113        struct yahoo_chat_member *currentmember = NULL;
    1044         int msgtype = 1;
    1045         int utf8 = 0;
    1046         int firstjoin = 0;
    1047         int membercount = 0;
    1048         int chaterr = 0;
     1114        int  msgtype = 1;
     1115        int  utf8 = 0;
     1116        int  firstjoin = 0;
     1117        int  membercount = 0;
     1118        int  chaterr=0;
    10491119        YList *l;
    1050 
     1120       
    10511121        yahoo_dump_unhandled(pkt);
    10521122        for (l = pkt->hash; l; l = l->next) {
     
    10781148
    10791149                        if (pkt->service == YAHOO_SERVICE_CHATJOIN) {
    1080                                 currentmember =
    1081                                         y_new0(struct yahoo_chat_member, 1);
     1150                                currentmember = y_new0(struct yahoo_chat_member, 1);
    10821151                                currentmember->id = strdup(pair->value);
    10831152                                members = y_list_append(members, currentmember);
     
    11091178                }
    11101179
     1180
    11111181                if (pair->key == 130) {
    11121182                        /* first join */
     
    11261196                        /* message error not sure what all the pair values mean */
    11271197                        /* but -1 means no session in room */
    1128                         chaterr = atoi(pair->value);
    1129                 }
    1130         }
    1131 
    1132         if (!room) {
    1133                 if (pkt->service == YAHOO_SERVICE_CHATLOGOUT) { /* yahoo originated chat logout */
    1134                         YAHOO_CALLBACK(ext_yahoo_chat_yahoologout) (yid->yd->
    1135                                 client_id, id);
     1198                        chaterr= atoi(pair->value);
     1199                }
     1200        }
     1201
     1202        if(!room) {
     1203                if (pkt->service == YAHOO_SERVICE_CHATLOGOUT) { /* yahoo originated chat logout */
     1204                        YAHOO_CALLBACK(ext_yahoo_chat_yahoologout)(yid->yd->client_id, id);
     1205                        return ;
     1206                }
     1207                if (pkt->service == YAHOO_SERVICE_COMMENT && chaterr)  {
     1208                        YAHOO_CALLBACK(ext_yahoo_chat_yahooerror)(yid->yd->client_id, id);
    11361209                        return;
    11371210                }
    1138                 if (pkt->service == YAHOO_SERVICE_COMMENT && chaterr) {
    1139                         YAHOO_CALLBACK(ext_yahoo_chat_yahooerror) (yid->yd->
    1140                                 client_id, id);
    1141                         return;
    1142                 }
    11431211
    11441212                WARNING(("We didn't get a room name, ignoring packet"));
     
    11461214        }
    11471215
    1148         switch (pkt->service) {
     1216        switch(pkt->service) {
    11491217        case YAHOO_SERVICE_CHATJOIN:
    1150                 if (y_list_length(members) != membercount) {
     1218                if(y_list_length(members) != membercount) {
    11511219                        WARNING(("Count of members doesn't match No. of members we got"));
    11521220                }
    1153                 if (firstjoin && members) {
    1154                         YAHOO_CALLBACK(ext_yahoo_chat_join) (yid->yd->client_id,
    1155                                 id, room, topic, members, yid->fd);
    1156                 } else if (who) {
    1157                         if (y_list_length(members) != 1) {
     1221                if(firstjoin && members) {
     1222                        YAHOO_CALLBACK(ext_yahoo_chat_join)(yid->yd->client_id, id, room, topic, members, yid->fd);
     1223                } else if(who) {
     1224                        if(y_list_length(members) != 1) {
    11581225                                WARNING(("Got more than 1 member on a normal join"));
    11591226                        }
    11601227                        /* this should only ever have one, but just in case */
    1161                         while (members) {
     1228                        while(members) {
    11621229                                YList *n = members->next;
    11631230                                currentmember = members->data;
    1164                                 YAHOO_CALLBACK(ext_yahoo_chat_userjoin) (yid->
    1165                                         yd->client_id, id, room, currentmember);
     1231                                YAHOO_CALLBACK(ext_yahoo_chat_userjoin)(yid->yd->client_id, id, room, currentmember);
    11661232                                y_list_free_1(members);
    1167                                 members = n;
     1233                                members=n;
    11681234                        }
    11691235                }
    11701236                break;
    11711237        case YAHOO_SERVICE_CHATEXIT:
    1172                 if (who) {
    1173                         YAHOO_CALLBACK(ext_yahoo_chat_userleave) (yid->yd->
    1174                                 client_id, id, room, who);
     1238                if(who) {
     1239                        YAHOO_CALLBACK(ext_yahoo_chat_userleave)(yid->yd->client_id, id, room, who);
    11751240                }
    11761241                break;
    11771242        case YAHOO_SERVICE_COMMENT:
    1178                 if (who) {
    1179                         YAHOO_CALLBACK(ext_yahoo_chat_message) (yid->yd->
    1180                                 client_id, id, who, room, msg, msgtype, utf8);
     1243                if(who) {
     1244                        YAHOO_CALLBACK(ext_yahoo_chat_message)(yid->yd->client_id, id, who, room, msg, msgtype, utf8);
    11811245                }
    11821246                break;
     
    11841248}
    11851249
    1186 static void yahoo_process_message(struct yahoo_input_data *yid,
    1187         struct yahoo_packet *pkt)
     1250static void yahoo_process_message(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    11881251{
    11891252        struct yahoo_data *yd = yid->yd;
    11901253        YList *l;
    1191         YList *messages = NULL;
     1254        YList * messages = NULL;
    11921255
    11931256        struct m {
    1194                 int i_31;
    1195                 int i_32;
     1257                int  i_31;
     1258                int  i_32;
    11961259                char *to;
    11971260                char *from;
    11981261                long tm;
    11991262                char *msg;
    1200                 int utf8;
    1201                 char *gunk;
     1263                int  utf8;
    12021264        } *message = y_new0(struct m, 1);
    12031265
    12041266        for (l = pkt->hash; l; l = l->next) {
    12051267                struct yahoo_pair *pair = l->data;
    1206                 if (pair->key == 1 || pair->key == 4) {
    1207                         if (!message->from)
     1268                if (pair->key == 1 || pair->key == 4)
     1269                {
     1270                        if(!message->from)
    12081271                                message->from = pair->value;
    1209                 } else if (pair->key == 5)
     1272                }
     1273                else if (pair->key == 5)
    12101274                        message->to = pair->value;
    12111275                else if (pair->key == 15)
     
    12131277                else if (pair->key == 97)
    12141278                        message->utf8 = atoi(pair->value);
    1215                 /* This comes when the official client sends us a message */
    1216                 else if (pair->key == 429)
    1217                         message->gunk = pair->value;
    1218                 /* user message *//* sys message */
     1279                        /* user message */  /* sys message */
    12191280                else if (pair->key == 14 || pair->key == 16)
    12201281                        message->msg = pair->value;
    12211282                else if (pair->key == 31) {
    1222                         if (message->i_31) {
     1283                        if(message->i_31) {
    12231284                                messages = y_list_append(messages, message);
    12241285                                message = y_new0(struct m, 1);
    12251286                        }
    12261287                        message->i_31 = atoi(pair->value);
    1227                 } else if (pair->key == 32)
     1288                }
     1289                else if (pair->key == 32)
    12281290                        message->i_32 = atoi(pair->value);
    12291291                else
    1230                         LOG(("yahoo_process_message: status: %d, key: %d, value: %s", pkt->status, pair->key, pair->value));
     1292                        LOG(("yahoo_process_message: status: %d, key: %d, value: %s",
     1293                                        pkt->status, pair->key, pair->value));
    12311294        }
    12321295
    12331296        messages = y_list_append(messages, message);
    12341297
    1235         for (l = messages; l; l = l->next) {
     1298        for (l = messages; l; l=l->next) {
    12361299                message = l->data;
    12371300                if (pkt->service == YAHOO_SERVICE_SYSMESSAGE) {
    1238                         YAHOO_CALLBACK(ext_yahoo_system_message) (yd->client_id,
    1239                                 message->to, message->from, message->msg);
     1301                        YAHOO_CALLBACK(ext_yahoo_system_message)(yd->client_id, message->msg);
    12401302                } else if (pkt->status <= 2 || pkt->status == 5) {
    1241                         /* Confirm message receipt if we got the gunk */
    1242                         if(message->gunk) {
    1243                                 struct yahoo_packet *outpkt;
    1244                        
    1245                                 outpkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE_CONFIRM,
    1246                                         YPACKET_STATUS_DEFAULT, 0);
    1247                                 yahoo_packet_hash(outpkt, 1, yd->user);
    1248                                 yahoo_packet_hash(outpkt, 5, message->from);
    1249                                 yahoo_packet_hash(outpkt, 302, "430");
    1250                                 yahoo_packet_hash(outpkt, 430, message->gunk);
    1251                                 yahoo_packet_hash(outpkt, 303, "430");
    1252                                 yahoo_packet_hash(outpkt, 450, "0");
    1253                                 yahoo_send_packet(yid, outpkt, 0);
    1254                        
    1255                                 yahoo_packet_free(outpkt);
    1256                         }
    1257 
    1258                         if (!strcmp(message->msg, "<ding>"))
    1259                                 YAHOO_CALLBACK(ext_yahoo_got_buzz) (yd->client_id,
    1260                                         message->to, message->from, message->tm);
    1261                         else
    1262                                 YAHOO_CALLBACK(ext_yahoo_got_im) (yd->client_id,
    1263                                         message->to, message->from, message->msg,
    1264                                         message->tm, pkt->status, message->utf8);
     1303                        YAHOO_CALLBACK(ext_yahoo_got_im)(yd->client_id, message->to, message->from, message->msg, message->tm, pkt->status, message->utf8);
    12651304                } else if (pkt->status == 0xffffffff) {
    1266                         YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id,
    1267                                 message->msg, 0, E_SYSTEM);
    1268                 }
    1269                 FREE(message);
     1305                        YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, message->msg, 0, E_SYSTEM);
     1306                }
     1307                free(message);
    12701308        }
    12711309
     
    12731311}
    12741312
    1275 /*
    1276  * Here's what multi-level packets look like. Data in brackets is the value.
    1277  *
    1278  * 3 level:
    1279  * =======
    1280  *
    1281  * 302 (318) - Beginning level 1
    1282  *      300 (318) - Begin level 2
    1283  *      302 (319) - End level 2 header
    1284  *              300 (319) - Begin level 3
    1285  *              301 (319) - End level 3
    1286  *      303 (319) - End level 2
    1287  * 303 (318) - End level 1
    1288  *
    1289  * 2 level:
    1290  * =======
    1291  *
    1292  * 302 (315) - Beginning level 1
    1293  *      300 (315) - Begin level 2
    1294  *      301 (315) - End level 2
    1295  * 303 (315) - End level 1
    1296  *
    1297  */
    12981313static void yahoo_process_status(struct yahoo_input_data *yid,
    12991314        struct yahoo_packet *pkt)
     
    13121327        }
    13131328
    1314         /*
    1315          * Status updates may be spread accross multiple packets and not
    1316          * even on buddy boundaries, so keeping some state is important.
    1317          * So, continue where we left off, and only add a user entry to
    1318          * the list once it's complete (301-315 End buddy).
    1319          */
     1329        /* Status updates may be spread accross multiple packets and not
     1330           even on buddy boundaries, so keeping some state is important.
     1331           So, continue where we left off, and only add a user entry to
     1332           the list once it's complete (301-315 End buddy). */
    13201333        u = yd->half_user;
    13211334
     
    15811594}
    15821595
    1583 static void yahoo_process_verify(struct yahoo_input_data *yid,
    1584         struct yahoo_packet *pkt)
     1596static void yahoo_process_verify(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    15851597{
    15861598        struct yahoo_data *yd = yid->yd;
    15871599
    1588         if (pkt->status != 0x01) {
     1600        if(pkt->status != 0x01) {
    15891601                DEBUG_MSG(("expected status: 0x01, got: %d", pkt->status));
    1590                 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id,
    1591                         YAHOO_LOGIN_LOCK, "");
    1592                 return;
    1593         }
    1594 
    1595         pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YPACKET_STATUS_DEFAULT,
    1596                 yd->session_id);
     1602                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_LOCK, "");
     1603                return;
     1604        }
     1605
     1606        pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, yd->session_id);
    15971607
    15981608        yahoo_packet_hash(pkt, 1, yd->user);
     
    16031613}
    16041614
    1605 static void yahoo_process_picture_checksum(struct yahoo_input_data *yid,
    1606         struct yahoo_packet *pkt)
     1615static void yahoo_process_picture_checksum( struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    16071616{
    16081617        struct yahoo_data *yd = yid->yd;
     
    16121621        YList *l;
    16131622
    1614         for (l = pkt->hash; l; l = l->next) {
     1623        for(l = pkt->hash; l; l = l->next)
     1624        {
    16151625                struct yahoo_pair *pair = l->data;
    16161626
    1617                 switch (pair->key) {
    1618                 case 1:
    1619                 case 4:
    1620                         from = pair->value;
    1621                 case 5:
    1622                         to = pair->value;
    1623                         break;
    1624                 case 212:
    1625                         break;
    1626                 case 192:
    1627                         checksum = atoi(pair->value);
    1628                         break;
    1629                 }
    1630         }
    1631 
    1632         YAHOO_CALLBACK(ext_yahoo_got_buddyicon_checksum) (yd->client_id, to,
    1633                 from, checksum);
    1634 }
    1635 
    1636 static void yahoo_process_picture(struct yahoo_input_data *yid,
    1637         struct yahoo_packet *pkt)
     1627                switch(pair->key)
     1628                {
     1629                        case 1:
     1630                        case 4:
     1631                                from = pair->value;
     1632                        case 5:
     1633                                to = pair->value;
     1634                                break;
     1635                        case 212:
     1636                                break;
     1637                        case 192:
     1638                                checksum = atoi( pair->value );
     1639                                break;
     1640                }
     1641        }
     1642
     1643        YAHOO_CALLBACK(ext_yahoo_got_buddyicon_checksum)(yd->client_id,to,from,checksum);
     1644}
     1645
     1646static void yahoo_process_picture(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    16381647{
    16391648        struct yahoo_data *yd = yid->yd;
     
    16441653        int checksum = 0;
    16451654        YList *l;
    1646 
    1647         for (l = pkt->hash; l; l = l->next) {
     1655       
     1656        for(l = pkt->hash; l; l = l->next)
     1657        {
    16481658                struct yahoo_pair *pair = l->data;
    16491659
    1650                 switch (pair->key) {
     1660                switch(pair->key)
     1661                {
    16511662                case 1:
    1652                 case 4: /* sender */
     1663                case 4:         /* sender */
    16531664                        from = pair->value;
    16541665                        break;
    1655                 case 5: /* we */
     1666                case 5:         /* we */
    16561667                        to = pair->value;
    16571668                        break;
    1658                 case 13:        /* request / sending */
    1659                         status = atoi(pair->value);
    1660                         break;
    1661                 case 20:        /* url */
     1669                case 13:                /* request / sending */
     1670                        status = atoi( pair->value );
     1671                        break;
     1672                case 20:                /* url */
    16621673                        url = pair->value;
    16631674                        break;
    16641675                case 192:       /*checksum */
    1665                         checksum = atoi(pair->value);
    1666                         break;
    1667                 }
    1668         }
    1669 
    1670         switch (status) {
    1671         case 1:         /* this is a request, ignore for now */
    1672                 YAHOO_CALLBACK(ext_yahoo_got_buddyicon_request) (yd->client_id,
    1673                         to, from);
    1674                 break;
    1675         case 2:         /* this is cool - we get a picture :) */
    1676                 YAHOO_CALLBACK(ext_yahoo_got_buddyicon) (yd->client_id, to,
    1677                         from, url, checksum);
    1678                 break;
    1679         }
    1680 }
    1681 
    1682 static void yahoo_process_picture_upload(struct yahoo_input_data *yid,
    1683         struct yahoo_packet *pkt)
     1676                        checksum = atoi( pair->value );
     1677                        break;
     1678                }
     1679        }
     1680
     1681        switch( status )
     1682        {
     1683                case 1: /* this is a request, ignore for now */
     1684                        YAHOO_CALLBACK(ext_yahoo_got_buddyicon_request)(yd->client_id, to, from);
     1685                        break;
     1686                case 2: /* this is cool - we get a picture :) */
     1687                        YAHOO_CALLBACK(ext_yahoo_got_buddyicon)(yd->client_id,to, from, url, checksum);
     1688                        break;
     1689        }
     1690}
     1691
     1692static void yahoo_process_picture_upload(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    16841693{
    16851694        struct yahoo_data *yd = yid->yd;
     
    16871696        char *url = NULL;
    16881697
    1689         if (pkt->status != 1)
     1698        if ( pkt->status != 1 )
    16901699                return;         /* something went wrong */
    1691 
    1692         for (l = pkt->hash; l; l = l->next) {
     1700       
     1701        for(l = pkt->hash; l; l = l->next)
     1702        {
    16931703                struct yahoo_pair *pair = l->data;
    16941704
    1695                 switch (pair->key) {
    1696                 case 5: /* we */
    1697                         break;
    1698                 case 20:        /* url */
    1699                         url = pair->value;
    1700                         break;
    1701                 case 27:        /* local filename */
    1702                         break;
    1703                 case 38:        /* time */
    1704                         break;
    1705                 }
    1706         }
    1707 
    1708         YAHOO_CALLBACK(ext_yahoo_buddyicon_uploaded) (yd->client_id, url);
    1709 }
    1710 
    1711 void yahoo_login(int id, int initial)
    1712 {
    1713         struct yahoo_data *yd = find_conn_by_id(id);
    1714         struct connect_callback_data *ccd;
    1715         struct yahoo_server_settings *yss;
    1716         int tag;
    1717 
    1718         char *host;
    1719 
    1720         struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1);
    1721         yid->yd = yd;
    1722         yid->type = YAHOO_CONNECTION_PAGER;
    1723         inputs = y_list_prepend(inputs, yid);
    1724 
    1725         yd->initial_status = initial;
    1726         yss = yd->server_settings;
    1727 
    1728         ccd = y_new0(struct connect_callback_data, 1);
    1729         ccd->yd = yd;
    1730 
    1731         host = yss->pager_host;
    1732 
    1733         if (!host)
    1734                 host = yss->pager_host_list[0];
    1735 
    1736         tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->client_id,
    1737                 host, yss->pager_port, yahoo_connected, ccd, 0);
    1738 
    1739         /*
    1740          * if tag <= 0, then callback has already been called
    1741          * so ccd will have been freed
     1705                switch(pair->key)
     1706                {
     1707                        case 5:         /* we */
     1708                                break;
     1709                        case 20:                /* url */
     1710                                url = pair->value;
     1711                                break;
     1712                        case 27:                /* local filename */
     1713                                break;
     1714                        case 38:                /* time */
     1715                                break;
     1716                }
     1717        }
     1718
     1719        YAHOO_CALLBACK(ext_yahoo_buddyicon_uploaded)(yd->client_id, url);
     1720}
     1721
     1722static void yahoo_process_auth_pre_0x0b(struct yahoo_input_data *yid,
     1723                const char *seed, const char *sn)
     1724{
     1725        struct yahoo_data *yd = yid->yd;
     1726       
     1727        /* So, Yahoo has stopped supporting its older clients in India, and
     1728         * undoubtedly will soon do so in the rest of the world.
     1729         *
     1730         * The new clients use this authentication method.  I warn you in
     1731         * advance, it's bizzare, convoluted, inordinately complicated. 
     1732         * It's also no more secure than crypt() was.  The only purpose this
     1733         * scheme could serve is to prevent third part clients from connecting
     1734         * to their servers.
     1735         *
     1736         * Sorry, Yahoo.
    17421737         */
    1743         if (tag > 0)
    1744                 ccd->tag = tag;
    1745         else if (tag < 0)
    1746                 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id,
    1747                         YAHOO_LOGIN_SOCK, NULL);
     1738
     1739        struct yahoo_packet *pack;
     1740       
     1741        md5_byte_t result[16];
     1742        md5_state_t ctx;
     1743        char *crypt_result;
     1744        unsigned char *password_hash = malloc(25);
     1745        unsigned char *crypt_hash = malloc(25);
     1746        unsigned char *hash_string_p = malloc(50 + strlen(sn));
     1747        unsigned char *hash_string_c = malloc(50 + strlen(sn));
     1748       
     1749        char checksum;
     1750       
     1751        int sv;
     1752       
     1753        unsigned char *result6 = malloc(25);
     1754        unsigned char *result96 = malloc(25);
     1755
     1756        sv = seed[15];
     1757        sv = (sv % 8) % 5;
     1758
     1759        md5_init(&ctx);
     1760        md5_append(&ctx, (md5_byte_t *)yd->password, strlen(yd->password));
     1761        md5_finish(&ctx, result);
     1762        to_y64(password_hash, result, 16);
     1763       
     1764        md5_init(&ctx);
     1765        crypt_result = yahoo_crypt(yd->password, "$1$_2S43d5f$"); 
     1766        md5_append(&ctx, (md5_byte_t *)crypt_result, strlen(crypt_result));
     1767        md5_finish(&ctx, result);
     1768        to_y64(crypt_hash, result, 16);
     1769        free(crypt_result);
     1770
     1771        switch (sv) {
     1772        case 0:
     1773                checksum = seed[seed[7] % 16];
     1774                snprintf((char *)hash_string_p, strlen(sn) + 50,
     1775                        "%c%s%s%s", checksum, password_hash, yd->user, seed);
     1776                snprintf((char *)hash_string_c, strlen(sn) + 50,
     1777                        "%c%s%s%s", checksum, crypt_hash, yd->user, seed);
     1778                break;
     1779        case 1:
     1780                checksum = seed[seed[9] % 16];
     1781                snprintf((char *)hash_string_p, strlen(sn) + 50,
     1782                        "%c%s%s%s", checksum, yd->user, seed, password_hash);
     1783                snprintf((char *)hash_string_c, strlen(sn) + 50,
     1784                        "%c%s%s%s", checksum, yd->user, seed, crypt_hash);
     1785                break;
     1786        case 2:
     1787                checksum = seed[seed[15] % 16];
     1788                snprintf((char *)hash_string_p, strlen(sn) + 50,
     1789                        "%c%s%s%s", checksum, seed, password_hash, yd->user);
     1790                snprintf((char *)hash_string_c, strlen(sn) + 50,
     1791                        "%c%s%s%s", checksum, seed, crypt_hash, yd->user);
     1792                break;
     1793        case 3:
     1794                checksum = seed[seed[1] % 16];
     1795                snprintf((char *)hash_string_p, strlen(sn) + 50,
     1796                        "%c%s%s%s", checksum, yd->user, password_hash, seed);
     1797                snprintf((char *)hash_string_c, strlen(sn) + 50,
     1798                        "%c%s%s%s", checksum, yd->user, crypt_hash, seed);
     1799                break;
     1800        case 4:
     1801                checksum = seed[seed[3] % 16];
     1802                snprintf((char *)hash_string_p, strlen(sn) + 50,
     1803                        "%c%s%s%s", checksum, password_hash, seed, yd->user);
     1804                snprintf((char *)hash_string_c, strlen(sn) + 50,
     1805                        "%c%s%s%s", checksum, crypt_hash, seed, yd->user);
     1806                break;
     1807        }
     1808               
     1809        md5_init(&ctx); 
     1810        md5_append(&ctx, (md5_byte_t *)hash_string_p, strlen((char *)hash_string_p));
     1811        md5_finish(&ctx, result);
     1812        to_y64(result6, result, 16);
     1813
     1814        md5_init(&ctx); 
     1815        md5_append(&ctx, (md5_byte_t *)hash_string_c, strlen((char *)hash_string_c));
     1816        md5_finish(&ctx, result);
     1817        to_y64(result96, result, 16);
     1818
     1819        pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id);
     1820        yahoo_packet_hash(pack, 0, yd->user);
     1821        yahoo_packet_hash(pack, 6, (char *)result6);
     1822        yahoo_packet_hash(pack, 96, (char *)result96);
     1823        yahoo_packet_hash(pack, 1, yd->user);
     1824               
     1825        yahoo_send_packet(yid, pack, 0);
     1826               
     1827        FREE(result6);
     1828        FREE(result96);
     1829        FREE(password_hash);
     1830        FREE(crypt_hash);
     1831        FREE(hash_string_p);
     1832        FREE(hash_string_c);
     1833
     1834        yahoo_packet_free(pack);
     1835
     1836}
     1837
     1838/*
     1839 * New auth protocol cracked by Cerulean Studios and sent in to Gaim
     1840 */
     1841static void yahoo_process_auth_0x0b(struct yahoo_input_data *yid, const char *seed, const char *sn)
     1842{
     1843        struct yahoo_packet *pack = NULL;
     1844        struct yahoo_data *yd = yid->yd;
     1845
     1846        md5_byte_t         result[16];
     1847        md5_state_t        ctx;
     1848
     1849        sha1_state_t       ctx1;
     1850        sha1_state_t       ctx2;
     1851
     1852        char *alphabet1 = "FBZDWAGHrJTLMNOPpRSKUVEXYChImkwQ";
     1853        char *alphabet2 = "F0E1D2C3B4A59687abcdefghijklmnop";
     1854
     1855        char *challenge_lookup = "qzec2tb3um1olpar8whx4dfgijknsvy5";
     1856        char *operand_lookup = "+|&%/*^-";
     1857        char *delimit_lookup = ",;";
     1858
     1859        unsigned char *password_hash = malloc(25);
     1860        unsigned char *crypt_hash = malloc(25);
     1861        char *crypt_result = NULL;
     1862        unsigned char pass_hash_xor1[64];
     1863        unsigned char pass_hash_xor2[64];
     1864        unsigned char crypt_hash_xor1[64];
     1865        unsigned char crypt_hash_xor2[64];
     1866        unsigned char chal[7];
     1867        char resp_6[100];
     1868        char resp_96[100];
     1869
     1870        unsigned char digest1[20];
     1871        unsigned char digest2[20];
     1872        unsigned char magic_key_char[4];
     1873        const unsigned char *magic_ptr;
     1874
     1875        unsigned int  magic[64];
     1876        unsigned int  magic_work=0;
     1877
     1878        char comparison_src[20];
     1879
     1880        int x, j, i;
     1881        int cnt = 0;
     1882        int magic_cnt = 0;
     1883        int magic_len;
     1884        int depth =0, table =0;
     1885
     1886        memset(&pass_hash_xor1, 0, 64);
     1887        memset(&pass_hash_xor2, 0, 64);
     1888        memset(&crypt_hash_xor1, 0, 64);
     1889        memset(&crypt_hash_xor2, 0, 64);
     1890        memset(&digest1, 0, 20);
     1891        memset(&digest2, 0, 20);
     1892        memset(&magic, 0, 64);
     1893        memset(&resp_6, 0, 100);
     1894        memset(&resp_96, 0, 100);
     1895        memset(&magic_key_char, 0, 4);
     1896
     1897        /*
     1898         * Magic: Phase 1.  Generate what seems to be a 30
     1899         * byte value (could change if base64
     1900         * ends up differently?  I don't remember and I'm
     1901         * tired, so use a 64 byte buffer.
     1902         */
     1903
     1904        magic_ptr = (unsigned char *)seed;
     1905
     1906        while (*magic_ptr != 0) {
     1907                char *loc;
     1908
     1909                /* Ignore parentheses.  */
     1910
     1911                if (*magic_ptr == '(' || *magic_ptr == ')') {
     1912                        magic_ptr++;
     1913                        continue;
     1914                }
     1915
     1916                /* Characters and digits verify against
     1917                   the challenge lookup.
     1918                */
     1919
     1920                if (isalpha(*magic_ptr) || isdigit(*magic_ptr)) {
     1921                        loc = strchr(challenge_lookup, *magic_ptr);
     1922                        if (!loc) {
     1923                                /* This isn't good */
     1924                                continue;
     1925                        }
     1926
     1927                        /* Get offset into lookup table and lsh 3. */
     1928
     1929                        magic_work = loc - challenge_lookup;
     1930                        magic_work <<= 3;
     1931
     1932                        magic_ptr++;
     1933                        continue;
     1934                } else {
     1935                        unsigned int local_store;
     1936
     1937                        loc = strchr(operand_lookup, *magic_ptr);
     1938                        if (!loc) {
     1939                                /* Also not good. */
     1940                                continue;
     1941                        }
     1942
     1943                        local_store = loc - operand_lookup;
     1944
     1945                        /* Oops; how did this happen? */
     1946                        if (magic_cnt >= 64)
     1947                                break;
     1948
     1949                        magic[magic_cnt++] = magic_work | local_store;
     1950                        magic_ptr++;
     1951                        continue;
     1952                }
     1953        }
     1954
     1955        magic_len = magic_cnt;
     1956        magic_cnt = 0;
     1957
     1958        /* Magic: Phase 2.  Take generated magic value and
     1959         * sprinkle fairy dust on the values. */
     1960
     1961        for (magic_cnt = magic_len-2; magic_cnt >= 0; magic_cnt--) {
     1962                unsigned char byte1;
     1963                unsigned char byte2;
     1964
     1965                /* Bad.  Abort.
     1966                 */
     1967                if (magic_cnt >= magic_len) {
     1968                        WARNING(("magic_cnt(%d)  magic_len(%d)", magic_cnt, magic_len))
     1969                        break;
     1970                }
     1971
     1972                byte1 = magic[magic_cnt];
     1973                byte2 = magic[magic_cnt+1];
     1974
     1975                byte1 *= 0xcd;
     1976                byte1 ^= byte2;
     1977
     1978                magic[magic_cnt+1] = byte1;
     1979        }
     1980
     1981        /* Magic: Phase 3.  This computes 20 bytes.  The first 4 bytes are used as our magic
     1982         * key (and may be changed later); the next 16 bytes are an MD5 sum of the magic key
     1983         * plus 3 bytes.  The 3 bytes are found by looping, and they represent the offsets
     1984         * into particular functions we'll later call to potentially alter the magic key.
     1985         *
     1986         * %-)
     1987         */
     1988       
     1989        magic_cnt = 1;
     1990        x = 0;
     1991       
     1992        do {
     1993                unsigned int     bl = 0; 
     1994                unsigned int     cl = magic[magic_cnt++];
     1995               
     1996                if (magic_cnt >= magic_len)
     1997                        break;
     1998               
     1999                if (cl > 0x7F) {
     2000                        if (cl < 0xe0) 
     2001                                bl = cl = (cl & 0x1f) << 6; 
     2002                        else {
     2003                                bl = magic[magic_cnt++]; 
     2004                              cl = (cl & 0x0f) << 6; 
     2005                              bl = ((bl & 0x3f) + cl) << 6; 
     2006                        } 
     2007                       
     2008                        cl = magic[magic_cnt++]; 
     2009                        bl = (cl & 0x3f) + bl; 
     2010                } else
     2011                        bl = cl; 
     2012               
     2013                comparison_src[x++] = (bl & 0xff00) >> 8; 
     2014                comparison_src[x++] = bl & 0xff; 
     2015        } while (x < 20);
     2016
     2017        /* Dump magic key into a char for SHA1 action. */
     2018       
     2019               
     2020        for(x = 0; x < 4; x++)
     2021                magic_key_char[x] = comparison_src[x];
     2022
     2023        /* Compute values for recursive function table! */
     2024        memcpy( chal, magic_key_char, 4 );
     2025        x = 1;
     2026        for( i = 0; i < 0xFFFF && x; i++ )
     2027        {
     2028                for( j = 0; j < 5 && x; j++ )
     2029                {
     2030                        chal[4] = i;
     2031                        chal[5] = i >> 8;
     2032                        chal[6] = j;
     2033                        md5_init( &ctx );
     2034                        md5_append( &ctx, chal, 7 );
     2035                        md5_finish( &ctx, result );
     2036                        if( memcmp( comparison_src + 4, result, 16 ) == 0 )
     2037                        {
     2038                                depth = i;
     2039                                table = j;
     2040                                x = 0;
     2041                        }
     2042                }
     2043        }
     2044
     2045        /* Transform magic_key_char using transform table */
     2046        x = magic_key_char[3] << 24  | magic_key_char[2] << 16
     2047                | magic_key_char[1] << 8 | magic_key_char[0];
     2048        x = yahoo_xfrm( table, depth, x );
     2049        x = yahoo_xfrm( table, depth, x );
     2050        magic_key_char[0] = x & 0xFF;
     2051        magic_key_char[1] = x >> 8 & 0xFF;
     2052        magic_key_char[2] = x >> 16 & 0xFF;
     2053        magic_key_char[3] = x >> 24 & 0xFF;
     2054
     2055        /* Get password and crypt hashes as per usual. */
     2056        md5_init(&ctx);
     2057        md5_append(&ctx, (md5_byte_t *)yd->password,  strlen(yd->password));
     2058        md5_finish(&ctx, result);
     2059        to_y64(password_hash, result, 16);
     2060
     2061        md5_init(&ctx);
     2062        crypt_result = yahoo_crypt(yd->password, "$1$_2S43d5f$"); 
     2063        md5_append(&ctx, (md5_byte_t *)crypt_result, strlen(crypt_result));
     2064        md5_finish(&ctx, result);
     2065        to_y64(crypt_hash, result, 16);
     2066        free(crypt_result);
     2067
     2068        /* Our first authentication response is based off
     2069         * of the password hash. */
     2070
     2071        for (x = 0; x < (int)strlen((char *)password_hash); x++)
     2072                pass_hash_xor1[cnt++] = password_hash[x] ^ 0x36;
     2073
     2074        if (cnt < 64)
     2075                memset(&(pass_hash_xor1[cnt]), 0x36, 64-cnt);
     2076
     2077        cnt = 0;
     2078
     2079        for (x = 0; x < (int)strlen((char *)password_hash); x++)
     2080                pass_hash_xor2[cnt++] = password_hash[x] ^ 0x5c;
     2081
     2082        if (cnt < 64)
     2083                memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt);
     2084
     2085        sha1_init(&ctx1);
     2086        sha1_init(&ctx2);
     2087
     2088        /* The first context gets the password hash XORed
     2089         * with 0x36 plus a magic value
     2090         * which we previously extrapolated from our
     2091         * challenge. */
     2092
     2093        sha1_append(&ctx1, pass_hash_xor1, 64);
     2094        if (j >= 3 )
     2095                ctx1.Length_Low = 0x1ff;
     2096        sha1_append(&ctx1, magic_key_char, 4);
     2097        sha1_finish(&ctx1, digest1);
     2098
     2099         /* The second context gets the password hash XORed
     2100          * with 0x5c plus the SHA-1 digest
     2101          * of the first context. */
     2102
     2103        sha1_append(&ctx2, pass_hash_xor2, 64);
     2104        sha1_append(&ctx2, digest1, 20);
     2105        sha1_finish(&ctx2, digest2);
     2106
     2107        /* Now that we have digest2, use it to fetch
     2108         * characters from an alphabet to construct
     2109         * our first authentication response. */
     2110
     2111        for (x = 0; x < 20; x += 2) {
     2112                unsigned int    val = 0;
     2113                unsigned int    lookup = 0;
     2114                char            byte[6];
     2115
     2116                memset(&byte, 0, 6);
     2117
     2118                /* First two bytes of digest stuffed
     2119                 *  together.
     2120                 */
     2121
     2122                val = digest2[x];
     2123                val <<= 8;
     2124                val += digest2[x+1];
     2125
     2126                lookup = (val >> 0x0b);
     2127                lookup &= 0x1f;
     2128                if (lookup >= strlen(alphabet1))
     2129                        break;
     2130                sprintf(byte, "%c", alphabet1[lookup]);
     2131                strcat(resp_6, byte);
     2132                strcat(resp_6, "=");
     2133
     2134                lookup = (val >> 0x06);
     2135                lookup &= 0x1f;
     2136                if (lookup >= strlen(alphabet2))
     2137                        break;
     2138                sprintf(byte, "%c", alphabet2[lookup]);
     2139                strcat(resp_6, byte);
     2140
     2141                lookup = (val >> 0x01);
     2142                lookup &= 0x1f;
     2143                if (lookup >= strlen(alphabet2))
     2144                        break;
     2145                sprintf(byte, "%c", alphabet2[lookup]);
     2146                strcat(resp_6, byte);
     2147
     2148                lookup = (val & 0x01);
     2149                if (lookup >= strlen(delimit_lookup))
     2150                        break;
     2151                sprintf(byte, "%c", delimit_lookup[lookup]);
     2152                strcat(resp_6, byte);
     2153        }
     2154
     2155        /* Our second authentication response is based off
     2156         * of the crypto hash. */
     2157
     2158        cnt = 0;
     2159        memset(&digest1, 0, 20);
     2160        memset(&digest2, 0, 20);
     2161
     2162        for (x = 0; x < (int)strlen((char *)crypt_hash); x++)
     2163                crypt_hash_xor1[cnt++] = crypt_hash[x] ^ 0x36;
     2164
     2165        if (cnt < 64)
     2166                memset(&(crypt_hash_xor1[cnt]), 0x36, 64-cnt);
     2167
     2168        cnt = 0;
     2169
     2170        for (x = 0; x < (int)strlen((char *)crypt_hash); x++)
     2171                crypt_hash_xor2[cnt++] = crypt_hash[x] ^ 0x5c;
     2172
     2173        if (cnt < 64)
     2174                memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt);
     2175
     2176        sha1_init(&ctx1);
     2177        sha1_init(&ctx2);
     2178
     2179        /* The first context gets the password hash XORed
     2180         * with 0x36 plus a magic value
     2181         * which we previously extrapolated from our
     2182         * challenge. */
     2183
     2184        sha1_append(&ctx1, crypt_hash_xor1, 64);
     2185        if (j >= 3 )
     2186                ctx1.Length_Low = 0x1ff;
     2187        sha1_append(&ctx1, magic_key_char, 4);
     2188        sha1_finish(&ctx1, digest1);
     2189
     2190        /* The second context gets the password hash XORed
     2191         * with 0x5c plus the SHA-1 digest
     2192         * of the first context. */
     2193
     2194        sha1_append(&ctx2, crypt_hash_xor2, 64);
     2195        sha1_append(&ctx2, digest1, 20);
     2196        sha1_finish(&ctx2, digest2);
     2197
     2198        /* Now that we have digest2, use it to fetch
     2199         * characters from an alphabet to construct
     2200         * our first authentication response.  */
     2201
     2202        for (x = 0; x < 20; x += 2) {
     2203                unsigned int val = 0;
     2204                unsigned int lookup = 0;
     2205
     2206                char byte[6];
     2207
     2208                memset(&byte, 0, 6);
     2209
     2210                /* First two bytes of digest stuffed
     2211                 *  together. */
     2212
     2213                val = digest2[x];
     2214                val <<= 8;
     2215                val += digest2[x+1];
     2216
     2217                lookup = (val >> 0x0b);
     2218                lookup &= 0x1f;
     2219                if (lookup >= strlen(alphabet1))
     2220                        break;
     2221                sprintf(byte, "%c", alphabet1[lookup]);
     2222                strcat(resp_96, byte);
     2223                strcat(resp_96, "=");
     2224
     2225                lookup = (val >> 0x06);
     2226                lookup &= 0x1f;
     2227                if (lookup >= strlen(alphabet2))
     2228                        break;
     2229                sprintf(byte, "%c", alphabet2[lookup]);
     2230                strcat(resp_96, byte);
     2231
     2232                lookup = (val >> 0x01);
     2233                lookup &= 0x1f;
     2234                if (lookup >= strlen(alphabet2))
     2235                        break;
     2236                sprintf(byte, "%c", alphabet2[lookup]);
     2237                strcat(resp_96, byte);
     2238
     2239                lookup = (val & 0x01);
     2240                if (lookup >= strlen(delimit_lookup))
     2241                        break;
     2242                sprintf(byte, "%c", delimit_lookup[lookup]);
     2243                strcat(resp_96, byte);
     2244        }
     2245
     2246        pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id);
     2247        yahoo_packet_hash(pack, 0, sn);
     2248        yahoo_packet_hash(pack, 6, resp_6);
     2249        yahoo_packet_hash(pack, 96, resp_96);
     2250        yahoo_packet_hash(pack, 1, sn);
     2251        yahoo_send_packet(yid, pack, 0);
     2252        yahoo_packet_free(pack);
     2253
     2254        free(password_hash);
     2255        free(crypt_hash);
    17482256}
    17492257
     
    17952303}
    17962304
    1797 static void yahoo_https_auth(struct yahoo_input_data *yid, const char *seed, const char *sn)
     2305static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn)
    17982306{
    17992307        struct yahoo_https_auth_data *had = g_new0(struct yahoo_https_auth_data, 1);
     
    18452353       
    18462354        if (req->status_code != 200) {
    1847                 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 2000 + req->status_code, NULL);
     2355                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL);
    18482356                goto fail;
    18492357        }
    18502358       
    18512359        if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) {
    1852                 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, yahoo_https_status_parse(st), NULL);
     2360                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL);
    18532361                goto fail;
    18542362        }
    18552363       
    18562364        if ((had->token = yahoo_ha_find_key(req->reply_body, "ymsgr")) == NULL) {
    1857                 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 3001, NULL);
     2365                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3001, NULL);
    18582366                goto fail;
    18592367        }
     
    19012409
    19022410        if (req->status_code != 200) {
    1903                 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 2000 + req->status_code, NULL);
     2411                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL);
    19042412                goto fail;
    19052413        }
    19062414       
    19072415        if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) {
    1908                 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, yahoo_https_status_parse(st), NULL);
     2416                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL);
    19092417                goto fail;
    19102418        }
     
    19132421            (yd->cookie_t = yahoo_ha_find_key(req->reply_body, "T")) == NULL ||
    19142422            (crumb = yahoo_ha_find_key(req->reply_body, "crumb")) == NULL) {
    1915                 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 3002, NULL);
     2423                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3002, NULL);
    19162424                goto fail;
    19172425        }
     
    19462454}
    19472455
    1948 static void yahoo_process_auth(struct yahoo_input_data *yid,
    1949         struct yahoo_packet *pkt)
     2456static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    19502457{
    19512458        char *seed = NULL;
    1952         char *sn = NULL;
     2459        char *sn   = NULL;
    19532460        YList *l = pkt->hash;
    19542461        int m = 0;
    1955         struct yahoo_data *yd = yid->yd;
    19562462
    19572463        while (l) {
    19582464                struct yahoo_pair *pair = l->data;
    1959 
    1960                 switch (pair->key) {
    1961                 case 94:
     2465                if (pair->key == 94)
    19622466                        seed = pair->value;
     2467                if (pair->key == 1)
     2468                        sn = pair->value;
     2469                if (pair->key == 13)
     2470                        m = atoi(pair->value);
     2471                l = l->next;
     2472        }
     2473
     2474        if (!seed)
     2475                return;
     2476
     2477        switch (m) {
     2478                case 0:
     2479                        yahoo_process_auth_pre_0x0b(yid, seed, sn);
    19632480                        break;
    19642481                case 1:
    1965                         sn = pair->value;
    1966                         break;
    1967                 case 13:
    1968                         m = atoi(pair->value);
    1969                         break;
    1970                 }
    1971                 l = l->next;
    1972         }
    1973 
    1974         if (!seed)
    1975                 return;
    1976 
    1977         if (m==2)
    1978                 yahoo_https_auth(yid, seed, sn);
    1979         else {
    1980                 /* call error */
    1981                 WARNING(("unknown auth type %d", m));
    1982                 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id,
    1983                         YAHOO_LOGIN_UNKNOWN, NULL);
    1984         }
    1985 }
    1986 
    1987 static void yahoo_process_auth_resp(struct yahoo_input_data *yid,
    1988         struct yahoo_packet *pkt)
     2482                        yahoo_process_auth_0x0b(yid, seed, sn);
     2483                        break;
     2484                case 2:
     2485                        yahoo_process_auth_0x10(yid, seed, sn);
     2486                        break;
     2487                default:
     2488                        /* call error */
     2489                        WARNING(("unknown auth type %d", m));
     2490                        yahoo_process_auth_0x0b(yid, seed, sn);
     2491                        break;
     2492        }
     2493}
     2494
     2495static void yahoo_process_auth_resp(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    19892496{
    19902497        struct yahoo_data *yd = yid->yd;
    19912498        char *login_id;
    19922499        char *handle;
    1993         char *url = NULL;
    1994         int login_status = -1;
     2500        char *url=NULL;
     2501        int  login_status=0;
    19952502
    19962503        YList *l;
     
    20082515        }
    20092516
    2010         if (pkt->status == YPACKET_STATUS_DISCONNECTED) {
    2011                 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id,
    2012                         login_status, url);
    2013                 /*      yahoo_logoff(yd->client_id); */
    2014         }
    2015 }
    2016 
    2017 static void yahoo_process_mail(struct yahoo_input_data *yid,
    2018         struct yahoo_packet *pkt)
     2517        if(pkt->status == 0xffffffff) {
     2518                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, login_status, url);
     2519        /*      yahoo_logoff(yd->client_id);*/
     2520        }
     2521}
     2522
     2523static void yahoo_process_mail(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    20192524{
    20202525        struct yahoo_data *yd = yid->yd;
     
    20422547                char from[1024];
    20432548                snprintf(from, sizeof(from), "%s (%s)", who, email);
    2044                 YAHOO_CALLBACK(ext_yahoo_mail_notify) (yd->client_id, from,
    2045                         subj, count);
    2046         } else if (count > 0)
    2047                 YAHOO_CALLBACK(ext_yahoo_mail_notify) (yd->client_id, NULL,
    2048                         NULL, count);
    2049 }
    2050 
    2051 static void yahoo_process_new_contact(struct yahoo_input_data *yid,
    2052         struct yahoo_packet *pkt)
    2053 {
    2054         struct yahoo_data *yd = yid->yd;
    2055         char *me = NULL;
    2056         char *who = NULL;
    2057         char *msg = NULL;
    2058         int online = -1;
    2059 
    2060         YList *l;
    2061 
    2062         for (l = pkt->hash; l; l = l->next) {
    2063                 struct yahoo_pair *pair = l->data;
    2064                 if (pair->key == 4)
    2065                         who = pair->value;
    2066                 else if (pair->key == 5)
    2067                         me = pair->value;
    2068                 else if (pair->key == 14)
    2069                         msg = pair->value;
    2070                 else if (pair->key == 13)
    2071                         online = strtol(pair->value, NULL, 10);
    2072         }
    2073 
    2074         if (who && online < 0)
    2075                 YAHOO_CALLBACK(ext_yahoo_contact_added) (yd->client_id, me, who,
    2076                         msg);
    2077         else if (online == 2)
    2078                 YAHOO_CALLBACK(ext_yahoo_rejected) (yd->client_id, who, msg);
    2079 }
    2080 
    2081 /* UNUSED? */
    2082 static void yahoo_process_contact(struct yahoo_input_data *yid,
    2083         struct yahoo_packet *pkt)
     2549                YAHOO_CALLBACK(ext_yahoo_mail_notify)(yd->client_id, from, subj, count);
     2550        } else if(count > 0)
     2551                YAHOO_CALLBACK(ext_yahoo_mail_notify)(yd->client_id, NULL, NULL, count);
     2552}
     2553
     2554static void yahoo_process_contact(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    20842555{
    20852556        struct yahoo_data *yd = yid->yd;
     
    20902561        long tm = 0L;
    20912562        int state = YAHOO_STATUS_AVAILABLE;
    2092         int online = 0;
     2563        int online = FALSE;
    20932564        int away = 0;
    20942565        int idle = 0;
     
    21192590                else if (pair->key == 60)
    21202591                        mobile = strtol(pair->value, NULL, 10);
    2121 
     2592               
    21222593        }
    21232594
    21242595        if (id)
    2125                 YAHOO_CALLBACK(ext_yahoo_contact_added) (yd->client_id, id, who,
    2126                         msg);
     2596                YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, id, who, msg);
    21272597        else if (name)
    2128                 YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->client_id, name,
    2129                         state, msg, away, idle, mobile);
    2130         else if (pkt->status == 0x07)
    2131                 YAHOO_CALLBACK(ext_yahoo_rejected) (yd->client_id, who, msg);
    2132 }
    2133 
    2134 static void yahoo_process_buddyadd(struct yahoo_input_data *yid,
    2135         struct yahoo_packet *pkt)
     2598                YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, msg, away, idle, mobile);
     2599        else if(pkt->status == 0x07)
     2600                YAHOO_CALLBACK(ext_yahoo_rejected)(yd->client_id, who, msg);
     2601}
     2602
     2603static void yahoo_process_buddyadd(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    21362604{
    21372605        struct yahoo_data *yd = yid->yd;
     
    21412609        char *me = NULL;
    21422610
    2143         struct yahoo_buddy *bud = NULL;
     2611        struct yahoo_buddy *bud=NULL;
    21442612
    21452613        YList *l;
     
    21562624        }
    21572625
    2158         if (!who)
    2159                 return;
    2160         if (!where)
     2626        yahoo_dump_unhandled(pkt);
     2627
     2628        if(!who)
     2629                return;
     2630        if(!where)
    21612631                where = "Unknown";
    21622632
    2163         bud = y_new0(struct yahoo_buddy, 1);
    2164         bud->id = strdup(who);
    2165         bud->group = strdup(where);
    2166         bud->real_name = NULL;
    2167 
    2168         yd->buddies = y_list_append(yd->buddies, bud);
    2169 
    2170         /* A non-zero status (i've seen 2) seems to mean the buddy is already
    2171          * added and is online */
    2172         if (status) {
    2173                 LOG(("Setting online see packet for info"));
    2174                 yahoo_dump_unhandled(pkt);
    2175                 YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->client_id, who,
    2176                         YAHOO_STATUS_AVAILABLE, NULL, 0, 0, 0);
    2177         }
    2178 }
    2179 
    2180 static void yahoo_process_buddydel(struct yahoo_input_data *yid,
    2181         struct yahoo_packet *pkt)
     2633        /* status: 0 == Successful, 1 == Error (does not exist), 2 == Already in list */
     2634        if( status == 0 ) {
     2635                bud = y_new0(struct yahoo_buddy, 1);
     2636                bud->id = strdup(who);
     2637                bud->group = strdup(where);
     2638                bud->real_name = NULL;
     2639               
     2640                yd->buddies = y_list_append(yd->buddies, bud);
     2641       
     2642                /* Possibly called already, but at least the call above doesn't
     2643                   seem to happen every time (not anytime I tried). */
     2644                YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, me, who, NULL);
     2645        }
     2646
     2647/*      YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, who, status, NULL, (status==YAHOO_STATUS_AVAILABLE?0:1)); */
     2648}
     2649
     2650static void yahoo_process_contact_ymsg13(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     2651{
     2652        char* who=NULL;
     2653        char* me=NULL; 
     2654        char* msg=NULL;
     2655        YList *l;
     2656        for (l = pkt->hash; l; l = l->next) {
     2657                struct yahoo_pair *pair = l->data;
     2658                if (pair->key == 4)
     2659                        who = pair->value;
     2660                else if (pair->key == 5)
     2661                        me = pair->value;
     2662                else
     2663                        DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value));
     2664        }
     2665
     2666        if(pkt->status==3)
     2667                YAHOO_CALLBACK(ext_yahoo_contact_auth_request)(yid->yd->client_id, me, who, msg);
     2668}
     2669
     2670static void yahoo_process_buddydel(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    21822671{
    21832672        struct yahoo_data *yd = yid->yd;
     
    22022691                        unk_66 = strtol(pair->value, NULL, 10);
    22032692                else
    2204                         DEBUG_MSG(("unknown key: %d = %s", pair->key,
    2205                                         pair->value));
    2206         }
    2207 
    2208         if (!who || !where)
    2209                 return;
    2210 
     2693                        DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value));
     2694        }
     2695
     2696        if(!who || !where)
     2697                return;
     2698       
    22112699        bud = y_new0(struct yahoo_buddy, 1);
    22122700        bud->id = strdup(who);
     
    22192707        FREE(bud);
    22202708
    2221         if (buddy) {
     2709        if(buddy) {
    22222710                bud = buddy->data;
    22232711                yd->buddies = y_list_remove_link(yd->buddies, buddy);
     
    22292717                FREE(bud);
    22302718
    2231                 bud = NULL;
    2232         }
    2233 }
    2234 
    2235 static void yahoo_process_ignore(struct yahoo_input_data *yid,
    2236         struct yahoo_packet *pkt)
     2719                bud=NULL;
     2720        }
     2721}
     2722
     2723static void yahoo_process_ignore(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    22372724{
    22382725        char *who = NULL;
    2239         int status = 0;
     2726        int  status = 0;
    22402727        char *me = NULL;
    2241         int un_ignore = 0;
     2728        int  un_ignore = 0;
    22422729
    22432730        YList *l;
     
    22482735                if (pair->key == 1)
    22492736                        me = pair->value;
    2250                 if (pair->key == 13)    /* 1 == ignore, 2 == unignore */
     2737                if (pair->key == 13) /* 1 == ignore, 2 == unignore */
    22512738                        un_ignore = strtol(pair->value, NULL, 10);
    2252                 if (pair->key == 66)
     2739                if (pair->key == 66) 
    22532740                        status = strtol(pair->value, NULL, 10);
    22542741        }
     2742
    22552743
    22562744        /*
    22572745         * status
    2258          *      0  - ok
    2259          *      2  - already in ignore list, could not add
    2260          *      3  - not in ignore list, could not delete
    2261          *      12 - is a buddy, could not add
     2746         *      0  - ok
     2747         *      2  - already in ignore list, could not add
     2748         *      3  - not in ignore list, could not delete
     2749         *      12 - is a buddy, could not add
    22622750         */
    22632751
    22642752/*      if(status)
    22652753                YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, who, 0, status);
    2266 */
    2267 }
    2268 
    2269 static void yahoo_process_voicechat(struct yahoo_input_data *yid,
    2270         struct yahoo_packet *pkt)
     2754*/     
     2755}
     2756
     2757static void yahoo_process_voicechat(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    22712758{
    22722759        char *who = NULL;
     
    22832770                        me = pair->value;
    22842771                if (pair->key == 13)
    2285                         voice_room = pair->value;
    2286                 if (pair->key == 57)
    2287                         room = pair->value;
    2288         }
    2289 
    2290         NOTICE(("got voice chat invite from %s in %s to identity %s", who, room,
    2291                         me));
     2772                        voice_room=pair->value;
     2773                if (pair->key == 57)
     2774                        room=pair->value;
     2775        }
     2776
     2777        NOTICE(("got voice chat invite from %s in %s to identity %s", who, room, me));
    22922778        /*
    22932779         * send: s:0 1:me 5:who 57:room 13:1
     
    23012787}
    23022788
    2303 static void yahoo_process_ping(struct yahoo_input_data *yid,
    2304         struct yahoo_packet *pkt)
     2789static void yahoo_process_ping(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    23052790{
    23062791        char *errormsg = NULL;
    2307 
     2792       
    23082793        YList *l;
    23092794        for (l = pkt->hash; l; l = l->next) {
     
    23122797                        errormsg = pair->value;
    23132798        }
    2314 
     2799       
    23152800        NOTICE(("got ping packet"));
    2316         YAHOO_CALLBACK(ext_yahoo_got_ping) (yid->yd->client_id, errormsg);
    2317 }
    2318 
    2319 static void yahoo_process_buddy_change_group(struct yahoo_input_data *yid,
    2320         struct yahoo_packet *pkt)
    2321 {
    2322         YList *l;
    2323         char *me = NULL;
    2324         char *who = NULL;
    2325         char *old_group = NULL;
    2326         char *new_group = NULL;
    2327 
    2328         for (l = pkt->hash; l; l = l->next) {
    2329                 struct yahoo_pair *pair = l->data;
    2330                 if (pair->key == 1)
    2331                         me = pair->value;
    2332                 if (pair->key == 7)
    2333                         who = pair->value;
    2334                 if (pair->key == 224)
    2335                         old_group = pair->value;
    2336                 if (pair->key == 264)
    2337                         new_group = pair->value;
    2338         }
    2339 
    2340         YAHOO_CALLBACK(ext_yahoo_got_buddy_change_group) (yid->yd->client_id,
    2341                 me, who, old_group, new_group);
    2342 }
    2343 
    2344 static void _yahoo_webcam_get_server_connected(void *fd, int error, void *d)
     2801        YAHOO_CALLBACK(ext_yahoo_got_ping)(yid->yd->client_id, errormsg);
     2802}
     2803
     2804static void _yahoo_webcam_get_server_connected(int fd, int error, void *d)
    23452805{
    23462806        struct yahoo_input_data *yid = d;
     
    23482808        char *data = NULL;
    23492809        char *packet = NULL;
    2350         unsigned char magic_nr[] = { 0, 1, 0 };
     2810        unsigned char magic_nr[] = {0, 1, 0};
    23512811        unsigned char header_len = 8;
    23522812        unsigned int len = 0;
    23532813        unsigned int pos = 0;
    23542814
    2355         if (error || !fd) {
     2815        if(error || fd <= 0) {
    23562816                FREE(who);
    23572817                FREE(yid);
     
    23612821        yid->fd = fd;
    23622822        inputs = y_list_prepend(inputs, yid);
    2363 
     2823       
    23642824        /* send initial packet */
    23652825        if (who)
     
    23712831
    23722832        /* send data */
    2373         if (who) {
     2833        if (who)
     2834        {
    23742835                data = strdup("g=");
    23752836                data = y_string_append(data, who);
     
    23902851        FREE(data);
    23912852
    2392         yid->read_tag =
    2393                 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd,
    2394                 YAHOO_INPUT_READ, yid);
    2395 }
    2396 
    2397 static void yahoo_webcam_get_server(struct yahoo_input_data *y, char *who,
    2398         char *key)
     2853        yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, fd, YAHOO_INPUT_READ, yid);
     2854}
     2855
     2856static void yahoo_webcam_get_server(struct yahoo_input_data *y, char *who, char *key)
    23992857{
    24002858        struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1);
     
    24042862        yid->yd = y->yd;
    24052863        yid->wcm = y_new0(struct yahoo_webcam, 1);
    2406         yid->wcm->user = who ? strdup(who) : NULL;
    2407         yid->wcm->direction = who ? YAHOO_WEBCAM_DOWNLOAD : YAHOO_WEBCAM_UPLOAD;
     2864        yid->wcm->user = who?strdup(who):NULL;
     2865        yid->wcm->direction = who?YAHOO_WEBCAM_DOWNLOAD:YAHOO_WEBCAM_UPLOAD;
    24082866        yid->wcm->key = strdup(key);
    24092867
    2410         YAHOO_CALLBACK(ext_yahoo_connect_async) (yid->yd->client_id,
    2411                 yss->webcam_host, yss->webcam_port,
    2412                 _yahoo_webcam_get_server_connected, yid, 0);
    2413 
    2414 }
    2415 
    2416 static YList *webcam_queue = NULL;
    2417 static void yahoo_process_webcam_key(struct yahoo_input_data *yid,
    2418         struct yahoo_packet *pkt)
     2868        YAHOO_CALLBACK(ext_yahoo_connect_async)(yid->yd->client_id, yss->webcam_host, yss->webcam_port,
     2869                        _yahoo_webcam_get_server_connected, yid);
     2870
     2871}
     2872
     2873static YList *webcam_queue=NULL;
     2874static void yahoo_process_webcam_key(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    24192875{
    24202876        char *me = NULL;
     
    24232879
    24242880        YList *l;
    2425         yahoo_dump_unhandled(pkt);
     2881        // yahoo_dump_unhandled(pkt);
    24262882        for (l = pkt->hash; l; l = l->next) {
    24272883                struct yahoo_pair *pair = l->data;
    24282884                if (pair->key == 5)
    24292885                        me = pair->value;
    2430                 if (pair->key == 61)
    2431                         key = pair->value;
     2886                if (pair->key == 61) 
     2887                        key=pair->value;
    24322888        }
    24332889
    24342890        l = webcam_queue;
    2435         if (!l)
     2891        if(!l)
    24362892                return;
    24372893        who = l->data;
     
    24422898}
    24432899
    2444 static void yahoo_packet_process(struct yahoo_input_data *yid,
    2445         struct yahoo_packet *pkt)
     2900static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    24462901{
    24472902        DEBUG_MSG(("yahoo_packet_process: 0x%02x", pkt->service));
    2448         switch (pkt->service) {
     2903        yahoo_dump_unhandled(pkt);
     2904        switch (pkt->service)
     2905        {
    24492906        case YAHOO_SERVICE_USERSTAT:
    24502907        case YAHOO_SERVICE_LOGON:
     
    24572914        case YAHOO_SERVICE_IDDEACT:
    24582915        case YAHOO_SERVICE_Y6_STATUS_UPDATE:
    2459         case YAHOO_SERVICE_Y8_STATUS:
     2916        case YAHOO_SERVICE_YMSG15_STATUS:
    24602917                yahoo_process_status(yid, pkt);
    24612918                break;
     
    24712928                yahoo_process_mail(yid, pkt);
    24722929                break;
    2473         case YAHOO_SERVICE_Y7_AUTHORIZATION:
    2474                 yahoo_process_new_contact(yid, pkt);
    2475                 break;
     2930        case YAHOO_SERVICE_REJECTCONTACT:
    24762931        case YAHOO_SERVICE_NEWCONTACT:
    24772932                yahoo_process_contact(yid, pkt);
     
    25082963                break;
    25092964        case YAHOO_SERVICE_P2PFILEXFER:
    2510         case YAHOO_SERVICE_Y7_FILETRANSFER:
     2965        case YAHOO_SERVICE_FILETRANSFER:
    25112966                yahoo_process_filetransfer(yid, pkt);
    2512                 break;
    2513         case YAHOO_SERVICE_Y7_FILETRANSFERINFO:
    2514                 yahoo_process_filetransferinfo(yid, pkt);
    2515                 break;
    2516         case YAHOO_SERVICE_Y7_FILETRANSFERACCEPT:
    2517                 yahoo_process_filetransferaccept(yid, pkt);
    25182967                break;
    25192968        case YAHOO_SERVICE_ADDBUDDY:
    25202969                yahoo_process_buddyadd(yid, pkt);
     2970                break;
     2971        case YAHOO_SERVICE_CONTACT_YMSG13:
     2972                yahoo_process_contact_ymsg13(yid,pkt);
    25212973                break;
    25222974        case YAHOO_SERVICE_REMBUDDY:
     
    25352987                yahoo_process_ping(yid, pkt);
    25362988                break;
    2537         case YAHOO_SERVICE_Y7_CHANGE_GROUP:
    2538                 yahoo_process_buddy_change_group(yid, pkt);
    2539                 break;
    25402989        case YAHOO_SERVICE_IDLE:
    25412990        case YAHOO_SERVICE_MAILSTAT:
     
    25513000        case YAHOO_SERVICE_CHATLOGOFF:
    25523001        case YAHOO_SERVICE_CHATMSG:
    2553         case YAHOO_SERVICE_REJECTCONTACT:
    25543002        case YAHOO_SERVICE_PEERTOPEER:
    25553003                WARNING(("unhandled service 0x%02x", pkt->service));
     
    25643012        case YAHOO_SERVICE_PICTURE_UPLOAD:
    25653013                yahoo_process_picture_upload(yid, pkt);
    2566                 break;
    2567         case YAHOO_SERVICE_Y8_LIST:     /* Buddy List */
     3014                break; 
     3015        case YAHOO_SERVICE_YMSG15_BUDDY_LIST:   /* Buddy List */
    25683016                yahoo_process_buddy_list(yid, pkt);
    2569                 break;
    25703017        default:
    25713018                WARNING(("unknown service 0x%02x", pkt->service));
     
    25753022}
    25763023
    2577 static struct yahoo_packet *yahoo_getdata(struct yahoo_input_data *yid)
     3024static struct yahoo_packet * yahoo_getdata(struct yahoo_input_data * yid)
    25783025{
    25793026        struct yahoo_packet *pkt;
     
    25823029        int pktlen;
    25833030
    2584         if (!yd)
     3031        if(!yd)
    25853032                return NULL;
    25863033
     
    25913038        }
    25923039
    2593         pos += 4;               /* YMSG */
     3040        pos += 4; /* YMSG */
    25943041        pos += 2;
    25953042        pos += 2;
    25963043
    2597         pktlen = yahoo_get16(yid->rxqueue + pos);
    2598         pos += 2;
    2599         DEBUG_MSG(("%d bytes to read, rxlen is %d", pktlen, yid->rxlen));
     3044        pktlen = yahoo_get16(yid->rxqueue + pos); pos += 2;
     3045        DEBUG_MSG(("%d bytes to read, rxlen is %d",
     3046                        pktlen, yid->rxlen));
    26003047
    26013048        if (yid->rxlen < (YAHOO_PACKET_HDRLEN + pktlen)) {
     
    26093056        pkt = yahoo_packet_new(0, 0, 0);
    26103057
    2611         pkt->service = yahoo_get16(yid->rxqueue + pos);
    2612         pos += 2;
    2613         pkt->status = yahoo_get32(yid->rxqueue + pos);
    2614         pos += 4;
     3058        pkt->service = yahoo_get16(yid->rxqueue + pos); pos += 2;
     3059        pkt->status = yahoo_get32(yid->rxqueue + pos); pos += 4;
    26153060        DEBUG_MSG(("Yahoo Service: 0x%02x Status: %d", pkt->service,
    2616                         pkt->status));
    2617         pkt->id = yahoo_get32(yid->rxqueue + pos);
    2618         pos += 4;
     3061                                pkt->status));
     3062        pkt->id = yahoo_get32(yid->rxqueue + pos); pos += 4;
    26193063
    26203064        yd->session_id = pkt->id;
     
    26243068        yid->rxlen -= YAHOO_PACKET_HDRLEN + pktlen;
    26253069        DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
    2626         if (yid->rxlen > 0) {
    2627                 unsigned char *tmp = y_memdup(yid->rxqueue + YAHOO_PACKET_HDRLEN
    2628                         + pktlen, yid->rxlen);
     3070        if (yid->rxlen>0) {
     3071                unsigned char *tmp = y_memdup(yid->rxqueue + YAHOO_PACKET_HDRLEN 
     3072                                + pktlen, yid->rxlen);
    26293073                FREE(yid->rxqueue);
    26303074                yid->rxqueue = tmp;
    2631                 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen,
    2632                                 yid->rxqueue));
     3075                DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
    26333076        } else {
    26343077                DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue));
     
    26393082}
    26403083
    2641 static struct yab *yahoo_yab_read(unsigned char *d, int len)
     3084static void yahoo_yab_read(struct yab *yab, unsigned char *d, int len)
    26423085{
    26433086        char *st, *en;
    26443087        char *data = (char *)d;
     3088        data[len]='\0';
     3089
     3090        DEBUG_MSG(("Got yab: %s", data));
     3091        st = en = strstr(data, "userid=\"");
     3092        if(st) {
     3093                st += strlen("userid=\"");
     3094                en = strchr(st, '"'); *en++ = '\0';
     3095                yab->id = yahoo_xmldecode(st);
     3096        }
     3097
     3098        st = strstr(en, "fname=\"");
     3099        if(st) {
     3100                st += strlen("fname=\"");
     3101                en = strchr(st, '"'); *en++ = '\0';
     3102                yab->fname = yahoo_xmldecode(st);
     3103        }
     3104
     3105        st = strstr(en, "lname=\"");
     3106        if(st) {
     3107                st += strlen("lname=\"");
     3108                en = strchr(st, '"'); *en++ = '\0';
     3109                yab->lname = yahoo_xmldecode(st);
     3110        }
     3111
     3112        st = strstr(en, "nname=\"");
     3113        if(st) {
     3114                st += strlen("nname=\"");
     3115                en = strchr(st, '"'); *en++ = '\0';
     3116                yab->nname = yahoo_xmldecode(st);
     3117        }
     3118
     3119        st = strstr(en, "email=\"");
     3120        if(st) {
     3121                st += strlen("email=\"");
     3122                en = strchr(st, '"'); *en++ = '\0';
     3123                yab->email = yahoo_xmldecode(st);
     3124        }
     3125
     3126        st = strstr(en, "hphone=\"");
     3127        if(st) {
     3128                st += strlen("hphone=\"");
     3129                en = strchr(st, '"'); *en++ = '\0';
     3130                yab->hphone = yahoo_xmldecode(st);
     3131        }
     3132
     3133        st = strstr(en, "wphone=\"");
     3134        if(st) {
     3135                st += strlen("wphone=\"");
     3136                en = strchr(st, '"'); *en++ = '\0';
     3137                yab->wphone = yahoo_xmldecode(st);
     3138        }
     3139
     3140        st = strstr(en, "mphone=\"");
     3141        if(st) {
     3142                st += strlen("mphone=\"");
     3143                en = strchr(st, '"'); *en++ = '\0';
     3144                yab->mphone = yahoo_xmldecode(st);
     3145        }
     3146
     3147        st = strstr(en, "dbid=\"");
     3148        if(st) {
     3149                st += strlen("dbid=\"");
     3150                en = strchr(st, '"'); *en++ = '\0';
     3151                yab->dbid = atoi(st);
     3152        }
     3153}
     3154
     3155static struct yab * yahoo_getyab(struct yahoo_input_data *yid)
     3156{
    26453157        struct yab *yab = NULL;
    2646 
    2647         data[len] = '\0';
    2648 
    2649         DEBUG_MSG(("Got yab: %s", data));
    2650         st = en = strstr(data, "e0=\"");
    2651         if (st) {
    2652                 yab = y_new0(struct yab, 1);
    2653 
    2654                 st += strlen("e0=\"");
    2655                 en = strchr(st, '"');
    2656                 *en++ = '\0';
    2657                 yab->email = yahoo_xmldecode(st);
    2658         }
    2659 
    2660         if (!en)
     3158        int pos = 0, end=0;
     3159        struct yahoo_data *yd = yid->yd;
     3160
     3161        if(!yd)
    26613162                return NULL;
    26623163
    2663         st = strstr(en, "id=\"");
    2664         if (st) {
    2665                 st += strlen("id=\"");
    2666                 en = strchr(st, '"');
    2667                 *en++ = '\0';
    2668                 yab->yid = atoi(yahoo_xmldecode(st));
    2669         }
    2670 
    2671         st = strstr(en, "fn=\"");
    2672         if (st) {
    2673                 st += strlen("fn=\"");
    2674                 en = strchr(st, '"');
    2675                 *en++ = '\0';
    2676                 yab->fname = yahoo_xmldecode(st);
    2677         }
    2678 
    2679         st = strstr(en, "ln=\"");
    2680         if (st) {
    2681                 st += strlen("ln=\"");
    2682                 en = strchr(st, '"');
    2683                 *en++ = '\0';
    2684                 yab->lname = yahoo_xmldecode(st);
    2685         }
    2686 
    2687         st = strstr(en, "nn=\"");
    2688         if (st) {
    2689                 st += strlen("nn=\"");
    2690                 en = strchr(st, '"');
    2691                 *en++ = '\0';
    2692                 yab->nname = yahoo_xmldecode(st);
    2693         }
    2694 
    2695         st = strstr(en, "yi=\"");
    2696         if (st) {
    2697                 st += strlen("yi=\"");
    2698                 en = strchr(st, '"');
    2699                 *en++ = '\0';
    2700                 yab->id = yahoo_xmldecode(st);
    2701         }
    2702 
    2703         st = strstr(en, "hphone=\"");
    2704         if (st) {
    2705                 st += strlen("hphone=\"");
    2706                 en = strchr(st, '"');
    2707                 *en++ = '\0';
    2708                 yab->hphone = yahoo_xmldecode(st);
    2709         }
    2710 
    2711         st = strstr(en, "wphone=\"");
    2712         if (st) {
    2713                 st += strlen("wphone=\"");
    2714                 en = strchr(st, '"');
    2715                 *en++ = '\0';
    2716                 yab->wphone = yahoo_xmldecode(st);
    2717         }
    2718 
    2719         st = strstr(en, "mphone=\"");
    2720         if (st) {
    2721                 st += strlen("mphone=\"");
    2722                 en = strchr(st, '"');
    2723                 *en++ = '\0';
    2724                 yab->mphone = yahoo_xmldecode(st);
    2725         }
    2726 
    2727         st = strstr(en, "dbid=\"");
    2728         if (st) {
    2729                 st += strlen("dbid=\"");
    2730                 en = strchr(st, '"');
    2731                 *en++ = '\0';
    2732                 yab->dbid = atoi(st);
    2733         }
     3164        DEBUG_MSG(("rxlen is %d", yid->rxlen));
     3165
     3166        if(yid->rxlen <= strlen("<record"))
     3167                return NULL;
     3168
     3169        /* start with <record */
     3170        while(pos < yid->rxlen-strlen("<record")+1
     3171                        && memcmp(yid->rxqueue + pos, "<record", strlen("<record")))
     3172                pos++;
     3173
     3174        if(pos >= yid->rxlen-1)
     3175                return NULL;
     3176
     3177        end = pos+2;
     3178        /* end with /> */
     3179        while(end < yid->rxlen-strlen("/>")+1 && memcmp(yid->rxqueue + end, "/>", strlen("/>")))
     3180                end++;
     3181
     3182        if(end >= yid->rxlen-1)
     3183                return NULL;
     3184
     3185        yab = y_new0(struct yab, 1);
     3186        yahoo_yab_read(yab, yid->rxqueue + pos, end+2-pos);
     3187       
     3188
     3189        yid->rxlen -= end+1;
     3190        DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
     3191        if (yid->rxlen>0) {
     3192                unsigned char *tmp = y_memdup(yid->rxqueue + end + 1, yid->rxlen);
     3193                FREE(yid->rxqueue);
     3194                yid->rxqueue = tmp;
     3195                DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
     3196        } else {
     3197                DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue));
     3198                FREE(yid->rxqueue);
     3199        }
     3200
    27343201
    27353202        return yab;
    27363203}
    27373204
    2738 static struct yab *yahoo_getyab(struct yahoo_input_data *yid)
    2739 {
    2740         struct yab *yab = NULL;
    2741         int pos = 0, end = 0;
     3205static char * yahoo_getwebcam_master(struct yahoo_input_data *yid)
     3206{
     3207        unsigned int pos=0;
     3208        unsigned int len=0;
     3209        unsigned int status=0;
     3210        char *server=NULL;
    27423211        struct yahoo_data *yd = yid->yd;
    27433212
    2744         if (!yd)
    2745                 return NULL;
    2746 
    2747         do {
    2748                 DEBUG_MSG(("rxlen is %d", yid->rxlen));
    2749 
    2750                 if (yid->rxlen <= strlen("<ct"))
    2751                         return NULL;
    2752 
    2753                 /* start with <ct */
    2754                 while (pos < yid->rxlen - strlen("<ct") + 1
    2755                         && memcmp(yid->rxqueue + pos, "<ct", strlen("<ct")))
    2756                         pos++;
    2757 
    2758                 if (pos >= yid->rxlen - 1)
    2759                         return NULL;
    2760 
    2761                 end = pos + 2;
    2762                 /* end with > */
    2763                 while (end < yid->rxlen - strlen(">")
    2764                         && memcmp(yid->rxqueue + end, ">", strlen(">")))
    2765                         end++;
    2766 
    2767                 if (end >= yid->rxlen - 1)
    2768                         return NULL;
    2769 
    2770                 yab = yahoo_yab_read(yid->rxqueue + pos, end + 2 - pos);
    2771 
    2772                 yid->rxlen -= end + 1;
    2773                 DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen,
    2774                                 yid->rxqueue));
    2775                 if (yid->rxlen > 0) {
    2776                         unsigned char *tmp =
    2777                                 y_memdup(yid->rxqueue + end + 1, yid->rxlen);
    2778                         FREE(yid->rxqueue);
    2779                         yid->rxqueue = tmp;
    2780                         DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen,
    2781                                         yid->rxqueue));
    2782                 } else {
    2783                         DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue));
    2784                         FREE(yid->rxqueue);
    2785                 }
    2786 
    2787         } while (!yab && end < yid->rxlen - 1);
    2788 
    2789         return yab;
    2790 }
    2791 
    2792 static char *yahoo_getwebcam_master(struct yahoo_input_data *yid)
    2793 {
    2794         unsigned int pos = 0;
    2795         unsigned int len = 0;
    2796         unsigned int status = 0;
    2797         char *server = NULL;
    2798         struct yahoo_data *yd = yid->yd;
    2799 
    2800         if (!yid || !yd)
     3213        if(!yid || !yd)
    28013214                return NULL;
    28023215
     
    28103223        status = yid->rxqueue[pos++];
    28113224
    2812         if (status == 0) {
    2813                 pos += 2;       /* skip next 2 bytes */
    2814                 server = y_memdup(yid->rxqueue + pos, 16);
     3225        if (status == 0)
     3226        {
     3227                pos += 2; /* skip next 2 bytes */
     3228                server =  y_memdup(yid->rxqueue+pos, 16);
    28153229                pos += 16;
    2816         } else if (status == 6) {
     3230        }
     3231        else if (status == 6)
     3232        {
    28173233                YAHOO_CALLBACK(ext_yahoo_webcam_closed)
    28183234                        (yd->client_id, yid->wcm->user, 4);
     
    28233239        yid->rxlen -= len;
    28243240        DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
    2825         if (yid->rxlen > 0) {
     3241        if (yid->rxlen>0) {
    28263242                unsigned char *tmp = y_memdup(yid->rxqueue + pos, yid->rxlen);
    28273243                FREE(yid->rxqueue);
    28283244                yid->rxqueue = tmp;
    2829                 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen,
    2830                                 yid->rxqueue));
     3245                DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
    28313246        } else {
    28323247                DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue));
     
    28393254static int yahoo_get_webcam_data(struct yahoo_input_data *yid)
    28403255{
    2841         unsigned char reason = 0;
    2842         unsigned int pos = 0;
    2843         unsigned int begin = 0;
    2844         unsigned int end = 0;
    2845         unsigned int closed = 0;
    2846         unsigned char header_len = 0;
     3256        unsigned char reason=0;
     3257        unsigned int pos=0;
     3258        unsigned int begin=0;
     3259        unsigned int end=0;
     3260        unsigned int closed=0;
     3261        unsigned char header_len=0;
    28473262        char *who;
    2848         int connect = 0;
     3263        int connect=0;
    28493264        struct yahoo_data *yd = yid->yd;
    28503265
    2851         if (!yd)
     3266        if(!yd)
    28523267                return -1;
    28533268
    2854         if (!yid->wcm || !yid->wcd || !yid->rxlen)
     3269        if(!yid->wcm || !yid->wcd || !yid->rxlen)
    28553270                return -1;
    28563271
     
    28583273
    28593274        /* if we are not reading part of image then read header */
    2860         if (!yid->wcd->to_read) {
    2861                 header_len = yid->rxqueue[pos++];
    2862                 yid->wcd->packet_type = 0;
     3275        if (!yid->wcd->to_read)
     3276        {
     3277                header_len=yid->rxqueue[pos++];
     3278                yid->wcd->packet_type=0;
    28633279
    28643280                if (yid->rxlen < header_len)
    28653281                        return 0;
    28663282
    2867                 if (header_len >= 8) {
     3283                if (header_len >= 8)
     3284                {
    28683285                        reason = yid->rxqueue[pos++];
    28693286                        /* next 2 bytes should always be 05 00 */
     
    28733290                        yid->wcd->to_read = yid->wcd->data_size;
    28743291                }
    2875                 if (header_len >= 13) {
     3292                if (header_len >= 13)
     3293                {
    28763294                        yid->wcd->packet_type = yid->rxqueue[pos++];
    28773295                        yid->wcd->timestamp = yahoo_get32(yid->rxqueue + pos);
     
    28853303        begin = pos;
    28863304        pos += yid->wcd->to_read;
    2887         if (pos > yid->rxlen)
    2888                 pos = yid->rxlen;
     3305        if (pos > yid->rxlen) pos = yid->rxlen;
    28893306
    28903307        /* if it is not an image then make sure we have the whole packet */
     
    28993316
    29003317        DEBUG_MSG(("packet type %.2X, data length %d", yid->wcd->packet_type,
    2901                         yid->wcd->data_size));
     3318                yid->wcd->data_size));
    29023319
    29033320        /* find out what kind of packet we got */
    2904         switch (yid->wcd->packet_type) {
    2905         case 0x00:
    2906                 /* user requests to view webcam (uploading) */
    2907                 if (yid->wcd->data_size &&
    2908                         yid->wcm->direction == YAHOO_WEBCAM_UPLOAD) {
    2909                         end = begin;
    2910                         while (end <= yid->rxlen && yid->rxqueue[end++] != 13) ;
    2911                         if (end > begin) {
    2912                                 who = y_memdup(yid->rxqueue + begin,
    2913                                         end - begin);
    2914                                 who[end - begin - 1] = 0;
    2915                                 YAHOO_CALLBACK(ext_yahoo_webcam_viewer) (yd->
    2916                                         client_id, who + 2, 2);
     3321        switch (yid->wcd->packet_type)
     3322        {
     3323                case 0x00:
     3324                        /* user requests to view webcam (uploading) */
     3325                        if (yid->wcd->data_size &&
     3326                                yid->wcm->direction == YAHOO_WEBCAM_UPLOAD) {
     3327                                end = begin;
     3328                                while (end <= yid->rxlen &&
     3329                                        yid->rxqueue[end++] != 13);
     3330                                if (end > begin)
     3331                                {
     3332                                        who = y_memdup(yid->rxqueue + begin, end - begin);
     3333                                        who[end - begin - 1] = 0;
     3334                                        YAHOO_CALLBACK(ext_yahoo_webcam_viewer)(yd->client_id, who + 2, 2);
     3335                                        FREE(who);
     3336                                }
     3337                        }
     3338
     3339                        if (yid->wcm->direction == YAHOO_WEBCAM_DOWNLOAD) {
     3340                                /* timestamp/status field */
     3341                                /* 0 = declined viewing permission */
     3342                                /* 1 = accepted viewing permission */
     3343                                if (yid->wcd->timestamp == 0) {
     3344                                        YAHOO_CALLBACK(ext_yahoo_webcam_closed)(yd->client_id, yid->wcm->user, 3);
     3345                                }
     3346                        }
     3347                        break;
     3348                case 0x01: /* status packets?? */
     3349                        /* timestamp contains status info */
     3350                        /* 00 00 00 01 = we have data?? */
     3351                        break;
     3352                case 0x02: /* image data */
     3353                        YAHOO_CALLBACK(ext_yahoo_got_webcam_image)(yd->client_id,
     3354                                        yid->wcm->user, yid->rxqueue + begin,
     3355                                        yid->wcd->data_size, pos - begin,
     3356                                        yid->wcd->timestamp);
     3357                        break;
     3358                case 0x05: /* response packets when uploading */
     3359                        if (!yid->wcd->data_size) {
     3360                                YAHOO_CALLBACK(ext_yahoo_webcam_data_request)(yd->client_id, yid->wcd->timestamp);
     3361                        }
     3362                        break;
     3363                case 0x07: /* connection is closing */
     3364                        switch(reason)
     3365                        {
     3366                                case 0x01: /* user closed connection */
     3367                                        closed = 1;
     3368                                        break;
     3369                                case 0x0F: /* user cancelled permission */
     3370                                        closed = 2;
     3371                                        break;
     3372                        }
     3373                        YAHOO_CALLBACK(ext_yahoo_webcam_closed)(yd->client_id, yid->wcm->user, closed);
     3374                        break;
     3375                case 0x0C: /* user connected */
     3376                case 0x0D: /* user disconnected */
     3377                        if (yid->wcd->data_size) {
     3378                                who = y_memdup(yid->rxqueue + begin, pos - begin + 1);
     3379                                who[pos - begin] = 0;
     3380                                if (yid->wcd->packet_type == 0x0C)
     3381                                        connect=1;
     3382                                else
     3383                                        connect=0;
     3384                                YAHOO_CALLBACK(ext_yahoo_webcam_viewer)(yd->client_id, who, connect);
    29173385                                FREE(who);
    29183386                        }
    2919                 }
    2920 
    2921                 if (yid->wcm->direction == YAHOO_WEBCAM_DOWNLOAD) {
    2922                         /* timestamp/status field */
    2923                         /* 0 = declined viewing permission */
    2924                         /* 1 = accepted viewing permission */
    2925                         if (yid->wcd->timestamp == 0) {
    2926                                 YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd->
    2927                                         client_id, yid->wcm->user, 3);
    2928                         }
    2929                 }
    2930                 break;
    2931         case 0x01:              /* status packets?? */
    2932                 /* timestamp contains status info */
    2933                 /* 00 00 00 01 = we have data?? */
    2934                 break;
    2935         case 0x02:              /* image data */
    2936                 YAHOO_CALLBACK(ext_yahoo_got_webcam_image) (yd->client_id,
    2937                         yid->wcm->user, yid->rxqueue + begin,
    2938                         yid->wcd->data_size, pos - begin, yid->wcd->timestamp);
    2939                 break;
    2940         case 0x05:              /* response packets when uploading */
    2941                 if (!yid->wcd->data_size) {
    2942                         YAHOO_CALLBACK(ext_yahoo_webcam_data_request) (yd->
    2943                                 client_id, yid->wcd->timestamp);
    2944                 }
    2945                 break;
    2946         case 0x07:              /* connection is closing */
    2947                 switch (reason) {
    2948                 case 0x01:      /* user closed connection */
    2949                         closed = 1;
    2950                         break;
    2951                 case 0x0F:      /* user cancelled permission */
    2952                         closed = 2;
    2953                         break;
    2954                 }
    2955                 YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd->client_id,
    2956                         yid->wcm->user, closed);
    2957                 break;
    2958         case 0x0C:              /* user connected */
    2959         case 0x0D:              /* user disconnected */
    2960                 if (yid->wcd->data_size) {
    2961                         who = y_memdup(yid->rxqueue + begin, pos - begin + 1);
    2962                         who[pos - begin] = 0;
    2963                         if (yid->wcd->packet_type == 0x0C)
    2964                                 connect = 1;
    2965                         else
    2966                                 connect = 0;
    2967                         YAHOO_CALLBACK(ext_yahoo_webcam_viewer) (yd->client_id,
    2968                                 who, connect);
    2969                         FREE(who);
    2970                 }
    2971                 break;
    2972         case 0x13:              /* user data */
    2973                 /* i=user_ip (ip of the user we are viewing) */
    2974                 /* j=user_ext_ip (external ip of the user we */
    2975                 /*                are viewing) */
    2976                 break;
    2977         case 0x17:              /* ?? */
    2978                 break;
     3387                        break;
     3388                case 0x13: /* user data */
     3389                        /* i=user_ip (ip of the user we are viewing) */
     3390                        /* j=user_ext_ip (external ip of the user we */
     3391                        /*                are viewing) */
     3392                        break;
     3393                case 0x17: /* ?? */
     3394                        break;
    29793395        }
    29803396        yid->wcd->to_read -= pos - begin;
     
    29823398        yid->rxlen -= pos;
    29833399        DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
    2984         if (yid->rxlen > 0) {
     3400        if (yid->rxlen>0) {
    29853401                unsigned char *tmp = y_memdup(yid->rxqueue + pos, yid->rxlen);
    29863402                FREE(yid->rxqueue);
    29873403                yid->rxqueue = tmp;
    2988                 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen,
    2989                                 yid->rxqueue));
     3404                DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
    29903405        } else {
    29913406                DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue));
     
    30003415}
    30013416
    3002 int yahoo_write_ready(int id, void *fd, void *data)
     3417int yahoo_write_ready(int id, int fd, void *data)
    30033418{
    30043419        struct yahoo_input_data *yid = data;
     
    30063421        struct data_queue *tx;
    30073422
    3008         LOG(("write callback: id=%d fd=%p data=%p", id, fd, data));
    3009         if (!yid || !yid->txqueues)
     3423        LOG(("write callback: id=%d fd=%d data=%p", id, fd, data));
     3424        if(!yid || !yid->txqueues || !find_conn_by_id(id))
    30103425                return -2;
    3011 
     3426       
    30123427        tx = yid->txqueues->data;
    30133428        LOG(("writing %d bytes", tx->len));
    30143429        len = yahoo_send_data(fd, tx->queue, MIN(1024, tx->len));
    30153430
    3016         if (len == -1 && errno == EAGAIN)
     3431        if(len == -1 && errno == EAGAIN)
    30173432                return 1;
    30183433
    3019         if (len <= 0) {
     3434        if(len <= 0) {
    30203435                int e = errno;
    30213436                DEBUG_MSG(("len == %d (<= 0)", len));
    3022                 while (yid->txqueues) {
    3023                         YList *l = yid->txqueues;
     3437                while(yid->txqueues) {
     3438                        YList *l=yid->txqueues;
    30243439                        tx = l->data;
    30253440                        free(tx->queue);
    30263441                        free(tx);
    3027                         yid->txqueues =
    3028                                 y_list_remove_link(yid->txqueues,
    3029                                 yid->txqueues);
     3442                        yid->txqueues = y_list_remove_link(yid->txqueues, yid->txqueues);
    30303443                        y_list_free_1(l);
    30313444                }
    3032                 LOG(("yahoo_write_ready(%d, %p) len < 0", id, fd));
    3033                 YAHOO_CALLBACK(ext_yahoo_remove_handler) (id, yid->write_tag);
     3445                LOG(("yahoo_write_ready(%d, %d) len < 0", id, fd));
     3446                YAHOO_CALLBACK(ext_yahoo_remove_handler)(id, yid->write_tag);
    30343447                yid->write_tag = 0;
    3035                 errno = e;
     3448                errno=e;
    30363449                return 0;
    30373450        }
     
    30393452
    30403453        tx->len -= len;
    3041         if (tx->len > 0) {
     3454        if(tx->len > 0) {
    30423455                unsigned char *tmp = y_memdup(tx->queue + len, tx->len);
    30433456                FREE(tx->queue);
    30443457                tx->queue = tmp;
    30453458        } else {
    3046                 YList *l = yid->txqueues;
     3459                YList *l=yid->txqueues;
    30473460                free(tx->queue);
    30483461                free(tx);
    3049                 yid->txqueues =
    3050                         y_list_remove_link(yid->txqueues, yid->txqueues);
     3462                yid->txqueues = y_list_remove_link(yid->txqueues, yid->txqueues);
    30513463                y_list_free_1(l);
    30523464                /*
    3053                    if(!yid->txqueues)
    3054                    LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd));
    3055                  */
    3056                 if (!yid->txqueues) {
    3057                         LOG(("yahoo_write_ready(%d, %p) !txqueues", id, fd));
    3058                         YAHOO_CALLBACK(ext_yahoo_remove_handler) (id,
    3059                                 yid->write_tag);
     3465                if(!yid->txqueues)
     3466                        LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd));
     3467                */
     3468                if(!yid->txqueues) {
     3469                        LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd));
     3470                        YAHOO_CALLBACK(ext_yahoo_remove_handler)(id, yid->write_tag);
    30603471                        yid->write_tag = 0;
    30613472                }
     
    30653476}
    30663477
    3067 static void yahoo_process_pager_connection(struct yahoo_input_data *yid,
    3068         int over)
     3478static void yahoo_process_pager_connection(struct yahoo_input_data *yid, int over)
    30693479{
    30703480        struct yahoo_packet *pkt;
     
    30723482        int id = yd->client_id;
    30733483
    3074         if (over)
    3075                 return;
    3076 
    3077         while (find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER)
    3078                 && (pkt = yahoo_getdata(yid)) != NULL) {
     3484        if(over)
     3485                return;
     3486
     3487        while (find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER) 
     3488                        && (pkt = yahoo_getdata(yid)) != NULL) {
    30793489
    30803490                yahoo_packet_process(yid, pkt);
     
    30843494}
    30853495
    3086 static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid,
    3087         int over)
    3088 {
    3089         if (over)
    3090                 return;
    3091 
    3092         if (strstr((char *)yid->rxqueue + (yid->rxlen - 20), "</content>")) {
    3093                 YAHOO_CALLBACK(ext_yahoo_chat_cat_xml) (yid->yd->client_id,
    3094                         (char *)yid->rxqueue);
     3496static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over)
     3497{
     3498}
     3499
     3500static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid, int over)
     3501{
     3502        if(over)
     3503                return;
     3504
     3505        if (strstr((char*)yid->rxqueue+(yid->rxlen-20), "</content>")) {
     3506                YAHOO_CALLBACK(ext_yahoo_chat_cat_xml)(yid->yd->client_id, (char*)yid->rxqueue);
    30953507        }
    30963508}
     
    31013513        struct yab *yab;
    31023514        YList *buds;
    3103         int changed = 0;
     3515        int changed=0;
    31043516        int id = yd->client_id;
    3105         int yab_used = 0;
    3106 
    3107         LOG(("Got data for YAB"));
    3108 
    3109         if (over)
    3110                 return;
    3111 
    3112         while (find_input_by_id_and_type(id, YAHOO_CONNECTION_YAB)
    3113                 && (yab = yahoo_getyab(yid)) != NULL) {
    3114                 if (!yab->id)
     3517
     3518        if(over)
     3519                return;
     3520
     3521        while(find_input_by_id_and_type(id, YAHOO_CONNECTION_YAB)
     3522                        && (yab = yahoo_getyab(yid)) != NULL) {
     3523                if(!yab->id)
    31153524                        continue;
    3116 
    3117                 changed = 1;
    3118                 yab_used = 0;
    3119                 for (buds = yd->buddies; buds; buds = buds->next) {
    3120                         struct yahoo_buddy *bud = buds->data;
    3121                         if (!strcmp(bud->id, yab->id)) {
    3122                                 yab_used = 1;
     3525                changed=1;
     3526                for(buds = yd->buddies; buds; buds=buds->next) {
     3527                        struct yahoo_buddy * bud = buds->data;
     3528                        if(!strcmp(bud->id, yab->id)) {
    31233529                                bud->yab_entry = yab;
    3124                                 if (yab->nname) {
     3530                                if(yab->nname) {
    31253531                                        bud->real_name = strdup(yab->nname);
    3126                                 } else if (yab->fname && yab->lname) {
    3127                                         bud->real_name = y_new0(char,
    3128                                                 strlen(yab->fname) +
    3129                                                 strlen(yab->lname) + 2);
     3532                                } else if(yab->fname && yab->lname) {
     3533                                        bud->real_name = y_new0(char,
     3534                                                        strlen(yab->fname)+
     3535                                                        strlen(yab->lname)+2
     3536                                                        );
    31303537                                        sprintf(bud->real_name, "%s %s",
    3131                                                 yab->fname, yab->lname);
    3132                                 } else if (yab->fname) {
     3538                                                        yab->fname, yab->lname);
     3539                                } else if(yab->fname) {
    31333540                                        bud->real_name = strdup(yab->fname);
    31343541                                }
    3135                                 break;  /* for */
     3542                                break; /* for */
    31363543                        }
    31373544                }
    3138 
    3139                 if (!yab_used) {
    3140                         FREE(yab->fname);
    3141                         FREE(yab->lname);
    3142                         FREE(yab->nname);
    3143                         FREE(yab->id);
    3144                         FREE(yab->email);
    3145                         FREE(yab->hphone);
    3146                         FREE(yab->wphone);
    3147                         FREE(yab->mphone);
    3148                         FREE(yab);
    3149                 }
    3150 
    3151         }
    3152 
    3153         if (changed)
    3154                 YAHOO_CALLBACK(ext_yahoo_got_buddies) (yd->client_id,
    3155                         yd->buddies);
    3156 }
    3157 
    3158 static void yahoo_process_search_connection(struct yahoo_input_data *yid,
    3159         int over)
    3160 {
    3161         struct yahoo_found_contact *yct = NULL;
     3545        }
     3546
     3547        if(changed)
     3548                YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies);
     3549}
     3550
     3551static void yahoo_process_search_connection(struct yahoo_input_data *yid, int over)
     3552{
     3553        struct yahoo_found_contact *yct=NULL;
    31623554        char *p = (char *)yid->rxqueue, *np, *cp;
    31633555        int k, n;
    3164         int start = 0, found = 0, total = 0;
    3165         YList *contacts = NULL;
    3166         struct yahoo_input_data *pyid =
    3167                 find_input_by_id_and_type(yid->yd->client_id,
    3168                 YAHOO_CONNECTION_PAGER);
    3169 
    3170         if (!over || !pyid)
    3171                 return;
    3172 
    3173         if (p && (p = strstr(p, "\r\n\r\n"))) {
     3556        int start=0, found=0, total=0;
     3557        YList *contacts=NULL;
     3558        struct yahoo_input_data *pyid = find_input_by_id_and_type(yid->yd->client_id, YAHOO_CONNECTION_PAGER);
     3559
     3560        if(!over || !pyid)
     3561                return;
     3562
     3563        if(p && (p=strstr(p, "\r\n\r\n"))) {
    31743564                p += 4;
    31753565
    3176                 for (k = 0; (p = strchr(p, 4)) && (k < 4); k++) {
     3566                for(k = 0; (p = strchr(p, 4)) && (k < 4); k++) {
    31773567                        p++;
    31783568                        n = atoi(p);
    3179                         switch (k) {
    3180                         case 0:
    3181                                 found = pyid->ys->lsearch_nfound = n;
    3182                                 break;
    3183                         case 2:
    3184                                 start = pyid->ys->lsearch_nstart = n;
    3185                                 break;
    3186                         case 3:
    3187                                 total = pyid->ys->lsearch_ntotal = n;
    3188                                 break;
     3569                        switch(k) {
     3570                                case 0: found = pyid->ys->lsearch_nfound = n; break;
     3571                                case 2: start = pyid->ys->lsearch_nstart = n; break;
     3572                                case 3: total = pyid->ys->lsearch_ntotal = n; break;
    31893573                        }
    31903574                }
    31913575
    3192                 if (p)
     3576                if(p)
    31933577                        p++;
    31943578
    3195                 k = 0;
    3196                 while (p && *p) {
     3579                k=0;
     3580                while(p && *p) {
    31973581                        cp = p;
    31983582                        np = strchr(p, 4);
    31993583
    3200                         if (!np)
     3584                        if(!np)
    32013585                                break;
    32023586                        *np = 0;
    3203                         p = np + 1;
    3204 
    3205                         switch (k++) {
    3206                         case 1:
    3207                                 if (strlen(cp) > 2
    3208                                         && y_list_length(contacts) < total) {
    3209                                         yct = y_new0(struct yahoo_found_contact,
    3210                                                 1);
    3211                                         contacts = y_list_append(contacts, yct);
    3212                                         yct->id = cp + 2;
    3213                                 } else {
    3214                                         *p = 0;
    3215                                 }
    3216                                 break;
    3217                         case 2:
    3218                                 yct->online = !strcmp(cp, "2") ? 1 : 0;
    3219                                 break;
    3220                         case 3:
    3221                                 yct->gender = cp;
    3222                                 break;
    3223                         case 4:
    3224                                 yct->age = atoi(cp);
    3225                                 break;
    3226                         case 5:
    3227                                 /* not worth the context switch for strcmp */
    3228                                 if (cp[0] != '\005' || cp[1] != '\000')
    3229                                         yct->location = cp;
    3230                                 k = 0;
    3231                                 break;
     3587                        p = np+1;
     3588
     3589                        switch(k++) {
     3590                                case 1:
     3591                                        if(strlen(cp) > 2 && y_list_length(contacts) < total) {
     3592                                                yct = y_new0(struct yahoo_found_contact, 1);
     3593                                                contacts = y_list_append(contacts, yct);
     3594                                                yct->id = cp+2;
     3595                                        } else {
     3596                                                *p = 0;
     3597                                        }
     3598                                        break;
     3599                                case 2:
     3600                                        yct->online = !strcmp(cp, "2") ? 1 : 0;
     3601                                        break;
     3602                                case 3:
     3603                                        yct->gender = cp;
     3604                                        break;
     3605                                case 4:
     3606                                        yct->age = atoi(cp);
     3607                                        break;
     3608                                case 5:
     3609                                        if(strcmp(cp, "5") != 0)
     3610                                                yct->location = cp;
     3611                                        k = 0;
     3612                                        break;
    32323613                        }
    32333614                }
    32343615        }
    32353616
    3236         YAHOO_CALLBACK(ext_yahoo_got_search_result) (yid->yd->client_id, found,
    3237                 start, total, contacts);
    3238 
    3239         while (contacts) {
     3617        YAHOO_CALLBACK(ext_yahoo_got_search_result)(yid->yd->client_id, found, start, total, contacts);
     3618
     3619        while(contacts) {
    32403620                YList *node = contacts;
    32413621                contacts = y_list_remove_link(contacts, node);
     
    32453625}
    32463626
    3247 static void _yahoo_webcam_connected(void *fd, int error, void *d)
     3627static void _yahoo_webcam_connected(int fd, int error, void *d)
    32483628{
    32493629        struct yahoo_input_data *yid = d;
     
    32513631        struct yahoo_data *yd = yid->yd;
    32523632        char conn_type[100];
    3253         char *data = NULL;
    3254         char *packet = NULL;
    3255         unsigned char magic_nr[] = { 1, 0, 0, 0, 1 };
    3256         unsigned header_len = 0;
    3257         unsigned int len = 0;
    3258         unsigned int pos = 0;
    3259 
    3260         if (error || !fd) {
     3633        char *data=NULL;
     3634        char *packet=NULL;
     3635        unsigned char magic_nr[] = {1, 0, 0, 0, 1};
     3636        unsigned header_len=0;
     3637        unsigned int len=0;
     3638        unsigned int pos=0;
     3639
     3640        if(error || fd <= 0) {
    32613641                FREE(yid);
    32623642                return;
     
    32683648        LOG(("Connected"));
    32693649        /* send initial packet */
    3270         switch (wcm->direction) {
    3271         case YAHOO_WEBCAM_DOWNLOAD:
    3272                 data = strdup("<REQIMG>");
    3273                 break;
    3274         case YAHOO_WEBCAM_UPLOAD:
    3275                 data = strdup("<SNDIMG>");
    3276                 break;
    3277         default:
    3278                 return;
     3650        switch (wcm->direction)
     3651        {
     3652                case YAHOO_WEBCAM_DOWNLOAD:
     3653                        data = strdup("<REQIMG>");
     3654                        break;
     3655                case YAHOO_WEBCAM_UPLOAD:       
     3656                        data = strdup("<SNDIMG>");
     3657                        break;
     3658                default:
     3659                        return;
    32793660        }
    32803661        yahoo_add_to_send_queue(yid, data, strlen(data));
     
    32823663
    32833664        /* send data */
    3284         switch (wcm->direction) {
    3285         case YAHOO_WEBCAM_DOWNLOAD:
    3286                 header_len = 8;
    3287                 data = strdup("a=2\r\nc=us\r\ne=21\r\nu=");
    3288                 data = y_string_append(data, yd->user);
    3289                 data = y_string_append(data, "\r\nt=");
    3290                 data = y_string_append(data, wcm->key);
    3291                 data = y_string_append(data, "\r\ni=");
    3292                 data = y_string_append(data, wcm->my_ip);
    3293                 data = y_string_append(data, "\r\ng=");
    3294                 data = y_string_append(data, wcm->user);
    3295                 data = y_string_append(data, "\r\no=w-2-5-1\r\np=");
    3296                 snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type);
    3297                 data = y_string_append(data, conn_type);
    3298                 data = y_string_append(data, "\r\n");
    3299                 break;
    3300         case YAHOO_WEBCAM_UPLOAD:
    3301                 header_len = 13;
    3302                 data = strdup("a=2\r\nc=us\r\nu=");
    3303                 data = y_string_append(data, yd->user);
    3304                 data = y_string_append(data, "\r\nt=");
    3305                 data = y_string_append(data, wcm->key);
    3306                 data = y_string_append(data, "\r\ni=");
    3307                 data = y_string_append(data, wcm->my_ip);
    3308                 data = y_string_append(data, "\r\no=w-2-5-1\r\np=");
    3309                 snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type);
    3310                 data = y_string_append(data, conn_type);
    3311                 data = y_string_append(data, "\r\nb=");
    3312                 data = y_string_append(data, wcm->description);
    3313                 data = y_string_append(data, "\r\n");
    3314                 break;
     3665        switch (wcm->direction)
     3666        {
     3667                case YAHOO_WEBCAM_DOWNLOAD:
     3668                        header_len = 8;
     3669                        data = strdup("a=2\r\nc=us\r\ne=21\r\nu=");
     3670                        data = y_string_append(data, yd->user);
     3671                        data = y_string_append(data, "\r\nt=");
     3672                        data = y_string_append(data, wcm->key);
     3673                        data = y_string_append(data, "\r\ni=");
     3674                        data = y_string_append(data, wcm->my_ip);
     3675                        data = y_string_append(data, "\r\ng=");
     3676                        data = y_string_append(data, wcm->user);
     3677                        data = y_string_append(data, "\r\no=w-2-5-1\r\np=");
     3678                        snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type);
     3679                        data = y_string_append(data, conn_type);
     3680                        data = y_string_append(data, "\r\n");
     3681                        break;
     3682                case YAHOO_WEBCAM_UPLOAD:
     3683                        header_len = 13;
     3684                        data = strdup("a=2\r\nc=us\r\nu=");
     3685                        data = y_string_append(data, yd->user);
     3686                        data = y_string_append(data, "\r\nt=");
     3687                        data = y_string_append(data, wcm->key);
     3688                        data = y_string_append(data, "\r\ni=");
     3689                        data = y_string_append(data, wcm->my_ip);
     3690                        data = y_string_append(data, "\r\no=w-2-5-1\r\np=");
     3691                        snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type);
     3692                        data = y_string_append(data, conn_type);
     3693                        data = y_string_append(data, "\r\nb=");
     3694                        data = y_string_append(data, wcm->description);
     3695                        data = y_string_append(data, "\r\n");
     3696                        break;
    33153697        }
    33163698
     
    33193701        packet[pos++] = header_len;
    33203702        packet[pos++] = 0;
    3321         switch (wcm->direction) {
    3322         case YAHOO_WEBCAM_DOWNLOAD:
    3323                 packet[pos++] = 1;
    3324                 packet[pos++] = 0;
    3325                 break;
    3326         case YAHOO_WEBCAM_UPLOAD:
    3327                 packet[pos++] = 5;
    3328                 packet[pos++] = 0;
    3329                 break;
     3703        switch (wcm->direction)
     3704        {
     3705                case YAHOO_WEBCAM_DOWNLOAD:
     3706                        packet[pos++] = 1;
     3707                        packet[pos++] = 0;
     3708                        break;
     3709                case YAHOO_WEBCAM_UPLOAD:
     3710                        packet[pos++] = 5;
     3711                        packet[pos++] = 0;
     3712                        break;
    33303713        }
    33313714
    33323715        pos += yahoo_put32(packet + pos, len);
    3333         if (wcm->direction == YAHOO_WEBCAM_UPLOAD) {
     3716        if (wcm->direction == YAHOO_WEBCAM_UPLOAD)
     3717        {
    33343718                memcpy(packet + pos, magic_nr, sizeof(magic_nr));
    33353719                pos += sizeof(magic_nr);
     
    33403724        FREE(data);
    33413725
    3342         yid->read_tag =
    3343                 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id,
    3344                 yid->fd, YAHOO_INPUT_READ, yid);
     3726        yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_READ, yid);
    33453727}
    33463728
     
    33673749
    33683750        LOG(("Connecting to: %s:%d", wcm->server, wcm->port));
    3369         YAHOO_CALLBACK(ext_yahoo_connect_async) (y->yd->client_id, wcm->server,
    3370                 wcm->port, _yahoo_webcam_connected, yid, 0);
    3371 
    3372 }
    3373 
    3374 static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid,
    3375         int over)
    3376 {
    3377         char *server;
     3751        YAHOO_CALLBACK(ext_yahoo_connect_async)(y->yd->client_id, wcm->server, wcm->port,
     3752                        _yahoo_webcam_connected, yid);
     3753
     3754}
     3755
     3756static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid, int over)
     3757{
     3758        char* server;
    33783759        struct yahoo_server_settings *yss;
    33793760
    3380         if (over)
     3761        if(over)
    33813762                return;
    33823763
    33833764        server = yahoo_getwebcam_master(yid);
    33843765
    3385         if (server) {
     3766        if (server)
     3767        {
    33863768                yss = yid->yd->server_settings;
    33873769                yid->wcm->server = strdup(server);
     
    33963778}
    33973779
    3398 static void yahoo_process_webcam_connection(struct yahoo_input_data *yid,
    3399         int over)
     3780static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int over)
    34003781{
    34013782        int id = yid->yd->client_id;
    3402         void *fd = yid->fd;
    3403 
    3404         if (over)
     3783        int fd = yid->fd;
     3784
     3785        if(over)
    34053786                return;
    34063787
    34073788        /* as long as we still have packets available keep processing them */
    3408         while (find_input_by_id_and_fd(id, fd)
    3409                 && yahoo_get_webcam_data(yid) == 1) ;
    3410 }
    3411 
    3412 static void (*yahoo_process_connection[]) (struct yahoo_input_data *,
    3413         int over) = {
    3414 yahoo_process_pager_connection, yahoo_process_ft_connection,
    3415                 yahoo_process_yab_connection,
    3416                 yahoo_process_webcam_master_connection,
    3417                 yahoo_process_webcam_connection,
    3418                 yahoo_process_chatcat_connection,
    3419                 yahoo_process_search_connection};
    3420 
    3421 int yahoo_read_ready(int id, void *fd, void *data)
     3789        while (find_input_by_id_and_fd(id, fd)
     3790                        && yahoo_get_webcam_data(yid) == 1);
     3791}
     3792
     3793static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = {
     3794        yahoo_process_pager_connection,
     3795        yahoo_process_ft_connection,
     3796        yahoo_process_yab_connection,
     3797        yahoo_process_webcam_master_connection,
     3798        yahoo_process_webcam_connection,
     3799        yahoo_process_chatcat_connection,
     3800        yahoo_process_search_connection,
     3801};
     3802
     3803int yahoo_read_ready(int id, int fd, void *data)
    34223804{
    34233805        struct yahoo_input_data *yid = data;
     
    34253807        int len;
    34263808
    3427         LOG(("read callback: id=%d fd=%p data=%p", id, fd, data));
    3428         if (!yid)
     3809        LOG(("read callback: id=%d fd=%d data=%p", id, fd, data));
     3810        if(!yid)
    34293811                return -2;
    34303812
     3813       
    34313814        do {
    3432                 len = YAHOO_CALLBACK(ext_yahoo_read) (fd, buf, sizeof(buf));
    3433         } while (len == -1 && errno == EINTR);
    3434 
    3435         if (len == -1 && (errno == EAGAIN || errno == EINTR))   /* we'll try again later */
     3815                len = read(fd, buf, sizeof(buf));
     3816        } while(len == -1 && errno == EINTR);
     3817
     3818        if(len == -1 && (errno == EAGAIN||errno == EINTR))      /* we'll try again later */
    34363819                return 1;
    34373820
     
    34403823                DEBUG_MSG(("len == %d (<= 0)", len));
    34413824
    3442                 if (yid->type == YAHOO_CONNECTION_PAGER) {
    3443                         YAHOO_CALLBACK(ext_yahoo_login_response) (yid->yd->
    3444                                 client_id, YAHOO_LOGIN_SOCK, NULL);
    3445                 }
    3446 
    3447                 yahoo_process_connection[yid->type] (yid, 1);
     3825                if(yid->type == YAHOO_CONNECTION_PAGER) {
     3826                        YAHOO_CALLBACK(ext_yahoo_error)(yid->yd->client_id, "Connection closed by server", 1, E_CONNECTION);
     3827                }
     3828
     3829                yahoo_process_connection[yid->type](yid, 1);
    34483830                yahoo_input_close(yid);
    34493831
    34503832                /* no need to return an error, because we've already fixed it */
    3451                 if (len == 0)
     3833                if(len == 0)
    34523834                        return 1;
    34533835
    3454                 errno = e;
     3836                errno=e;
    34553837                LOG(("read error: %s", strerror(errno)));
    34563838                return -1;
    34573839        }
    34583840
    3459         yid->rxqueue =
    3460                 y_renew(unsigned char, yid->rxqueue, len + yid->rxlen + 1);
     3841        yid->rxqueue = y_renew(unsigned char, yid->rxqueue, len + yid->rxlen);
    34613842        memcpy(yid->rxqueue + yid->rxlen, buf, len);
    34623843        yid->rxlen += len;
    3463         yid->rxqueue[yid->rxlen] = 0;
    3464 
    3465         yahoo_process_connection[yid->type] (yid, 0);
     3844
     3845        yahoo_process_connection[yid->type](yid, 0);
    34663846
    34673847        return len;
     
    34753855        yd = y_new0(struct yahoo_data, 1);
    34763856
    3477         if (!yd)
     3857        if(!yd)
    34783858                return 0;
    34793859
     
    35003880}
    35013881
    3502 static void yahoo_connected(void *fd, int error, void *data)
     3882struct connect_callback_data {
     3883        struct yahoo_data *yd;
     3884        int tag;
     3885        int i;
     3886};
     3887
     3888static void yahoo_connected(int fd, int error, void *data)
    35033889{
    35043890        struct connect_callback_data *ccd = data;
     
    35083894        struct yahoo_server_settings *yss = yd->server_settings;
    35093895
    3510         if (error) {
    3511                 int tag;
    3512                 if (fallback_ports[ccd->i]) {
    3513                         char *host = yss->pager_host;
    3514 
    3515                         if (!host)
    3516                                 host = yss->pager_host_list[ccd->server_i];
    3517 
     3896        if(error) {
     3897                if(fallback_ports[ccd->i]) {
     3898                        int tag;
    35183899                        yss->pager_port = fallback_ports[ccd->i++];
    3519                         tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->
    3520                                 client_id, host, yss->pager_port,
    3521                                 yahoo_connected, ccd, 0);
    3522 
    3523                         if (tag > 0)
    3524                                 ccd->tag = tag;
    3525                 } else if (yss->pager_host_list
    3526                                 && yss->pager_host_list[ccd->server_i]) {
    3527 
    3528                         /* Get back to the default port */
    3529                         yss->pager_port = pager_port;
    3530                         ccd->server_i++;
    3531                         LOG(("Fallback: Connecting to %s:%d", yss->pager_host_list[ccd->server_i], yss->pager_port));
    3532 
    3533                         ccd->i = 0;
    3534                         tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->client_id,
    3535                                 yss->pager_host_list[ccd->server_i], yss->pager_port,
    3536                                 yahoo_connected, ccd, 0);
     3900                        tag = YAHOO_CALLBACK(ext_yahoo_connect_async)(yd->client_id, yss->pager_host,
     3901                                        yss->pager_port, yahoo_connected, ccd);
     3902
     3903                        if(tag > 0)
     3904                                ccd->tag=tag;
    35373905                } else {
    35383906                        FREE(ccd);
    3539                         YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id,
    3540                                 YAHOO_LOGIN_SOCK, NULL);
     3907                        YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_SOCK, NULL);
    35413908                }
    35423909                return;
     
    35453912        FREE(ccd);
    35463913
    3547         /* fd == NULL && error == 0 means connect was cancelled */
    3548         if (!fd)
    3549                 return;
    3550 
    3551         pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YPACKET_STATUS_DEFAULT,
    3552                 yd->session_id);
     3914        /* fd < 0 && error == 0 means connect was cancelled */
     3915        if(fd < 0)
     3916                return;
     3917
     3918        pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, yd->session_id);
    35533919        NOTICE(("Sending initial packet"));
    35543920
    35553921        yahoo_packet_hash(pkt, 1, yd->user);
    35563922
    3557         yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER);
     3923        yid = y_new0(struct yahoo_input_data, 1);
     3924        yid->yd = yd;
    35583925        yid->fd = fd;
     3926        inputs = y_list_prepend(inputs, yid);
    35593927
    35603928        yahoo_send_packet(yid, pkt, 0);
     
    35623930        yahoo_packet_free(pkt);
    35633931
    3564         yid->read_tag =
    3565                 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id,
    3566                 yid->fd, YAHOO_INPUT_READ, yid);
    3567 }
    3568 
    3569 void *yahoo_get_fd(int id)
    3570 {
    3571         struct yahoo_input_data *yid =
    3572                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    3573         if (!yid)
     3932        yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_READ, yid);
     3933}
     3934
     3935void yahoo_login(int id, int initial)
     3936{
     3937        struct yahoo_data *yd = find_conn_by_id(id);
     3938        struct connect_callback_data *ccd;
     3939        struct yahoo_server_settings *yss;
     3940        int tag;
     3941
     3942        if(!yd)
     3943                return;
     3944
     3945        yss = yd->server_settings;
     3946
     3947        yd->initial_status = initial;
     3948
     3949        ccd = y_new0(struct connect_callback_data, 1);
     3950        ccd->yd = yd;
     3951        tag = YAHOO_CALLBACK(ext_yahoo_connect_async)(yd->client_id, yss->pager_host, yss->pager_port,
     3952                        yahoo_connected, ccd);
     3953
     3954        /*
     3955         * if tag <= 0, then callback has already been called
     3956         * so ccd will have been freed
     3957         */
     3958        if(tag > 0)
     3959                ccd->tag = tag;
     3960        else if(tag < 0)
     3961                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_SOCK, NULL);
     3962}
     3963
     3964
     3965int yahoo_get_fd(int id)
     3966{
     3967        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     3968        if(!yid)
    35743969                return 0;
    35753970        else
     
    35773972}
    35783973
    3579 void yahoo_send_buzz(int id, const char *from, const char *who)
    3580 {
    3581         yahoo_send_im(id, from, who, "<ding>", 1, 0);
    3582 }
    3583 
    3584 void yahoo_send_im(int id, const char *from, const char *who, const char *what,
    3585         int utf8, int picture)
    3586 {
    3587         struct yahoo_input_data *yid =
    3588                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     3974void yahoo_send_im(int id, const char *from, const char *who, const char *what, int utf8, int picture)
     3975{
     3976        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    35893977        struct yahoo_packet *pkt = NULL;
    35903978        struct yahoo_data *yd;
    35913979        char pic_str[10];
    35923980
    3593         if (!yid)
     3981        if(!yid)
    35943982                return;
    35953983
    35963984        yd = yid->yd;
    35973985
    3598         pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE,
    3599                 yd->session_id);
     3986        pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, yd->session_id);
    36003987
    36013988        snprintf(pic_str, sizeof(pic_str), "%d", picture);
    3602 
    3603         if (from && strcmp(from, yd->user))
     3989       
     3990        if(from && strcmp(from, yd->user))
    36043991                yahoo_packet_hash(pkt, 0, yd->user);
    3605         yahoo_packet_hash(pkt, 1, from ? from : yd->user);
     3992        yahoo_packet_hash(pkt, 1, from?from:yd->user);
    36063993        yahoo_packet_hash(pkt, 5, who);
    36073994        yahoo_packet_hash(pkt, 14, what);
    36083995
    3609         if (utf8)
     3996        if(utf8)
    36103997                yahoo_packet_hash(pkt, 97, "1");
    36113998
     
    36144001        yahoo_packet_hash(pkt, 206, pic_str);
    36154002
     4003
    36164004        yahoo_send_packet(yid, pkt, 0);
    36174005
     
    36214009void yahoo_send_typing(int id, const char *from, const char *who, int typ)
    36224010{
    3623         struct yahoo_input_data *yid =
    3624                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4011        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    36254012        struct yahoo_data *yd;
    36264013        struct yahoo_packet *pkt = NULL;
    3627         if (!yid)
     4014        if(!yid)
    36284015                return;
    36294016
    36304017        yd = yid->yd;
    3631         pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YPACKET_STATUS_NOTIFY,
    3632                 yd->session_id);
     4018        pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yd->session_id);
    36334019
    36344020        yahoo_packet_hash(pkt, 5, who);
    3635         yahoo_packet_hash(pkt, 1, from ? from : yd->user);
     4021        yahoo_packet_hash(pkt, 1, from?from:yd->user);
    36364022        yahoo_packet_hash(pkt, 14, " ");
    36374023        yahoo_packet_hash(pkt, 13, typ ? "1" : "0");
     
    36454031void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away)
    36464032{
    3647         struct yahoo_input_data *yid =
    3648                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4033        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    36494034        struct yahoo_data *yd;
    36504035        struct yahoo_packet *pkt = NULL;
     
    36524037        char s[4];
    36534038
    3654         if (!yid)
     4039        if(!yid)
    36554040                return;
    36564041
    36574042        yd = yid->yd;
    3658 
    36594043        old_status = yd->current_status;
    36604044        yd->current_status = state;
     
    36624046        /* Thank you libpurple :) */
    36634047        if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
    3664                 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE,
    3665                         YAHOO_STATUS_AVAILABLE, 0);
     4048                pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0);
    36664049                yahoo_packet_hash(pkt, 13, "2");
    36674050                yahoo_send_packet(yid, pkt, 0);
     
    36714054        }
    36724055
    3673         pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE,
    3674                 yd->current_status, yd->session_id);
     4056        pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id);
    36754057        snprintf(s, sizeof(s), "%d", yd->current_status);
    36764058        yahoo_packet_hash(pkt, 10, s);
     
    36804062        yahoo_packet_free(pkt);
    36814063
    3682         if (old_status == YAHOO_STATUS_INVISIBLE) {
    3683                 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE,
    3684                         YAHOO_STATUS_AVAILABLE, 0);
     4064        if(old_status == YAHOO_STATUS_INVISIBLE) {
     4065                pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0);
    36854066                yahoo_packet_hash(pkt, 13, "1");
    36864067                yahoo_send_packet(yid, pkt, 0);
     
    36914072void yahoo_logoff(int id)
    36924073{
    3693         struct yahoo_input_data *yid =
    3694                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4074        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    36954075        struct yahoo_data *yd;
    36964076        struct yahoo_packet *pkt = NULL;
    36974077
    3698         if (!yid)
     4078        if(!yid)
    36994079                return;
    37004080        yd = yid->yd;
     
    37024082        LOG(("yahoo_logoff: current status: %d", yd->current_status));
    37034083
    3704         if (yd->current_status != -1 && 0) {
     4084        if(yd->current_status != -1 && 0) {
    37054085                /* Meh. Don't send this. The event handlers are not going to
    37064086                   get to do this so it'll just leak memory. And the TCP
    37074087                   connection reset will hopefully be clear enough. */
    3708                 pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF,
    3709                         YPACKET_STATUS_DEFAULT, yd->session_id);
     4088                pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id);
    37104089                yd->current_status = -1;
    37114090
     
    37164095        }
    37174096
    3718 /*      do {
     4097        do {
    37194098                yahoo_input_close(yid);
    3720         } while((yid = find_input_by_id(id)));*/
    3721 
     4099        } while((yid = find_input_by_id(id)));
    37224100}
    37234101
    37244102void yahoo_get_list(int id)
    37254103{
    3726         struct yahoo_input_data *yid =
    3727                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4104        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    37284105        struct yahoo_data *yd;
    37294106        struct yahoo_packet *pkt = NULL;
    37304107
    3731         if (!yid)
     4108        if(!yid)
    37324109                return;
    37334110        yd = yid->yd;
    37344111
    3735         pkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YPACKET_STATUS_DEFAULT,
    3736                 yd->session_id);
     4112        pkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_AVAILABLE, yd->session_id);
    37374113        yahoo_packet_hash(pkt, 1, yd->user);
    37384114        if (pkt) {
     
    37424118}
    37434119
    3744 static void _yahoo_http_connected(int id, void *fd, int error, void *data)
     4120static void _yahoo_http_connected(int id, int fd, int error, void *data)
    37454121{
    37464122        struct yahoo_input_data *yid = data;
    3747         if (fd == NULL || error) {
     4123        if(fd <= 0) {
    37484124                inputs = y_list_remove(inputs, yid);
    37494125                FREE(yid);
     
    37524128
    37534129        yid->fd = fd;
    3754         yid->read_tag =
    3755                 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd,
    3756                 YAHOO_INPUT_READ, yid);
    3757 }
    3758 
    3759 /* FIXME Get address book from address.yahoo.com instead */
     4130        yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, fd, YAHOO_INPUT_READ, yid);
     4131}
     4132
    37604133void yahoo_get_yab(int id)
    37614134{
    3762         struct yahoo_data *yd = find_conn_by_id(id);
    3763         struct yahoo_input_data *yid;
    3764         char url[1024];
    3765         char buff[2048];
    3766 
    3767         if (!yd)
    3768                 return;
    3769 
    3770         yid = y_new0(struct yahoo_input_data, 1);
    3771         yid->yd = yd;
    3772         yid->type = YAHOO_CONNECTION_YAB;
    3773 
    3774         LOG(("Sending request for Address Book"));
    3775 
    3776         snprintf(url, 1024,
    3777                 "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us"
    3778                 "&diffs=1&t=0&tags=short&rt=0&prog-ver=8.1.0.249&useutf8=1&legenc=codepage-1252");
    3779 
    3780         snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t);
    3781 
    3782         inputs = y_list_prepend(inputs, yid);
    3783 
    3784         yahoo_http_get(yid->yd->client_id, url, buff, 0, 0,
    3785                 _yahoo_http_connected, yid);
    3786 }
    3787 
    3788 struct yahoo_post_data {
    3789         struct yahoo_input_data *yid;
    3790         char *data;
    3791 };
    3792 
    3793 static void _yahoo_http_post_connected(int id, void *fd, int error, void *data)
    3794 {
    3795         struct yahoo_post_data *yad = data;
    3796         struct yahoo_input_data *yid = yad->yid;
    3797         char *buff = yad->data;
    3798 
    3799         if (!fd) {
    3800                 inputs = y_list_remove(inputs, yid);
    3801                 FREE(yid);
    3802                 return;
    3803         }
    3804 
    3805         YAHOO_CALLBACK(ext_yahoo_write) (fd, buff, strlen(buff));
    3806 
    3807         yid->fd = fd;
    3808         yid->read_tag =
    3809                 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd,
    3810                 YAHOO_INPUT_READ, yid);
    3811 
    3812         FREE(buff);
    3813         FREE(yad);
    3814 }
    3815 
    3816 /* FIXME This is also likely affected */
    3817 void yahoo_set_yab(int id, struct yab *yab)
    3818 {
    3819         struct yahoo_post_data *yad = y_new0(struct yahoo_post_data, 1);
    38204135        struct yahoo_data *yd = find_conn_by_id(id);
    38214136        struct yahoo_input_data *yid;
    38224137        char url[1024];
    38234138        char buff[1024];
    3824         char post[1024];
    3825         int size = 0;
    3826 
    3827         if (!yd)
     4139
     4140        if(!yd)
     4141                return;
     4142
     4143        yid = y_new0(struct yahoo_input_data, 1);
     4144        yid->yd = yd;
     4145        yid->type = YAHOO_CONNECTION_YAB;
     4146
     4147        snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?ab2=0");
     4148
     4149        snprintf(buff, sizeof(buff), "Y=%s; T=%s",
     4150                        yd->cookie_y, yd->cookie_t);
     4151
     4152        inputs = y_list_prepend(inputs, yid);
     4153
     4154        yahoo_http_get(yid->yd->client_id, url, buff,
     4155                        _yahoo_http_connected, yid);
     4156}
     4157
     4158void yahoo_set_yab(int id, struct yab * yab)
     4159{
     4160        struct yahoo_data *yd = find_conn_by_id(id);
     4161        struct yahoo_input_data *yid;
     4162        char url[1024];
     4163        char buff[1024];
     4164        char *temp;
     4165        int size = sizeof(url)-1;
     4166
     4167        if(!yd)
    38284168                return;
    38294169
     
    38324172        yid->yd = yd;
    38334173
    3834         if(yab->yid)
    3835                 size = snprintf(post, sizeof(post), "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
    3836                         "<ab k=\"%s\" cc=\"%d\">"
    3837                         "<ct id=\"%d\" e=\"1\" yi=\"%s\" nn=\"%s\" />"
    3838                         "</ab>", yd->user, 9, yab->yid, /* Don't know why */
    3839                         yab->id, yab->nname?yab->nname:"");
    3840         else
    3841                 size = snprintf(post, sizeof(post), "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
    3842                         "<ab k=\"%s\" cc=\"%d\">"
    3843                         "<ct a=\"1\" yi=\"%s\" nn=\"%s\" />"
    3844                         "</ab>", yd->user, 1,   /* Don't know why */
    3845                         yab->id, yab->nname?yab->nname:"");
    3846 
    3847         yad->yid = yid;
    3848         yad->data = strdup(post);
    3849 
    3850         strcpy(url, "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us"
    3851                 "&sync=1&tags=short&noclear=1&useutf8=1&legenc=codepage-1252");
    3852 
    3853         snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t);
     4174        strncpy(url, "http://insider.msg.yahoo.com/ycontent/?addab2=0", size);
     4175
     4176        if(yab->dbid) {
     4177                /* change existing yab */
     4178                char tmp[32];
     4179                strncat(url, "&ee=1&ow=1&id=", size - strlen(url));
     4180                snprintf(tmp, sizeof(tmp), "%d", yab->dbid);
     4181                strncat(url, tmp, size - strlen(url));
     4182        }
     4183
     4184        if(yab->fname) {
     4185                strncat(url, "&fn=", size - strlen(url));
     4186                temp = yahoo_urlencode(yab->fname);
     4187                strncat(url, temp, size - strlen(url));
     4188                free(temp);
     4189        }
     4190        if(yab->lname) {
     4191                strncat(url, "&ln=", size - strlen(url));
     4192                temp = yahoo_urlencode(yab->lname);
     4193                strncat(url, temp, size - strlen(url));
     4194                free(temp);
     4195        }
     4196        strncat(url, "&yid=", size - strlen(url));
     4197        temp = yahoo_urlencode(yab->id);
     4198        strncat(url, temp, size - strlen(url));
     4199        free(temp);
     4200        if(yab->nname) {
     4201                strncat(url, "&nn=", size - strlen(url));
     4202                temp = yahoo_urlencode(yab->nname);
     4203                strncat(url, temp, size - strlen(url));
     4204                free(temp);
     4205        }
     4206        if(yab->email) {
     4207                strncat(url, "&e=", size - strlen(url));
     4208                temp = yahoo_urlencode(yab->email);
     4209                strncat(url, temp, size - strlen(url));
     4210                free(temp);
     4211        }
     4212        if(yab->hphone) {
     4213                strncat(url, "&hp=", size - strlen(url));
     4214                temp = yahoo_urlencode(yab->hphone);
     4215                strncat(url, temp, size - strlen(url));
     4216                free(temp);
     4217        }
     4218        if(yab->wphone) {
     4219                strncat(url, "&wp=", size - strlen(url));
     4220                temp = yahoo_urlencode(yab->wphone);
     4221                strncat(url, temp, size - strlen(url));
     4222                free(temp);
     4223        }
     4224        if(yab->mphone) {
     4225                strncat(url, "&mp=", size - strlen(url));
     4226                temp = yahoo_urlencode(yab->mphone);
     4227                strncat(url, temp, size - strlen(url));
     4228                free(temp);
     4229        }
     4230        strncat(url, "&pp=0", size - strlen(url));
     4231
     4232        snprintf(buff, sizeof(buff), "Y=%s; T=%s",
     4233                        yd->cookie_y, yd->cookie_t);
    38544234
    38554235        inputs = y_list_prepend(inputs, yid);
    38564236
    3857         yahoo_http_post(yid->yd->client_id, url, buff, size,
    3858                 _yahoo_http_post_connected, yad);
    3859 }
    3860 
    3861 void yahoo_set_identity_status(int id, const char *identity, int active)
    3862 {
    3863         struct yahoo_input_data *yid =
    3864                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4237        yahoo_http_get(yid->yd->client_id, url, buff,
     4238                        _yahoo_http_connected, yid);
     4239}
     4240
     4241void yahoo_set_identity_status(int id, const char * identity, int active)
     4242{
     4243        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    38654244        struct yahoo_data *yd;
    38664245        struct yahoo_packet *pkt = NULL;
    38674246
    3868         if (!yid)
     4247        if(!yid)
    38694248                return;
    38704249        yd = yid->yd;
    38714250
    3872         pkt = yahoo_packet_new(active ? YAHOO_SERVICE_IDACT :
    3873                 YAHOO_SERVICE_IDDEACT, YPACKET_STATUS_DEFAULT, yd->session_id);
     4251        pkt = yahoo_packet_new(active?YAHOO_SERVICE_IDACT:YAHOO_SERVICE_IDDEACT,
     4252                        YAHOO_STATUS_AVAILABLE, yd->session_id);
    38744253        yahoo_packet_hash(pkt, 3, identity);
    38754254        if (pkt) {
     
    38814260void yahoo_refresh(int id)
    38824261{
    3883         struct yahoo_input_data *yid =
    3884                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4262        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    38854263        struct yahoo_data *yd;
    38864264        struct yahoo_packet *pkt = NULL;
    38874265
    3888         if (!yid)
     4266        if(!yid)
    38894267                return;
    38904268        yd = yid->yd;
    38914269
    3892         pkt = yahoo_packet_new(YAHOO_SERVICE_USERSTAT, YPACKET_STATUS_DEFAULT,
    3893                 yd->session_id);
     4270        pkt = yahoo_packet_new(YAHOO_SERVICE_USERSTAT, YAHOO_STATUS_AVAILABLE, yd->session_id);
    38944271        if (pkt) {
    38954272                yahoo_send_packet(yid, pkt, 0);
     
    39004277void yahoo_keepalive(int id)
    39014278{
    3902         struct yahoo_input_data *yid =
    3903                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4279        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4280        struct yahoo_data *yd;
     4281        struct yahoo_packet *pkt=NULL;
     4282        if(!yid)
     4283                return;
     4284        yd = yid->yd;
     4285
     4286        pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4287        yahoo_send_packet(yid, pkt, 0);
     4288        yahoo_packet_free(pkt);
     4289}
     4290
     4291void yahoo_chat_keepalive (int id)
     4292{
     4293        struct yahoo_input_data *yid = find_input_by_id_and_type (id, YAHOO_CONNECTION_PAGER);
    39044294        struct yahoo_data *yd;
    39054295        struct yahoo_packet *pkt = NULL;
     4296
    39064297        if (!yid)
    3907                 return;
     4298            return;
     4299
    39084300        yd = yid->yd;
    39094301
    3910         pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YPACKET_STATUS_DEFAULT,
    3911                 yd->session_id);
    3912         yahoo_send_packet(yid, pkt, 0);
    3913         yahoo_packet_free(pkt);
    3914 }
    3915 
    3916 void yahoo_chat_keepalive(int id)
    3917 {
    3918         struct yahoo_input_data *yid =
    3919                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    3920         struct yahoo_data *yd;
    3921         struct yahoo_packet *pkt = NULL;
    3922 
    3923         if (!yid)
    3924                 return;
    3925 
    3926         yd = yid->yd;
    3927 
    3928         pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YPACKET_STATUS_DEFAULT,
    3929                 yd->session_id);
    3930         yahoo_send_packet(yid, pkt, 0);
    3931         yahoo_packet_free(pkt);
    3932 }
    3933 
    3934 void yahoo_add_buddy(int id, const char *who, const char *group,
    3935         const char *msg)
    3936 {
    3937         struct yahoo_input_data *yid =
    3938                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4302        pkt = yahoo_packet_new (YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4303        yahoo_send_packet (yid, pkt, 0);
     4304        yahoo_packet_free (pkt);
     4305}
     4306
     4307void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg)
     4308{
     4309        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    39394310        struct yahoo_data *yd;
    39404311        struct yahoo_packet *pkt;
    39414312
    3942         if (!yid)
     4313        if(!yid)
    39434314                return;
    39444315        yd = yid->yd;
     
    39474318                return;
    39484319
    3949         pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT,
    3950                 yd->session_id);
    3951         if (msg != NULL)        /* add message/request "it's me add me" */
     4320        pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, yd->session_id);
     4321
     4322        if (msg != NULL) /* add message/request "it's me add me" */
    39524323                yahoo_packet_hash(pkt, 14, msg);
    39534324        else
    3954                 yahoo_packet_hash(pkt, 14, "");
     4325                yahoo_packet_hash(pkt,14,"");
     4326
    39554327        yahoo_packet_hash(pkt, 65, group);
    39564328        yahoo_packet_hash(pkt, 97, "1");
     
    39624334        yahoo_packet_hash(pkt, 301, "319");
    39634335        yahoo_packet_hash(pkt, 303, "319");
     4336
     4337
    39644338        yahoo_send_packet(yid, pkt, 0);
    39654339        yahoo_packet_free(pkt);
     
    39684342void yahoo_remove_buddy(int id, const char *who, const char *group)
    39694343{
    3970         struct yahoo_input_data *yid =
    3971                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4344        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    39724345        struct yahoo_data *yd;
    39734346        struct yahoo_packet *pkt = NULL;
    39744347
    3975         if (!yid)
     4348        if(!yid)
    39764349                return;
    39774350        yd = yid->yd;
    39784351
    3979         pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YPACKET_STATUS_DEFAULT,
    3980                 yd->session_id);
     4352        pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id);
    39814353
    39824354        yahoo_packet_hash(pkt, 1, yd->user);
     
    39874359}
    39884360
    3989 void yahoo_confirm_buddy(int id, const char *who, int reject, const char *msg)
    3990 {
    3991         struct yahoo_input_data *yid =
    3992                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4361void yahoo_accept_buddy_ymsg13(int id,const char* me,const char* who){
     4362        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4363        struct yahoo_data *yd;
     4364
     4365        if(!yid)
     4366                return;
     4367        yd = yid->yd;
     4368
     4369        struct yahoo_packet* pkt=NULL;
     4370        pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0);
     4371
     4372        yahoo_packet_hash(pkt,1,me ?: yd->user);       
     4373        yahoo_packet_hash(pkt,5,who);
     4374        yahoo_packet_hash(pkt,13,"1");
     4375        yahoo_packet_hash(pkt,334,"0");
     4376        yahoo_send_packet(yid, pkt, 0);
     4377        yahoo_packet_free(pkt);
     4378}
     4379
     4380void yahoo_reject_buddy_ymsg13(int id,const char* me,const char* who,const char* msg){
     4381        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4382        struct yahoo_data *yd;
     4383
     4384        if(!yid)
     4385                return;
     4386        yd = yid->yd;
     4387
     4388        struct yahoo_packet* pkt=NULL;
     4389        pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0);
     4390
     4391        yahoo_packet_hash(pkt,1,me ?: yd->user);       
     4392        yahoo_packet_hash(pkt,5,who);
     4393//      yahoo_packet_hash(pkt,241,YAHOO_PROTO_VER);
     4394        yahoo_packet_hash(pkt,13,"2");
     4395        yahoo_packet_hash(pkt,334,"0");
     4396        yahoo_packet_hash(pkt,97,"1");
     4397        yahoo_packet_hash(pkt,14,msg?:"");
     4398
     4399        yahoo_send_packet(yid, pkt, 0);
     4400        yahoo_packet_free(pkt);
     4401
     4402}
     4403
     4404void yahoo_reject_buddy(int id, const char *who, const char *msg)
     4405{
     4406        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    39934407        struct yahoo_data *yd;
    39944408        struct yahoo_packet *pkt;
    39954409
    3996         if (!yid)
     4410        if(!yid)
    39974411                return;
    39984412        yd = yid->yd;
     
    40014415                return;
    40024416
    4003         pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_AUTHORIZATION,
    4004                 YPACKET_STATUS_DEFAULT, yd->session_id);
     4417        pkt = yahoo_packet_new(YAHOO_SERVICE_REJECTCONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
    40054418        yahoo_packet_hash(pkt, 1, yd->user);
    4006         yahoo_packet_hash(pkt, 5, who);
    4007         if (reject)
    4008                 yahoo_packet_hash(pkt, 13, "2");
    4009         else {
    4010                 yahoo_packet_hash(pkt, 241, "0");
    4011                 yahoo_packet_hash(pkt, 13, "1");
    4012         }
    4013 
    4014         yahoo_packet_hash(pkt, 334, "0");
    4015 
    4016         if (reject) {
    4017                 yahoo_packet_hash(pkt, 14, msg ? msg : "");
    4018                 yahoo_packet_hash(pkt, 97, "1");
    4019         }
    4020 
     4419        yahoo_packet_hash(pkt, 7, who);
     4420        yahoo_packet_hash(pkt, 14, msg);
    40214421        yahoo_send_packet(yid, pkt, 0);
    40224422        yahoo_packet_free(pkt);
     
    40254425void yahoo_ignore_buddy(int id, const char *who, int unignore)
    40264426{
    4027         struct yahoo_input_data *yid =
    4028                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4427        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    40294428        struct yahoo_data *yd;
    40304429        struct yahoo_packet *pkt;
    40314430
    4032         if (!yid)
     4431        if(!yid)
    40334432                return;
    40344433        yd = yid->yd;
     
    40374436                return;
    40384437
    4039         pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT,
    4040                 YPACKET_STATUS_DEFAULT, yd->session_id);
     4438        pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
    40414439        yahoo_packet_hash(pkt, 1, yd->user);
    40424440        yahoo_packet_hash(pkt, 7, who);
    4043         yahoo_packet_hash(pkt, 13, unignore ? "2" : "1");
     4441        yahoo_packet_hash(pkt, 13, unignore?"2":"1");
    40444442        yahoo_send_packet(yid, pkt, 0);
    40454443        yahoo_packet_free(pkt);
     
    40484446void yahoo_stealth_buddy(int id, const char *who, int unstealth)
    40494447{
    4050         struct yahoo_input_data *yid =
    4051                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4448        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    40524449        struct yahoo_data *yd;
    40534450        struct yahoo_packet *pkt;
    40544451
    4055         if (!yid)
     4452        if(!yid)
    40564453                return;
    40574454        yd = yid->yd;
     
    40604457                return;
    40614458
    4062         pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM,
    4063                 YPACKET_STATUS_DEFAULT, yd->session_id);
     4459        pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id);
    40644460        yahoo_packet_hash(pkt, 1, yd->user);
    40654461        yahoo_packet_hash(pkt, 7, who);
    4066         yahoo_packet_hash(pkt, 31, unstealth ? "2" : "1");
     4462        yahoo_packet_hash(pkt, 31, unstealth?"2":"1");
    40674463        yahoo_packet_hash(pkt, 13, "2");
    40684464        yahoo_send_packet(yid, pkt, 0);
     
    40704466}
    40714467
    4072 void yahoo_change_buddy_group(int id, const char *who, const char *old_group,
    4073         const char *new_group)
    4074 {
    4075         struct yahoo_input_data *yid =
    4076                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4468void yahoo_change_buddy_group(int id, const char *who, const char *old_group, const char *new_group)
     4469{
     4470        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    40774471        struct yahoo_data *yd;
    40784472        struct yahoo_packet *pkt = NULL;
    40794473
    4080         if (!yid)
     4474        if(!yid)
    40814475                return;
    40824476        yd = yid->yd;
    40834477
    4084         pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_CHANGE_GROUP,
    4085                 YPACKET_STATUS_DEFAULT, yd->session_id);
     4478        pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id);
    40864479        yahoo_packet_hash(pkt, 1, yd->user);
    4087         yahoo_packet_hash(pkt, 302, "240");
    4088         yahoo_packet_hash(pkt, 300, "240");
    40894480        yahoo_packet_hash(pkt, 7, who);
    4090         yahoo_packet_hash(pkt, 224, old_group);
    4091         yahoo_packet_hash(pkt, 264, new_group);
    4092         yahoo_packet_hash(pkt, 301, "240");
    4093         yahoo_packet_hash(pkt, 303, "240");
     4481        yahoo_packet_hash(pkt, 65, new_group);
     4482        yahoo_packet_hash(pkt, 14, " ");
    40944483
    40954484        yahoo_send_packet(yid, pkt, 0);
    40964485        yahoo_packet_free(pkt);
     4486
     4487        pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4488        yahoo_packet_hash(pkt, 1, yd->user);
     4489        yahoo_packet_hash(pkt, 7, who);
     4490        yahoo_packet_hash(pkt, 65, old_group);
     4491        yahoo_send_packet(yid, pkt, 0);
     4492        yahoo_packet_free(pkt);
    40974493}
    40984494
    40994495void yahoo_group_rename(int id, const char *old_group, const char *new_group)
    41004496{
    4101         struct yahoo_input_data *yid =
    4102                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4497        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    41034498        struct yahoo_data *yd;
    41044499        struct yahoo_packet *pkt = NULL;
    41054500
    4106         if (!yid)
     4501        if(!yid)
    41074502                return;
    41084503        yd = yid->yd;
    41094504
    4110         pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME,
    4111                 YPACKET_STATUS_DEFAULT, yd->session_id);
     4505        pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, YAHOO_STATUS_AVAILABLE, yd->session_id);
    41124506        yahoo_packet_hash(pkt, 1, yd->user);
    41134507        yahoo_packet_hash(pkt, 65, old_group);
     
    41184512}
    41194513
    4120 void yahoo_conference_addinvite(int id, const char *from, const char *who,
    4121         const char *room, const YList *members, const char *msg)
    4122 {
    4123         struct yahoo_input_data *yid =
    4124                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4514void yahoo_conference_addinvite(int id, const char * from, const char *who, const char *room, const YList * members, const char *msg)
     4515{
     4516        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    41254517        struct yahoo_data *yd;
    41264518        struct yahoo_packet *pkt;
    4127 
    4128         if (!yid)
     4519               
     4520        if(!yid)
    41294521                return;
    41304522        yd = yid->yd;
    41314523
    4132         pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE,
    4133                 YPACKET_STATUS_DEFAULT, yd->session_id);
    4134 
    4135         yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
     4524        pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4525
     4526        yahoo_packet_hash(pkt, 1, (from?from:yd->user));
    41364527        yahoo_packet_hash(pkt, 51, who);
    41374528        yahoo_packet_hash(pkt, 57, room);
    41384529        yahoo_packet_hash(pkt, 58, msg);
    41394530        yahoo_packet_hash(pkt, 13, "0");
    4140         for (; members; members = members->next) {
     4531        for(; members; members = members->next) {
    41414532                yahoo_packet_hash(pkt, 52, (char *)members->data);
    41424533                yahoo_packet_hash(pkt, 53, (char *)members->data);
     
    41494540}
    41504541
    4151 void yahoo_conference_invite(int id, const char *from, YList *who,
    4152         const char *room, const char *msg)
    4153 {
    4154         struct yahoo_input_data *yid =
    4155                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4542void yahoo_conference_invite(int id, const char * from, YList *who, const char *room, const char *msg)
     4543{
     4544        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    41564545        struct yahoo_data *yd;
    41574546        struct yahoo_packet *pkt;
    4158 
    4159         if (!yid)
     4547               
     4548        if(!yid)
    41604549                return;
    41614550        yd = yid->yd;
    41624551
    4163         pkt = yahoo_packet_new(YAHOO_SERVICE_CONFINVITE, YPACKET_STATUS_DEFAULT,
    4164                 yd->session_id);
    4165 
    4166         yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
     4552        pkt = yahoo_packet_new(YAHOO_SERVICE_CONFINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4553
     4554        yahoo_packet_hash(pkt, 1, (from?from:yd->user));
    41674555        yahoo_packet_hash(pkt, 50, yd->user);
    4168         for (; who; who = who->next) {
     4556        for(; who; who = who->next) {
    41694557                yahoo_packet_hash(pkt, 52, (char *)who->data);
    41704558        }
     
    41784566}
    41794567
    4180 void yahoo_conference_logon(int id, const char *from, YList *who,
    4181         const char *room)
    4182 {
    4183         struct yahoo_input_data *yid =
    4184                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4568void yahoo_conference_logon(int id, const char *from, YList *who, const char *room)
     4569{
     4570        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    41854571        struct yahoo_data *yd;
    41864572        struct yahoo_packet *pkt;
    4187 
    4188         if (!yid)
     4573               
     4574        if(!yid)
    41894575                return;
    41904576        yd = yid->yd;
    41914577
    4192         pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YPACKET_STATUS_DEFAULT,
    4193                 yd->session_id);
    4194 
    4195         yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
    4196         yahoo_packet_hash(pkt, 3, (from ? from : yd->user));
     4578        pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4579
     4580        yahoo_packet_hash(pkt, 1, (from?from:yd->user));
     4581        for(; who; who = who->next) {
     4582                yahoo_packet_hash(pkt, 3, (char *)who->data);
     4583        }
    41974584        yahoo_packet_hash(pkt, 57, room);
    4198         for (; who; who = who->next)
    4199                 yahoo_packet_hash(pkt, 3, (char *)who->data);
    42004585
    42014586        yahoo_send_packet(yid, pkt, 0);
     
    42044589}
    42054590
    4206 void yahoo_conference_decline(int id, const char *from, YList *who,
    4207         const char *room, const char *msg)
    4208 {
    4209         struct yahoo_input_data *yid =
    4210                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4591void yahoo_conference_decline(int id, const char * from, YList *who, const char *room, const char *msg)
     4592{
     4593        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    42114594        struct yahoo_data *yd;
    42124595        struct yahoo_packet *pkt;
    4213 
    4214         if (!yid)
     4596               
     4597        if(!yid)
    42154598                return;
    42164599        yd = yid->yd;
    42174600
    4218         pkt = yahoo_packet_new(YAHOO_SERVICE_CONFDECLINE,
    4219                 YPACKET_STATUS_DEFAULT, yd->session_id);
    4220 
    4221         yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
    4222         yahoo_packet_hash(pkt, 3, (from ? from : yd->user));
    4223         for (; who; who = who->next)
     4601        pkt = yahoo_packet_new(YAHOO_SERVICE_CONFDECLINE, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4602
     4603        yahoo_packet_hash(pkt, 1, (from?from:yd->user));
     4604        for(; who; who = who->next) {
    42244605                yahoo_packet_hash(pkt, 3, (char *)who->data);
     4606        }
    42254607        yahoo_packet_hash(pkt, 57, room);
    42264608        yahoo_packet_hash(pkt, 14, msg);
     
    42314613}
    42324614
    4233 void yahoo_conference_logoff(int id, const char *from, YList *who,
    4234         const char *room)
    4235 {
    4236         struct yahoo_input_data *yid =
    4237                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4615void yahoo_conference_logoff(int id, const char * from, YList *who, const char *room)
     4616{
     4617        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    42384618        struct yahoo_data *yd;
    42394619        struct yahoo_packet *pkt;
    4240 
    4241         if (!yid)
     4620               
     4621        if(!yid)
    42424622                return;
    42434623        yd = yid->yd;
    42444624
    4245         pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YPACKET_STATUS_DEFAULT,
    4246                 yd->session_id);
    4247 
    4248         yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
    4249         yahoo_packet_hash(pkt, 3, (from ? from : yd->user));
    4250         for (; who; who = who->next)
     4625        pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4626
     4627        yahoo_packet_hash(pkt, 1, (from?from:yd->user));
     4628        for(; who; who = who->next) {
    42514629                yahoo_packet_hash(pkt, 3, (char *)who->data);
    4252 
     4630        }
    42534631        yahoo_packet_hash(pkt, 57, room);
    42544632
     
    42584636}
    42594637
    4260 void yahoo_conference_message(int id, const char *from, YList *who,
    4261         const char *room, const char *msg, int utf8)
    4262 {
    4263         struct yahoo_input_data *yid =
    4264                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4638void yahoo_conference_message(int id, const char * from, YList *who, const char *room, const char *msg, int utf8)
     4639{
     4640        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    42654641        struct yahoo_data *yd;
    42664642        struct yahoo_packet *pkt;
    4267 
    4268         if (!yid)
     4643               
     4644        if(!yid)
    42694645                return;
    42704646        yd = yid->yd;
    42714647
    4272         pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YPACKET_STATUS_DEFAULT,
    4273                 yd->session_id);
    4274 
    4275         yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
    4276         yahoo_packet_hash(pkt, 53, (from ? from : yd->user));
    4277         for (; who; who = who->next)
     4648        pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4649
     4650        yahoo_packet_hash(pkt, 1, (from?from:yd->user));
     4651        for(; who; who = who->next) {
    42784652                yahoo_packet_hash(pkt, 53, (char *)who->data);
    4279 
     4653        }
    42804654        yahoo_packet_hash(pkt, 57, room);
    42814655        yahoo_packet_hash(pkt, 14, msg);
    42824656
    4283         if (utf8)
     4657        if(utf8)
    42844658                yahoo_packet_hash(pkt, 97, "1");
    42854659
     
    42964670        char buff[1024];
    42974671
    4298         if (!yd)
     4672        if(!yd)
    42994673                return;
    43004674
     
    43044678
    43054679        if (chatroomid == 0) {
    4306                 snprintf(url, 1024,
    4307                         "http://insider.msg.yahoo.com/ycontent/?chatcat=0");
     4680                snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatcat=0");
    43084681        } else {
    4309                 snprintf(url, 1024,
    4310                         "http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0",
    4311                         chatroomid);
     4682                snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0",chatroomid);
    43124683        }
    43134684
     
    43164687        inputs = y_list_prepend(inputs, yid);
    43174688
    4318         yahoo_http_get(yid->yd->client_id, url, buff, 0, 0,
    4319                 _yahoo_http_connected, yid);
    4320 }
    4321 
    4322 void yahoo_chat_logon(int id, const char *from, const char *room,
    4323         const char *roomid)
    4324 {
    4325         struct yahoo_input_data *yid =
    4326                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4689        yahoo_http_get(yid->yd->client_id, url, buff, _yahoo_http_connected, yid);
     4690}
     4691
     4692void yahoo_chat_logon(int id, const char *from, const char *room, const char *roomid)
     4693{
     4694        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    43274695        struct yahoo_data *yd;
    43284696        struct yahoo_packet *pkt;
    4329 
    4330         if (!yid)
     4697               
     4698        if(!yid)
    43314699                return;
    43324700
    43334701        yd = yid->yd;
    43344702
    4335         pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YPACKET_STATUS_DEFAULT,
    4336                 yd->session_id);
    4337 
    4338         yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
     4703        pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4704
     4705        yahoo_packet_hash(pkt, 1, (from?from:yd->user));
    43394706        yahoo_packet_hash(pkt, 109, yd->user);
    43404707        yahoo_packet_hash(pkt, 6, "abcde");
     
    43444711        yahoo_packet_free(pkt);
    43454712
    4346         pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YPACKET_STATUS_DEFAULT,
    4347                 yd->session_id);
    4348 
    4349         yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
     4713        pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4714
     4715        yahoo_packet_hash(pkt, 1, (from?from:yd->user));
    43504716        yahoo_packet_hash(pkt, 104, room);
    43514717        yahoo_packet_hash(pkt, 129, roomid);
    4352         yahoo_packet_hash(pkt, 62, "2");        /* ??? */
     4718        yahoo_packet_hash(pkt, 62, "2"); /* ??? */
    43534719
    43544720        yahoo_send_packet(yid, pkt, 0);
     
    43574723}
    43584724
    4359 void yahoo_chat_message(int id, const char *from, const char *room,
    4360         const char *msg, const int msgtype, const int utf8)
    4361 {
    4362         struct yahoo_input_data *yid =
    4363                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4725
     4726void  yahoo_chat_message(int id, const char *from, const char *room, const char *msg, const int msgtype, const int utf8)
     4727{
     4728        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    43644729        struct yahoo_data *yd;
    43654730        struct yahoo_packet *pkt;
    43664731        char buf[2];
    4367 
    4368         if (!yid)
     4732               
     4733        if(!yid)
    43694734                return;
    43704735
    43714736        yd = yid->yd;
    43724737
    4373         pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YPACKET_STATUS_DEFAULT,
    4374                 yd->session_id);
    4375 
    4376         yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
     4738        pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4739
     4740        yahoo_packet_hash(pkt, 1, (from?from:yd->user));
    43774741        yahoo_packet_hash(pkt, 104, room);
    43784742        yahoo_packet_hash(pkt, 117, msg);
    4379 
     4743       
    43804744        snprintf(buf, sizeof(buf), "%d", msgtype);
    43814745        yahoo_packet_hash(pkt, 124, buf);
    43824746
    4383         if (utf8)
     4747        if(utf8)
    43844748                yahoo_packet_hash(pkt, 97, "1");
    43854749
     
    43894753}
    43904754
     4755
    43914756void yahoo_chat_logoff(int id, const char *from)
    43924757{
    4393         struct yahoo_input_data *yid =
    4394                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4758        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    43954759        struct yahoo_data *yd;
    43964760        struct yahoo_packet *pkt;
    4397 
    4398         if (!yid)
     4761               
     4762        if(!yid)
    43994763                return;
    44004764
    44014765        yd = yid->yd;
    44024766
    4403         pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, YPACKET_STATUS_DEFAULT,
    4404                 yd->session_id);
    4405 
    4406         yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
     4767        pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4768
     4769        yahoo_packet_hash(pkt, 1, (from?from:yd->user));
    44074770
    44084771        yahoo_send_packet(yid, pkt, 0);
     
    44134776void yahoo_buddyicon_request(int id, const char *who)
    44144777{
    4415         struct yahoo_input_data *yid =
    4416                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4778        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    44174779        struct yahoo_data *yd;
    44184780        struct yahoo_packet *pkt;
    44194781
    4420         if (!yid)
     4782        if( !yid )
    44214783                return;
    44224784
    44234785        yd = yid->yd;
    4424 
    4425         pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YPACKET_STATUS_DEFAULT,
    4426                 0);
     4786       
     4787        pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0);
    44274788        yahoo_packet_hash(pkt, 4, yd->user);
    44284789        yahoo_packet_hash(pkt, 5, who);
     
    44334794}
    44344795
    4435 void yahoo_send_picture_info(int id, const char *who, const char *url,
    4436         int checksum)
    4437 {
    4438         struct yahoo_input_data *yid =
    4439                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4796void yahoo_send_picture_info(int id, const char *who, const char *url, int checksum)
     4797{
     4798        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    44404799        struct yahoo_data *yd;
    44414800        struct yahoo_packet *pkt;
    44424801        char checksum_str[10];
    44434802
    4444         if (!yid)
     4803        if( !yid )
    44454804                return;
    44464805
     
    44494808        snprintf(checksum_str, sizeof(checksum_str), "%d", checksum);
    44504809
    4451         pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YPACKET_STATUS_DEFAULT,
    4452                 0);
     4810        pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0);
    44534811        yahoo_packet_hash(pkt, 1, yd->user);
    44544812        yahoo_packet_hash(pkt, 4, yd->user);
     
    44644822void yahoo_send_picture_update(int id, const char *who, int type)
    44654823{
    4466         struct yahoo_input_data *yid =
    4467                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4824        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    44684825        struct yahoo_data *yd;
    44694826        struct yahoo_packet *pkt;
    44704827        char type_str[10];
    44714828
    4472         if (!yid)
     4829        if( !yid )
    44734830                return;
    44744831
     
    44774834        snprintf(type_str, sizeof(type_str), "%d", type);
    44784835
    4479         pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE,
    4480                 YPACKET_STATUS_DEFAULT, 0);
     4836        pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE, YAHOO_STATUS_AVAILABLE, 0);
    44814837        yahoo_packet_hash(pkt, 1, yd->user);
    44824838        yahoo_packet_hash(pkt, 5, who);
     
    44894845void yahoo_send_picture_checksum(int id, const char *who, int checksum)
    44904846{
    4491         struct yahoo_input_data *yid =
    4492                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4847        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    44934848        struct yahoo_data *yd;
    44944849        struct yahoo_packet *pkt;
    44954850        char checksum_str[10];
    44964851
    4497         if (!yid)
     4852        if( !yid )
    44984853                return;
    44994854
    45004855        yd = yid->yd;
    4501 
     4856       
    45024857        snprintf(checksum_str, sizeof(checksum_str), "%d", checksum);
    45034858
    4504         pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM,
    4505                 YPACKET_STATUS_DEFAULT, 0);
     4859        pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, YAHOO_STATUS_AVAILABLE, 0);
    45064860        yahoo_packet_hash(pkt, 1, yd->user);
    4507         if (who != 0)
     4861        if( who != 0 )
    45084862                yahoo_packet_hash(pkt, 5, who);
    45094863        yahoo_packet_hash(pkt, 192, checksum_str);
     
    45164870void yahoo_webcam_close_feed(int id, const char *who)
    45174871{
    4518         struct yahoo_input_data *yid =
    4519                 find_input_by_id_and_webcam_user(id, who);
    4520 
    4521         if (yid)
     4872        struct yahoo_input_data *yid = find_input_by_id_and_webcam_user(id, who);
     4873
     4874        if(yid)
    45224875                yahoo_input_close(yid);
    45234876}
     
    45254878void yahoo_webcam_get_feed(int id, const char *who)
    45264879{
    4527         struct yahoo_input_data *yid =
    4528                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4880        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    45294881        struct yahoo_data *yd;
    45304882        struct yahoo_packet *pkt;
    4531 
    4532         if (!yid)
     4883               
     4884        if(!yid)
    45334885                return;
    45344886
     
    45404892         * The queue is popped in yahoo_process_webcam_key
    45414893         */
    4542         webcam_queue = y_list_append(webcam_queue, who ? strdup(who) : NULL);
     4894        webcam_queue = y_list_append(webcam_queue, who?strdup(who):NULL);
    45434895
    45444896        yd = yid->yd;
    45454897
    4546         pkt = yahoo_packet_new(YAHOO_SERVICE_WEBCAM, YPACKET_STATUS_DEFAULT,
    4547                 yd->session_id);
     4898        pkt = yahoo_packet_new(YAHOO_SERVICE_WEBCAM, YAHOO_STATUS_AVAILABLE, yd->session_id);
    45484899
    45494900        yahoo_packet_hash(pkt, 1, yd->user);
     
    45554906}
    45564907
    4557 void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length,
    4558         unsigned int timestamp)
    4559 {
    4560         struct yahoo_input_data *yid =
    4561                 find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM);
     4908void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length, unsigned int timestamp)
     4909{
     4910        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM);
    45624911        unsigned char *packet;
    45634912        unsigned char header_len = 13;
     
    45714920        packet[pos++] = header_len;
    45724921        packet[pos++] = 0;
    4573         packet[pos++] = 5;      /* version byte?? */
     4922        packet[pos++] = 5; /* version byte?? */
    45744923        packet[pos++] = 0;
    45754924        pos += yahoo_put32(packet + pos, length);
    4576         packet[pos++] = 2;      /* packet type, image */
     4925        packet[pos++] = 2; /* packet type, image */
    45774926        pos += yahoo_put32(packet + pos, timestamp);
    45784927        yahoo_add_to_send_queue(yid, packet, header_len);
     
    45834932}
    45844933
    4585 void yahoo_webcam_accept_viewer(int id, const char *who, int accept)
    4586 {
    4587         struct yahoo_input_data *yid =
    4588                 find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM);
     4934void yahoo_webcam_accept_viewer(int id, const char* who, int accept)
     4935{
     4936        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM);
    45894937        char *packet = NULL;
    45904938        char *data = NULL;
     
    45974945
    45984946        data = strdup("u=");
    4599         data = y_string_append(data, (char *)who);
     4947        data = y_string_append(data, (char*)who);
    46004948        data = y_string_append(data, "\r\n");
    46014949        len = strlen(data);
     
    46044952        packet[pos++] = header_len;
    46054953        packet[pos++] = 0;
    4606         packet[pos++] = 5;      /* version byte?? */
     4954        packet[pos++] = 5; /* version byte?? */
    46074955        packet[pos++] = 0;
    46084956        pos += yahoo_put32(packet + pos, len);
    4609         packet[pos++] = 0;      /* packet type */
     4957        packet[pos++] = 0; /* packet type */
    46104958        pos += yahoo_put32(packet + pos, accept);
    46114959        memcpy(packet + pos, data, len);
     
    46174965void yahoo_webcam_invite(int id, const char *who)
    46184966{
    4619         struct yahoo_input_data *yid =
    4620                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4967        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    46214968        struct yahoo_packet *pkt;
    4622 
    4623         if (!yid)
    4624                 return;
    4625 
    4626         pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YPACKET_STATUS_NOTIFY,
    4627                 yid->yd->session_id);
     4969               
     4970        if(!yid)
     4971                return;
     4972
     4973        pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yid->yd->session_id);
    46284974
    46294975        yahoo_packet_hash(pkt, 49, "WEBCAMINVITE");
     
    46374983}
    46384984
    4639 static void yahoo_search_internal(int id, int t, const char *text, int g,
    4640         int ar, int photo, int yahoo_only, int startpos, int total)
     4985static void yahoo_search_internal(int id, int t, const char *text, int g, int ar, int photo, int yahoo_only, int startpos, int total)
    46414986{
    46424987        struct yahoo_data *yd = find_conn_by_id(id);
     
    46464991        char *ctext, *p;
    46474992
    4648         if (!yd)
     4993        if(!yd)
    46494994                return;
    46504995
     
    46544999
    46555000        /*
    4656            age range
    4657            .ar=1 - 13-18, 2 - 18-25, 3 - 25-35, 4 - 35-50, 5 - 50-70, 6 - 70+
    4658          */
    4659 
    4660         snprintf(buff, sizeof(buff), "&.sq=%%20&.tt=%d&.ss=%d", total,
    4661                 startpos);
     5001        age range
     5002        .ar=1 - 13-18, 2 - 18-25, 3 - 25-35, 4 - 35-50, 5 - 50-70, 6 - 70+
     5003        */
     5004
     5005        snprintf(buff, sizeof(buff), "&.sq=%%20&.tt=%d&.ss=%d", total, startpos);
    46625006
    46635007        ctext = strdup(text);
    4664         while ((p = strchr(ctext, ' ')))
     5008        while((p = strchr(ctext, ' ')))
    46655009                *p = '+';
    46665010
    4667         snprintf(url, 1024,
    4668                 "http://members.yahoo.com/interests?.oc=m&.kw=%s&.sb=%d&.g=%d&.ar=0%s%s%s",
    4669                 ctext, t, g, photo ? "&.p=y" : "", yahoo_only ? "&.pg=y" : "",
    4670                 startpos ? buff : "");
     5011        snprintf(url, 1024, "http://members.yahoo.com/interests?.oc=m&.kw=%s&.sb=%d&.g=%d&.ar=0%s%s%s",
     5012                        ctext, t, g, photo ? "&.p=y" : "", yahoo_only ? "&.pg=y" : "",
     5013                        startpos ? buff : "");
    46715014
    46725015        FREE(ctext);
     
    46755018
    46765019        inputs = y_list_prepend(inputs, yid);
    4677         yahoo_http_get(yid->yd->client_id, url, buff, 0, 0,
    4678                 _yahoo_http_connected, yid);
    4679 }
    4680 
    4681 void yahoo_search(int id, enum yahoo_search_type t, const char *text,
    4682         enum yahoo_search_gender g, enum yahoo_search_agerange ar, int photo,
    4683         int yahoo_only)
    4684 {
    4685         struct yahoo_input_data *yid =
    4686                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     5020        yahoo_http_get(yid->yd->client_id, url, buff, _yahoo_http_connected, yid);
     5021}
     5022
     5023void yahoo_search(int id, enum yahoo_search_type t, const char *text, enum yahoo_search_gender g, enum yahoo_search_agerange ar,
     5024                int photo, int yahoo_only)
     5025{
     5026        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    46875027        struct yahoo_search_state *yss;
    46885028
    4689         if (!yid)
    4690                 return;
    4691 
    4692         if (!yid->ys)
     5029        if(!yid)
     5030                return;
     5031
     5032        if(!yid->ys)
    46935033                yid->ys = y_new0(struct yahoo_search_state, 1);
    46945034
     
    47085048void yahoo_search_again(int id, int start)
    47095049{
    4710         struct yahoo_input_data *yid =
    4711                 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     5050        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    47125051        struct yahoo_search_state *yss;
    47135052
    4714         if (!yid || !yid->ys)
     5053        if(!yid || !yid->ys)
    47155054                return;
    47165055
    47175056        yss = yid->ys;
    47185057
    4719         if (start == -1)
     5058        if(start == -1)
    47205059                start = yss->lsearch_nstart + yss->lsearch_nfound;
    47215060
    4722         yahoo_search_internal(id, yss->lsearch_type, yss->lsearch_text,
    4723                 yss->lsearch_gender, yss->lsearch_agerange,
    4724                 yss->lsearch_photo, yss->lsearch_yahoo_only,
    4725                 start, yss->lsearch_ntotal);
    4726 }
    4727 
    4728 void yahoo_send_picture(int id, const char *name, unsigned long size,
    4729         yahoo_get_fd_callback callback, void *data)
    4730 {
    4731         /* Not Implemented */
    4732 }
    4733 
    4734 /* File Transfer */
    4735 static YList *active_file_transfers = NULL;
    4736 
    4737 enum {
    4738         FT_STATE_HEAD = 1,
    4739         FT_STATE_RECV,
    4740         FT_STATE_RECV_START,
    4741         FT_STATE_SEND
     5061        yahoo_search_internal(id, yss->lsearch_type, yss->lsearch_text,
     5062                        yss->lsearch_gender, yss->lsearch_agerange,
     5063                        yss->lsearch_photo, yss->lsearch_yahoo_only,
     5064                        start, yss->lsearch_ntotal);
     5065}
     5066
     5067struct send_file_data {
     5068        struct yahoo_packet *pkt;
     5069        yahoo_get_fd_callback callback;
     5070        void *user_data;
    47425071};
    47435072
    4744 struct send_file_data {
    4745         int client_id;
    4746         char *id;
    4747         char *who;
    4748         char *filename;
    4749         char *ip_addr;
    4750         char *token;
    4751         int size;
    4752 
    4753         struct yahoo_input_data *yid;
    4754         int state;
    4755 
    4756         yahoo_get_fd_callback callback;
    4757         void *data;
    4758 };
    4759 
    4760 static char *yahoo_get_random(void)
    4761 {
    4762         int i = 0;
    4763         int r = 0;
    4764         int c = 0;
    4765         char out[25];
    4766 
    4767         out[24] = '\0';
    4768         out[23] = '$';
    4769         out[22] = '$';
    4770        
    4771         for (i = 0; i < 22; i++) {
    4772                 if(r == 0)
    4773                         r = rand();
    4774 
    4775                 c = r%61;
    4776 
    4777                 if(c<26)
    4778                         out[i] = c + 'a';
    4779                 else if (c<52)
    4780                         out[i] = c - 26 + 'A';
    4781                 else
    4782                         out[i] = c - 52 + '0';
    4783 
    4784                 r /= 61;
    4785         }
    4786 
    4787         return strdup(out);
    4788 }
    4789 
    4790 static int _are_same_id(const void *sfd1, const void *id)
    4791 {
    4792         return strcmp(((struct send_file_data *)sfd1)->id, (char *)id);
    4793 }
    4794 
    4795 static int _are_same_yid(const void *sfd1, const void *yid)
    4796 {
    4797         if(((struct send_file_data *)sfd1)->yid == yid)
    4798                 return 0;
    4799         else
    4800                 return 1;
    4801 }
    4802 
    4803 static struct send_file_data *yahoo_get_active_transfer(char *id)
    4804 {
    4805         YList *l = y_list_find_custom(active_file_transfers, id,
    4806                 _are_same_id);
    4807 
    4808         if(l)
    4809                 return (struct send_file_data *)l->data;
    4810        
    4811         return NULL;
    4812 }
    4813 
    4814 static struct send_file_data *yahoo_get_active_transfer_with_yid(void *yid)
    4815 {
    4816         YList *l = y_list_find_custom(active_file_transfers, yid,
    4817                 _are_same_yid);
    4818 
    4819         if(l)
    4820                 return (struct send_file_data *)l->data;
    4821        
    4822         return NULL;
    4823 }
    4824 
    4825 static void yahoo_add_active_transfer(struct send_file_data *sfd)
    4826 {
    4827         active_file_transfers = y_list_prepend(active_file_transfers, sfd);
    4828 }
    4829 
    4830 static void yahoo_remove_active_transfer(struct send_file_data *sfd)
    4831 {
    4832         active_file_transfers = y_list_remove(active_file_transfers, sfd);
    4833         free(sfd->id);
    4834         free(sfd->who);
    4835         free(sfd->filename);
    4836         free(sfd->ip_addr);
    4837         FREE(sfd);
    4838 }
    4839 
    4840 static void _yahoo_ft_upload_connected(int id, void *fd, int error, void *data)
    4841 {
     5073static void _yahoo_send_picture_connected(int id, int fd, int error, void *data)
     5074{
     5075        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_FT);
    48425076        struct send_file_data *sfd = data;
    4843         struct yahoo_input_data *yid = sfd->yid;
    4844 
    4845         if (!fd) {
     5077        struct yahoo_packet *pkt = sfd->pkt;
     5078        unsigned char buff[1024];
     5079
     5080        if(fd <= 0) {
     5081                sfd->callback(id, fd, error, sfd->user_data);
     5082                FREE(sfd);
     5083                yahoo_packet_free(pkt);
    48465084                inputs = y_list_remove(inputs, yid);
    48475085                FREE(yid);
     
    48495087        }
    48505088
    4851         sfd->callback(id, fd, error, sfd->data);
    4852 
    48535089        yid->fd = fd;
    4854         yid->read_tag =
    4855                 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd,
    4856                 YAHOO_INPUT_READ, yid);
    4857 }
    4858 
    4859 static void yahoo_file_transfer_upload(struct yahoo_data *yd,
    4860         struct send_file_data *sfd)
    4861 {
    4862         char url[256];
    4863         char buff[4096];
    4864         char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL;
    4865 
    4866         struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1);
    4867 
     5090        yahoo_send_packet(yid, pkt, 8);
     5091        yahoo_packet_free(pkt);
     5092
     5093        snprintf((char *)buff, sizeof(buff), "29");
     5094        buff[2] = 0xc0;
     5095        buff[3] = 0x80;
     5096       
     5097        write(yid->fd, buff, 4);
     5098
     5099        /*      YAHOO_CALLBACK(ext_yahoo_add_handler)(nyd->fd, YAHOO_INPUT_READ); */
     5100
     5101        sfd->callback(id, fd, error, sfd->user_data);
     5102        FREE(sfd);
     5103        inputs = y_list_remove(inputs, yid);
     5104        /*
     5105        while(yahoo_tcp_readline(buff, sizeof(buff), nyd->fd) > 0) {
     5106        if(!strcmp(buff, ""))
     5107        break;
     5108}
     5109
     5110        */
     5111        yahoo_input_close(yid);
     5112}
     5113
     5114void yahoo_send_picture(int id, const char *name, unsigned long size,
     5115                                                        yahoo_get_fd_callback callback, void *data)
     5116{
     5117        struct yahoo_data *yd = find_conn_by_id(id);
     5118        struct yahoo_input_data *yid;
     5119        struct yahoo_server_settings *yss;
     5120        struct yahoo_packet *pkt = NULL;
     5121        char size_str[10];
     5122        char expire_str[10];
     5123        long content_length=0;
     5124        unsigned char buff[1024];
     5125        char url[255];
     5126        struct send_file_data *sfd;
     5127
     5128        if(!yd)
     5129                return;
     5130
     5131        yss = yd->server_settings;
     5132
     5133        yid = y_new0(struct yahoo_input_data, 1);
    48685134        yid->yd = yd;
    48695135        yid->type = YAHOO_CONNECTION_FT;
    48705136
     5137        pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPLOAD, YAHOO_STATUS_AVAILABLE, yd->session_id);
     5138
     5139        snprintf(size_str, sizeof(size_str), "%ld", size);
     5140        snprintf(expire_str, sizeof(expire_str), "%ld", (long)604800);
     5141
     5142        yahoo_packet_hash(pkt, 0, yd->user);
     5143        yahoo_packet_hash(pkt, 1, yd->user);
     5144        yahoo_packet_hash(pkt, 14, "");
     5145        yahoo_packet_hash(pkt, 27, name);
     5146        yahoo_packet_hash(pkt, 28, size_str);
     5147        yahoo_packet_hash(pkt, 38, expire_str);
     5148       
     5149
     5150        content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt);
     5151
     5152        snprintf(url, sizeof(url), "http://%s:%d/notifyft",
     5153                                yss->filetransfer_host, yss->filetransfer_port);
     5154        snprintf((char *)buff, sizeof(buff), "Y=%s; T=%s",
     5155                                 yd->cookie_y, yd->cookie_t);
    48715156        inputs = y_list_prepend(inputs, yid);
    4872         sfd->yid = yid;
    4873         sfd->state = FT_STATE_SEND;
    4874 
    4875         token_enc = yahoo_urlencode(sfd->token);
    4876         sender_enc = yahoo_urlencode(yd->user);
    4877         recv_enc = yahoo_urlencode(sfd->who);
    4878 
    4879         snprintf(url, sizeof(url),
    4880                 "http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr,
    4881                 token_enc, sender_enc, recv_enc);
    4882 
    4883         snprintf(buff, sizeof(buff), "T=%s; Y=%s", yd->cookie_t, yd->cookie_y);
    4884 
    4885         yahoo_http_post(yd->client_id, url, buff, sfd->size,
    4886                 _yahoo_ft_upload_connected, sfd);
    4887 
    4888         FREE(token_enc);
    4889         FREE(sender_enc);
    4890         FREE(recv_enc);
    4891 }
    4892 
    4893 static void yahoo_init_ft_recv(struct yahoo_data *yd,
    4894         struct send_file_data *sfd)
    4895 {
    4896         char url[256];
    4897         char buff[1024];
    4898         char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL;
    4899 
    4900         struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1);
    4901 
     5157
     5158        sfd = y_new0(struct send_file_data, 1);
     5159        sfd->pkt = pkt;
     5160        sfd->callback = callback;
     5161        sfd->user_data = data;
     5162        yahoo_http_post(yid->yd->client_id, url, (char *)buff, content_length+4+size,
     5163                                                _yahoo_send_picture_connected, sfd);
     5164}
     5165
     5166static void _yahoo_send_file_connected(int id, int fd, int error, void *data)
     5167{
     5168        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_FT);
     5169        struct send_file_data *sfd = data;
     5170        struct yahoo_packet *pkt = sfd->pkt;
     5171        unsigned char buff[1024];
     5172
     5173        if(fd <= 0) {
     5174                sfd->callback(id, fd, error, sfd->user_data);
     5175                FREE(sfd);
     5176                yahoo_packet_free(pkt);
     5177                inputs = y_list_remove(inputs, yid);
     5178                FREE(yid);
     5179                return;
     5180        }
     5181
     5182        yid->fd = fd;
     5183        yahoo_send_packet(yid, pkt, 8);
     5184        yahoo_packet_free(pkt);
     5185
     5186        snprintf((char *)buff, sizeof(buff), "29");
     5187        buff[2] = 0xc0;
     5188        buff[3] = 0x80;
     5189       
     5190        write(yid->fd, buff, 4);
     5191
     5192/*      YAHOO_CALLBACK(ext_yahoo_add_handler)(nyd->fd, YAHOO_INPUT_READ); */
     5193
     5194        sfd->callback(id, fd, error, sfd->user_data);
     5195        FREE(sfd);
     5196        inputs = y_list_remove(inputs, yid);
     5197        /*
     5198        while(yahoo_tcp_readline(buff, sizeof(buff), nyd->fd) > 0) {
     5199                if(!strcmp(buff, ""))
     5200                        break;
     5201        }
     5202
     5203        */
     5204        yahoo_input_close(yid);
     5205}
     5206
     5207void yahoo_send_file(int id, const char *who, const char *msg,
     5208                const char *name, unsigned long size,
     5209                yahoo_get_fd_callback callback, void *data)
     5210{
     5211        struct yahoo_data *yd = find_conn_by_id(id);
     5212        struct yahoo_input_data *yid;
     5213        struct yahoo_server_settings *yss;
     5214        struct yahoo_packet *pkt = NULL;
     5215        char size_str[10];
     5216        long content_length=0;
     5217        unsigned char buff[1024];
     5218        char url[255];
     5219        struct send_file_data *sfd;
     5220
     5221        if(!yd)
     5222                return;
     5223
     5224        yss = yd->server_settings;
     5225
     5226        yid = y_new0(struct yahoo_input_data, 1);
    49025227        yid->yd = yd;
    49035228        yid->type = YAHOO_CONNECTION_FT;
    49045229
    4905         inputs = y_list_prepend(inputs, yid);
    4906         sfd->yid = yid;
    4907         sfd->state = FT_STATE_HEAD;
    4908 
    4909         token_enc = yahoo_urlencode(sfd->token);
    4910         sender_enc = yahoo_urlencode(sfd->who);
    4911         recv_enc = yahoo_urlencode(yd->user);
    4912 
    4913         snprintf(url, sizeof(url),
    4914                 "http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr,
    4915                 token_enc, sender_enc, recv_enc);
    4916 
    4917         snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t);
    4918 
    4919         yahoo_http_head(yid->yd->client_id, url, buff, 0, NULL,
    4920                 _yahoo_http_connected, yid);
    4921 
    4922         FREE(token_enc);
    4923         FREE(sender_enc);
    4924         FREE(recv_enc);
    4925 }
    4926 
    4927 static void yahoo_file_transfer_accept(struct yahoo_input_data *yid,
    4928         struct send_file_data *sfd)
    4929 {
    4930         struct yahoo_packet *pkt;
    4931 
    4932         pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFERACCEPT,
    4933                 YPACKET_STATUS_DEFAULT, yid->yd->session_id);
    4934 
    4935         yahoo_packet_hash(pkt, 1, yid->yd->user);
    4936         yahoo_packet_hash(pkt, 5, sfd->who);
    4937         yahoo_packet_hash(pkt, 265, sfd->id);
    4938         yahoo_packet_hash(pkt, 27, sfd->filename);
    4939         yahoo_packet_hash(pkt, 249, "3");
    4940         yahoo_packet_hash(pkt, 251, sfd->token);
    4941 
    4942         yahoo_send_packet(yid, pkt, 0);
    4943 
    4944         yahoo_packet_free(pkt);
    4945 
    4946         yahoo_init_ft_recv(yid->yd, sfd);
    4947 }
    4948 
    4949 static void yahoo_process_filetransferaccept(struct yahoo_input_data *yid,
    4950         struct yahoo_packet *pkt)
    4951 {
    4952         YList *l;
    4953         struct send_file_data *sfd;
    4954         char *who = NULL;
    4955         char *filename = NULL;
    4956         char *id = NULL;
    4957         char *token = NULL;
    4958 
    4959         for (l = pkt->hash; l; l = l->next) {
    4960                 struct yahoo_pair *pair = l->data;
    4961                 switch (pair->key) {
    4962                 case 4:
    4963                         who = pair->value;
    4964                         break;
    4965                 case 5:
    4966                         /* Me... don't care */
    4967                         break;
    4968                 case 249:
    4969                         break;
    4970                 case 265:
    4971                         id = pair->value;
    4972                         break;
    4973                 case 251:
    4974                         token = pair->value;
    4975                         break;
    4976                 case 27:
    4977                         filename = pair->value;
    4978                         break;
    4979                 }
    4980         }
    4981 
    4982         sfd = yahoo_get_active_transfer(id);
    4983 
    4984         if (sfd) {
    4985                 sfd->token = strdup(token);
    4986 
    4987                 yahoo_file_transfer_upload(yid->yd, sfd);
    4988         }
    4989         else {
    4990                 YAHOO_CALLBACK(ext_yahoo_file_transfer_done)
    4991                         (yid->yd->client_id, YAHOO_FILE_TRANSFER_UNKNOWN,
    4992                         sfd->data);
    4993 
    4994                 yahoo_remove_active_transfer(sfd);
    4995         }
    4996 }
    4997 
    4998 static void yahoo_process_filetransferinfo(struct yahoo_input_data *yid,
    4999         struct yahoo_packet *pkt)
    5000 {
    5001         YList *l;
    5002         char *who = NULL;
    5003         char *filename = NULL;
    5004         char *id = NULL;
    5005         char *token = NULL;
    5006         char *ip_addr = NULL;
    5007 
    5008         struct send_file_data *sfd;
    5009 
    5010         for (l = pkt->hash; l; l = l->next) {
    5011                 struct yahoo_pair *pair = l->data;
    5012                 switch (pair->key) {
    5013                 case 1:
    5014                 case 4:
    5015                         who = pair->value;
    5016                         break;
    5017                 case 5:
    5018                         /* Me... don't care */
    5019                         break;
    5020                 case 249:
    5021                         break;
    5022                 case 265:
    5023                         id = pair->value;
    5024                         break;
    5025                 case 250:
    5026                         ip_addr = pair->value;
    5027                         break;
    5028                 case 251:
    5029                         token = pair->value;
    5030                         break;
    5031                 case 27:
    5032                         filename = pair->value;
    5033                         break;
    5034                 }
    5035         }
    5036 
    5037         sfd = yahoo_get_active_transfer(id);
    5038 
    5039         if (sfd) {
    5040                 sfd->token = strdup(token);
    5041                 sfd->ip_addr = strdup(ip_addr);
    5042 
    5043                 yahoo_file_transfer_accept(yid, sfd);
    5044         }
    5045         else {
    5046                 YAHOO_CALLBACK(ext_yahoo_file_transfer_done)
    5047                         (yid->yd->client_id, YAHOO_FILE_TRANSFER_UNKNOWN,
    5048                         sfd->data);
    5049 
    5050                 yahoo_remove_active_transfer(sfd);
    5051         }
    5052 }
    5053 
    5054 static void yahoo_send_filetransferinfo(struct yahoo_data *yd,
    5055         struct send_file_data *sfd)
    5056 {
    5057         struct yahoo_input_data *yid;
    5058         struct yahoo_packet *pkt;
    5059 
    5060         yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER);
    5061         sfd->ip_addr = YAHOO_CALLBACK(ext_yahoo_get_ip_addr)("relay.yahoo.com");
    5062 
    5063         if (!sfd->ip_addr) {
    5064                 YAHOO_CALLBACK(ext_yahoo_file_transfer_done)
    5065                         (yd->client_id, YAHOO_FILE_TRANSFER_RELAY, sfd->data);
    5066 
    5067                 yahoo_remove_active_transfer(sfd);
    5068 
    5069                 return;
    5070         }
    5071 
    5072         pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFERINFO,
    5073                 YPACKET_STATUS_DEFAULT, yd->session_id);
    5074 
    5075         yahoo_packet_hash(pkt, 1, yd->user);
    5076         yahoo_packet_hash(pkt, 5, sfd->who);
    5077         yahoo_packet_hash(pkt, 265, sfd->id);
    5078         yahoo_packet_hash(pkt, 27, sfd->filename);
    5079         yahoo_packet_hash(pkt, 249, "3");
    5080         yahoo_packet_hash(pkt, 250, sfd->ip_addr);
    5081 
    5082         yahoo_send_packet(yid, pkt, 0);
    5083 
    5084         yahoo_packet_free(pkt);
    5085 }
    5086 
    5087 static void yahoo_process_filetransfer(struct yahoo_input_data *yid,
    5088         struct yahoo_packet *pkt)
    5089 {
    5090         YList *l;
    5091         char *who = NULL;
    5092         char *filename = NULL;
    5093         char *msg = NULL;
    5094         char *id = NULL;
    5095         int action = 0;
    5096         int size = 0;
    5097         struct yahoo_data *yd = yid->yd;
    5098 
    5099         struct send_file_data *sfd;
    5100 
    5101         for (l = pkt->hash; l; l = l->next) {
    5102                 struct yahoo_pair *pair = l->data;
    5103                 switch (pair->key) {
    5104                 case 4:
    5105                         who = pair->value;
    5106                         break;
    5107                 case 5:
    5108                         /* Me... don't care */
    5109                         break;
    5110                 case 222:
    5111                         action = atoi(pair->value);
    5112                         break;
    5113                 case 265:
    5114                         id = pair->value;
    5115                         break;
    5116                 case 266: /* Don't know */
    5117                         break;
    5118                 case 302: /* Start Data? */
    5119                         break;
    5120                 case 300:
    5121                         break;
    5122                 case 27:
    5123                         filename = pair->value;
    5124                         break;
    5125                 case 28:
    5126                         size = atoi(pair->value);
    5127                         break;
    5128                 case 14:
    5129                         msg = pair->value;
    5130                 case 301: /* End Data? */
    5131                         break;
    5132                 case 303:
    5133                         break;
    5134 
    5135                 }
    5136         }
    5137 
    5138         if (action == YAHOO_FILE_TRANSFER_INIT) {
    5139                 /* Received a FT request from buddy */
    5140                 sfd = y_new0(struct send_file_data, 1);
    5141        
    5142                 sfd->client_id = yd->client_id;
    5143                 sfd->id = strdup(id);
    5144                 sfd->who = strdup(who);
    5145                 sfd->filename = strdup(filename);
    5146                 sfd->size = size;
    5147        
    5148                 yahoo_add_active_transfer(sfd);
    5149 
    5150                 YAHOO_CALLBACK(ext_yahoo_got_file) (yd->client_id, yd->user,
    5151                         who, msg, filename, size, sfd->id);
    5152         }
    5153         else {
    5154                 /* Response to our request */
    5155                 sfd = yahoo_get_active_transfer(id);
    5156 
    5157                 if (sfd && action == YAHOO_FILE_TRANSFER_ACCEPT) {
    5158                         yahoo_send_filetransferinfo(yd, sfd);
    5159                 }
    5160                 else if (!sfd || action == YAHOO_FILE_TRANSFER_REJECT) {
    5161                         YAHOO_CALLBACK(ext_yahoo_file_transfer_done)
    5162                                 (yd->client_id, YAHOO_FILE_TRANSFER_REJECT,
    5163                                 sfd->data);
    5164 
    5165                         yahoo_remove_active_transfer(sfd);
    5166                 }
    5167         }
    5168 }
    5169 
    5170 void yahoo_send_file(int id, const char *who, const char *msg,
    5171         const char *name, unsigned long size,
    5172         yahoo_get_fd_callback callback, void *data)
    5173 {
    5174         struct yahoo_packet *pkt = NULL;
    5175         char size_str[10];
    5176         struct yahoo_input_data *yid;
    5177         struct yahoo_data *yd;
    5178         struct send_file_data *sfd;
    5179        
    5180         yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    5181         yd = find_conn_by_id(id);
    5182         sfd = y_new0(struct send_file_data, 1);
    5183 
    5184         sfd->client_id = id;
    5185         sfd->id = yahoo_get_random();
    5186         sfd->who = strdup(who);
    5187         sfd->filename = strdup(name);
    5188         sfd->size = size;
    5189         sfd->callback = callback;
    5190         sfd->data = data;
    5191 
    5192         yahoo_add_active_transfer(sfd);
    5193 
    5194         if (!yd)
    5195                 return;
    5196 
    5197         pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFER,
    5198                 YPACKET_STATUS_DEFAULT, yd->session_id);
     5230        pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER, YAHOO_STATUS_AVAILABLE, yd->session_id);
    51995231
    52005232        snprintf(size_str, sizeof(size_str), "%ld", size);
    52015233
    5202         yahoo_packet_hash(pkt, 1, yd->user);
     5234        yahoo_packet_hash(pkt, 0, yd->user);
    52035235        yahoo_packet_hash(pkt, 5, who);
    5204         yahoo_packet_hash(pkt, 265, sfd->id);
    5205         yahoo_packet_hash(pkt, 222, "1");
    5206         yahoo_packet_hash(pkt, 266, "1");
    5207         yahoo_packet_hash(pkt, 302, "268");
    5208         yahoo_packet_hash(pkt, 300, "268");
     5236        yahoo_packet_hash(pkt, 14, msg);
    52095237        yahoo_packet_hash(pkt, 27, name);
    52105238        yahoo_packet_hash(pkt, 28, size_str);
    5211         yahoo_packet_hash(pkt, 301, "268");
    5212         yahoo_packet_hash(pkt, 303, "268");
    5213 
    5214         yahoo_send_packet(yid, pkt, 0);
    5215 
    5216         yahoo_packet_free(pkt);
    5217 }
    5218 
    5219 void yahoo_send_file_transfer_response(int client_id, int response, char *id, void *data)
    5220 {
    5221         struct yahoo_packet *pkt = NULL;
    5222         char resp[2];
    5223         struct yahoo_input_data *yid;
    5224        
    5225         struct send_file_data *sfd = yahoo_get_active_transfer(id);
    5226 
    5227         sfd->data = data;
    5228 
    5229         yid = find_input_by_id_and_type(client_id, YAHOO_CONNECTION_PAGER);
    5230 
    5231         pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFER,
    5232                 YPACKET_STATUS_DEFAULT, yid->yd->session_id);
    5233 
    5234         snprintf(resp, sizeof(resp), "%d", response);
    5235 
    5236         yahoo_packet_hash(pkt, 1, yid->yd->user);
    5237         yahoo_packet_hash(pkt, 5, sfd->who);
    5238         yahoo_packet_hash(pkt, 265, sfd->id);
    5239         yahoo_packet_hash(pkt, 222, resp);
    5240 
    5241         yahoo_send_packet(yid, pkt, 0);
    5242 
    5243         yahoo_packet_free(pkt);
    5244 
    5245         if(response == YAHOO_FILE_TRANSFER_REJECT)
    5246                 yahoo_remove_active_transfer(sfd);
    5247 }
    5248 
    5249 static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over)
    5250 {
    5251         struct send_file_data *sfd;
    5252         struct yahoo_data *yd = yid->yd;
    5253        
    5254         sfd = yahoo_get_active_transfer_with_yid(yid);
    5255 
    5256         if (!sfd) {
    5257                 LOG(("Something funny happened. yid %p has no sfd.\n", yid));
    5258                 return;
    5259         }
    5260 
    5261         /*
    5262          * We want to handle only the complete data with HEAD since we don't
    5263          * want a situation where both the GET and HEAD are active.
    5264          * With SEND, we really can't do much with partial response
    5265          */
    5266         if ((sfd->state == FT_STATE_HEAD || sfd->state == FT_STATE_SEND)
    5267                         && !over)
    5268                 return;
    5269 
    5270         if (sfd->state == FT_STATE_HEAD) {
    5271                 /* Do a GET */
    5272                 char url[256];
    5273                 char buff[1024];
    5274                 char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL;
    5275 
    5276                 struct yahoo_input_data *yid_ft =
    5277                         y_new0(struct yahoo_input_data, 1);
    5278        
    5279                 yid_ft->yd = yid->yd;
    5280                 yid_ft->type = YAHOO_CONNECTION_FT;
    5281        
    5282                 inputs = y_list_prepend(inputs, yid_ft);
    5283                 sfd->yid = yid_ft;
    5284                 sfd->state = FT_STATE_RECV;
    5285 
    5286                 token_enc = yahoo_urlencode(sfd->token);
    5287                 sender_enc = yahoo_urlencode(sfd->who);
    5288                 recv_enc = yahoo_urlencode(yd->user);
    5289        
    5290                 snprintf(url, sizeof(url),
    5291                         "http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr,
    5292                         token_enc, sender_enc, recv_enc);
    5293 
    5294                 snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y,
    5295                         yd->cookie_t);
    5296 
    5297 
    5298                 yahoo_http_get(yd->client_id, url, buff, 1, 1,
    5299                         _yahoo_http_connected, yid_ft);
    5300 
    5301                 FREE(token_enc);
    5302                 FREE(sender_enc);
    5303                 FREE(recv_enc);
    5304         }
    5305         else if (sfd->state == FT_STATE_RECV ||
    5306                 sfd->state == FT_STATE_RECV_START) {
    5307 
    5308                 unsigned char *data_begin = NULL;
    5309 
    5310                 if (yid->rxlen == 0)
    5311                         yahoo_remove_active_transfer(sfd);
    5312 
    5313                 if (sfd->state != FT_STATE_RECV_START &&
    5314                         (data_begin =
    5315                                 (unsigned char *)strstr((char *)yid->rxqueue,
    5316                                 "\r\n\r\n"))) {
    5317 
    5318                         sfd->state = FT_STATE_RECV_START;
    5319 
    5320                         yid->rxlen -= 4+(data_begin-yid->rxqueue)/sizeof(char);
    5321                         data_begin += 4;
    5322 
    5323                         if (yid->rxlen > 0)
    5324                                 YAHOO_CALLBACK(ext_yahoo_got_ft_data)
    5325                                         (yd->client_id, data_begin,
    5326                                         yid->rxlen, sfd->data);
    5327                 }
    5328                 else if (sfd->state == FT_STATE_RECV_START)
    5329                         YAHOO_CALLBACK(ext_yahoo_got_ft_data) (yd->client_id,
    5330                                 yid->rxqueue, yid->rxlen, sfd->data);
    5331 
    5332                 FREE(yid->rxqueue);
    5333                 yid->rxqueue = NULL;
    5334                 yid->rxlen = 0;
    5335         }
    5336         else if (sfd->state == FT_STATE_SEND) {
    5337                 /* Sent file completed */
    5338                 int len = 0;
    5339                 char *off = strstr((char *)yid->rxqueue, "Content-Length: ");
    5340 
    5341                 if (off) {
    5342                         off += 16;
    5343                         len = atoi(off);
    5344                 }
    5345 
    5346                 if (len < sfd->size)
    5347                         YAHOO_CALLBACK(ext_yahoo_file_transfer_done)
    5348                                 (yd->client_id,
    5349                                 YAHOO_FILE_TRANSFER_FAILED, sfd->data);
    5350                 else
    5351                         YAHOO_CALLBACK(ext_yahoo_file_transfer_done)
    5352                                 (yd->client_id,
    5353                                 YAHOO_FILE_TRANSFER_DONE, sfd->data);
    5354 
    5355                 yahoo_remove_active_transfer(sfd);
    5356         }
    5357 }
    5358 
    5359 /* End File Transfer */
     5239
     5240        content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt);
     5241
     5242        snprintf(url, sizeof(url), "http://%s:%d/notifyft",
     5243                        yss->filetransfer_host, yss->filetransfer_port);
     5244        snprintf((char *)buff, sizeof(buff), "Y=%s; T=%s",
     5245                        yd->cookie_y, yd->cookie_t);
     5246        inputs = y_list_prepend(inputs, yid);
     5247
     5248        sfd = y_new0(struct send_file_data, 1);
     5249        sfd->pkt = pkt;
     5250        sfd->callback = callback;
     5251        sfd->user_data = data;
     5252        yahoo_http_post(yid->yd->client_id, url, (char *)buff, content_length+4+size,
     5253                        _yahoo_send_file_connected, sfd);
     5254}
     5255
    53605256
    53615257enum yahoo_status yahoo_current_status(int id)
    53625258{
    53635259        struct yahoo_data *yd = find_conn_by_id(id);
    5364         if (!yd)
     5260        if(!yd)
    53655261                return YAHOO_STATUS_OFFLINE;
    53665262        return yd->current_status;
    53675263}
    53685264
    5369 const YList *yahoo_get_buddylist(int id)
     5265const YList * yahoo_get_buddylist(int id)
    53705266{
    53715267        struct yahoo_data *yd = find_conn_by_id(id);
    5372         if (!yd)
     5268        if(!yd)
    53735269                return NULL;
    53745270        return yd->buddies;
    53755271}
    53765272
    5377 const YList *yahoo_get_ignorelist(int id)
     5273const YList * yahoo_get_ignorelist(int id)
    53785274{
    53795275        struct yahoo_data *yd = find_conn_by_id(id);
    5380         if (!yd)
     5276        if(!yd)
    53815277                return NULL;
    53825278        return yd->ignore;
    53835279}
    53845280
    5385 const YList *yahoo_get_identities(int id)
     5281const YList * yahoo_get_identities(int id)
    53865282{
    53875283        struct yahoo_data *yd = find_conn_by_id(id);
    5388         if (!yd)
     5284        if(!yd)
    53895285                return NULL;
    53905286        return yd->identities;
    53915287}
    53925288
    5393 const char *yahoo_get_cookie(int id, const char *which)
     5289const char * yahoo_get_cookie(int id, const char *which)
    53945290{
    53955291        struct yahoo_data *yd = find_conn_by_id(id);
    5396         if (!yd)
     5292        if(!yd)
    53975293                return NULL;
    5398         if (!strncasecmp(which, "y", 1))
     5294        if(!strncasecmp(which, "y", 1))
    53995295                return yd->cookie_y;
    5400         if (!strncasecmp(which, "b", 1))
    5401                 return yd->cookie_b;
    5402         if (!strncasecmp(which, "t", 1))
     5296        if(!strncasecmp(which, "t", 1))
    54035297                return yd->cookie_t;
    5404         if (!strncasecmp(which, "c", 1))
     5298        if(!strncasecmp(which, "c", 1))
    54055299                return yd->cookie_c;
    5406         if (!strncasecmp(which, "login", 5))
     5300        if(!strncasecmp(which, "login", 5))
    54075301                return yd->login_cookie;
    54085302        return NULL;
    54095303}
    54105304
    5411 const char *yahoo_get_profile_url(void)
     5305void yahoo_get_url_handle(int id, const char *url,
     5306                yahoo_get_url_handle_callback callback, void *data)
     5307{
     5308        struct yahoo_data *yd = find_conn_by_id(id);
     5309        if(!yd)
     5310                return;
     5311
     5312        yahoo_get_url_fd(id, url, yd, callback, data);
     5313}
     5314
     5315const char * yahoo_get_profile_url( void )
    54125316{
    54135317        return profile_url;
    54145318}
     5319
Note: See TracChangeset for help on using the changeset viewer.