tocprotocol.cpp

00001 /* 00002 $Id: tocprotocol_8cpp-source.html,v 1.1 2004/10/05 21:12:03 mentat Exp $ 00003 00004 GNU Messenger - The secure instant messenger 00005 00006 Original TOC implementation: 00007 Copyright (C) 1999-2001 Henrik Abelsson <henrik@abelsson.com> 00008 00009 Re-written implementation in C++: 00010 Copyright (C) 2002-2004 Jesse Lovelace <jesse at aslogicsys dot com> 00011 00012 This program is free software; you can redistribute it and/or modify 00013 it under the terms of the GNU General Public License as published by 00014 the Free Software Foundation; either version 2 of the License, or 00015 (at your option) any later version. 00016 00017 This program is distributed in the hope that it will be useful, 00018 but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 GNU General Public License for more details. 00021 00022 You should have received a copy of the GNU General Public License 00023 along with this program; if not, write to the Free Software 00024 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00025 */ 00026 00027 #include <iostream> 00028 #include <iomanip> 00029 #include <string> 00030 #include <sstream> 00031 00032 #include "gm/tocprotocol.h" 00033 #include "gm/basenetwork.h" 00034 #include "gm/protocol.h" 00035 #include "gm/tree.h" 00036 #include "gm/buffer.h" 00037 00038 #include "cryptopp/misc.h" 00039 00040 #define TOC_VER 1 00041 #define TOC_TLV 1 00042 #define UID_AIM_CHAT "748F2420-6287-11D1-8222-444553540000" 00043 00044 namespace GNUMessenger { 00045 00046 using namespace std; 00047 using namespace CryptoPP; 00048 00049 string TocProtocol::getErrorText(int i, const string& name) 00050 { 00051 switch (i) 00052 { 00053 case(901): return name + string(" not currently available"); break; 00054 case(902): return string("Warning of ") + name + (" not currently available"); break; 00055 case(903): return "A message has been dropped, you are exceeding the server speed limit"; break; 00056 00057 case(911): return "Error validating input"; break; 00058 case(912): return "Invalid account"; break; 00059 case(913): return "Error encountered while processing request"; break; 00060 case(914): return "Service unavailable"; break; 00061 case(950): return string("Chat in ") + name + string("is unavailable"); break; 00062 case(960): return string("You are sending message too fast to ") + name; break; 00063 case(961): return string("You missed an im from ") + name + (" because it was too big."); break; 00064 case(962): return string("You missed an im from ") + name + (" because it sent to fast."); break; 00065 case(970): return "Failure"; break; 00066 case(971): return "Too many matches"; break; 00067 case(972): return "Need more qualifiers"; break; 00068 case(973): return "Dir service temporarily unavailable"; break; 00069 case(974): return "Email lookup restricted"; break; 00070 case(975): return "Keyword Ignored"; break; 00071 case(976): return "No Keywords"; break; 00072 case(977): return "Language not supported"; break; 00073 case(978): return "Country not supported"; break; 00074 case(979): return string("Failure unknown ") + name; break; 00075 case(980): return "Incorrect nickname or password."; break; 00076 case(981): return "The service is temporarily unavailable."; break; 00077 case(982): return "Your warning level is currently too high to sign on."; break; 00078 case(983): return string("You have been connecting and disconnecting too frequently. " 00079 "Wait 10 minutes and try again. " 00080 "If you continue to try, you will need to wait even longer."); break; 00081 case(989): return string("An unknown signon error has occurred ") + name; break; 00082 default: return "An unknown error has occured."; break; 00083 } 00084 } 00085 00086 00087 /* 00088 * General Errors * 00089 901 - $1 not currently available 00090 902 - Warning of $1 not currently available 00091 903 - A message has been dropped, you are exceeding 00092 the server speed limit 00093 00094 * Admin Errors * 00095 911 - Error validating input 00096 912 - Invalid account 00097 913 - Error encountered while processing request 00098 914 - Service unavailable 00099 00100 * Chat Errors * 00101 950 - Chat in $1 is unavailable. 00102 00103 * IM & Info Errors * 00104 960 - You are sending message too fast to $1 00105 961 - You missed an im from $1 because it was too big. 00106 962 - You missed an im from $1 because it was sent too fast. 00107 00108 * Dir Errors * 00109 970 - Failure 00110 971 - Too many matches 00111 972 - Need more qualifiers 00112 973 - Dir service temporarily unavailable 00113 974 - Email lookup restricted 00114 975 - Keyword Ignored 00115 976 - No Keywords 00116 977 - Language not supported 00117 978 - Country not supported 00118 979 - Failure unknown $1 00119 00120 00121 * Auth errors * 00122 980 - Incorrect nickname or password. 00123 981 - The service is temporarily unavailable. 00124 982 - Your warning level is currently too high to sign on. 00125 983 - You have been connecting and 00126 disconnecting too frequently. Wait 10 minutes and try again. 00127 If you continue to try, you will need to wait even longer. 00128 989 - An unknown signon error has occurred $1 00129 */ 00130 00131 00132 class TocProtocol::FlapHeader { 00133 public: 00134 00135 FlapHeader() 00136 { 00137 m_ast = (byte)'*'; 00138 m_type = (byte)2; 00139 m_seq = Network::NBO(real_seq++); 00140 m_len = (byte)0; 00141 } 00142 00143 static word16 real_seq; 00144 00145 private: 00146 byte m_ast; 00147 word16 m_seq; 00148 00149 public: 00150 byte m_type; 00151 word16 m_len; 00152 00153 VBuffer getHdr() 00154 { 00155 VBuffer header; 00156 00157 header += m_ast; 00158 header += m_type; 00159 header += (byte) (m_seq & 0xff); 00160 header += (byte) ((m_seq >> 8)& 0xff); 00161 header += (byte) (m_len & 0xff); 00162 header += (byte) ((m_len >> 8)& 0xff); 00163 00164 return header; 00165 } 00166 00167 }; 00168 00169 word16 TocProtocol::FlapHeader::real_seq = 1; 00170 00171 00172 string 00173 TocProtocol::aim_encode(const string& s) 00174 { 00175 string buf; 00176 buf.reserve(s.length()); 00177 for (unsigned int i = 0; i < s.length(); i++) { 00178 switch (s[i]) { 00179 case '$': case '{': case '}': 00180 case '[': case ']': case '(': 00181 case ')': case '\"': case '\\': 00182 buf += '\\'; buf += s[i]; 00183 break; 00184 case '\n': buf += "<BR>"; break; 00185 default: buf += s[i]; break; 00186 } 00187 } 00188 return buf; 00189 } 00190 00191 string TocProtocol::aim_normalize(const string& s) 00192 { 00193 string buf; 00194 buf.reserve(s.length()); 00195 00196 for (unsigned int i=0; i<s.length(); i++) { 00197 char c = s[i]; 00198 if (c != ' ' && c!='\t' && c!='\n') 00199 buf += tolower(c); 00200 } 00201 return buf; 00202 } 00203 00204 string TocProtocol::roastPassword(const VBuffer& pass) 00205 { 00206 /* Trivial "encryption" */ 00207 stringstream pword; 00208 pword << "0x"; 00209 string roast("Tic/Toc"); 00210 00211 for (unsigned int i = 0; i < pass.size(); i++) { 00212 pword << hex << setfill('0') << setw(2) << (word16)(pass[i] ^ roast[i % roast.length()]); 00213 } 00214 00215 return pword.str(); 00216 } 00217 00218 void TocProtocol::reset() 00219 { 00220 logout(); 00221 login(); 00222 00223 } 00224 00225 void TocProtocol::send_flap(int type, const VBuffer& data) 00226 { 00227 m_net->sendData(return_flap(type, data)); 00228 } 00229 00230 VBuffer TocProtocol::return_flap(int type, const VBuffer& data) 00231 { 00232 // output buffer object 00233 VBuffer buffer; 00234 00235 /* 00236 * FLAP Header (6 bytes) 00237 * ----------- 00238 00239 00240 * Offset Size Type 00241 * 0 1 ASTERISK (literal ASCII '*') 00242 * 1 1 Frame Type 00243 * 2 2 Sequence Number 00244 * 4 2 Data Length 00245 */ 00246 00247 // flap header object 00248 FlapHeader fh; 00249 00250 // set length to payload length 00251 word16 len = (word16)data.size(); 00252 00253 // set flap type 00254 fh.m_type = (byte)type; 00255 // put length in network byte order 00256 fh.m_len = Network::NBO(len); 00257 00258 // get the header and return it to the output buffer 00259 buffer = fh.getHdr(); 00260 00261 if (len > 0) 00262 buffer += data; 00263 00264 return buffer; 00265 } 00266 00267 TocProtocol::TocProtocol(const XMLNode &n, ProtocolManager *manager): 00268 Protocol(n, manager, "toc"), m_realLength(0) 00269 { 00270 m_away = false; 00271 m_net = addNet(); 00272 00273 LOG_DEBUG("New TocProtocol instance, initializing hashmap..."); 00274 00275 m_funcMap["UPDATE_BUDDY"] = &TocProtocol::processUpdateBuddy; 00276 m_funcMap["FLAP SIGNON"] = &TocProtocol::processSignon; 00277 m_funcMap["IM_IN"] = &TocProtocol::processIM; 00278 m_funcMap["SIGN_ON"] = &TocProtocol::processSignon; 00279 m_funcMap["CONFIG"] = &TocProtocol::processGotConfig; 00280 m_funcMap["NICK"] = &TocProtocol::processNick; 00281 m_funcMap["ERROR"] = &TocProtocol::processError; 00282 00283 } 00284 00285 TocProtocol::~TocProtocol() 00286 { 00287 //LOG_DEBUG("Deleting TocProtocol instance"); 00288 if (m_net) 00289 removeNet(m_net); 00290 } 00291 00292 00293 void TocProtocol::login() //string server, int port, string name, string pass) 00294 { 00295 LOG_DEBUG("TOC: login()"); 00296 // initiate socket connection to host 00297 if (!m_net) 00298 m_net = addNet(); 00299 00300 m_net->connectTo(m_conf.child("server").property("host"), 00301 m_conf.child("server").intProperty("port")); 00302 00303 // fire connecting event 00304 eventStateChange(S_connecting); 00305 00306 } 00307 00308 void TocProtocol::shutdown() { 00309 m_net->disconnect(); 00310 removeNet(m_net); 00311 m_net = 0; 00312 } 00313 00314 void TocProtocol::logout() 00315 { 00316 LOG_DEBUG("TOC: logout()"); 00317 //shutdown(); 00318 00319 eventStateChange(S_offline); 00320 eventLoggedOut(); 00321 } 00322 00323 bool TocProtocol::sendMessage(const Contact &c, const string &message) 00324 { 00325 LOG_DEBUG("sendMessage [" << c.getServerId(getProtocol()) << "] " << message); 00326 00327 VBuffer msg; 00328 msg += string("toc_send_im "); 00329 msg += aim_normalize(c.getServerId(getProtocol())); 00330 msg += string(" \""); 00331 msg += aim_encode(message); 00332 msg += string("\""); 00333 msg += (byte)0; 00334 00335 send_flap(TYPE_DATA,msg); 00336 return true; 00337 } 00338 00339 00340 void TocProtocol::sendMessageAuto(const Contact &c, const string &message) 00341 { 00342 LOG_DEBUG("sendMessageAuto"); 00343 VBuffer msg; 00344 msg += string("toc_send_im "); 00345 msg += aim_normalize(c.getServerId(getProtocol())); 00346 msg += (byte)' '; 00347 msg += (byte)'\"'; 00348 msg += aim_encode(message); 00349 msg += string("\" \"auto\""); 00350 msg += (byte)0; 00351 00352 send_flap(TYPE_DATA,msg); 00353 } 00354 00355 void TocProtocol::addContact(const Contact &c) 00356 { 00357 m_buddies[aim_normalize(c.getServerId(getProtocol()))] = c; 00358 00359 if (getState() == S_online) { 00363 forceContactUpdate(c); 00364 } else { 00365 m_buddies[aim_normalize(c.getServerId(getProtocol()))]. 00366 setStatus(getProtocol(), Contact::Offline); 00367 } 00368 00369 LOG_DEBUG("TocProtocol::addContact: I am not adding to TOC"); 00370 /*if (m_state==S_online) 00371 send_flap(TYPE_DATA, "toc_add_buddy " + aim_normalize(c.getServerId(getProtocol()))); 00372 00373 m_buddies[aim_normalize(c.getServerId(getProtocol()))] = c; 00374 m_buddies[aim_normalize(c.getServerId(getProtocol()))].setStatus(getProtocol(), Contact::Offline); 00375 eventStatusChange(c);*/ 00376 } 00377 00378 void TocProtocol::addBuddies() 00379 { 00380 LOG_DEBUG("TocProtocol::addBuddies"); 00381 VBuffer msg; 00382 msg += string("toc_add_buddy"); 00383 00384 map<string, Contact>::const_iterator it = m_buddies.begin(); 00385 for (; it != m_buddies.end(); it++) { 00386 msg += string(" "); 00387 msg += it->first; 00388 } 00389 00390 msg += (byte)0; 00391 send_flap(TYPE_DATA, msg); 00392 } 00393 00394 void TocProtocol::forceContactUpdate(const Contact& c) 00395 { 00396 LOG_DEBUG("TocProtocol::forceContactUpdate"); 00397 00398 VBuffer msg; 00399 msg += string("toc_get_status "); 00400 msg += c.getServerId(getProtocol()); 00401 msg += (byte)0; 00402 send_flap(TYPE_DATA, msg); 00403 00404 } 00405 00406 void TocProtocol::tocSendKeepalive() 00407 { 00408 send_flap(TYPE_KEEPALIVE, VBuffer()); 00409 } 00410 00411 void TocProtocol::delContact(const Contact &c) 00412 { 00413 map<string, Contact>::iterator it = m_buddies.find( 00414 aim_normalize(c.getServerId(getProtocol()))); 00415 00416 if (it != m_buddies.end()) 00417 m_buddies.erase(it); 00418 00419 LOG_DEBUG("TocProtocol::delContact: I am not removing from TOC"); 00420 } 00421 00422 00423 // some kind of error occured. 00424 void TocProtocol::connectionError(Network *net, int e) 00425 { 00426 eventError(e, "A Network error occured."); 00427 00428 LOG_DEBUG("TocProtocol::connectionError: Connection closed!"); 00429 00430 m_net->disconnect(); 00431 00432 eventStateChange(S_offline); 00433 eventLoggedOut(); 00434 } 00435 00436 void TocProtocol::connectedToServer(Network *net) 00437 { 00438 // when socket tells that we are connected, start TOC process 00439 VBuffer flap("FLAPON\r\n\r\n", 10); 00440 m_net->sendData(flap); 00441 00442 LOG_DEBUG("FLAPON"); 00443 00444 // update state to connecting 00445 eventStateChange(S_connecting); 00446 } 00447 00448 void TocProtocol::signup() 00449 { 00450 LOG_DEBUG("Doing FLAP SIGNON"); 00451 00452 string normalizedUsername(aim_normalize(m_conf.child("user").property("username"))); 00453 word16 usernameLength = (word16)normalizedUsername.length(); 00454 00455 // create pre-flapon packet (same packet really) 00456 FlapHeader pre; 00457 pre.m_type = (byte)TYPE_SIGNON; 00458 pre.m_len = Network::NBO(word16(usernameLength + 8)); 00459 00460 usernameLength = Network::NBO(usernameLength); 00461 00462 word32 ver = Network::NBO(word32(TOC_VER)); 00463 word16 tlv = Network::NBO(word16(TOC_TLV)); 00464 00465 // create flapon packet 00466 VBuffer flapOn; 00467 flapOn += (byte) (ver & 0xff); 00468 flapOn += (byte) ((ver >> 8) & 0xff); 00469 flapOn += (byte) ((ver >> 16) & 0xff); 00470 flapOn += (byte) ((ver >> 24) & 0xff); 00471 flapOn += (byte) (tlv & 0xff); 00472 flapOn += (byte) ((tlv >> 8) & 0xff); 00473 00474 flapOn += (byte) (usernameLength & 0xff); 00475 flapOn += (byte) ((usernameLength >> 8) & 0xff); 00476 00477 flapOn += normalizedUsername; 00478 00479 send_flap(TYPE_SIGNON, flapOn); 00480 00481 /* 00482 * toc_signon <authorizer host> <authorizer port> <User Name> <Password> 00483 * <language> <version> 00484 */ 00485 00486 VBuffer tocSignon; 00487 tocSignon += string("toc_signon "); 00488 tocSignon += m_conf.child("loginserver").property("host"); 00489 tocSignon += (byte)' '; 00490 tocSignon += m_conf.child("loginserver").property("port"); 00491 tocSignon += (byte)' '; 00492 tocSignon += normalizedUsername; 00493 tocSignon += (byte)' '; 00494 tocSignon += roastPassword(m_conf.child("user").property("password")); 00495 tocSignon += string(" english \"NNIM\""); 00496 tocSignon += (byte)0; 00497 00498 send_flap(TYPE_DATA, tocSignon); 00499 00500 eventStateChange(S_online); 00501 } 00502 00503 void TocProtocol::sendCap() 00504 { 00505 VBuffer caps; 00506 caps += string("toc_set_caps "); 00507 caps += string(UID_AIM_CHAT); 00508 send_flap(TYPE_DATA, caps); 00509 } 00510 00511 vector<string> TocProtocol::splitStr(const string& str) 00512 { 00513 unsigned int i=0; 00514 vector<string> words; 00515 00516 string tmp; 00517 while (i < str.length()) 00518 { 00519 while(str[i]!=':' && i<str.length()) 00520 tmp+=str[i++]; 00521 i++; 00522 words.push_back(tmp); 00523 00524 tmp=""; 00525 } 00526 00527 return words; 00528 00529 } 00530 00531 vector<string> TocProtocol::splitStrLF(const string& str) 00532 { 00533 unsigned int i=0; 00534 vector<string> words; 00535 string tmp; 00536 00537 while (i < str.length()) 00538 { 00539 while(str[i]!=0xA && i<str.length()) 00540 tmp+=str[i++]; 00541 i++; 00542 words.push_back(tmp); 00543 tmp=""; 00544 } 00545 return words; 00546 00547 } 00548 00549 void TocProtocol::handleData(Network *net) 00550 { 00551 VBuffer data; 00552 net->socketData(data); 00553 00554 if (data.size() == 0) 00555 return; 00556 00557 handleData(net,data); 00558 00559 } 00560 00561 void TocProtocol::handleData(Network *net, const VBuffer &data) 00562 { 00563 00564 byte frameType = data[1]; 00565 00566 switch (frameType) { 00567 case (1): LOG_DEBUG("TOC: Signon Frame"); break; 00568 case (2): LOG_DEBUG("TOC: Data Frame"); break; 00569 case (5): LOG_DEBUG("TOC: Keep Alive"); return; 00570 default: 00571 LOG_ERROR("TOC: Unknown Frame Type: " << (unsigned char)data[1]); 00572 } 00573 00574 if (m_buffer.size() != 0) { // means we have some partitial data 00575 VBuffer newData; 00576 // do concat buffer with present data 00577 00578 newData += m_buffer; 00579 m_buffer.clear(); 00580 00581 newData += data; 00582 handleData(net, newData); 00583 return; 00584 } 00585 00586 // extract payload length from data 00587 word16 payLoadLength; 00588 payLoadLength = (word16)data[4]; 00589 payLoadLength |= (word16)(data[5] << 8); 00590 00591 // convert from network byte order 00592 payLoadLength = Network::NBO(payLoadLength); 00593 00594 // see if payload length is greater then actual payload, 00595 // if so, more on the way 00596 00597 LOG_DEBUG("Payload length: " << payLoadLength << " Data length: " << (unsigned int)data.size()); 00598 00599 if (payLoadLength > (data.size() - 6)) { 00600 m_buffer += data; 00601 } else { 00602 handleRealData(net, string((const char *)(data.data()+6), payLoadLength)); 00603 00604 // recurse if there is more than one command in data stream 00605 if (data.size() > (unsigned int)(payLoadLength+6)) { 00606 LOG_DEBUG("More than one command in data stream."); 00607 handleData(net, data.sub(payLoadLength + 6)); 00608 } 00609 } 00610 } 00611 00612 void TocProtocol::handleRealData(Network *net, const string& data) 00613 { 00615 if (data.length() < 80) 00616 LOG_DEBUG("Got Data: " << data); 00617 00618 string command; 00619 00620 // if we are connecting, we should just go to signup 00621 // but the actual data should be the flap signon msg 00622 if (getState() == S_connecting) { 00623 signup(); 00624 return; 00625 } 00626 00627 unsigned int position((unsigned int)data.find(':', 0)); 00628 00629 command = data.substr(0, position); 00630 00631 LOG_DEBUG(command); 00632 00633 FuncMap::iterator it = m_funcMap.find(command); 00634 00635 if (it == m_funcMap.end()) { 00636 LOG_DEBUG("TOC: Function not found in hashtable: " << command); 00637 } else { 00638 (this->*(it->second))(data); 00639 } 00640 00641 } 00642 00643 void TocProtocol::processUpdateBuddy(const string& data) 00644 { 00645 LOG_DEBUG("TOC: UPDATE_BUDDY"); 00646 vector <string> words=splitStr(data); 00647 00648 string user = aim_normalize(words[1]); 00649 00650 /* are we online? */ 00651 bool online = (words[2] == "T") ? true : false; 00652 00653 if (m_buddies.find(user) != m_buddies.end()) 00654 { 00655 if (online) { 00656 if (words[6][2] == 'U') { 00657 LOG_DEBUG("Buddy is away"); 00658 m_buddies[user].setStatus(getProtocol(), Contact::Away); 00659 } else { 00660 m_buddies[user].setStatus(getProtocol(), Contact::Online); 00661 } 00662 } else { 00663 m_buddies[user].setStatus(getProtocol(), Contact::Offline); 00664 } 00665 00666 switch (words[6][1]) { 00667 case ('A'): LOG_DEBUG("Buddy is Oscar Admin"); break; // Oscar Admin 00668 case ('U'): LOG_DEBUG("Buddy is Oscar Unconfirmed"); break; // Oscar Unconfirmed 00669 case ('O'): LOG_DEBUG("Buddy is Oscar Normal"); break; // Oscar Normal 00670 } 00671 00672 eventStatusChange(m_buddies[user]); 00673 } 00674 } 00675 00676 void TocProtocol::processFlapSignon(const string& data) 00677 { 00678 LOG_DEBUG("TocProtocol::processFlapSignon"); 00679 signup(); 00680 } 00682 void TocProtocol::processSignon(const string& data) 00683 { 00684 LOG_DEBUG("TocProtocol::processSignon"); 00685 } 00687 void TocProtocol::processGotConfig(const string& data) 00688 { 00689 LOG_DEBUG("TocProtocol::processGotConfig"); 00690 00691 VBuffer setInfo("toc_set_info \""); 00692 setInfo += aim_encode("<html><body><b>Yes, I'm using NNIM!<br>" 00693 "Visit NNIM at <a href=\"http://nnim.sf.net\">http://nnim.sf.net</a>.</b>" 00694 "</body></html>"); 00695 00696 setInfo += '\"'; 00697 setInfo += (byte)0; 00698 send_flap(TYPE_DATA, setInfo); 00699 00701 addBuddies(); 00702 00703 VBuffer initDone("toc_init_done"); 00704 initDone += (byte)0; 00705 00706 send_flap(TYPE_DATA, initDone); 00707 00708 // send capabilities 00709 //sendCap(); 00710 00711 eventStateChange(S_online); 00712 eventLoggedIn(); 00713 00714 tocParseConfig(data.substr(7,data.length())); 00715 } 00716 00718 void TocProtocol::processIM(const string& data) 00719 { 00720 LOG_DEBUG("TocProtocol::processIM"); 00721 00722 vector <string> words = splitStr(data); 00723 00724 string msg = words[3]; 00725 string name = aim_normalize(words[1]); 00726 00727 if (m_buddies.find(name)==m_buddies.end() || 00728 (!m_buddies[words[1]].isOK())) // also see if contact is destroyed, it would be better if i was notified 00729 { 00730 LOG_DEBUG("Anonymous user msg."); 00731 // if we can't find the user, we prompt for acceptance 00732 Contact c; 00733 c.addProtocol(getProtocol()); 00734 c.setServerId(getProtocol(), words[1]); 00735 c.setStatus(getProtocol(), Contact::Online); 00736 //c.activateProtocol(getProtocol()); 00737 c.setName(words[1]); 00738 00739 eventRecvdMessageNotBuddy(c, msg); 00740 return; 00741 } 00742 00743 // if we are away, respond with away message 00744 if (m_away) 00745 { 00746 if (m_awayMessage == "") 00747 sendMessageAuto(m_buddies[name], "I am away"); 00748 else 00749 sendMessageAuto(m_buddies[name], m_awayMessage); 00750 } 00751 // if is auto responce maybe say so 00752 if (words[2] == "T") 00753 msg = "Auto responce: " + msg; 00754 00755 eventRecvdMessage(m_buddies[name],msg); 00756 00757 } 00759 void TocProtocol::processError(const string& data) 00760 { 00761 LOG_DEBUG("TocProtocol::processError"); 00762 int num; 00763 stringstream err; 00764 err << data.substr(6,data.length()); 00765 err >> num; 00766 00767 LOG_DEBUG("Err Num: " << num); 00768 00769 eventError(E_protocol, getErrorText(num, data.substr(6, data.length()))); 00770 LOG_ERROR(getErrorText(num, data.substr(6, data.length()))); 00771 00772 eventStateChange(S_offline); 00773 } 00774 00776 void TocProtocol::processNick(const string& data) 00777 { 00778 LOG_DEBUG("TocProtocol::processNick"); 00779 00780 m_screenName = data.substr(5, data.length()); 00781 } 00782 00783 void TocProtocol::update() 00784 { 00785 00786 } 00787 void TocProtocol::newUser(const string& userName, const VBuffer& password) 00788 { 00789 00790 } 00791 00792 void TocProtocol::getPubkey() 00793 { 00794 00795 } 00796 00797 void TocProtocol::getInfo(const string& contact) 00798 { 00799 LOG_DEBUG("TocProtocol::getInfo " << aim_normalize(contact)); 00800 00801 VBuffer msg; 00802 msg += string("toc_get_info "); 00803 msg += aim_normalize(contact); 00804 msg += (byte)0; 00805 00806 send_flap(TYPE_DATA, msg); 00807 } 00808 00809 void TocProtocol::setAway(const string& msg) 00810 { 00811 LOG_DEBUG("TocProtocol::setAway"); 00812 if (msg.length() == 0) 00813 { 00814 m_away = false; 00815 m_awayMessage = ""; 00816 } else { 00817 m_away = true; 00818 m_awayMessage = aim_encode(msg); 00819 } 00820 00821 VBuffer setAway; 00822 setAway += string("toc_set_away \""); 00823 setAway += aim_encode(msg); 00824 setAway += (byte)'\"'; 00825 setAway += (byte)0; 00826 00827 send_flap(TYPE_DATA, setAway); 00828 00829 } 00830 00831 void TocProtocol::setInfo(const string& info) 00832 { 00833 LOG_DEBUG("TocProtocol::setInfo"); 00834 VBuffer tSetInfo; 00835 tSetInfo += string("toc_set_info \""); 00836 tSetInfo += aim_encode(info); 00837 tSetInfo += (byte)'\"'; 00838 tSetInfo += (byte)0; 00839 00840 send_flap(TYPE_DATA, tSetInfo); 00841 00842 } 00843 00844 void TocProtocol::tocParseConfig(const string& config) 00845 { 00846 00847 vector<string> myContacts = splitStrLF(config); 00848 LOG_DEBUG("TocProtocol::tocParseConfig: " << myContacts.size() << " contacts from server"); 00849 00850 vector<buddy> buddies; 00851 00853 00854 string currentGroup = "Buddies"; 00855 00856 buddy temp; 00857 temp.proto = getProtocol(); 00858 00859 for (unsigned int it = 0; it < myContacts.size(); it++) 00860 { 00861 if (myContacts[it][0] == 'g') { // this is a group definition 00862 currentGroup = myContacts[it].substr(2); 00863 } 00864 else 00865 if (myContacts[it][0] == 'b') { 00866 00867 temp.name = myContacts[it].substr(2); 00868 temp.group = currentGroup; 00869 buddies.push_back(temp); 00870 } 00871 } 00872 00873 if (buddies.size() > 0) 00874 eventGotContacts(buddies); 00875 00876 } 00877 00878 } 00879 00880 /* 00881 ----- 00882 $Log: tocprotocol.cpp,v $ 00883 Revision 1.5 2004/10/04 23:28:44 mentat 00884 Adding VC 2003 project file and compiles on Win32 00885 00886 Revision 1.4 2004/10/04 05:14:20 mentat 00887 Adding info get support and HTTP. 00888 00889 Revision 1.3 2004/10/03 18:39:40 mentat 00890 Merging in hash_map changes to TOC and getInfo methods. 00891 00892 Revision 1.2.2.1 2004/10/03 18:36:03 mentat 00893 Added hash_map to toc protocol and working in getInfo methods. 00894 00895 Revision 1.2 2004/10/03 15:22:57 mentat 00896 Fixed a pure virtual function error and improved TOC. 00897 00898 Revision 1.1.1.1 2004/10/03 06:17:37 mentat 00899 Initial re-import. 00900 00901 Revision 1.4 2003/04/13 18:43:58 mentat 00902 Heavy commits. 00903 00904 Revision 1.3 2003/04/09 21:19:56 mentat 00905 Updating to compile. 00906 00907 Revision 1.2 2003/03/25 23:33:10 mentat 00908 Hopefully getting things working again. 00909 00910 Revision 1.1 2003/03/02 16:19:05 mentat 00911 Importing new sources. 00912 00913 Revision 1.23 2003/01/22 19:51:35 mentat 00914 Large laptop checkin, most stuff won't work probably. 00915 00916 Revision 1.20 2002/11/09 03:13:27 mentat 00917 Temp. Checkin. 00918 00919 Revision 1.19 2002/11/04 21:18:35 mentat 00920 Fixed all those pesky leaks with scoped_arrays in Xerces code. 00921 00922 Revision 1.18 2002/07/04 22:45:44 mentat 00923 Major changes to NNIM's contact interface and wizards. 00924 00925 Revision 1.17 2002/06/30 16:53:12 mentat 00926 Fixed glitch in treectrl that caused assert and shaved 5 megs off of CryptoPP 00927 00928 Revision 1.16 2002/06/29 16:45:06 mentat 00929 Added multi-protocol support to Contact and fixed AuthLoad code. 00930 00931 Revision 1.15 2002/06/28 18:34:50 mentat 00932 SF CVS merge. 00933 00934 Revision 1.11 2002/06/27 22:33:27 thementat 00935 Fixed TOC error and applied patch for gcc 2.95 in AuthLoad 00936 00937 Revision 1.10 2002/06/27 11:52:51 thementat 00938 More event handling fixes. 00939 00940 Revision 1.9 2002/06/26 17:40:12 thementat 00941 Added the Open-Source ssh2 lib from Bitvise. 00942 00943 Revision 1.8 2002/06/26 04:27:08 thementat 00944 Event fixes. 00945 00946 Revision 1.7 2002/06/25 16:48:14 thementat 00947 Got TOC done! (mostly) 00948 00949 Revision 1.6 2002/06/25 04:46:21 thementat 00950 More toc work. 00951 00952 Revision 1.5 2002/06/24 18:00:50 thementat 00953 Fixed TOC sequence bug. 00954 00955 Revision 1.4 2002/06/24 12:07:40 thementat 00956 Toc fixes. 00957 00958 Revision 1.3 2002/06/23 18:35:51 thementat 00959 Added vbuf class and changing all protocol to use. 00960 00961 Revision 1.2 2002/06/23 14:50:01 thementat 00962 Work on TOC protocol and new buffer class. 00963 00964 Revision 1.1.1.1 2002/06/06 17:21:50 thementat 00965 Checkin of new sources BETA 2 00966 00967 Revision 1.13 2001/12/17 18:33:42 mentat 00968 Importing changes for NNIM Beta 1 client. 00969 00970 Revision 1.11 2001/12/16 19:46:50 mentat 00971 Updates to TOC protocol and authload class. 00972 00973 Revision 1.10 2001/12/13 19:01:54 mentat 00974 Took out some logging i added from toc, fixed a bug in toc that was 00975 confusing my client (and me), it was: m_state was defined as private 00976 in tocprotocol.h (int) but it was also defined in the parent protocol.h, so 00977 when I called getState, the protocol would return the wrong one. Fixed now. 00978 00979 Revision 1.9 2001/12/12 02:10:46 mentat 00980 Added #include <sys/time.h> to tocprotocol.cpp to resolve FreeBSD compile error, fixed small error in authload.cpp 00981 00982 Revision 1.8 2001/12/08 21:45:27 mentat 00983 Added setAway and setAllAway to Protocol Manager along with modifying some protocol code. 00984 00985 Revision 1.7 2001/12/06 04:46:40 mentat 00986 Added setAway() and setAllAway(...) to manager class and to toc protocol, also added changes to toc so that will log in with wx client. 00987 00988 Revision 1.6 2001/11/24 00:32:44 henrik 00989 Addcontact dialog restructuring, chat improvements, login/logout improvements. 00990 00991 Revision 1.5 2001/10/05 14:11:00 abelsson 00992 Added debug() macro for debug output. 00993 00994 Revision 1.4 2001/10/04 16:26:37 abelsson 00995 Added missing protocol status callbacks. 00996 00997 00998 00999 Revision 1.3 2001/10/02 22:51:57 estyrke 01000 Added some more boilerplates... 01001 01002 */ 01003

Generated on Tue Oct 5 14:41:47 2004 for GNU Messenger by doxygen 1.3.8