char const *ICQClient::localCharset(ICQUser *u) { if (u && *u->Encoding.c_str()) return u->Encoding.c_str(); if (*Encoding.c_str()) return Encoding.c_str(); return localCharset(); }
const char *ICQClient::serverCharset() { const char *p = localCharset(); if (!strcasecmp(p, "KOI8-R")) return "CP1251"; if (!strcasecmp(p, "KOI8-U")) return "CP1251"; if (!strcasecmp(p, "ISO8859-5")) return "CP1251"; return p; }
void ICQClient::toServer(string &str) { translate(serverCharset(), localCharset(), str); }
void ICQClient::fromServer(string &str) { translate(localCharset(), serverCharset(), str); }
void ICQClient::toUTF(string &str) { translate("UTF-8", localCharset(), str); }
void ICQClient::fromUTF(string &str) { translate(localCharset(), "UTF-8", str); }
void ICQClient::snac_lists(unsigned short type, unsigned short seq) { bool bFull = false; switch (type){ case ICQ_SNACxLISTS_RIGHTS: log(L_DEBUG, "List rights"); break; case ICQ_SNACxLISTS_ROSTER:{ char c; unsigned short list_len; log(L_DEBUG,"Rosters"); if (m_bRosters){ log(L_DEBUG, "Rosters part 2"); break; } readBuffer >> c; if (c){ log(L_WARN, "Bad first roster byte %02X", c); break; } vector<ICQGroup*>::iterator it_grp; list<ICQUser*>::iterator it_usr; for (it_grp = contacts.groups.begin(); it_grp != contacts.groups.end(); it_grp++) (*it_grp)->bChecked = false; for (it_usr = contacts.users.begin(); it_usr != contacts.users.end(); it_usr++){ if ((*it_usr)->Type != USER_TYPE_ICQ) continue; (*it_usr)->Id = 0; (*it_usr)->GrpId = 0; (*it_usr)->inIgnore = false; (*it_usr)->inVisible = false; (*it_usr)->inInvisible = false; } readBuffer >> list_len; for (unsigned i = 0; i < list_len; i++){ string str; unsigned short id, grp_id, type, len; readBuffer.unpackStr(str); readBuffer >> grp_id >> id >> type >> len; TlvList *inf = NULL; if (len){ Buffer b(len); b.pack(readBuffer.Data(readBuffer.readPos()), len); readBuffer.incReadPos(len); inf = new TlvList(b); } switch (type){ case 0x0000: /* User */{ unsigned long uin = atol(str.c_str()); if (uin == 0){ log(L_WARN, "Bad uin record %s\n", str.c_str()); break; } Tlv *tlv_name = NULL; if (inf) tlv_name = (*inf)(0x0131); string alias = tlv_name ? (char*)(*tlv_name) : ""; fromUTF(alias); bool needAuth = false; if (inf && (*inf)(0x0066)) needAuth = true; ICQUser *user = getUser(uin, true); user->Id = id; user->GrpId = grp_id; user->Alias = alias; user->WaitAuth = needAuth; break; } case ICQ_GROUPS:{ if (str.size() == 0) break; fromUTF(str); ICQGroup *grp = getGroup(grp_id, true); if (grp == NULL){ grp = new ICQGroup(); contacts.groups.push_back(grp); } grp->Id = grp_id; grp->Name = str; grp->bChecked = true; break; } case ICQ_VISIBLE_LIST:{ unsigned long uin = atol(str.c_str()); if (uin) getUser(atol(str.c_str()), true)->inVisible = true; break; } case ICQ_INVISIBLE_LIST:{ unsigned long uin = atol(str.c_str()); if (uin) getUser(atol(str.c_str()), true)->inInvisible = true; break; } case ICQ_IGNORE_LIST:{ unsigned long uin = atol(str.c_str()); if (uin) getUser(atol(str.c_str()), true)->inIgnore = true; break; } case ICQ_INVISIBLE_STATE: contacts.Invisible = id; break; case 0x0009: break; default: log(L_WARN,"Unknown roster type %04X", type); } if (inf) delete inf; } unsigned long time; readBuffer >> time; contacts.Time = time; for (;;){ bool ok = true; for (it_grp = contacts.groups.begin(); it_grp != contacts.groups.end(); it_grp++){ if (!(*it_grp)->bChecked){ contacts.groups.erase(it_grp); ok = false; break; } } if (ok) break; } for (it_usr = contacts.users.begin(); it_usr != contacts.users.end(); it_usr++){ unsigned short grpId = (*it_usr)->GrpId(); bool ok = false; for (it_grp = contacts.groups.begin(); it_grp != contacts.groups.end(); it_grp++){ if ((*it_grp)->Id() == grpId){ ok = true; break; } } if (!ok) (*it_usr)->GrpId = 0; } ICQEvent e(EVENT_GROUP_CHANGED); process_event(&e); m_state = Logged; bFull = true; } case ICQ_SNACxLISTS_ROSTERxOK: // FALLTHROUGH { m_bRosters = true; log(L_DEBUG, "Rosters OK"); snac(ICQ_SNACxFAM_LISTS, ICQ_SNACxLISTS_UNKNOWN); sendPacket(); sendCapability(); sendICMB(); sendLogonStatus(); sendClientReady(); sendMessageRequest(); sendPhoneInit(); sendPhoneStatus(); if (bFull || (Nick.size() == 0)){ addInfoRequest(Uin); searchByUin(Uin); } list<ICQUser*>::iterator it; for (it = contacts.users.begin(); it != contacts.users.end(); it++){ if ((*it)->inIgnore()) continue; if (!bFull && (*it)->Nick.size()) continue; addInfoRequest((*it)->Uin); } if (contacts.groups.size() == 0){ m_state = Logged; createGroup("General"); } break; } case ICQ_SNACxLISTS_ADDED:{ readBuffer.incReadPos(8); unsigned long uin = readBuffer.unpackUin(); ICQAddedToList *m = new ICQAddedToList; m->Uin.push_back(uin); messageReceived(m); break; } case ICQ_SNACxLISTS_AUTHxREQUEST:{ readBuffer.incReadPos(8); unsigned long uin = readBuffer.unpackUin(); ICQUser *u = getUser(uin); string message; string charset; unsigned short have_charset; readBuffer.unpackStr(message); readBuffer >> have_charset; if (have_charset){ readBuffer.incReadPos(2); readBuffer.unpackStr(charset); } if (charset.size()){ translate(localCharset(u), charset.c_str(), message); }else{ fromServer(message, u); } log(L_DEBUG, "Auth request %lu", uin); ICQAuthRequest *m = new ICQAuthRequest; m->Uin.push_back(uin); m->Message = message; messageReceived(m); break; } case ICQ_SNACxLISTS_AUTH:{ readBuffer.incReadPos(8); unsigned long uin = readBuffer.unpackUin(); char auth_ok; readBuffer >> auth_ok; string message; string charset; unsigned short have_charset; readBuffer.unpackStr(message); readBuffer >> have_charset; if (have_charset){ readBuffer.incReadPos(2); readBuffer.unpackStr(charset); } ICQUser *u = getUser(uin); if (charset.size()){ translate(localCharset(u), charset.c_str(), message); }else{ fromServer(message, u); } log(L_DEBUG, "Auth %u %lu", auth_ok, uin); if (auth_ok){ ICQUser *user = getUser(uin); if (user){ user->WaitAuth = false; ICQEvent e(EVENT_INFO_CHANGED, uin); process_event(&e); } ICQAuthGranted *m = new ICQAuthGranted(); m->Uin.push_back(uin); messageReceived(m); }else{ ICQAuthRefused *m = new ICQAuthRefused(); m->Uin.push_back(uin); m->Message = message; messageReceived(m); } break; } case ICQ_SNACxLISTS_DONE:{ ICQEvent *e = findListEvent(seq); if (e == NULL) break; readBuffer.incReadPos(8); unsigned short res; readBuffer >> res; e->processAnswer(this, readBuffer, res); delete e; break; } default: log(L_WARN, "Unknown lists family type %04X", type); } }
void ICQClient::toServer(string &str, const char *lclCharset) { if (lclCharset == NULL) lclCharset = localCharset(); translate(serverCharset(lclCharset), lclCharset, str); }
void ICQClient::toServer(string &str, ICQUser *u) { toServer(str, localCharset(u)); }