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; }