Example #1
0
void ICQClient::snac_message(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxMSG_RIGHTSxGRANTED:
        log(L_DEBUG, "Message rights granted");
        break;
    case ICQ_SNACxMSG_ACK:
        log(L_DEBUG, "Ack message");
        break;
    case ICQ_SNACxMSG_AUTOREPLY:{
            unsigned long timestamp1, timestamp2;
            readBuffer >> timestamp1 >> timestamp2;
            readBuffer.incReadPos(2);
            unsigned long uin = readBuffer.unpackUin();
            readBuffer.incReadPos(6);
            unsigned long t1, t2;
            readBuffer >> t1 >> t2;
            unsigned short seq;
            readBuffer.incReadPos(0x0F);
            readBuffer >> seq;
            if ((t1 == 0) && (t2 == 0)){
                readBuffer.incReadPos(0x16);
                string answer;
                readBuffer >> answer;
                fromServer(answer);
                if (timestamp1 || timestamp2){
                    log(L_DEBUG, "Message declined %s", answer.c_str());
                    list<ICQEvent*>::iterator it;
                    for (it = processQueue.begin(); it != processQueue.end(); ++it){
                        ICQEvent *e = *it;
                        if (e->type() != EVENT_MESSAGE_SEND) continue;
                        ICQMessage *msg = e->message();
                        if (msg == NULL) continue;
                        if ((msg->Uin == uin) && (msg->timestamp1 == timestamp1) && (msg->timestamp2 == timestamp2)){
                            msg->DeclineReason = answer;
                            cancelMessage(msg, false);
                            break;
                        }
                    }
                    if (it == processQueue.end())
                        log(L_WARN, "Decline file answer: message not found");
                }else{
                    log(L_DEBUG, "[%X] Autoreply from %u %s", seq, uin, answer.c_str());
                    ICQUser *u = getUser(uin);
                    if (u) u->AutoReply = answer;
                    ICQEvent e(EVENT_STATUS_CHANGED, uin);
                    process_event(&e);
                    processResponseRequestQueue(seq);
                }
            }
            if ((t1 == 0xA0E93F37L) && (t2 == 0x4FE9D311L)){
                ICQUser *u = getUser(uin);
                if (u == NULL){
                    log(L_WARN, "Request info no my user %lu", uin);
                    return;
                }
                if (u->inIgnore()){
                    log(L_WARN, "Request info ignore user %lu", uin);
                    return;
                }

                readBuffer.incReadPos(0x1D);
                unsigned long cookie;
                readBuffer >> cookie;
                readBuffer.incReadPos(4);
                readBuffer.unpack(t1);
                if (t1 == 3){
                    u->PhoneBookTime = (unsigned long)htonl(cookie);
                    u->bPhoneChanged = false;
                    log(L_DEBUG, "[%X] Phone book info %u", seq, uin);
                    PhoneBook::iterator it;
                    PhonePtrList myNumbers;
                    for (it = u->Phones.begin(); it != u->Phones.end(); ++it){
                        PhoneInfo *phone = static_cast<PhoneInfo*>(*it);
                        if (!phone->MyInfo()) continue;
                        PhoneInfo *myPhone = new PhoneInfo;
                        *myPhone = *phone;
                        myNumbers.push_back(myPhone);
                    }
                    u->Phones.clear();
                    unsigned long nPhones;
                    readBuffer.unpack(nPhones);
                    for (unsigned i = 0; i < nPhones; i++){
                        PhoneInfo *phone = new PhoneInfo;
                        u->Phones.push_back(phone);
                        readBuffer.unpackStr32(phone->Name);
                        readBuffer.unpackStr32(phone->AreaCode);
                        readBuffer.unpackStr32(phone->Number);
                        readBuffer.unpackStr32(phone->Extension);
                        readBuffer.unpackStr32(phone->Country);
                        unsigned long type;
                        readBuffer.unpack(type);
                        if (type) phone->Active = true;
                        if (readBuffer.readPos() >= readBuffer.size()) break;
                    }
                    for (it = u->Phones.begin(); it != u->Phones.end(); it++){
                        PhoneInfo *phone = static_cast<PhoneInfo*>(*it);
                        string prop;
                        readBuffer.unpackStr32(prop);
                        Buffer b;
                        b.pack(prop.c_str(), prop.length());
                        b.unpack(phone->Type);
                        b.unpackStr32(phone->Provider);
                        if (readBuffer.readPos() >= readBuffer.size()) break;
                    }
                    for (;;){
                        for (it = u->Phones.begin(); it != u->Phones.end(); it++){
                            PhoneInfo *phone = static_cast<PhoneInfo*>(*it);
                            bool bOK = (phone->getNumber().length() > 0);
                            if (bOK && !*phone->Number.c_str()) bOK = false;
                            if (bOK)
                                for (const char *p = phone->Number.c_str(); *p; p++){
                                    if ((*p >= '0') && (*p <= '9')) continue;
                                    if ((*p == ' ') || (*p == '-')) continue;
                                    bOK = false;
                                    break;
                                }
                            if (bOK) continue;
                            u->Phones.remove(phone);
                            break;
                        }
                        if (it == u->Phones.end()) break;
                    }
                    u->adjustPhones();
                    u->Phones.add(myNumbers);
                    ICQEvent e(EVENT_INFO_CHANGED, uin);
                    process_event(&e);
                    processPhoneRequestQueue(seq);
                }
            }
            break;
        }