Changeset c8791f2


Ignore:
Timestamp:
2010-07-24T13:29:48Z (9 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
03f3828
Parents:
938c305 (diff), c495217 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merging libyahoo2 fixes. Now completely up-to-date with libyahoo2 svn
again, should try to keep it up a little bit better and submit my fixes
upstream.

This also adds code for Yahoo! file transfers but BitlBee isn't using it
yet. (It doesn't seem to support flow control which makes this complicated.)

Location:
protocols/yahoo
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • protocols/yahoo/Makefile

    r938c305 rc8791f2  
    1515objects = yahoo.o crypt.o libyahoo2.o yahoo_fn.o yahoo_httplib.o yahoo_util.o
    1616
    17 CFLAGS += -Wall -DSTDC_HEADERS -DHAVE_STRING_H -DHAVE_STRCHR -DHAVE_MEMCPY -DHAVE_GLIB
     17CFLAGS += -Wall -DSTDC_HEADERS -DHAVE_STRING_H -DHAVE_STRCHR -DHAVE_MEMCPY -DHAVE_GLIB -Wno-pointer-to-int-cast
    1818LFLAGS += -r
    1919
  • protocols/yahoo/libyahoo2.c

    r938c305 rc8791f2  
    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>
    57 *
    68 * Yahoo Search copyright (C) 2003, Konstantin Klyagin <konst AT konst.org.ua>
     
    2729 *     <hiro-y@kcn.ne.jp>
    2830 *
     31 * YMSG16 authentication code based mostly on write-up at:
     32 *      http://www.carbonize.co.uk/ymsg16.html
    2933 *
    3034 * This program is free software; you can redistribute it and/or modify
     
    9296
    9397#ifdef USE_STRUCT_CALLBACKS
    94 struct yahoo_callbacks *yc=NULL;
    95 
    96 void yahoo_register_callbacks(struct yahoo_callbacks * tyc)
     98struct yahoo_callbacks *yc = NULL;
     99
     100void yahoo_register_callbacks(struct yahoo_callbacks *tyc)
    97101{
    98102        yc = tyc;
     
    104108#endif
    105109
    106 static int yahoo_send_data(int fd, void *data, int len);
    107 
    108 int yahoo_log_message(char * fmt, ...)
     110static int yahoo_send_data(void *fd, void *data, int len);
     111static void _yahoo_http_connected(int id, void *fd, int error, void *data);
     112static void yahoo_connected(void *fd, int error, void *data);
     113
     114int yahoo_log_message(char *fmt, ...)
    109115{
    110116        char out[1024];
     
    113119        vsnprintf(out, sizeof(out), fmt, ap);
    114120        va_end(ap);
    115         return YAHOO_CALLBACK(ext_yahoo_log)("%s", out);
    116 }
    117 
    118 int yahoo_connect(char * host, int port)
    119 {
    120         return YAHOO_CALLBACK(ext_yahoo_connect)(host, port);
     121        return YAHOO_CALLBACK(ext_yahoo_log) ("%s", out);
     122}
     123
     124int yahoo_connect(char *host, int port)
     125{
     126        return YAHOO_CALLBACK(ext_yahoo_connect) (host, port);
    121127}
    122128
     
    136142
    137143/* default values for servers */
    138 static char pager_host[] = "scs.msg.yahoo.com";
     144static 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
    139150static int pager_port = 5050;
    140 static int fallback_ports[]={23, 25, 80, 20, 119, 8001, 8002, 5050, 0};
    141 static char filetransfer_host[]="filetransfer.msg.yahoo.com";
    142 static int filetransfer_port=80;
    143 static char webcam_host[]="webcam.yahoo.com";
    144 static int webcam_port=5100;
    145 static char webcam_description[]="";
    146 static char local_host[]="";
    147 static int conn_type=Y_WCM_DSL;
     151static int fallback_ports[] = { 23, 25, 80, 20, 119, 8001, 8002, 5050, 0 };
     152
     153static char filetransfer_host[] = "filetransfer.msg.yahoo.com";
     154static int filetransfer_port = 80;
     155static char webcam_host[] = "webcam.yahoo.com";
     156static int webcam_port = 5100;
     157static char webcam_description[] = "";
     158static char local_host[] = "";
     159static int conn_type = Y_WCM_DSL;
    148160
    149161static char profile_url[] = "http://profiles.yahoo.com/";
    150162
    151 enum 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,
     163struct connect_callback_data {
     164        struct yahoo_data *yd;
     165        int tag;
     166        int i;
     167        int server_i;
    229168};
    230169
     
    242181
    243182struct yahoo_search_state {
    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;
     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;
    253192};
    254193
     
    264203        struct yahoo_search_state *ys;
    265204
    266         int   fd;
     205        void *fd;
    267206        enum yahoo_connection_type type;
    268        
    269         unsigned char   *rxqueue;
    270         int   rxlen;
    271         int   read_tag;
     207
     208        unsigned char *rxqueue;
     209        int rxlen;
     210        int read_tag;
    272211
    273212        YList *txqueues;
    274         int   write_tag;
     213        int write_tag;
    275214};
    276215
    277216struct yahoo_server_settings {
    278217        char *pager_host;
    279         int   pager_port;
     218        int pager_port;
    280219        char *filetransfer_host;
    281         int   filetransfer_port;
     220        int filetransfer_port;
    282221        char *webcam_host;
    283         int   webcam_port;
     222        int webcam_port;
    284223        char *webcam_description;
    285224        char *local_host;
    286         int   conn_type;
     225        int conn_type;
     226        char **pager_host_list;
    287227};
    288228
    289 static 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);
     229static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over);
     230
     231static void yahoo_process_filetransfer(struct yahoo_input_data *yid,
     232        struct yahoo_packet *pkt);
     233static void yahoo_process_filetransferinfo(struct yahoo_input_data *yid,
     234        struct yahoo_packet *pkt);
     235static void yahoo_process_filetransferaccept(struct yahoo_input_data *yid,
     236        struct yahoo_packet *pkt);
     237
     238static void yahoo_https_auth(struct yahoo_input_data *yid, const char *seed, const char *sn);
     239
     240static 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
    294251        yss->pager_port = pager_port;
    295252        yss->filetransfer_host = strdup(filetransfer_host);
     
    304261}
    305262
    306 static void * _yahoo_assign_server_settings(va_list ap)
     263static void *_yahoo_assign_server_settings(va_list ap)
    307264{
    308265        struct yahoo_server_settings *yss = _yahoo_default_server_settings();
    309266        char *key;
    310267        char *svalue;
    311         int   nvalue;
    312 
    313         while(1) {
     268        int nvalue;
     269        char **pvalue;
     270
     271        while (1) {
    314272                key = va_arg(ap, char *);
    315                 if(key == NULL)
    316                         break;
    317 
    318                 if(!strcmp(key, "pager_host")) {
     273                if (key == NULL)
     274                        break;
     275
     276                if (!strcmp(key, "pager_host")) {
    319277                        svalue = va_arg(ap, char *);
    320278                        free(yss->pager_host);
    321279                        yss->pager_host = strdup(svalue);
    322                 } else if(!strcmp(key, "pager_port")) {
     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")) {
    323287                        nvalue = va_arg(ap, int);
    324288                        yss->pager_port = nvalue;
    325                 } else if(!strcmp(key, "filetransfer_host")) {
     289                } else if (!strcmp(key, "filetransfer_host")) {
    326290                        svalue = va_arg(ap, char *);
    327291                        free(yss->filetransfer_host);
    328292                        yss->filetransfer_host = strdup(svalue);
    329                 } else if(!strcmp(key, "filetransfer_port")) {
     293                } else if (!strcmp(key, "filetransfer_port")) {
    330294                        nvalue = va_arg(ap, int);
    331295                        yss->filetransfer_port = nvalue;
    332                 } else if(!strcmp(key, "webcam_host")) {
     296                } else if (!strcmp(key, "webcam_host")) {
    333297                        svalue = va_arg(ap, char *);
    334298                        free(yss->webcam_host);
    335299                        yss->webcam_host = strdup(svalue);
    336                 } else if(!strcmp(key, "webcam_port")) {
     300                } else if (!strcmp(key, "webcam_port")) {
    337301                        nvalue = va_arg(ap, int);
    338302                        yss->webcam_port = nvalue;
    339                 } else if(!strcmp(key, "webcam_description")) {
     303                } else if (!strcmp(key, "webcam_description")) {
    340304                        svalue = va_arg(ap, char *);
    341305                        free(yss->webcam_description);
    342306                        yss->webcam_description = strdup(svalue);
    343                 } else if(!strcmp(key, "local_host")) {
     307                } else if (!strcmp(key, "local_host")) {
    344308                        svalue = va_arg(ap, char *);
    345309                        free(yss->local_host);
    346310                        yss->local_host = strdup(svalue);
    347                 } else if(!strcmp(key, "conn_type")) {
     311                } else if (!strcmp(key, "conn_type")) {
    348312                        nvalue = va_arg(ap, int);
    349313                        yss->conn_type = nvalue;
    350314                } else {
    351315                        WARNING(("Unknown key passed to yahoo_init, "
    352                                 "perhaps you didn't terminate the list "
    353                                 "with NULL"));
     316                                        "perhaps you didn't terminate the list "
     317                                        "with NULL"));
    354318                }
    355319        }
     
    360324static void yahoo_free_server_settings(struct yahoo_server_settings *yss)
    361325{
    362         if(!yss)
     326        if (!yss)
    363327                return;
    364328
     
    372336}
    373337
    374 static YList *conns=NULL;
    375 static YList *inputs=NULL;
    376 static int last_id=0;
     338static YList *conns = NULL;
     339static YList *inputs = NULL;
     340static int last_id = 0;
    377341
    378342static void add_to_list(struct yahoo_data *yd)
     
    380344        conns = y_list_prepend(conns, yd);
    381345}
    382 static struct yahoo_data * find_conn_by_id(int id)
     346
     347static struct yahoo_data *find_conn_by_id(int id)
    383348{
    384349        YList *l;
    385         for(l = conns; l; l = y_list_next(l)) {
     350        for (l = conns; l; l = y_list_next(l)) {
    386351                struct yahoo_data *yd = l->data;
    387                 if(yd->client_id == id)
     352                if (yd->client_id == id)
    388353                        return yd;
    389354        }
    390355        return NULL;
    391356}
     357
    392358static void del_from_list(struct yahoo_data *yd)
    393359{
     
    396362
    397363/* call repeatedly to get the next one */
     364/*
    398365static struct yahoo_input_data * find_input_by_id(int id)
    399366{
     
    406373        return NULL;
    407374}
    408 
    409 static struct yahoo_input_data * find_input_by_id_and_webcam_user(int id, const char * who)
     375*/
     376
     377static struct yahoo_input_data *find_input_by_id_and_webcam_user(int id,
     378        const char *who)
    410379{
    411380        YList *l;
    412381        LOG(("find_input_by_id_and_webcam_user"));
    413         for(l = inputs; l; l = y_list_next(l)) {
     382        for (l = inputs; l; l = y_list_next(l)) {
    414383                struct yahoo_input_data *yid = l->data;
    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)))
     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)))
    419389                        return yid;
    420390        }
     
    422392}
    423393
    424 static struct yahoo_input_data * find_input_by_id_and_type(int id, enum yahoo_connection_type type)
     394static struct yahoo_input_data *find_input_by_id_and_type(int id,
     395        enum yahoo_connection_type type)
    425396{
    426397        YList *l;
    427398        LOG(("find_input_by_id_and_type"));
    428         for(l = inputs; l; l = y_list_next(l)) {
     399        for (l = inputs; l; l = y_list_next(l)) {
    429400                struct yahoo_input_data *yid = l->data;
    430                 if(yid->type == type && yid->yd->client_id == id)
     401                if (yid->type == type && yid->yd->client_id == id)
    431402                        return yid;
    432403        }
     
    434405}
    435406
    436 static struct yahoo_input_data * find_input_by_id_and_fd(int id, int fd)
     407static struct yahoo_input_data *find_input_by_id_and_fd(int id, void *fd)
    437408{
    438409        YList *l;
    439410        LOG(("find_input_by_id_and_fd"));
    440         for(l = inputs; l; l = y_list_next(l)) {
     411        for (l = inputs; l; l = y_list_next(l)) {
    441412                struct yahoo_input_data *yid = l->data;
    442                 if(yid->fd == fd && yid->yd->client_id == id)
     413                if (yid->fd == fd && yid->yd->client_id == id)
    443414                        return yid;
    444415        }
     
    448419static int count_inputs_with_id(int id)
    449420{
    450         int c=0;
     421        int c = 0;
    451422        YList *l;
    452423        LOG(("counting %d", id));
    453         for(l = inputs; l; l = y_list_next(l)) {
     424        for (l = inputs; l; l = y_list_next(l)) {
    454425                struct yahoo_input_data *yid = l->data;
    455                 if(yid->yd->client_id == id)
     426                if (yid->yd->client_id == id)
    456427                        c++;
    457428        }
     
    460431}
    461432
    462 
    463433extern char *yahoo_crypt(char *, char *);
    464434
    465435/* Free a buddy list */
    466 static void yahoo_free_buddies(YList * list)
     436static void yahoo_free_buddies(YList *list)
    467437{
    468438        YList *l;
    469439
    470         for(l = list; l; l = l->next)
    471         {
     440        for (l = list; l; l = l->next) {
    472441                struct yahoo_buddy *bud = l->data;
    473                 if(!bud)
     442                if (!bud)
    474443                        continue;
    475444
     
    477446                FREE(bud->id);
    478447                FREE(bud->real_name);
    479                 if(bud->yab_entry) {
     448                if (bud->yab_entry) {
    480449                        FREE(bud->yab_entry->fname);
    481450                        FREE(bud->yab_entry->lname);
     
    496465
    497466/* Free an identities list */
    498 static void yahoo_free_identities(YList * list)
     467static void yahoo_free_identities(YList *list)
    499468{
    500469        while (list) {
     
    525494        FREE(yd->cookie_y);
    526495        FREE(yd->cookie_t);
     496        FREE(yd->cookie_b);
    527497        FREE(yd->cookie_c);
    528498        FREE(yd->login_cookie);
     
    540510#define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4)
    541511
    542 static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, 
    543                 enum yahoo_status status, int id)
     512static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service,
     513        enum ypacket_status status, int id)
    544514{
    545515        struct yahoo_packet *pkt = y_new0(struct yahoo_packet, 1);
     
    552522}
    553523
    554 static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value)
     524static void yahoo_packet_hash(struct yahoo_packet *pkt, int key,
     525        const char *value)
    555526{
    556527        struct yahoo_pair *pair = y_new0(struct yahoo_pair, 1);
     
    597568                         (((*((buf)+3))&0xff)))
    598569
    599 static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data, int len)
     570static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data,
     571        int len)
    600572{
    601573        int pos = 0;
     
    650622                        FREE(value);
    651623                        pkt->hash = y_list_append(pkt->hash, pair);
    652                         DEBUG_MSG(("Key: %d  \tValue: %s", pair->key, pair->value));
     624                        DEBUG_MSG(("Key: %d  \tValue: %s", pair->key,
     625                                        pair->value));
    653626                } else {
    654627                        FREE(pair);
     
    690663}
    691664
    692 
    693665static void yahoo_packet_dump(unsigned char *data, int len)
    694666{
    695         if(yahoo_get_log_level() >= YAHOO_LOG_DEBUG) {
     667        if (yahoo_get_log_level() >= YAHOO_LOG_DEBUG) {
    696668                int i;
    697669                for (i = 0; i < len; i++) {
    698670                        if ((i % 8 == 0) && i)
    699                                 YAHOO_CALLBACK(ext_yahoo_log)(" ");
     671                                YAHOO_CALLBACK(ext_yahoo_log) (" ");
    700672                        if ((i % 16 == 0) && i)
    701                                 YAHOO_CALLBACK(ext_yahoo_log)("\n");
    702                         YAHOO_CALLBACK(ext_yahoo_log)("%02x ", data[i]);
    703                 }
    704                 YAHOO_CALLBACK(ext_yahoo_log)("\n");
     673                                YAHOO_CALLBACK(ext_yahoo_log) ("\n");
     674                        YAHOO_CALLBACK(ext_yahoo_log) ("%02x ", data[i]);
     675                }
     676                YAHOO_CALLBACK(ext_yahoo_log) ("\n");
    705677                for (i = 0; i < len; i++) {
    706678                        if ((i % 8 == 0) && i)
    707                                 YAHOO_CALLBACK(ext_yahoo_log)(" ");
     679                                YAHOO_CALLBACK(ext_yahoo_log) (" ");
    708680                        if ((i % 16 == 0) && i)
    709                                 YAHOO_CALLBACK(ext_yahoo_log)("\n");
     681                                YAHOO_CALLBACK(ext_yahoo_log) ("\n");
    710682                        if (isprint(data[i]))
    711                                 YAHOO_CALLBACK(ext_yahoo_log)(" %c ", data[i]);
     683                                YAHOO_CALLBACK(ext_yahoo_log) (" %c ", data[i]);
    712684                        else
    713                                 YAHOO_CALLBACK(ext_yahoo_log)(" . ");
    714                 }
    715                 YAHOO_CALLBACK(ext_yahoo_log)("\n");
     685                                YAHOO_CALLBACK(ext_yahoo_log) (" . ");
     686                }
     687                YAHOO_CALLBACK(ext_yahoo_log) ("\n");
    716688        }
    717689}
     
    723695}
    724696
    725 static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data, int length)
     697static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data,
     698        int length)
    726699{
    727700        struct data_queue *tx = y_new0(struct data_queue, 1);
     
    732705        yid->txqueues = y_list_append(yid->txqueues, tx);
    733706
    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 
    738 static void yahoo_send_packet(struct yahoo_input_data *yid, struct yahoo_packet *pkt, int extra_pad)
     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
     713static void yahoo_send_packet(struct yahoo_input_data *yid,
     714        struct yahoo_packet *pkt, int extra_pad)
    739715{
    740716        int pktlen = yahoo_packet_length(pkt);
    741717        int len = YAHOO_PACKET_HDRLEN + pktlen;
    742 
    743718        unsigned char *data;
    744719        int pos = 0;
     
    749724        data = y_new0(unsigned char, len + 1);
    750725
    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);
     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] */
    758734
    759735        yahoo_packet_write(pkt, data + pos);
    760736
    761737        yahoo_packet_dump(data, len);
    762        
    763         if( yid->type == YAHOO_CONNECTION_FT )
     738
     739        if (yid->type == YAHOO_CONNECTION_FT)
    764740                yahoo_send_data(yid->fd, data, len);
    765741        else
     
    782758}
    783759
    784 static int yahoo_send_data(int fd, void *data, int len)
     760static int yahoo_send_data(void *fd, void *data, int len)
    785761{
    786762        int ret;
    787763        int e;
    788764
    789         if (fd < 0)
     765        if (fd == NULL)
    790766                return -1;
    791767
     
    793769
    794770        do {
    795                 ret = write(fd, data, len);
    796         } while(ret == -1 && errno==EINTR);
    797         e=errno;
    798 
    799         if (ret == -1)  {
     771                ret = YAHOO_CALLBACK(ext_yahoo_write) (fd, data, len);
     772        } while (ret == -1 && errno == EINTR);
     773        e = errno;
     774
     775        if (ret == -1) {
    800776                LOG(("wrote data: ERR %s", strerror(errno)));
    801777        } else {
     
    803779        }
    804780
    805         errno=e;
     781        errno = e;
    806782        return ret;
    807783}
    808784
    809 void yahoo_close(int id) 
     785void yahoo_close(int id)
    810786{
    811787        struct yahoo_data *yd = find_conn_by_id(id);
    812        
    813         if(!yd)
     788        if (!yd)
    814789                return;
    815790
     
    817792
    818793        yahoo_free_data(yd);
    819         if(id == last_id)
     794        if (id == last_id)
    820795                last_id--;
    821796}
    822797
    823 static void yahoo_input_close(struct yahoo_input_data *yid) 
     798static void yahoo_input_close(struct yahoo_input_data *yid)
    824799{
    825800        inputs = y_list_remove(inputs, yid);
    826801
    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);
     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);
    831808        yid->read_tag = yid->write_tag = 0;
    832         if(yid->fd)
    833                 close(yid->fd);
     809        if (yid->fd)
     810                YAHOO_CALLBACK(ext_yahoo_close) (yid->fd);
    834811        yid->fd = 0;
    835812        FREE(yid->rxqueue);
    836         if(count_inputs_with_id(yid->yd->client_id) == 0) {
     813        if (count_inputs_with_id(yid->yd->client_id) == 0) {
    837814                LOG(("closing %d", yid->yd->client_id));
    838815                yahoo_close(yid->yd->client_id);
    839816        }
    840817        yahoo_free_webcam(yid->wcm);
    841         if(yid->wcd)
     818        if (yid->wcd)
    842819                FREE(yid->wcd);
    843         if(yid->ys) {
     820        if (yid->ys) {
    844821                FREE(yid->ys->lsearch_text);
    845822                FREE(yid->ys);
     
    848825}
    849826
    850 static int is_same_bud(const void * a, const void * b) {
     827static int is_same_bud(const void *a, const void *b)
     828{
    851829        const struct yahoo_buddy *subject = a;
    852830        const struct yahoo_buddy *object = b;
     
    855833}
    856834
    857 static char * getcookie(char *rawcookie)
    858 {
    859         char * cookie=NULL;
    860         char * tmpcookie;
    861         char * cookieend;
    862 
    863         if (strlen(rawcookie) < 2) 
     835static char *getcookie(char *rawcookie)
     836{
     837        char *cookie = NULL;
     838        char *tmpcookie;
     839        char *cookieend;
     840
     841        if (strlen(rawcookie) < 2)
    864842                return NULL;
    865843
    866         tmpcookie = strdup(rawcookie+2);
     844        tmpcookie = strdup(rawcookie + 2);
    867845        cookieend = strchr(tmpcookie, ';');
    868846
    869         if(cookieend)
     847        if (cookieend)
    870848                *cookieend = '\0';
    871849
     
    877855}
    878856
    879 static char * getlcookie(char *cookie)
     857static char *getlcookie(char *cookie)
    880858{
    881859        char *tmp;
     
    884862
    885863        tmpend = strstr(cookie, "n=");
    886         if(tmpend) {
    887                 tmp = strdup(tmpend+2);
     864        if (tmpend) {
     865                tmp = strdup(tmpend + 2);
    888866                tmpend = strchr(tmp, '&');
    889                 if(tmpend)
    890                         *tmpend='\0';
     867                if (tmpend)
     868                        *tmpend = '\0';
    891869                login_cookie = strdup(tmp);
    892870                FREE(tmp);
     
    896874}
    897875
    898 static void yahoo_process_notify(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     876static void yahoo_process_notify(struct yahoo_input_data *yid,
     877        struct yahoo_packet *pkt)
    899878{
    900879        struct yahoo_data *yd = yid->yd;
     
    927906        if (!msg)
    928907                return;
    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         {
     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"))) {
    936916                if (!strcmp(ind, " ")) {
    937                         YAHOO_CALLBACK(ext_yahoo_webcam_invite)(yd->client_id, to, from);
     917                        YAHOO_CALLBACK(ext_yahoo_webcam_invite) (yd->client_id,
     918                                to, from);
    938919                } else {
    939920                        accept = atoi(ind);
     
    941922                        if (accept < 0)
    942923                                accept = 0;
    943                         YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply)(yd->client_id, to, from, accept);
    944                 }
    945         }
    946         else
     924                        YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply) (yd->
     925                                client_id, to, from, accept);
     926                }
     927        } else
    947928                LOG(("Got unknown notification: %s", msg));
    948929}
    949930
    950 static 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 
    1006 static void yahoo_process_conference(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     931static void yahoo_process_conference(struct yahoo_input_data *yid,
     932        struct yahoo_packet *pkt)
    1007933{
    1008934        struct yahoo_data *yd = yid->yd;
     
    1012938        char *room = NULL;
    1013939        char *id = NULL;
    1014         int  utf8 = 0;
     940        int utf8 = 0;
    1015941        YList *members = NULL;
    1016942        YList *l;
    1017        
     943
    1018944        for (l = pkt->hash; l; l = l->next) {
    1019945                struct yahoo_pair *pair = l->data;
    1020946                if (pair->key == 50)
    1021947                        host = pair->value;
    1022                
    1023                 if (pair->key == 52) {          /* invite */
     948
     949                if (pair->key == 52) {  /* invite */
    1024950                        members = y_list_append(members, strdup(pair->value));
    1025951                }
    1026                 if (pair->key == 53)            /* logon */
     952                if (pair->key == 53)    /* logon */
    1027953                        who = pair->value;
    1028                 if (pair->key == 54)            /* decline */
     954                if (pair->key == 54)    /* decline */
    1029955                        who = pair->value;
    1030                 if (pair->key == 55)            /* unavailable (status == 2) */
     956                if (pair->key == 55)    /* unavailable (status == 2) */
    1031957                        who = pair->value;
    1032                 if (pair->key == 56)            /* logoff */
     958                if (pair->key == 56)    /* logoff */
    1033959                        who = pair->value;
    1034960
     
    1036962                        room = pair->value;
    1037963
    1038                 if (pair->key == 58)            /* join message */
     964                if (pair->key == 58)    /* join message */
    1039965                        msg = pair->value;
    1040                 if (pair->key == 14)            /* decline/conf message */
     966                if (pair->key == 14)    /* decline/conf message */
    1041967                        msg = pair->value;
    1042968
    1043                 if (pair->key == 13)
    1044                         ;
    1045                 if (pair->key == 16)            /* error */
     969                if (pair->key == 13) ;
     970                if (pair->key == 16)    /* error */
    1046971                        msg = pair->value;
    1047972
    1048                 if (pair->key == 1)             /* my id */
     973                if (pair->key == 1)     /* my id */
    1049974                        id = pair->value;
    1050                 if (pair->key == 3)             /* message sender */
     975                if (pair->key == 3)     /* message sender */
    1051976                        who = pair->value;
    1052977
     
    1055980        }
    1056981
    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))
     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))
    1064989                                break;
    1065990                }
    1066                 if(!l)
     991                if (!l)
    1067992                        members = y_list_append(members, strdup(host));
    1068993        }
    1069994        /* invite, decline, join, left, message -> status == 1 */
    1070995
    1071         switch(pkt->service) {
     996        switch (pkt->service) {
    1072997        case YAHOO_SERVICE_CONFINVITE:
    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);
     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);
    10791005                break;
    10801006        case YAHOO_SERVICE_CONFADDINVITE:
    1081                 if(pkt->status == 2)
    1082                         ;
    1083                 else
    1084                         YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members);
     1007                if (pkt->status == 1)
     1008                        YAHOO_CALLBACK(ext_yahoo_got_conf_invite) (yd->
     1009                                client_id, id, host, room, msg, members);
    10851010                break;
    10861011        case YAHOO_SERVICE_CONFDECLINE:
    1087                 if(who)
    1088                         YAHOO_CALLBACK(ext_yahoo_conf_userdecline)(yd->client_id, id, who, room, msg);
     1012                if (who)
     1013                        YAHOO_CALLBACK(ext_yahoo_conf_userdecline) (yd->
     1014                                client_id, id, who, room, msg);
    10891015                break;
    10901016        case YAHOO_SERVICE_CONFLOGON:
    1091                 if(who)
    1092                         YAHOO_CALLBACK(ext_yahoo_conf_userjoin)(yd->client_id, id, who, room);
     1017                if (who)
     1018                        YAHOO_CALLBACK(ext_yahoo_conf_userjoin) (yd->client_id,
     1019                                id, who, room);
    10931020                break;
    10941021        case YAHOO_SERVICE_CONFLOGOFF:
    1095                 if(who)
    1096                         YAHOO_CALLBACK(ext_yahoo_conf_userleave)(yd->client_id, id, who, room);
     1022                if (who)
     1023                        YAHOO_CALLBACK(ext_yahoo_conf_userleave) (yd->client_id,
     1024                                id, who, room);
    10971025                break;
    10981026        case YAHOO_SERVICE_CONFMSG:
    1099                 if(who)
    1100                         YAHOO_CALLBACK(ext_yahoo_conf_message)(yd->client_id, id, who, room, msg, utf8);
     1027                if (who)
     1028                        YAHOO_CALLBACK(ext_yahoo_conf_message) (yd->client_id,
     1029                                id, who, room, msg, utf8);
    11011030                break;
    11021031        }
    11031032}
    11041033
    1105 static void yahoo_process_chat(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     1034static void yahoo_process_chat(struct yahoo_input_data *yid,
     1035        struct yahoo_packet *pkt)
    11061036{
    11071037        char *msg = NULL;
     
    11121042        YList *members = NULL;
    11131043        struct yahoo_chat_member *currentmember = NULL;
    1114         int  msgtype = 1;
    1115         int  utf8 = 0;
    1116         int  firstjoin = 0;
    1117         int  membercount = 0;
    1118         int  chaterr=0;
     1044        int msgtype = 1;
     1045        int utf8 = 0;
     1046        int firstjoin = 0;
     1047        int membercount = 0;
     1048        int chaterr = 0;
    11191049        YList *l;
    1120        
     1050
    11211051        yahoo_dump_unhandled(pkt);
    11221052        for (l = pkt->hash; l; l = l->next) {
     
    11481078
    11491079                        if (pkt->service == YAHOO_SERVICE_CHATJOIN) {
    1150                                 currentmember = y_new0(struct yahoo_chat_member, 1);
     1080                                currentmember =
     1081                                        y_new0(struct yahoo_chat_member, 1);
    11511082                                currentmember->id = strdup(pair->value);
    11521083                                members = y_list_append(members, currentmember);
     
    11781109                }
    11791110
    1180 
    11811111                if (pair->key == 130) {
    11821112                        /* first join */
     
    11961126                        /* message error not sure what all the pair values mean */
    11971127                        /* but -1 means no session in room */
    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);
     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);
    12091136                        return;
    12101137                }
     1138                if (pkt->service == YAHOO_SERVICE_COMMENT && chaterr) {
     1139                        YAHOO_CALLBACK(ext_yahoo_chat_yahooerror) (yid->yd->
     1140                                client_id, id);
     1141                        return;
     1142                }
    12111143
    12121144                WARNING(("We didn't get a room name, ignoring packet"));
     
    12141146        }
    12151147
    1216         switch(pkt->service) {
     1148        switch (pkt->service) {
    12171149        case YAHOO_SERVICE_CHATJOIN:
    1218                 if(y_list_length(members) != membercount) {
     1150                if (y_list_length(members) != membercount) {
    12191151                        WARNING(("Count of members doesn't match No. of members we got"));
    12201152                }
    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) {
     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) {
    12251158                                WARNING(("Got more than 1 member on a normal join"));
    12261159                        }
    12271160                        /* this should only ever have one, but just in case */
    1228                         while(members) {
     1161                        while (members) {
    12291162                                YList *n = members->next;
    12301163                                currentmember = members->data;
    1231                                 YAHOO_CALLBACK(ext_yahoo_chat_userjoin)(yid->yd->client_id, id, room, currentmember);
     1164                                YAHOO_CALLBACK(ext_yahoo_chat_userjoin) (yid->
     1165                                        yd->client_id, id, room, currentmember);
    12321166                                y_list_free_1(members);
    1233                                 members=n;
     1167                                members = n;
    12341168                        }
    12351169                }
    12361170                break;
    12371171        case YAHOO_SERVICE_CHATEXIT:
    1238                 if(who) {
    1239                         YAHOO_CALLBACK(ext_yahoo_chat_userleave)(yid->yd->client_id, id, room, who);
     1172                if (who) {
     1173                        YAHOO_CALLBACK(ext_yahoo_chat_userleave) (yid->yd->
     1174                                client_id, id, room, who);
    12401175                }
    12411176                break;
    12421177        case YAHOO_SERVICE_COMMENT:
    1243                 if(who) {
    1244                         YAHOO_CALLBACK(ext_yahoo_chat_message)(yid->yd->client_id, id, who, room, msg, msgtype, utf8);
     1178                if (who) {
     1179                        YAHOO_CALLBACK(ext_yahoo_chat_message) (yid->yd->
     1180                                client_id, id, who, room, msg, msgtype, utf8);
    12451181                }
    12461182                break;
     
    12481184}
    12491185
    1250 static void yahoo_process_message(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     1186static void yahoo_process_message(struct yahoo_input_data *yid,
     1187        struct yahoo_packet *pkt)
    12511188{
    12521189        struct yahoo_data *yd = yid->yd;
    12531190        YList *l;
    1254         YList * messages = NULL;
     1191        YList *messages = NULL;
    12551192
    12561193        struct m {
    1257                 int  i_31;
    1258                 int  i_32;
     1194                int i_31;
     1195                int i_32;
    12591196                char *to;
    12601197                char *from;
    12611198                long tm;
    12621199                char *msg;
    1263                 int  utf8;
     1200                int utf8;
     1201                char *gunk;
    12641202        } *message = y_new0(struct m, 1);
    12651203
    12661204        for (l = pkt->hash; l; l = l->next) {
    12671205                struct yahoo_pair *pair = l->data;
    1268                 if (pair->key == 1 || pair->key == 4)
    1269                 {
    1270                         if(!message->from)
     1206                if (pair->key == 1 || pair->key == 4) {
     1207                        if (!message->from)
    12711208                                message->from = pair->value;
    1272                 }
    1273                 else if (pair->key == 5)
     1209                } else if (pair->key == 5)
    12741210                        message->to = pair->value;
    12751211                else if (pair->key == 15)
     
    12771213                else if (pair->key == 97)
    12781214                        message->utf8 = atoi(pair->value);
    1279                         /* user message */  /* sys message */
     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 */
    12801219                else if (pair->key == 14 || pair->key == 16)
    12811220                        message->msg = pair->value;
    12821221                else if (pair->key == 31) {
    1283                         if(message->i_31) {
     1222                        if (message->i_31) {
    12841223                                messages = y_list_append(messages, message);
    12851224                                message = y_new0(struct m, 1);
    12861225                        }
    12871226                        message->i_31 = atoi(pair->value);
    1288                 }
    1289                 else if (pair->key == 32)
     1227                } else if (pair->key == 32)
    12901228                        message->i_32 = atoi(pair->value);
    12911229                else
    1292                         LOG(("yahoo_process_message: status: %d, key: %d, value: %s",
    1293                                         pkt->status, pair->key, pair->value));
     1230                        LOG(("yahoo_process_message: status: %d, key: %d, value: %s", pkt->status, pair->key, pair->value));
    12941231        }
    12951232
    12961233        messages = y_list_append(messages, message);
    12971234
    1298         for (l = messages; l; l=l->next) {
     1235        for (l = messages; l; l = l->next) {
    12991236                message = l->data;
    13001237                if (pkt->service == YAHOO_SERVICE_SYSMESSAGE) {
    1301                         YAHOO_CALLBACK(ext_yahoo_system_message)(yd->client_id, message->msg);
     1238                        YAHOO_CALLBACK(ext_yahoo_system_message) (yd->client_id,
     1239                                message->to, message->from, message->msg);
    13021240                } else if (pkt->status <= 2 || pkt->status == 5) {
    1303                         YAHOO_CALLBACK(ext_yahoo_got_im)(yd->client_id, message->to, message->from, message->msg, message->tm, pkt->status, message->utf8);
     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);
    13041265                } else if (pkt->status == 0xffffffff) {
    1305                         YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, message->msg, 0, E_SYSTEM);
    1306                 }
    1307                 free(message);
     1266                        YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id,
     1267                                message->msg, 0, E_SYSTEM);
     1268                }
     1269                FREE(message);
    13081270        }
    13091271
     
    13111273}
    13121274
     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 */
    13131298static void yahoo_process_status(struct yahoo_input_data *yid,
    13141299        struct yahoo_packet *pkt)
     
    13271312        }
    13281313
    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). */
     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         */
    13331320        u = yd->half_user;
    13341321
     
    15941581}
    15951582
    1596 static void yahoo_process_verify(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     1583static void yahoo_process_verify(struct yahoo_input_data *yid,
     1584        struct yahoo_packet *pkt)
    15971585{
    15981586        struct yahoo_data *yd = yid->yd;
    15991587
    1600         if(pkt->status != 0x01) {
     1588        if (pkt->status != 0x01) {
    16011589                DEBUG_MSG(("expected status: 0x01, got: %d", pkt->status));
    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);
     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);
    16071597
    16081598        yahoo_packet_hash(pkt, 1, yd->user);
     
    16131603}
    16141604
    1615 static void yahoo_process_picture_checksum( struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     1605static void yahoo_process_picture_checksum(struct yahoo_input_data *yid,
     1606        struct yahoo_packet *pkt)
    16161607{
    16171608        struct yahoo_data *yd = yid->yd;
     
    16211612        YList *l;
    16221613
    1623         for(l = pkt->hash; l; l = l->next)
    1624         {
     1614        for (l = pkt->hash; l; l = l->next) {
    16251615                struct yahoo_pair *pair = l->data;
    16261616
    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 
    1646 static void yahoo_process_picture(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     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
     1636static void yahoo_process_picture(struct yahoo_input_data *yid,
     1637        struct yahoo_packet *pkt)
    16471638{
    16481639        struct yahoo_data *yd = yid->yd;
     
    16531644        int checksum = 0;
    16541645        YList *l;
    1655        
    1656         for(l = pkt->hash; l; l = l->next)
    1657         {
     1646
     1647        for (l = pkt->hash; l; l = l->next) {
    16581648                struct yahoo_pair *pair = l->data;
    16591649
    1660                 switch(pair->key)
    1661                 {
     1650                switch (pair->key) {
    16621651                case 1:
    1663                 case 4:         /* sender */
     1652                case 4: /* sender */
    16641653                        from = pair->value;
    16651654                        break;
    1666                 case 5:         /* we */
     1655                case 5: /* we */
    16671656                        to = pair->value;
    16681657                        break;
    1669                 case 13:                /* request / sending */
    1670                         status = atoi( pair->value );
    1671                         break;
    1672                 case 20:                /* url */
     1658                case 13:        /* request / sending */
     1659                        status = atoi(pair->value);
     1660                        break;
     1661                case 20:        /* url */
    16731662                        url = pair->value;
    16741663                        break;
    16751664                case 192:       /*checksum */
    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 
    1692 static void yahoo_process_picture_upload(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     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
     1682static void yahoo_process_picture_upload(struct yahoo_input_data *yid,
     1683        struct yahoo_packet *pkt)
    16931684{
    16941685        struct yahoo_data *yd = yid->yd;
     
    16961687        char *url = NULL;
    16971688
    1698         if ( pkt->status != 1 )
     1689        if (pkt->status != 1)
    16991690                return;         /* something went wrong */
    1700        
    1701         for(l = pkt->hash; l; l = l->next)
    1702         {
     1691
     1692        for (l = pkt->hash; l; l = l->next) {
    17031693                struct yahoo_pair *pair = l->data;
    17041694
    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 
    1722 static 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.
     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
     1711void 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
    17371742         */
    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  */
    1841 static 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);
     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);
    22561748}
    22571749
     
    23031795}
    23041796
    2305 static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn)
     1797static void yahoo_https_auth(struct yahoo_input_data *yid, const char *seed, const char *sn)
    23061798{
    23071799        struct yahoo_https_auth_data *had = g_new0(struct yahoo_https_auth_data, 1);
     
    23531845       
    23541846        if (req->status_code != 200) {
    2355                 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL);
     1847                YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 2000 + req->status_code, NULL);
    23561848                goto fail;
    23571849        }
    23581850       
    23591851        if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) {
    2360                 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL);
     1852                YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, yahoo_https_status_parse(st), NULL);
    23611853                goto fail;
    23621854        }
    23631855       
    23641856        if ((had->token = yahoo_ha_find_key(req->reply_body, "ymsgr")) == NULL) {
    2365                 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3001, NULL);
     1857                YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 3001, NULL);
    23661858                goto fail;
    23671859        }
     
    24091901
    24101902        if (req->status_code != 200) {
    2411                 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL);
     1903                YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 2000 + req->status_code, NULL);
    24121904                goto fail;
    24131905        }
    24141906       
    24151907        if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) {
    2416                 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL);
     1908                YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, yahoo_https_status_parse(st), NULL);
    24171909                goto fail;
    24181910        }
     
    24211913            (yd->cookie_t = yahoo_ha_find_key(req->reply_body, "T")) == NULL ||
    24221914            (crumb = yahoo_ha_find_key(req->reply_body, "crumb")) == NULL) {
    2423                 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3002, NULL);
     1915                YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 3002, NULL);
    24241916                goto fail;
    24251917        }
     
    24541946}
    24551947
    2456 static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     1948static void yahoo_process_auth(struct yahoo_input_data *yid,
     1949        struct yahoo_packet *pkt)
    24571950{
    24581951        char *seed = NULL;
    2459         char *sn   = NULL;
     1952        char *sn = NULL;
    24601953        YList *l = pkt->hash;
    24611954        int m = 0;
     1955        struct yahoo_data *yd = yid->yd;
    24621956
    24631957        while (l) {
    24641958                struct yahoo_pair *pair = l->data;
    2465                 if (pair->key == 94)
     1959
     1960                switch (pair->key) {
     1961                case 94:
    24661962                        seed = pair->value;
    2467                 if (pair->key == 1)
     1963                        break;
     1964                case 1:
    24681965                        sn = pair->value;
    2469                 if (pair->key == 13)
     1966                        break;
     1967                case 13:
    24701968                        m = atoi(pair->value);
     1969                        break;
     1970                }
    24711971                l = l->next;
    24721972        }
    24731973
    2474         if (!seed)
    2475                 return;
    2476 
    2477         switch (m) {
    2478                 case 0:
    2479                         yahoo_process_auth_pre_0x0b(yid, seed, sn);
    2480                         break;
    2481                 case 1:
    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 
    2495 static void yahoo_process_auth_resp(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     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
     1987static void yahoo_process_auth_resp(struct yahoo_input_data *yid,
     1988        struct yahoo_packet *pkt)
    24961989{
    24971990        struct yahoo_data *yd = yid->yd;
    24981991        char *login_id;
    24991992        char *handle;
    2500         char *url=NULL;
    2501         int  login_status=0;
     1993        char *url = NULL;
     1994        int login_status = -1;
    25021995
    25031996        YList *l;
     
    25152008        }
    25162009
    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 
    2523 static void yahoo_process_mail(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     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
     2017static void yahoo_process_mail(struct yahoo_input_data *yid,
     2018        struct yahoo_packet *pkt)
    25242019{
    25252020        struct yahoo_data *yd = yid->yd;
     
    25472042                char from[1024];
    25482043                snprintf(from, sizeof(from), "%s (%s)", who, email);
    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 
    2554 static void yahoo_process_contact(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     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
     2051static 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? */
     2082static void yahoo_process_contact(struct yahoo_input_data *yid,
     2083        struct yahoo_packet *pkt)
    25552084{
    25562085        struct yahoo_data *yd = yid->yd;
     
    25612090        long tm = 0L;
    25622091        int state = YAHOO_STATUS_AVAILABLE;
    2563         int online = FALSE;
     2092        int online = 0;
    25642093        int away = 0;
    25652094        int idle = 0;
     
    25902119                else if (pair->key == 60)
    25912120                        mobile = strtol(pair->value, NULL, 10);
    2592                
     2121
    25932122        }
    25942123
    25952124        if (id)
    2596                 YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, id, who, msg);
     2125                YAHOO_CALLBACK(ext_yahoo_contact_added) (yd->client_id, id, who,
     2126                        msg);
    25972127        else if (name)
    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 
    2603 static void yahoo_process_buddyadd(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     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
     2134static void yahoo_process_buddyadd(struct yahoo_input_data *yid,
     2135        struct yahoo_packet *pkt)
    26042136{
    26052137        struct yahoo_data *yd = yid->yd;
     
    26092141        char *me = NULL;
    26102142
    2611         struct yahoo_buddy *bud=NULL;
     2143        struct yahoo_buddy *bud = NULL;
    26122144
    26132145        YList *l;
     
    26242156        }
    26252157
    2626         yahoo_dump_unhandled(pkt);
    2627 
    2628         if(!who)
    2629                 return;
    2630         if(!where)
     2158        if (!who)
     2159                return;
     2160        if (!where)
    26312161                where = "Unknown";
    26322162
    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 
    2650 static 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 
    2670 static void yahoo_process_buddydel(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     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
     2180static void yahoo_process_buddydel(struct yahoo_input_data *yid,
     2181        struct yahoo_packet *pkt)
    26712182{
    26722183        struct yahoo_data *yd = yid->yd;
     
    26912202                        unk_66 = strtol(pair->value, NULL, 10);
    26922203                else
    2693                         DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value));
    2694         }
    2695 
    2696         if(!who || !where)
    2697                 return;
    2698        
     2204                        DEBUG_MSG(("unknown key: %d = %s", pair->key,
     2205                                        pair->value));
     2206        }
     2207
     2208        if (!who || !where)
     2209                return;
     2210
    26992211        bud = y_new0(struct yahoo_buddy, 1);
    27002212        bud->id = strdup(who);
     
    27072219        FREE(bud);
    27082220
    2709         if(buddy) {
     2221        if (buddy) {
    27102222                bud = buddy->data;
    27112223                yd->buddies = y_list_remove_link(yd->buddies, buddy);
     
    27172229                FREE(bud);
    27182230
    2719                 bud=NULL;
    2720         }
    2721 }
    2722 
    2723 static void yahoo_process_ignore(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     2231                bud = NULL;
     2232        }
     2233}
     2234
     2235static void yahoo_process_ignore(struct yahoo_input_data *yid,
     2236        struct yahoo_packet *pkt)
    27242237{
    27252238        char *who = NULL;
    2726         int  status = 0;
     2239        int status = 0;
    27272240        char *me = NULL;
    2728         int  un_ignore = 0;
     2241        int un_ignore = 0;
    27292242
    27302243        YList *l;
     
    27352248                if (pair->key == 1)
    27362249                        me = pair->value;
    2737                 if (pair->key == 13) /* 1 == ignore, 2 == unignore */
     2250                if (pair->key == 13)    /* 1 == ignore, 2 == unignore */
    27382251                        un_ignore = strtol(pair->value, NULL, 10);
    2739                 if (pair->key == 66) 
     2252                if (pair->key == 66)
    27402253                        status = strtol(pair->value, NULL, 10);
    27412254        }
    2742 
    27432255
    27442256        /*
    27452257         * status
    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
     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
    27502262         */
    27512263
    27522264/*      if(status)
    27532265                YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, who, 0, status);
    2754 */     
    2755 }
    2756 
    2757 static void yahoo_process_voicechat(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     2266*/
     2267}
     2268
     2269static void yahoo_process_voicechat(struct yahoo_input_data *yid,
     2270        struct yahoo_packet *pkt)
    27582271{
    27592272        char *who = NULL;
     
    27702283                        me = pair->value;
    27712284                if (pair->key == 13)
    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));
     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));
    27782292        /*
    27792293         * send: s:0 1:me 5:who 57:room 13:1
     
    27872301}
    27882302
    2789 static void yahoo_process_ping(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     2303static void yahoo_process_ping(struct yahoo_input_data *yid,
     2304        struct yahoo_packet *pkt)
    27902305{
    27912306        char *errormsg = NULL;
    2792        
     2307
    27932308        YList *l;
    27942309        for (l = pkt->hash; l; l = l->next) {
     
    27972312                        errormsg = pair->value;
    27982313        }
    2799        
     2314
    28002315        NOTICE(("got ping packet"));
    2801         YAHOO_CALLBACK(ext_yahoo_got_ping)(yid->yd->client_id, errormsg);
    2802 }
    2803 
    2804 static void _yahoo_webcam_get_server_connected(int fd, int error, void *d)
     2316        YAHOO_CALLBACK(ext_yahoo_got_ping) (yid->yd->client_id, errormsg);
     2317}
     2318
     2319static 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
     2344static void _yahoo_webcam_get_server_connected(void *fd, int error, void *d)
    28052345{
    28062346        struct yahoo_input_data *yid = d;
     
    28082348        char *data = NULL;
    28092349        char *packet = NULL;
    2810         unsigned char magic_nr[] = {0, 1, 0};
     2350        unsigned char magic_nr[] = { 0, 1, 0 };
    28112351        unsigned char header_len = 8;
    28122352        unsigned int len = 0;
    28132353        unsigned int pos = 0;
    28142354
    2815         if(error || fd <= 0) {
     2355        if (error || !fd) {
    28162356                FREE(who);
    28172357                FREE(yid);
     
    28212361        yid->fd = fd;
    28222362        inputs = y_list_prepend(inputs, yid);
    2823        
     2363
    28242364        /* send initial packet */
    28252365        if (who)
     
    28312371
    28322372        /* send data */
    2833         if (who)
    2834         {
     2373        if (who) {
    28352374                data = strdup("g=");
    28362375                data = y_string_append(data, who);
     
    28512390        FREE(data);
    28522391
    2853         yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, fd, YAHOO_INPUT_READ, yid);
    2854 }
    2855 
    2856 static void yahoo_webcam_get_server(struct yahoo_input_data *y, char *who, char *key)
     2392        yid->read_tag =
     2393                YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd,
     2394                YAHOO_INPUT_READ, yid);
     2395}
     2396
     2397static void yahoo_webcam_get_server(struct yahoo_input_data *y, char *who,
     2398        char *key)
    28572399{
    28582400        struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1);
     
    28622404        yid->yd = y->yd;
    28632405        yid->wcm = y_new0(struct yahoo_webcam, 1);
    2864         yid->wcm->user = who?strdup(who):NULL;
    2865         yid->wcm->direction = who?YAHOO_WEBCAM_DOWNLOAD:YAHOO_WEBCAM_UPLOAD;
     2406        yid->wcm->user = who ? strdup(who) : NULL;
     2407        yid->wcm->direction = who ? YAHOO_WEBCAM_DOWNLOAD : YAHOO_WEBCAM_UPLOAD;
    28662408        yid->wcm->key = strdup(key);
    28672409
    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 
    2873 static YList *webcam_queue=NULL;
    2874 static void yahoo_process_webcam_key(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     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
     2416static YList *webcam_queue = NULL;
     2417static void yahoo_process_webcam_key(struct yahoo_input_data *yid,
     2418        struct yahoo_packet *pkt)
    28752419{
    28762420        char *me = NULL;
     
    28792423
    28802424        YList *l;
    2881         // yahoo_dump_unhandled(pkt);
     2425        yahoo_dump_unhandled(pkt);
    28822426        for (l = pkt->hash; l; l = l->next) {
    28832427                struct yahoo_pair *pair = l->data;
    28842428                if (pair->key == 5)
    28852429                        me = pair->value;
    2886                 if (pair->key == 61) 
    2887                         key=pair->value;
     2430                if (pair->key == 61)
     2431                        key = pair->value;
    28882432        }
    28892433
    28902434        l = webcam_queue;
    2891         if(!l)
     2435        if (!l)
    28922436                return;
    28932437        who = l->data;
     
    28982442}
    28992443
    2900 static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     2444static void yahoo_packet_process(struct yahoo_input_data *yid,
     2445        struct yahoo_packet *pkt)
    29012446{
    29022447        DEBUG_MSG(("yahoo_packet_process: 0x%02x", pkt->service));
    2903         yahoo_dump_unhandled(pkt);
    2904         switch (pkt->service)
    2905         {
     2448        switch (pkt->service) {
    29062449        case YAHOO_SERVICE_USERSTAT:
    29072450        case YAHOO_SERVICE_LOGON:
     
    29142457        case YAHOO_SERVICE_IDDEACT:
    29152458        case YAHOO_SERVICE_Y6_STATUS_UPDATE:
    2916         case YAHOO_SERVICE_YMSG15_STATUS:
     2459        case YAHOO_SERVICE_Y8_STATUS:
    29172460                yahoo_process_status(yid, pkt);
    29182461                break;
     
    29282471                yahoo_process_mail(yid, pkt);
    29292472                break;
    2930         case YAHOO_SERVICE_REJECTCONTACT:
     2473        case YAHOO_SERVICE_Y7_AUTHORIZATION:
     2474                yahoo_process_new_contact(yid, pkt);
     2475                break;
    29312476        case YAHOO_SERVICE_NEWCONTACT:
    29322477                yahoo_process_contact(yid, pkt);
     
    29632508                break;
    29642509        case YAHOO_SERVICE_P2PFILEXFER:
    2965         case YAHOO_SERVICE_FILETRANSFER:
     2510        case YAHOO_SERVICE_Y7_FILETRANSFER:
    29662511                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);
    29672518                break;
    29682519        case YAHOO_SERVICE_ADDBUDDY:
    29692520                yahoo_process_buddyadd(yid, pkt);
    2970                 break;
    2971         case YAHOO_SERVICE_CONTACT_YMSG13:
    2972                 yahoo_process_contact_ymsg13(yid,pkt);
    29732521                break;
    29742522        case YAHOO_SERVICE_REMBUDDY:
     
    29872535                yahoo_process_ping(yid, pkt);
    29882536                break;
     2537        case YAHOO_SERVICE_Y7_CHANGE_GROUP:
     2538                yahoo_process_buddy_change_group(yid, pkt);
     2539                break;
    29892540        case YAHOO_SERVICE_IDLE:
    29902541        case YAHOO_SERVICE_MAILSTAT:
     
    30002551        case YAHOO_SERVICE_CHATLOGOFF:
    30012552        case YAHOO_SERVICE_CHATMSG:
     2553        case YAHOO_SERVICE_REJECTCONTACT:
    30022554        case YAHOO_SERVICE_PEERTOPEER:
    30032555                WARNING(("unhandled service 0x%02x", pkt->service));
     
    30122564        case YAHOO_SERVICE_PICTURE_UPLOAD:
    30132565                yahoo_process_picture_upload(yid, pkt);
    3014                 break; 
    3015         case YAHOO_SERVICE_YMSG15_BUDDY_LIST:   /* Buddy List */
     2566                break;
     2567        case YAHOO_SERVICE_Y8_LIST:     /* Buddy List */
    30162568                yahoo_process_buddy_list(yid, pkt);
     2569                break;
    30172570        default:
    30182571                WARNING(("unknown service 0x%02x", pkt->service));
     
    30222575}
    30232576
    3024 static struct yahoo_packet * yahoo_getdata(struct yahoo_input_data * yid)
     2577static struct yahoo_packet *yahoo_getdata(struct yahoo_input_data *yid)
    30252578{
    30262579        struct yahoo_packet *pkt;
     
    30292582        int pktlen;
    30302583
    3031         if(!yd)
     2584        if (!yd)
    30322585                return NULL;
    30332586
     
    30382591        }
    30392592
    3040         pos += 4; /* YMSG */
     2593        pos += 4;               /* YMSG */
    30412594        pos += 2;
    30422595        pos += 2;
    30432596
    3044         pktlen = yahoo_get16(yid->rxqueue + pos); pos += 2;
    3045         DEBUG_MSG(("%d bytes to read, rxlen is %d",
    3046                         pktlen, yid->rxlen));
     2597        pktlen = yahoo_get16(yid->rxqueue + pos);
     2598        pos += 2;
     2599        DEBUG_MSG(("%d bytes to read, rxlen is %d", pktlen, yid->rxlen));
    30472600
    30482601        if (yid->rxlen < (YAHOO_PACKET_HDRLEN + pktlen)) {
     
    30562609        pkt = yahoo_packet_new(0, 0, 0);
    30572610
    3058         pkt->service = yahoo_get16(yid->rxqueue + pos); pos += 2;
    3059         pkt->status = yahoo_get32(yid->rxqueue + pos); pos += 4;
     2611        pkt->service = yahoo_get16(yid->rxqueue + pos);
     2612        pos += 2;
     2613        pkt->status = yahoo_get32(yid->rxqueue + pos);
     2614        pos += 4;
    30602615        DEBUG_MSG(("Yahoo Service: 0x%02x Status: %d", pkt->service,
    3061                                 pkt->status));
    3062         pkt->id = yahoo_get32(yid->rxqueue + pos); pos += 4;
     2616                        pkt->status));
     2617        pkt->id = yahoo_get32(yid->rxqueue + pos);
     2618        pos += 4;
    30632619
    30642620        yd->session_id = pkt->id;
     
    30682624        yid->rxlen -= YAHOO_PACKET_HDRLEN + pktlen;
    30692625        DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
    3070         if (yid->rxlen>0) {
    3071                 unsigned char *tmp = y_memdup(yid->rxqueue + YAHOO_PACKET_HDRLEN 
    3072                                 + pktlen, yid->rxlen);
     2626        if (yid->rxlen > 0) {
     2627                unsigned char *tmp = y_memdup(yid->rxqueue + YAHOO_PACKET_HDRLEN
     2628                        + pktlen, yid->rxlen);
    30732629                FREE(yid->rxqueue);
    30742630                yid->rxqueue = tmp;
    3075                 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
     2631                DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen,
     2632                                yid->rxqueue));
    30762633        } else {
    30772634                DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue));
     
    30822639}
    30832640
    3084 static void yahoo_yab_read(struct yab *yab, unsigned char *d, int len)
     2641static struct yab *yahoo_yab_read(unsigned char *d, int len)
    30852642{
    30862643        char *st, *en;
    30872644        char *data = (char *)d;
    3088         data[len]='\0';
     2645        struct yab *yab = NULL;
     2646
     2647        data[len] = '\0';
    30892648
    30902649        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';
     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)
     2661                return NULL;
     2662
     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';
    30952700                yab->id = yahoo_xmldecode(st);
    30962701        }
    30972702
    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 
    31262703        st = strstr(en, "hphone=\"");
    3127         if(st) {
     2704        if (st) {
    31282705                st += strlen("hphone=\"");
    3129                 en = strchr(st, '"'); *en++ = '\0';
     2706                en = strchr(st, '"');
     2707                *en++ = '\0';
    31302708                yab->hphone = yahoo_xmldecode(st);
    31312709        }
    31322710
    31332711        st = strstr(en, "wphone=\"");
    3134         if(st) {
     2712        if (st) {
    31352713                st += strlen("wphone=\"");
    3136                 en = strchr(st, '"'); *en++ = '\0';
     2714                en = strchr(st, '"');
     2715                *en++ = '\0';
    31372716                yab->wphone = yahoo_xmldecode(st);
    31382717        }
    31392718
    31402719        st = strstr(en, "mphone=\"");
    3141         if(st) {
     2720        if (st) {
    31422721                st += strlen("mphone=\"");
    3143                 en = strchr(st, '"'); *en++ = '\0';
     2722                en = strchr(st, '"');
     2723                *en++ = '\0';
    31442724                yab->mphone = yahoo_xmldecode(st);
    31452725        }
    31462726
    31472727        st = strstr(en, "dbid=\"");
    3148         if(st) {
     2728        if (st) {
    31492729                st += strlen("dbid=\"");
    3150                 en = strchr(st, '"'); *en++ = '\0';
     2730                en = strchr(st, '"');
     2731                *en++ = '\0';
    31512732                yab->dbid = atoi(st);
    31522733        }
    3153 }
    3154 
    3155 static struct yab * yahoo_getyab(struct yahoo_input_data *yid)
     2734
     2735        return yab;
     2736}
     2737
     2738static struct yab *yahoo_getyab(struct yahoo_input_data *yid)
    31562739{
    31572740        struct yab *yab = NULL;
    3158         int pos = 0, end=0;
     2741        int pos = 0, end = 0;
    31592742        struct yahoo_data *yd = yid->yd;
    31602743
    3161         if(!yd)
     2744        if (!yd)
    31622745                return NULL;
    31632746
     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
     2792static 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)
     2801                return NULL;
     2802
    31642803        DEBUG_MSG(("rxlen is %d", yid->rxlen));
    31652804
    3166         if(yid->rxlen <= strlen("<record"))
     2805        len = yid->rxqueue[pos++];
     2806        if (yid->rxlen < len)
    31672807                return NULL;
    31682808
    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;
     2809        /* extract status (0 = ok, 6 = webcam not online) */
     2810        status = yid->rxqueue[pos++];
     2811
     2812        if (status == 0) {
     2813                pos += 2;       /* skip next 2 bytes */
     2814                server = y_memdup(yid->rxqueue + pos, 16);
     2815                pos += 16;
     2816        } else if (status == 6) {
     2817                YAHOO_CALLBACK(ext_yahoo_webcam_closed)
     2818                        (yd->client_id, yid->wcm->user, 4);
     2819        }
     2820
     2821        /* skip rest of the data */
     2822
     2823        yid->rxlen -= len;
    31902824        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);
     2825        if (yid->rxlen > 0) {
     2826                unsigned char *tmp = y_memdup(yid->rxqueue + pos, yid->rxlen);
    31932827                FREE(yid->rxqueue);
    31942828                yid->rxqueue = tmp;
    3195                 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
     2829                DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen,
     2830                                yid->rxqueue));
    31962831        } else {
    31972832                DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue));
     
    31992834        }
    32002835
    3201 
    3202         return yab;
    3203 }
    3204 
    3205 static 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;
     2836        return server;
     2837}
     2838
     2839static int yahoo_get_webcam_data(struct yahoo_input_data *yid)
     2840{
     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;
     2847        char *who;
     2848        int connect = 0;
    32112849        struct yahoo_data *yd = yid->yd;
    32122850
    3213         if(!yid || !yd)
    3214                 return NULL;
     2851        if (!yd)
     2852                return -1;
     2853
     2854        if (!yid->wcm || !yid->wcd || !yid->rxlen)
     2855                return -1;
    32152856
    32162857        DEBUG_MSG(("rxlen is %d", yid->rxlen));
    32172858
    3218         len = yid->rxqueue[pos++];
    3219         if (yid->rxlen < len)
    3220                 return NULL;
    3221 
    3222         /* extract status (0 = ok, 6 = webcam not online) */
    3223         status = yid->rxqueue[pos++];
    3224 
    3225         if (status == 0)
    3226         {
    3227                 pos += 2; /* skip next 2 bytes */
    3228                 server =  y_memdup(yid->rxqueue+pos, 16);
    3229                 pos += 16;
    3230         }
    3231         else if (status == 6)
    3232         {
    3233                 YAHOO_CALLBACK(ext_yahoo_webcam_closed)
    3234                         (yd->client_id, yid->wcm->user, 4);
    3235         }
    3236 
    3237         /* skip rest of the data */
    3238 
    3239         yid->rxlen -= len;
    3240         DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
    3241         if (yid->rxlen>0) {
    3242                 unsigned char *tmp = y_memdup(yid->rxqueue + pos, yid->rxlen);
    3243                 FREE(yid->rxqueue);
    3244                 yid->rxqueue = tmp;
    3245                 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
    3246         } else {
    3247                 DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue));
    3248                 FREE(yid->rxqueue);
    3249         }
    3250 
    3251         return server;
    3252 }
    3253 
    3254 static int yahoo_get_webcam_data(struct yahoo_input_data *yid)
    3255 {
    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;
    3262         char *who;
    3263         int connect=0;
    3264         struct yahoo_data *yd = yid->yd;
    3265 
    3266         if(!yd)
    3267                 return -1;
    3268 
    3269         if(!yid->wcm || !yid->wcd || !yid->rxlen)
    3270                 return -1;
    3271 
    3272         DEBUG_MSG(("rxlen is %d", yid->rxlen));
    3273 
    32742859        /* if we are not reading part of image then read header */
    3275         if (!yid->wcd->to_read)
    3276         {
    3277                 header_len=yid->rxqueue[pos++];
    3278                 yid->wcd->packet_type=0;
     2860        if (!yid->wcd->to_read) {
     2861                header_len = yid->rxqueue[pos++];
     2862                yid->wcd->packet_type = 0;
    32792863
    32802864                if (yid->rxlen < header_len)
    32812865                        return 0;
    32822866
    3283                 if (header_len >= 8)
    3284                 {
     2867                if (header_len >= 8) {
    32852868                        reason = yid->rxqueue[pos++];
    32862869                        /* next 2 bytes should always be 05 00 */
     
    32902873                        yid->wcd->to_read = yid->wcd->data_size;
    32912874                }
    3292                 if (header_len >= 13)
    3293                 {
     2875                if (header_len >= 13) {
    32942876                        yid->wcd->packet_type = yid->rxqueue[pos++];
    32952877                        yid->wcd->timestamp = yahoo_get32(yid->rxqueue + pos);
     
    33032885        begin = pos;
    33042886        pos += yid->wcd->to_read;
    3305         if (pos > yid->rxlen) pos = yid->rxlen;
     2887        if (pos > yid->rxlen)
     2888                pos = yid->rxlen;
    33062889
    33072890        /* if it is not an image then make sure we have the whole packet */
     
    33162899
    33172900        DEBUG_MSG(("packet type %.2X, data length %d", yid->wcd->packet_type,
    3318                 yid->wcd->data_size));
     2901                        yid->wcd->data_size));
    33192902
    33202903        /* find out what kind of packet we got */
    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);
     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);
    33852917                                FREE(who);
    33862918                        }
    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;
     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;
    33952979        }
    33962980        yid->wcd->to_read -= pos - begin;
     
    33982982        yid->rxlen -= pos;
    33992983        DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
    3400         if (yid->rxlen>0) {
     2984        if (yid->rxlen > 0) {
    34012985                unsigned char *tmp = y_memdup(yid->rxqueue + pos, yid->rxlen);
    34022986                FREE(yid->rxqueue);
    34032987                yid->rxqueue = tmp;
    3404                 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue));
     2988                DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen,
     2989                                yid->rxqueue));
    34052990        } else {
    34062991                DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue));
     
    34153000}
    34163001
    3417 int yahoo_write_ready(int id, int fd, void *data)
     3002int yahoo_write_ready(int id, void *fd, void *data)
    34183003{
    34193004        struct yahoo_input_data *yid = data;
     
    34213006        struct data_queue *tx;
    34223007
    3423         LOG(("write callback: id=%d fd=%d data=%p", id, fd, data));
    3424         if(!yid || !yid->txqueues || !find_conn_by_id(id))
     3008        LOG(("write callback: id=%d fd=%p data=%p", id, fd, data));
     3009        if (!yid || !yid->txqueues)
    34253010                return -2;
    3426        
     3011
    34273012        tx = yid->txqueues->data;
    34283013        LOG(("writing %d bytes", tx->len));
    34293014        len = yahoo_send_data(fd, tx->queue, MIN(1024, tx->len));
    34303015
    3431         if(len == -1 && errno == EAGAIN)
     3016        if (len == -1 && errno == EAGAIN)
    34323017                return 1;
    34333018
    3434         if(len <= 0) {
     3019        if (len <= 0) {
    34353020                int e = errno;
    34363021                DEBUG_MSG(("len == %d (<= 0)", len));
    3437                 while(yid->txqueues) {
    3438                         YList *l=yid->txqueues;
     3022                while (yid->txqueues) {
     3023                        YList *l = yid->txqueues;
    34393024                        tx = l->data;
    34403025                        free(tx->queue);
    34413026                        free(tx);
    3442                         yid->txqueues = y_list_remove_link(yid->txqueues, yid->txqueues);
     3027                        yid->txqueues =
     3028                                y_list_remove_link(yid->txqueues,
     3029                                yid->txqueues);
    34433030                        y_list_free_1(l);
    34443031                }
    3445                 LOG(("yahoo_write_ready(%d, %d) len < 0", id, fd));
    3446                 YAHOO_CALLBACK(ext_yahoo_remove_handler)(id, yid->write_tag);
     3032                LOG(("yahoo_write_ready(%d, %p) len < 0", id, fd));
     3033                YAHOO_CALLBACK(ext_yahoo_remove_handler) (id, yid->write_tag);
    34473034                yid->write_tag = 0;
    3448                 errno=e;
     3035                errno = e;
    34493036                return 0;
    34503037        }
     
    34523039
    34533040        tx->len -= len;
    3454         if(tx->len > 0) {
     3041        if (tx->len > 0) {
    34553042                unsigned char *tmp = y_memdup(tx->queue + len, tx->len);
    34563043                FREE(tx->queue);
    34573044                tx->queue = tmp;
    34583045        } else {
    3459                 YList *l=yid->txqueues;
     3046                YList *l = yid->txqueues;
    34603047                free(tx->queue);
    34613048                free(tx);
    3462                 yid->txqueues = y_list_remove_link(yid->txqueues, yid->txqueues);
     3049                yid->txqueues =
     3050                        y_list_remove_link(yid->txqueues, yid->txqueues);
    34633051                y_list_free_1(l);
    34643052                /*
    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);
     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);
    34713060                        yid->write_tag = 0;
    34723061                }
     
    34763065}
    34773066
    3478 static void yahoo_process_pager_connection(struct yahoo_input_data *yid, int over)
     3067static void yahoo_process_pager_connection(struct yahoo_input_data *yid,
     3068        int over)
    34793069{
    34803070        struct yahoo_packet *pkt;
     
    34823072        int id = yd->client_id;
    34833073
    3484         if(over)
    3485                 return;
    3486 
    3487         while (find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER) 
    3488                         && (pkt = yahoo_getdata(yid)) != NULL) {
     3074        if (over)
     3075                return;
     3076
     3077        while (find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER)
     3078                && (pkt = yahoo_getdata(yid)) != NULL) {
    34893079
    34903080                yahoo_packet_process(yid, pkt);
     
    34943084}
    34953085
    3496 static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over)
    3497 {
    3498 }
    3499 
    3500 static 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);
     3086static 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);
    35073095        }
    35083096}
     
    35133101        struct yab *yab;
    35143102        YList *buds;
    3515         int changed=0;
     3103        int changed = 0;
    35163104        int id = yd->client_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)
     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)
    35243115                        continue;
    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)) {
     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;
    35293123                                bud->yab_entry = yab;
    3530                                 if(yab->nname) {
     3124                                if (yab->nname) {
    35313125                                        bud->real_name = strdup(yab->nname);
    3532                                 } else if(yab->fname && yab->lname) {
    3533                                         bud->real_name = y_new0(char,
    3534                                                         strlen(yab->fname)+
    3535                                                         strlen(yab->lname)+2
    3536                                                         );
     3126                                } else if (yab->fname && yab->lname) {
     3127                                        bud->real_name = y_new0(char,
     3128                                                strlen(yab->fname) +
     3129                                                strlen(yab->lname) + 2);
    35373130                                        sprintf(bud->real_name, "%s %s",
    3538                                                         yab->fname, yab->lname);
    3539                                 } else if(yab->fname) {
     3131                                                yab->fname, yab->lname);
     3132                                } else if (yab->fname) {
    35403133                                        bud->real_name = strdup(yab->fname);
    35413134                                }
    3542                                 break; /* for */
     3135                                break;  /* for */
    35433136                        }
    35443137                }
    3545         }
    3546 
    3547         if(changed)
    3548                 YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies);
    3549 }
    3550 
    3551 static void yahoo_process_search_connection(struct yahoo_input_data *yid, int over)
    3552 {
    3553         struct yahoo_found_contact *yct=NULL;
     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
     3158static void yahoo_process_search_connection(struct yahoo_input_data *yid,
     3159        int over)
     3160{
     3161        struct yahoo_found_contact *yct = NULL;
    35543162        char *p = (char *)yid->rxqueue, *np, *cp;
    35553163        int k, 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"))) {
     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"))) {
    35643174                p += 4;
    35653175
    3566                 for(k = 0; (p = strchr(p, 4)) && (k < 4); k++) {
     3176                for (k = 0; (p = strchr(p, 4)) && (k < 4); k++) {
    35673177                        p++;
    35683178                        n = atoi(p);
    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;
     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;
    35733189                        }
    35743190                }
    35753191
    3576                 if(p)
     3192                if (p)
    35773193                        p++;
    35783194
    3579                 k=0;
    3580                 while(p && *p) {
     3195                k = 0;
     3196                while (p && *p) {
    35813197                        cp = p;
    35823198                        np = strchr(p, 4);
    35833199
    3584                         if(!np)
     3200                        if (!np)
    35853201                                break;
    35863202                        *np = 0;
    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;
     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;
    36133232                        }
    36143233                }
    36153234        }
    36163235
    3617         YAHOO_CALLBACK(ext_yahoo_got_search_result)(yid->yd->client_id, found, start, total, contacts);
    3618 
    3619         while(contacts) {
     3236        YAHOO_CALLBACK(ext_yahoo_got_search_result) (yid->yd->client_id, found,
     3237                start, total, contacts);
     3238
     3239        while (contacts) {
    36203240                YList *node = contacts;
    36213241                contacts = y_list_remove_link(contacts, node);
     
    36253245}
    36263246
    3627 static void _yahoo_webcam_connected(int fd, int error, void *d)
     3247static void _yahoo_webcam_connected(void *fd, int error, void *d)
    36283248{
    36293249        struct yahoo_input_data *yid = d;
     
    36313251        struct yahoo_data *yd = yid->yd;
    36323252        char conn_type[100];
    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) {
     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) {
    36413261                FREE(yid);
    36423262                return;
     
    36483268        LOG(("Connected"));
    36493269        /* send initial packet */
    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;
     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;
    36603279        }
    36613280        yahoo_add_to_send_queue(yid, data, strlen(data));
     
    36633282
    36643283        /* send data */
    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;
     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;
    36973315        }
    36983316
     
    37013319        packet[pos++] = header_len;
    37023320        packet[pos++] = 0;
    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;
     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;
    37133330        }
    37143331
    37153332        pos += yahoo_put32(packet + pos, len);
    3716         if (wcm->direction == YAHOO_WEBCAM_UPLOAD)
    3717         {
     3333        if (wcm->direction == YAHOO_WEBCAM_UPLOAD) {
    37183334                memcpy(packet + pos, magic_nr, sizeof(magic_nr));
    37193335                pos += sizeof(magic_nr);
     
    37243340        FREE(data);
    37253341
    3726         yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_READ, yid);
     3342        yid->read_tag =
     3343                YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id,
     3344                yid->fd, YAHOO_INPUT_READ, yid);
    37273345}
    37283346
     
    37493367
    37503368        LOG(("Connecting to: %s:%d", wcm->server, wcm->port));
    3751         YAHOO_CALLBACK(ext_yahoo_connect_async)(y->yd->client_id, wcm->server, wcm->port,
    3752                         _yahoo_webcam_connected, yid);
    3753 
    3754 }
    3755 
    3756 static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid, int over)
    3757 {
    3758         char* server;
     3369        YAHOO_CALLBACK(ext_yahoo_connect_async) (y->yd->client_id, wcm->server,
     3370                wcm->port, _yahoo_webcam_connected, yid, 0);
     3371
     3372}
     3373
     3374static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid,
     3375        int over)
     3376{
     3377        char *server;
    37593378        struct yahoo_server_settings *yss;
    37603379
    3761         if(over)
     3380        if (over)
    37623381                return;
    37633382
    37643383        server = yahoo_getwebcam_master(yid);
    37653384
    3766         if (server)
    3767         {
     3385        if (server) {
    37683386                yss = yid->yd->server_settings;
    37693387                yid->wcm->server = strdup(server);
     
    37783396}
    37793397
    3780 static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int over)
     3398static void yahoo_process_webcam_connection(struct yahoo_input_data *yid,
     3399        int over)
    37813400{
    37823401        int id = yid->yd->client_id;
    3783         int fd = yid->fd;
    3784 
    3785         if(over)
     3402        void *fd = yid->fd;
     3403
     3404        if (over)
    37863405                return;
    37873406
    37883407        /* as long as we still have packets available keep processing them */
    3789         while (find_input_by_id_and_fd(id, fd)
    3790                         && yahoo_get_webcam_data(yid) == 1);
    3791 }
    3792 
    3793 static 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 
    3803 int yahoo_read_ready(int id, int fd, void *data)
     3408        while (find_input_by_id_and_fd(id, fd)
     3409                && yahoo_get_webcam_data(yid) == 1) ;
     3410}
     3411
     3412static void (*yahoo_process_connection[]) (struct yahoo_input_data *,
     3413        int over) = {
     3414yahoo_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
     3421int yahoo_read_ready(int id, void *fd, void *data)
    38043422{
    38053423        struct yahoo_input_data *yid = data;
     
    38073425        int len;
    38083426
    3809         LOG(("read callback: id=%d fd=%d data=%p", id, fd, data));
    3810         if(!yid)
     3427        LOG(("read callback: id=%d fd=%p data=%p", id, fd, data));
     3428        if (!yid)
    38113429                return -2;
    38123430
    3813        
    38143431        do {
    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 */
     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 */
    38193436                return 1;
    38203437
     
    38233440                DEBUG_MSG(("len == %d (<= 0)", len));
    38243441
    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);
     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);
    38303448                yahoo_input_close(yid);
    38313449
    38323450                /* no need to return an error, because we've already fixed it */
    3833                 if(len == 0)
     3451                if (len == 0)
    38343452                        return 1;
    38353453
    3836                 errno=e;
     3454                errno = e;
    38373455                LOG(("read error: %s", strerror(errno)));
    38383456                return -1;
    38393457        }
    38403458
    3841         yid->rxqueue = y_renew(unsigned char, yid->rxqueue, len + yid->rxlen);
     3459        yid->rxqueue =
     3460                y_renew(unsigned char, yid->rxqueue, len + yid->rxlen + 1);
    38423461        memcpy(yid->rxqueue + yid->rxlen, buf, len);
    38433462        yid->rxlen += len;
    3844 
    3845         yahoo_process_connection[yid->type](yid, 0);
     3463        yid->rxqueue[yid->rxlen] = 0;
     3464
     3465        yahoo_process_connection[yid->type] (yid, 0);
    38463466
    38473467        return len;
     
    38553475        yd = y_new0(struct yahoo_data, 1);
    38563476
    3857         if(!yd)
     3477        if (!yd)
    38583478                return 0;
    38593479
     
    38803500}
    38813501
    3882 struct connect_callback_data {
    3883         struct yahoo_data *yd;
    3884         int tag;
    3885         int i;
    3886 };
    3887 
    3888 static void yahoo_connected(int fd, int error, void *data)
     3502static void yahoo_connected(void *fd, int error, void *data)
    38893503{
    38903504        struct connect_callback_data *ccd = data;
     
    38943508        struct yahoo_server_settings *yss = yd->server_settings;
    38953509
    3896         if(error) {
    3897                 if(fallback_ports[ccd->i]) {
    3898                         int tag;
     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
    38993518                        yss->pager_port = fallback_ports[ccd->i++];
    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;
     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);
    39053537                } else {
    39063538                        FREE(ccd);
    3907                         YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_SOCK, NULL);
     3539                        YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id,
     3540                                YAHOO_LOGIN_SOCK, NULL);
    39083541                }
    39093542                return;
     
    39123545        FREE(ccd);
    39133546
    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);
     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);
    39193553        NOTICE(("Sending initial packet"));
    39203554
    39213555        yahoo_packet_hash(pkt, 1, yd->user);
    39223556
    3923         yid = y_new0(struct yahoo_input_data, 1);
    3924         yid->yd = yd;
     3557        yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER);
    39253558        yid->fd = fd;
    3926         inputs = y_list_prepend(inputs, yid);
    39273559
    39283560        yahoo_send_packet(yid, pkt, 0);
     
    39303562        yahoo_packet_free(pkt);
    39313563
    3932         yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_READ, yid);
    3933 }
    3934 
    3935 void 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 
    3965 int 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)
     3564        yid->read_tag =
     3565                YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id,
     3566                yid->fd, YAHOO_INPUT_READ, yid);
     3567}
     3568
     3569void *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)
    39693574                return 0;
    39703575        else
     
    39723577}
    39733578
    3974 void 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);
     3579void yahoo_send_buzz(int id, const char *from, const char *who)
     3580{
     3581        yahoo_send_im(id, from, who, "<ding>", 1, 0);
     3582}
     3583
     3584void 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);
    39773589        struct yahoo_packet *pkt = NULL;
    39783590        struct yahoo_data *yd;
    39793591        char pic_str[10];
    39803592
    3981         if(!yid)
     3593        if (!yid)
    39823594                return;
    39833595
    39843596        yd = yid->yd;
    39853597
    3986         pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, yd->session_id);
     3598        pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE,
     3599                yd->session_id);
    39873600
    39883601        snprintf(pic_str, sizeof(pic_str), "%d", picture);
    3989        
    3990         if(from && strcmp(from, yd->user))
     3602
     3603        if (from && strcmp(from, yd->user))
    39913604                yahoo_packet_hash(pkt, 0, yd->user);
    3992         yahoo_packet_hash(pkt, 1, from?from:yd->user);
     3605        yahoo_packet_hash(pkt, 1, from ? from : yd->user);
    39933606        yahoo_packet_hash(pkt, 5, who);
    39943607        yahoo_packet_hash(pkt, 14, what);
    39953608
    3996         if(utf8)
     3609        if (utf8)
    39973610                yahoo_packet_hash(pkt, 97, "1");
    39983611
     
    40013614        yahoo_packet_hash(pkt, 206, pic_str);
    40023615
    4003 
    40043616        yahoo_send_packet(yid, pkt, 0);
    40053617
     
    40093621void yahoo_send_typing(int id, const char *from, const char *who, int typ)
    40103622{
    4011         struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     3623        struct yahoo_input_data *yid =
     3624                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    40123625        struct yahoo_data *yd;
    40133626        struct yahoo_packet *pkt = NULL;
    4014         if(!yid)
     3627        if (!yid)
    40153628                return;
    40163629
    40173630        yd = yid->yd;
    4018         pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yd->session_id);
     3631        pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YPACKET_STATUS_NOTIFY,
     3632                yd->session_id);
    40193633
    40203634        yahoo_packet_hash(pkt, 5, who);
    4021         yahoo_packet_hash(pkt, 1, from?from:yd->user);
     3635        yahoo_packet_hash(pkt, 1, from ? from : yd->user);
    40223636        yahoo_packet_hash(pkt, 14, " ");
    40233637        yahoo_packet_hash(pkt, 13, typ ? "1" : "0");
     
    40313645void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away)
    40323646{
    4033         struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     3647        struct yahoo_input_data *yid =
     3648                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    40343649        struct yahoo_data *yd;
    40353650        struct yahoo_packet *pkt = NULL;
     
    40373652        char s[4];
    40383653
    4039         if(!yid)
     3654        if (!yid)
    40403655                return;
    40413656
    40423657        yd = yid->yd;
     3658
    40433659        old_status = yd->current_status;
    40443660        yd->current_status = state;
     
    40463662        /* Thank you libpurple :) */
    40473663        if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
    4048                 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0);
     3664                pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE,
     3665                        YAHOO_STATUS_AVAILABLE, 0);
    40493666                yahoo_packet_hash(pkt, 13, "2");
    40503667                yahoo_send_packet(yid, pkt, 0);
     
    40543671        }
    40553672
    4056         pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id);
     3673        pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE,
     3674                yd->current_status, yd->session_id);
    40573675        snprintf(s, sizeof(s), "%d", yd->current_status);
    40583676        yahoo_packet_hash(pkt, 10, s);
     
    40623680        yahoo_packet_free(pkt);
    40633681
    4064         if(old_status == YAHOO_STATUS_INVISIBLE) {
    4065                 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0);
     3682        if (old_status == YAHOO_STATUS_INVISIBLE) {
     3683                pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE,
     3684                        YAHOO_STATUS_AVAILABLE, 0);
    40663685                yahoo_packet_hash(pkt, 13, "1");
    40673686                yahoo_send_packet(yid, pkt, 0);
     
    40723691void yahoo_logoff(int id)
    40733692{
    4074         struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     3693        struct yahoo_input_data *yid =
     3694                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    40753695        struct yahoo_data *yd;
    40763696        struct yahoo_packet *pkt = NULL;
    40773697
    4078         if(!yid)
     3698        if (!yid)
    40793699                return;
    40803700        yd = yid->yd;
     
    40823702        LOG(("yahoo_logoff: current status: %d", yd->current_status));
    40833703
    4084         if(yd->current_status != -1 && 0) {
     3704        if (yd->current_status != -1 && 0) {
    40853705                /* Meh. Don't send this. The event handlers are not going to
    40863706                   get to do this so it'll just leak memory. And the TCP
    40873707                   connection reset will hopefully be clear enough. */
    4088                 pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id);
     3708                pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF,
     3709                        YPACKET_STATUS_DEFAULT, yd->session_id);
    40893710                yd->current_status = -1;
    40903711
     
    40953716        }
    40963717
    4097         do {
     3718/*      do {
    40983719                yahoo_input_close(yid);
    4099         } while((yid = find_input_by_id(id)));
     3720        } while((yid = find_input_by_id(id)));*/
     3721
    41003722}
    41013723
    41023724void yahoo_get_list(int id)
    41033725{
    4104         struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     3726        struct yahoo_input_data *yid =
     3727                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    41053728        struct yahoo_data *yd;
    41063729        struct yahoo_packet *pkt = NULL;
    41073730
    4108         if(!yid)
     3731        if (!yid)
    41093732                return;
    41103733        yd = yid->yd;
    41113734
    4112         pkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_AVAILABLE, yd->session_id);
     3735        pkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YPACKET_STATUS_DEFAULT,
     3736                yd->session_id);
    41133737        yahoo_packet_hash(pkt, 1, yd->user);
    41143738        if (pkt) {
     
    41183742}
    41193743
    4120 static void _yahoo_http_connected(int id, int fd, int error, void *data)
     3744static void _yahoo_http_connected(int id, void *fd, int error, void *data)
    41213745{
    41223746        struct yahoo_input_data *yid = data;
    4123         if(fd <= 0) {
     3747        if (fd == NULL || error) {
    41243748                inputs = y_list_remove(inputs, yid);
    41253749                FREE(yid);
     
    41283752
    41293753        yid->fd = fd;
    4130         yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, fd, YAHOO_INPUT_READ, yid);
    4131 }
    4132 
     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 */
    41333760void yahoo_get_yab(int id)
    41343761{
     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
     3788struct yahoo_post_data {
     3789        struct yahoo_input_data *yid;
     3790        char *data;
     3791};
     3792
     3793static 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 */
     3817void yahoo_set_yab(int id, struct yab *yab)
     3818{
     3819        struct yahoo_post_data *yad = y_new0(struct yahoo_post_data, 1);
    41353820        struct yahoo_data *yd = find_conn_by_id(id);
    41363821        struct yahoo_input_data *yid;
    41373822        char url[1024];
    41383823        char buff[1024];
    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 
    4158 void 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)
     3824        char post[1024];
     3825        int size = 0;
     3826
     3827        if (!yd)
    41683828                return;
    41693829
     
    41723832        yid->yd = yd;
    41733833
    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);
     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);
    42343854
    42353855        inputs = y_list_prepend(inputs, yid);
    42363856
    4237         yahoo_http_get(yid->yd->client_id, url, buff,
    4238                         _yahoo_http_connected, yid);
    4239 }
    4240 
    4241 void 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);
     3857        yahoo_http_post(yid->yd->client_id, url, buff, size,
     3858                _yahoo_http_post_connected, yad);
     3859}
     3860
     3861void 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);
    42443865        struct yahoo_data *yd;
    42453866        struct yahoo_packet *pkt = NULL;
    42463867
    4247         if(!yid)
     3868        if (!yid)
    42483869                return;
    42493870        yd = yid->yd;
    42503871
    4251         pkt = yahoo_packet_new(active?YAHOO_SERVICE_IDACT:YAHOO_SERVICE_IDDEACT,
    4252                         YAHOO_STATUS_AVAILABLE, yd->session_id);
     3872        pkt = yahoo_packet_new(active ? YAHOO_SERVICE_IDACT :
     3873                YAHOO_SERVICE_IDDEACT, YPACKET_STATUS_DEFAULT, yd->session_id);
    42533874        yahoo_packet_hash(pkt, 3, identity);
    42543875        if (pkt) {
     
    42603881void yahoo_refresh(int id)
    42613882{
    4262         struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     3883        struct yahoo_input_data *yid =
     3884                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    42633885        struct yahoo_data *yd;
    42643886        struct yahoo_packet *pkt = NULL;
    42653887
    4266         if(!yid)
     3888        if (!yid)
    42673889                return;
    42683890        yd = yid->yd;
    42693891
    4270         pkt = yahoo_packet_new(YAHOO_SERVICE_USERSTAT, YAHOO_STATUS_AVAILABLE, yd->session_id);
     3892        pkt = yahoo_packet_new(YAHOO_SERVICE_USERSTAT, YPACKET_STATUS_DEFAULT,
     3893                yd->session_id);
    42713894        if (pkt) {
    42723895                yahoo_send_packet(yid, pkt, 0);
     
    42773900void yahoo_keepalive(int id)
    42783901{
    4279         struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     3902        struct yahoo_input_data *yid =
     3903                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    42803904        struct yahoo_data *yd;
    4281         struct yahoo_packet *pkt=NULL;
    4282         if(!yid)
     3905        struct yahoo_packet *pkt = NULL;
     3906        if (!yid)
    42833907                return;
    42843908        yd = yid->yd;
    42853909
    4286         pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, yd->session_id);
     3910        pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YPACKET_STATUS_DEFAULT,
     3911                yd->session_id);
    42873912        yahoo_send_packet(yid, pkt, 0);
    42883913        yahoo_packet_free(pkt);
    42893914}
    42903915
    4291 void yahoo_chat_keepalive (int id)
    4292 {
    4293         struct yahoo_input_data *yid = find_input_by_id_and_type (id, YAHOO_CONNECTION_PAGER);
     3916void yahoo_chat_keepalive(int id)
     3917{
     3918        struct yahoo_input_data *yid =
     3919                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    42943920        struct yahoo_data *yd;
    42953921        struct yahoo_packet *pkt = NULL;
    42963922
    42973923        if (!yid)
    4298             return;
     3924                return;
    42993925
    43003926        yd = yid->yd;
    43013927
    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 
    4307 void 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);
     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
     3934void 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);
    43103939        struct yahoo_data *yd;
    43113940        struct yahoo_packet *pkt;
    43123941
    4313         if(!yid)
     3942        if (!yid)
    43143943                return;
    43153944        yd = yid->yd;
     
    43183947                return;
    43193948
    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" */
     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" */
    43233952                yahoo_packet_hash(pkt, 14, msg);
    43243953        else
    4325                 yahoo_packet_hash(pkt,14,"");
    4326 
     3954                yahoo_packet_hash(pkt, 14, "");
    43273955        yahoo_packet_hash(pkt, 65, group);
    43283956        yahoo_packet_hash(pkt, 97, "1");
     
    43343962        yahoo_packet_hash(pkt, 301, "319");
    43353963        yahoo_packet_hash(pkt, 303, "319");
    4336 
    4337 
    43383964        yahoo_send_packet(yid, pkt, 0);
    43393965        yahoo_packet_free(pkt);
     
    43423968void yahoo_remove_buddy(int id, const char *who, const char *group)
    43433969{
    4344         struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     3970        struct yahoo_input_data *yid =
     3971                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    43453972        struct yahoo_data *yd;
    43463973        struct yahoo_packet *pkt = NULL;
    43473974
    4348         if(!yid)
     3975        if (!yid)
    43493976                return;
    43503977        yd = yid->yd;
    43513978
    4352         pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id);
     3979        pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YPACKET_STATUS_DEFAULT,
     3980                yd->session_id);
    43533981
    43543982        yahoo_packet_hash(pkt, 1, yd->user);
     
    43593987}
    43603988
    4361 void 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);
     3989void 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);
    43633993        struct yahoo_data *yd;
    4364 
    4365         if(!yid)
     3994        struct yahoo_packet *pkt;
     3995
     3996        if (!yid)
    43663997                return;
    43673998        yd = yid->yd;
    43683999
    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");
     4000        if (!yd->logged_in)
     4001                return;
     4002
     4003        pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_AUTHORIZATION,
     4004                YPACKET_STATUS_DEFAULT, yd->session_id);
     4005        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
    43764021        yahoo_send_packet(yid, pkt, 0);
    43774022        yahoo_packet_free(pkt);
    43784023}
    43794024
    4380 void 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);
     4025void yahoo_ignore_buddy(int id, const char *who, int unignore)
     4026{
     4027        struct yahoo_input_data *yid =
     4028                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    43824029        struct yahoo_data *yd;
    4383 
    4384         if(!yid)
     4030        struct yahoo_packet *pkt;
     4031
     4032        if (!yid)
    43854033                return;
    43864034        yd = yid->yd;
    43874035
    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 
     4036        if (!yd->logged_in)
     4037                return;
     4038
     4039        pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT,
     4040                YPACKET_STATUS_DEFAULT, yd->session_id);
     4041        yahoo_packet_hash(pkt, 1, yd->user);
     4042        yahoo_packet_hash(pkt, 7, who);
     4043        yahoo_packet_hash(pkt, 13, unignore ? "2" : "1");
    43994044        yahoo_send_packet(yid, pkt, 0);
    44004045        yahoo_packet_free(pkt);
    4401 
    4402 }
    4403 
    4404 void 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);
     4046}
     4047
     4048void yahoo_stealth_buddy(int id, const char *who, int unstealth)
     4049{
     4050        struct yahoo_input_data *yid =
     4051                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    44074052        struct yahoo_data *yd;
    44084053        struct yahoo_packet *pkt;
    44094054
    4410         if(!yid)
     4055        if (!yid)
    44114056                return;
    44124057        yd = yid->yd;
     
    44154060                return;
    44164061
    4417         pkt = yahoo_packet_new(YAHOO_SERVICE_REJECTCONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4062        pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM,
     4063                YPACKET_STATUS_DEFAULT, yd->session_id);
    44184064        yahoo_packet_hash(pkt, 1, yd->user);
    44194065        yahoo_packet_hash(pkt, 7, who);
    4420         yahoo_packet_hash(pkt, 14, msg);
    4421         yahoo_send_packet(yid, pkt, 0);
    4422         yahoo_packet_free(pkt);
    4423 }
    4424 
    4425 void yahoo_ignore_buddy(int id, const char *who, int unignore)
    4426 {
    4427         struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    4428         struct yahoo_data *yd;
    4429         struct yahoo_packet *pkt;
    4430 
    4431         if(!yid)
    4432                 return;
    4433         yd = yid->yd;
    4434 
    4435         if (!yd->logged_in)
    4436                 return;
    4437 
    4438         pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
    4439         yahoo_packet_hash(pkt, 1, yd->user);
    4440         yahoo_packet_hash(pkt, 7, who);
    4441         yahoo_packet_hash(pkt, 13, unignore?"2":"1");
    4442         yahoo_send_packet(yid, pkt, 0);
    4443         yahoo_packet_free(pkt);
    4444 }
    4445 
    4446 void yahoo_stealth_buddy(int id, const char *who, int unstealth)
    4447 {
    4448         struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    4449         struct yahoo_data *yd;
    4450         struct yahoo_packet *pkt;
    4451 
    4452         if(!yid)
    4453                 return;
    4454         yd = yid->yd;
    4455 
    4456         if (!yd->logged_in)
    4457                 return;
    4458 
    4459         pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id);
    4460         yahoo_packet_hash(pkt, 1, yd->user);
    4461         yahoo_packet_hash(pkt, 7, who);
    4462         yahoo_packet_hash(pkt, 31, unstealth?"2":"1");
     4066        yahoo_packet_hash(pkt, 31, unstealth ? "2" : "1");
    44634067        yahoo_packet_hash(pkt, 13, "2");
    44644068        yahoo_send_packet(yid, pkt, 0);
     
    44664070}
    44674071
    4468 void 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);
     4072void 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);
    44714077        struct yahoo_data *yd;
    44724078        struct yahoo_packet *pkt = NULL;
    44734079
    4474         if(!yid)
     4080        if (!yid)
    44754081                return;
    44764082        yd = yid->yd;
    44774083
    4478         pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4084        pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_CHANGE_GROUP,
     4085                YPACKET_STATUS_DEFAULT, yd->session_id);
    44794086        yahoo_packet_hash(pkt, 1, yd->user);
     4087        yahoo_packet_hash(pkt, 302, "240");
     4088        yahoo_packet_hash(pkt, 300, "240");
    44804089        yahoo_packet_hash(pkt, 7, who);
    4481         yahoo_packet_hash(pkt, 65, new_group);
    4482         yahoo_packet_hash(pkt, 14, " ");
     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");
    44834094
    44844095        yahoo_send_packet(yid, pkt, 0);
    44854096        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);
    44934097}
    44944098
    44954099void yahoo_group_rename(int id, const char *old_group, const char *new_group)
    44964100{
    4497         struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4101        struct yahoo_input_data *yid =
     4102                find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
    44984103        struct yahoo_data *yd;
    44994104        struct yahoo_packet *pkt = NULL;
    45004105
    4501         if(!yid)
     4106        if (!yid)
    45024107                return;
    45034108        yd = yid->yd;
    45044109
    4505         pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4110        pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME,
     4111                YPACKET_STATUS_DEFAULT, yd->session_id);
    45064112        yahoo_packet_hash(pkt, 1, yd->user);
    45074113        yahoo_packet_hash(pkt, 65, old_group);
     
    45124118}
    45134119
    4514 void 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);
     4120void 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);
    45174125        struct yahoo_data *yd;
    45184126        struct yahoo_packet *pkt;
    4519                
    4520         if(!yid)
     4127
     4128        if (!yid)
    45214129                return;
    45224130        yd = yid->yd;
    45234131
    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));
     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));
    45274136        yahoo_packet_hash(pkt, 51, who);
    45284137        yahoo_packet_hash(pkt, 57, room);
    45294138        yahoo_packet_hash(pkt, 58, msg);
    45304139        yahoo_packet_hash(pkt, 13, "0");
    4531         for(; members; members = members->next) {
     4140        for (; members; members = members->next) {
    45324141                yahoo_packet_hash(pkt, 52, (char *)members->data);
    45334142                yahoo_packet_hash(pkt, 53, (char *)members->data);
     
    45404149}
    45414150
    4542 void 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);
     4151void 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);
    45454156        struct yahoo_data *yd;
    45464157        struct yahoo_packet *pkt;
    4547                
    4548         if(!yid)
     4158
     4159        if (!yid)
    45494160                return;
    45504161        yd = yid->yd;
    45514162
    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));
     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));
    45554167        yahoo_packet_hash(pkt, 50, yd->user);
    4556         for(; who; who = who->next) {
     4168        for (; who; who = who->next) {
    45574169                yahoo_packet_hash(pkt, 52, (char *)who->data);
    45584170        }
     
    45664178}
    45674179
    4568 void 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);
     4180void 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);
    45714185        struct yahoo_data *yd;
    45724186        struct yahoo_packet *pkt;
    4573                
    4574         if(!yid)
     4187
     4188        if (!yid)
    45754189                return;
    45764190        yd = yid->yd;
    45774191
    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) {
     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));
     4197        yahoo_packet_hash(pkt, 57, room);
     4198        for (; who; who = who->next)
    45824199                yahoo_packet_hash(pkt, 3, (char *)who->data);
    4583         }
    4584         yahoo_packet_hash(pkt, 57, room);
    45854200
    45864201        yahoo_send_packet(yid, pkt, 0);
     
    45894204}
    45904205
    4591 void 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);
     4206void 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);
    45944211        struct yahoo_data *yd;
    45954212        struct yahoo_packet *pkt;
    4596                
    4597         if(!yid)
     4213
     4214        if (!yid)
    45984215                return;
    45994216        yd = yid->yd;
    46004217
    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) {
     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)
    46054224                yahoo_packet_hash(pkt, 3, (char *)who->data);
    4606         }
    46074225        yahoo_packet_hash(pkt, 57, room);
    46084226        yahoo_packet_hash(pkt, 14, msg);
     
    46134231}
    46144232
    4615 void 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);
     4233void 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);
    46184238        struct yahoo_data *yd;
    46194239        struct yahoo_packet *pkt;
    4620                
    4621         if(!yid)
     4240
     4241        if (!yid)
    46224242                return;
    46234243        yd = yid->yd;
    46244244
    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) {
     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)
    46294251                yahoo_packet_hash(pkt, 3, (char *)who->data);
    4630         }
     4252
    46314253        yahoo_packet_hash(pkt, 57, room);
    46324254
     
    46364258}
    46374259
    4638 void 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);
     4260void 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);
    46414265        struct yahoo_data *yd;
    46424266        struct yahoo_packet *pkt;
    4643                
    4644         if(!yid)
     4267
     4268        if (!yid)
    46454269                return;
    46464270        yd = yid->yd;
    46474271
    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) {
     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)
    46524278                yahoo_packet_hash(pkt, 53, (char *)who->data);
    4653         }
     4279
    46544280        yahoo_packet_hash(pkt, 57, room);
    46554281        yahoo_packet_hash(pkt, 14, msg);
    46564282
    4657         if(utf8)
     4283        if (utf8)
    46584284                yahoo_packet_hash(pkt, 97, "1");
    46594285
     
    46704296        char buff[1024];
    46714297
    4672         if(!yd)
     4298        if (!yd)
    46734299                return;
    46744300
     
    46784304
    46794305        if (chatroomid == 0) {
    4680                 snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatcat=0");
     4306                snprintf(url, 1024,
     4307                        "http://insider.msg.yahoo.com/ycontent/?chatcat=0");
    46814308        } else {
    4682                 snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0",chatroomid);
     4309                snprintf(url, 1024,
     4310                        "http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0",
     4311                        chatroomid);
    46834312        }
    46844313
     
    46874316        inputs = y_list_prepend(inputs, yid);
    46884317
    4689         yahoo_http_get(yid->yd->client_id, url, buff, _yahoo_http_connected, yid);
    4690 }
    4691 
    4692 void 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);
     4318        yahoo_http_get(yid->yd->client_id, url, buff, 0, 0,
     4319                _yahoo_http_connected, yid);
     4320}
     4321
     4322void 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);
    46954327        struct yahoo_data *yd;
    46964328        struct yahoo_packet *pkt;
    4697                
    4698         if(!yid)
     4329
     4330        if (!yid)
    46994331                return;
    47004332
    47014333        yd = yid->yd;
    47024334