1 /*
2 *
3 * centerim IM protocol abstraction class
4 * $Id: abstracthook.cc,v 1.58 2004/11/09 23:49:59 konst Exp $
5 *
6 * Copyright (C) 2001,2002,2003 by Konstantin Klyagin <k@thekonst.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 *
23 */
24 
25 #include "abstracthook.h"
26 
27 #include "icqhook.h"
28 #include "yahoohook.h"
29 #include "aimhook.h"
30 #include "irchook.h"
31 #include "jabberhook.h"
32 #include "rsshook.h"
33 #include "ljhook.h"
34 #include "gaduhook.h"
35 #include "msnhook.h"
36 #include "icqcontacts.h"
37 
38 #include "icqface.h"
39 
40 #include "md5.h"
41 
42 #include <time.h>
43 
44 #define NOTIFBUF 512
45 
46 time_t timer_current = time(0);
47 
abstracthook(protocolname aproto)48 abstracthook::abstracthook(protocolname aproto)
49     : proto(aproto), searchdest(0)
50 { }
51 
~abstracthook()52 abstracthook::~abstracthook() {
53 }
54 
init()55 void abstracthook::init() {
56 }
57 
connect()58 void abstracthook::connect() {
59 }
60 
disconnect()61 void abstracthook::disconnect() {
62 }
63 
exectimers()64 void abstracthook::exectimers() {
65 }
66 
main()67 void abstracthook::main() {
68 }
69 
setautostatus(imstatus st)70 void abstracthook::setautostatus(imstatus st) {
71 }
72 
restorestatus()73 void abstracthook::restorestatus() {
74     setautostatus(manualstatus);
75 }
76 
setstatus(imstatus st)77 void abstracthook::setstatus(imstatus st) {
78     setautostatus(manualstatus = st);
79 
80     for(protocolname pname = icq; pname != protocolname_size; pname++) {
81 	if(&gethook(pname) == this) {
82 	    conf->savestatus(pname, manualstatus);
83 	    break;
84 	}
85     }
86 }
87 
getsockets(fd_set & rfds,fd_set & wfds,fd_set & efds,int & hsocket) const88 void abstracthook::getsockets(fd_set &rfds, fd_set &wfds, fd_set &efds, int &hsocket) const {
89 }
90 
isoursocket(fd_set & rfds,fd_set & wfds,fd_set & efds) const91 bool abstracthook::isoursocket(fd_set &rfds, fd_set &wfds, fd_set &efds) const {
92     return false;
93 }
94 
online() const95 bool abstracthook::online() const {
96     return false;
97 }
98 
logged() const99 bool abstracthook::logged() const {
100     return false;
101 }
102 
isconnecting() const103 bool abstracthook::isconnecting() const {
104     return false;
105 }
106 
enabled() const107 bool abstracthook::enabled() const {
108     return false;
109 }
110 
send(const imevent & ev)111 bool abstracthook::send(const imevent &ev) {
112     return false;
113 }
114 
sendnewuser(const imcontact & c)115 void abstracthook::sendnewuser(const imcontact &c) {
116 }
117 
getstatus() const118 imstatus abstracthook::getstatus() const {
119     return offline;
120 }
121 
isdirectopen(const imcontact & c) const122 bool abstracthook::isdirectopen(const imcontact &c) const {
123     return false;
124 }
125 
removeuser(const imcontact & ic)126 void abstracthook::removeuser(const imcontact &ic) {
127 }
128 
requestinfo(const imcontact & c)129 void abstracthook::requestinfo(const imcontact &c) {
130 }
131 
lookup(const imsearchparams & params,verticalmenu & dest)132 void abstracthook::lookup(const imsearchparams &params, verticalmenu &dest) {
133 }
134 
stoplookup()135 void abstracthook::stoplookup() {
136     searchdest = 0;
137 }
138 
requestawaymsg(const imcontact & c)139 void abstracthook::requestawaymsg(const imcontact &c) {
140 }
141 
ouridchanged(const icqconf::imaccount & ia)142 void abstracthook::ouridchanged(const icqconf::imaccount &ia) {
143 }
144 
requestversion(const imcontact & c)145 void abstracthook::requestversion(const imcontact &c) {
146 }
147 
ping(const imcontact & c)148 void abstracthook::ping(const imcontact &c) {
149 }
150 
knowntransfer(const imfile & fr) const151 bool abstracthook::knowntransfer(const imfile &fr) const {
152     return false;
153 }
154 
replytransfer(const imfile & fr,bool accept,const string & localpath)155 void abstracthook::replytransfer(const imfile &fr, bool accept, const string &localpath) {
156 }
157 
aborttransfer(const imfile & fr)158 void abstracthook::aborttransfer(const imfile &fr) {
159 }
160 
conferencecreate(const imcontact & confid,const vector<imcontact> & lst)161 void abstracthook::conferencecreate(const imcontact &confid,
162 const vector<imcontact> &lst) {
163 }
164 
getservices(servicetype::enumeration st) const165 vector<string> abstracthook::getservices(servicetype::enumeration st) const {
166     return vector<string>();
167 }
168 
getsearchparameters(const string & agentname) const169 vector<pair< string, string> > abstracthook::getsearchparameters(const string &agentname) const {
170     return vector<pair<string, string> >();
171 }
172 
getregparameters(const string & agentname) const173 vector<pair<string, string> > abstracthook::getregparameters(const string &agentname) const {
174     return vector<pair<string, string> >();
175 }
176 
updatecontact(icqcontact * c)177 void abstracthook::updatecontact(icqcontact *c) {
178 }
179 
renamegroup(const string & oldname,const string & newname)180 void abstracthook::renamegroup(const string &oldname, const string &newname) {
181 }
182 
rushtmlconv(const string & tdir,const string & text,bool rus)183 string abstracthook::rushtmlconv(const string &tdir, const string &text, bool rus) {
184     int pos;
185     string r = rus ? rusconv(tdir, text) : text;
186 
187     if(tdir == "kw" || tdir == "ku") {
188 	pos = 0;
189 	while((pos = r.find_first_of("&<>", pos)) != -1) {
190 	    switch(r[pos]) {
191 		case '&':
192 		    if(r.substr(pos, 4) != "&lt;"
193 		    && r.substr(pos, 4) != "&gt;")
194 			r.replace(pos, 1, "&amp;");
195 		    break;
196 		case '<': r.replace(pos, 1, "&lt;"); break;
197 		case '>': r.replace(pos, 1, "&gt;"); break;
198 	    }
199 	    pos++;
200 	}
201 
202     } else if(tdir == "wk" || tdir == "uk") {
203 	pos = 0;
204 	while((pos = r.find("&", pos)) != -1) {
205 	    if(r.substr(pos+1, 4) == "amp;") r.replace(pos, 5, "&"); else
206 	    if(r.substr(pos+1, 3) == "lt;") r.replace(pos, 4, "<"); else
207 	    if(r.substr(pos+1, 3) == "gt;") r.replace(pos, 4, ">"); else
208 	    if(r.substr(pos+1, 5) == "#150;") r.replace(pos, 6, "-"); else
209 	    if(r.substr(pos+1, 5) == "#151;") r.replace(pos, 6, "--"); else
210 	    if(r.substr(pos+1, 5) == "#146;") r.replace(pos, 6, "`"); else
211 	    if(r.substr(pos+1, 4) == "#39;") r.replace(pos, 5, "'"); else
212 	    if(r.substr(pos+1, 6) == "#8211;") r.replace(pos, 7, "--"); else
213 	    if(r.substr(pos+1, 6) == "#8230;") r.replace(pos, 7, "..."); else
214 	    if(r.substr(pos+1, 7) == "hellip;") r.replace(pos, 8, "..."); else
215 	    if(r.substr(pos+1, 6) == "laquo;") r.replace(pos, 7, "<<"); else
216 	    if(r.substr(pos+1, 6) == "raquo;") r.replace(pos, 7, ">>"); else
217 	    if(r.substr(pos+1, 6) == "bdquo;") r.replace(pos, 7, "\""); else
218 	    if(r.substr(pos+1, 6) == "ldquo;") r.replace(pos, 7, "\""); else
219 	    if(r.substr(pos+1, 5) == "copy;") r.replace(pos, 8, "(c)"); else
220 	    if(r.substr(pos+1, 4) == "#13;") r.replace(pos, 5, "\r"); else
221 	    if(r.substr(pos+1, 4) == "#10;") r.replace(pos, 5, "\n");
222 	    pos++;
223 	}
224     }
225 
226     return r;
227 }
228 
ruscrlfconv(const string & tdir,const string & text)229 string abstracthook::ruscrlfconv(const string &tdir, const string &text) {
230     string r = rusconv(tdir, text);
231     int pos;
232 
233     for(pos = 0; (pos = r.find("\r")) != -1; pos++) {
234 	r.erase(pos, 1);
235     }
236 
237     return r;
238 }
239 
rusconv(const string & tdir,const string & text)240 string abstracthook::rusconv(const string &tdir, const string &text) {
241     string r;
242 
243     if(!conf->getcpconvert(proto) && tdir.find("u") == -1)
244 	return text;
245 
246 #ifdef HAVE_ICONV
247     if(tdir == "kw") r = siconv(text, conf->getconvertto(proto), conf->getconvertfrom(proto)); else
248     if(tdir == "wk") r = siconv(text, conf->getconvertfrom(proto), conf->getconvertto(proto)); else
249     if(tdir == "ku") r = siconv(text, conf->getconvertto(proto), "utf-8"); else
250     if(tdir == "uk") r = siconv(text, "utf-8", conf->getconvertto(proto)); else
251     if(tdir == "ck") r = siconv(text, "UCS-2BE", conf->getconvertto(proto)); else
252 #endif
253 	r = text;
254 
255 #ifndef HAVE_ICONV
256     static unsigned char kw[] = {
257 	128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
258 	144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
259 	160,161,162,184,164,165,166,167,168,169,170,171,172,173,174,175,
260 	176,177,178,168,180,181,182,183,184,185,186,187,188,189,190,191,
261 	254,224,225,246,228,229,244,227,245,232,233,234,235,236,237,238,
262 	239,255,240,241,242,243,230,226,252,251,231,248,253,249,247,250,
263 	222,192,193,214,196,197,212,195,213,200,201,202,203,204,205,206,
264 	207,223,208,209,210,211,198,194,220,219,199,216,221,217,215,218
265     };
266 
267     static unsigned char wk[] = {
268 	128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
269 	144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
270 	160,161,162,163,164,165,166,167,179,169,170,171,172,173,174,175,
271 	176,177,178,179,180,181,182,183,163,185,186,187,188,189,190,191,
272 	225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240,
273 	242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241,
274 	193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208,
275 	210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,209
276     };
277 
278     unsigned char c;
279     string::const_iterator i;
280     unsigned char *table = 0;
281 
282     if(tdir == "kw") table = kw; else
283     if(tdir == "wk") table = wk;
284 
285     if(table) {
286 	r = "";
287 
288 	for(i = text.begin(); i != text.end(); ++i) {
289 	    c = (unsigned char) *i;
290 	    c &= 0377;
291 	    if(c & 0200) c = table[c & 0177];
292 	    r += c;
293 	}
294     }
295 #endif
296 
297     return r;
298 }
299 
getmd5(const string & text)300 string abstracthook::getmd5(const string &text) {
301     md5_state_t state;
302     md5_byte_t digest[16];
303     string r;
304     char buf[3];
305 
306     md5_init(&state);
307     md5_append(&state, (md5_byte_t *) text.c_str(), text.size());
308     md5_finish(&state, digest);
309 
310     for(int i = 0; i < 16; i++) {
311         sprintf(buf, "%02x", digest[i]);
312         r += buf;
313     }
314 
315     return r;
316 }
317 
requestfromfound(const imcontact & ic)318 void abstracthook::requestfromfound(const imcontact &ic) {
319     vector<icqcontact *>::const_iterator ig = foundguys.begin();
320 
321     while(ig != foundguys.end()) {
322 	if((*ig)->getdesc() == ic) {
323 	    icqcontact *rc = clist.get(ic);
324 	    if(!rc) rc = clist.get(contactroot);
325 
326 	    rc->setnick((*ig)->getnick());
327 	    rc->setbasicinfo((*ig)->getbasicinfo());
328 	    rc->setmoreinfo((*ig)->getmoreinfo());
329 	    rc->setworkinfo((*ig)->getworkinfo());
330 	    rc->setinterests((*ig)->getinterests());
331 	    rc->setbackground((*ig)->getbackground());
332 	    rc->setabout((*ig)->getabout());
333 
334 	    break;
335 	}
336 
337 	++ig;
338     }
339 }
340 
regconnect(const string & aserv)341 bool abstracthook::regconnect(const string &aserv) {
342     return false;
343 }
344 
regattempt(unsigned int & auin,const string & apassword,const string & email)345 bool abstracthook::regattempt(unsigned int &auin, const string &apassword, const string &email) {
346     return false;
347 }
348 
log(logevent ev,...)349 void abstracthook::log(logevent ev, ...) {
350     va_list ap;
351     char buf[NOTIFBUF];
352     static map<logevent, string> lst;
353 
354     if(lst.empty()) {
355 	lst[logConnecting] = _("connecting to the server");
356 	lst[logLogged] = _("logged in");
357 	lst[logSearchFinished] = _("search finished, %d found");
358 	lst[logPasswordChanged] = _("password was changed successfully");
359 	lst[logDisconnected] = _("disconnected");
360 	lst[logContactAdd] = _("adding %s to the contacts");
361 	lst[logContactRemove] = _("removing %s from the contacts");
362 	lst[logConfMembers] = _("members list fetching finished, %d found");
363     }
364 
365     va_start(ap, ev);
366     vsnprintf(buf, NOTIFBUF, lst[ev].c_str(), ap);
367     va_end(ap);
368 
369     face.log((string) "+ [" + conf->getprotocolname(proto)  + "] " + buf);
370     face.xtermtitle((string) "[" + conf->getprotocolname(proto)  + "] " + buf);
371 }
372 
373 const unsigned short abstracthook::Country_table_size = 243;
374 
375 const abstracthook::Country_struct abstracthook::Country_table[Country_table_size] = {
376     { "Unspecified", 0 },
377     { "Afghanistan", 93 },
378     { "Albania", 355 },
379     { "Algeria", 213 },
380     { "American Samoa", 684 },
381     { "Andorra", 376 },
382     { "Angola", 244 },
383     { "Anguilla", 101 },
384     { "Antigua", 102 },
385     { "Argentina", 54 },
386     { "Armenia", 374 },
387     { "Aruba", 297 },
388     { "Ascension Island", 247 },
389     { "Australia", 61 },
390     { "Australian Antarctic Territory", 6721 },
391     { "Austria", 43 },
392     { "Azerbaijan", 994 },
393     { "Bahamas", 103 },
394     { "Bahrain", 973 },
395     { "Bangladesh", 880 },
396     { "Barbados", 104 },
397     { "Barbuda", 120 },
398     { "Belarus", 375 },
399     { "Belgium", 32 },
400     { "Belize", 501 },
401     { "Benin", 229 },
402     { "Bermuda", 105 },
403     { "Bhutan", 975 },
404     { "Bolivia", 591 },
405     { "Bosnia and Herzegovina", 387 },
406     { "Botswana", 267 },
407     { "Brazil", 55 },
408     { "British Virgin Islands", 106 },
409     { "Brunei", 673 },
410     { "Bulgaria", 359 },
411     { "Burkina Faso", 226 },
412     { "Burundi", 257 },
413     { "Cambodia", 855 },
414     { "Cameroon", 237 },
415     { "Canada", 107 },
416     { "Cape Verde Islands", 238 },
417     { "Cayman Islands", 108 },
418     { "Central African Republic", 236 },
419     { "Chad", 235 },
420     { "Chile", 56 },
421     { "China", 86 },
422     { "Christmas Island", 672 },
423     { "Cocos-Keeling Islands", 6101 },
424     { "Colombia", 57 },
425     { "Comoros", 2691 },
426     { "Congo", 242 },
427     { "Cook Islands", 682 },
428     { "Costa Rica", 506 },
429     { "Croatia", 385 },
430     { "Cuba", 53 },
431     { "Cyprus", 357 },
432     { "Czech Republic", 42 },
433     { "Denmark", 45 },
434     { "Diego Garcia", 246 },
435     { "Djibouti", 253 },
436     { "Dominica", 109 },
437     { "Dominican Republic", 110 },
438     { "Ecuador", 593 },
439     { "Egypt", 20 },
440     { "El Salvador", 503 },
441     { "Equatorial Guinea", 240 },
442     { "Eritrea", 291 },
443     { "Estonia", 372 },
444     { "Ethiopia", 251 },
445     { "Faeroe Islands", 298 },
446     { "Falkland Islands", 500 },
447     { "Fiji Islands", 679 },
448     { "Finland", 358 },
449     { "France", 33 },
450     { "French Antilles", 5901 },
451     { "French Guiana", 594 },
452     { "French Polynesia", 689 },
453     { "Gabon", 241 },
454     { "Gambia", 220 },
455     { "Georgia", 995 },
456     { "Germany", 49 },
457     { "Ghana", 233 },
458     { "Gibraltar", 350 },
459     { "Greece", 30 },
460     { "Greenland", 299 },
461     { "Grenada", 111 },
462     { "Guadeloupe", 590 },
463     { "Guam", 671 },
464     { "Guantanamo Bay", 5399 },
465     { "Guatemala", 502 },
466     { "Guinea", 224 },
467     { "Guinea-Bissau", 245 },
468     { "Guyana", 592 },
469     { "Haiti", 509 },
470     { "Honduras", 504 },
471     { "Hong Kong", 852 },
472     { "Hungary", 36 },
473     { "INMARSAT (Atlantic-East)", 871 },
474     { "INMARSAT (Atlantic-West)", 874 },
475     { "INMARSAT (Indian)", 873 },
476     { "INMARSAT (Pacific)", 872 },
477     { "INMARSAT", 870 },
478     { "Iceland", 354 },
479     { "India", 91 },
480     { "Indonesia", 62 },
481     { "International Freephone Service", 800 },
482     { "Iran", 98 },
483     { "Iraq", 964 },
484     { "Ireland", 353 },
485     { "Israel", 972 },
486     { "Italy", 39 },
487     { "Ivory Coast", 225 },
488     { "Jamaica", 112 },
489     { "Japan", 81 },
490     { "Jordan", 962 },
491     { "Kazakhstan", 705 },
492     { "Kenya", 254 },
493     { "Kiribati Republic", 686 },
494     { "Korea (North)", 850 },
495     { "Korea (Republic of)", 82 },
496     { "Kuwait", 965 },
497     { "Kyrgyz Republic", 706 },
498     { "Laos", 856 },
499     { "Latvia", 371 },
500     { "Lebanon", 961 },
501     { "Lesotho", 266 },
502     { "Liberia", 231 },
503     { "Libya", 218 },
504     { "Liechtenstein", 4101 },
505     { "Lithuania", 370 },
506     { "Luxembourg", 352 },
507     { "Macau", 853 },
508     { "Madagascar", 261 },
509     { "Malawi", 265 },
510     { "Malaysia", 60 },
511     { "Maldives", 960 },
512     { "Mali", 223 },
513     { "Malta", 356 },
514     { "Marshall Islands", 692 },
515     { "Martinique", 596 },
516     { "Mauritania", 222 },
517     { "Mauritius", 230 },
518     { "Mayotte Island", 269 },
519     { "Mexico", 52 },
520     { "Micronesia, Federated States of", 691 },
521     { "Moldova", 373 },
522     { "Monaco", 377 },
523     { "Mongolia", 976 },
524     { "Montserrat", 113 },
525     { "Morocco", 212 },
526     { "Mozambique", 258 },
527     { "Myanmar", 95 },
528     { "Namibia", 264 },
529     { "Nauru", 674 },
530     { "Nepal", 977 },
531     { "Netherlands Antilles", 599 },
532     { "Netherlands", 31 },
533     { "Nevis", 114 },
534     { "New Caledonia", 687 },
535     { "New Zealand", 64 },
536     { "Nicaragua", 505 },
537     { "Niger", 227 },
538     { "Nigeria", 234 },
539     { "Niue", 683 },
540     { "Norfolk Island", 6722 },
541     { "Norway", 47 },
542     { "Oman", 968 },
543     { "Pakistan", 92 },
544     { "Palau", 680 },
545     { "Panama", 507 },
546     { "Papua New Guinea", 675 },
547     { "Paraguay", 595 },
548     { "Peru", 51 },
549     { "Philippines", 63 },
550     { "Poland", 48 },
551     { "Portugal", 351 },
552     { "Puerto Rico", 121 },
553     { "Qatar", 974 },
554     { "Republic of Macedonia", 389 },
555     { "Reunion Island", 262 },
556     { "Romania", 40 },
557     { "Rota Island", 6701 },
558     { "Russia", 7 },
559     { "Rwanda", 250 },
560     { "Saint Lucia", 122 },
561     { "Saipan Island", 670 },
562     { "San Marino", 378 },
563     { "Sao Tome and Principe", 239 },
564     { "Saudi Arabia", 966 },
565     { "Senegal Republic", 221 },
566     { "Seychelle Islands", 248 },
567     { "Sierra Leone", 232 },
568     { "Singapore", 65 },
569     { "Slovak Republic", 4201 },
570     { "Slovenia", 386 },
571     { "Solomon Islands", 677 },
572     { "Somalia", 252 },
573     { "South Africa", 27 },
574     { "Spain", 34 },
575     { "Sri Lanka", 94 },
576     { "St. Helena", 290 },
577     { "St. Kitts", 115 },
578     { "St. Pierre and Miquelon", 508 },
579     { "St. Vincent and the Grenadines", 116 },
580     { "Sudan", 249 },
581     { "Suriname", 597 },
582     { "Swaziland", 268 },
583     { "Sweden", 46 },
584     { "Switzerland", 41 },
585     { "Syria", 963 },
586     { "Taiwan, Republic of China", 886 },
587     { "Tajikistan", 708 },
588     { "Tanzania", 255 },
589     { "Thailand", 66 },
590     { "Tinian Island", 6702 },
591     { "Togo", 228 },
592     { "Tokelau", 690 },
593     { "Tonga", 676 },
594     { "Trinidad and Tobago", 117 },
595     { "Tunisia", 216 },
596     { "Turkey", 90 },
597     { "Turkmenistan", 709 },
598     { "Turks and Caicos Islands", 118 },
599     { "Tuvalu", 688 },
600     { "USA", 1 },
601     { "Uganda", 256 },
602     { "Ukraine", 380 },
603     { "United Arab Emirates", 971 },
604     { "United Kingdom", 44 },
605     { "United States Virgin Islands", 123 },
606     { "Uruguay", 598 },
607     { "Uzbekistan", 711 },
608     { "Vanuatu", 678 },
609     { "Vatican City", 379 },
610     { "Venezuela", 58 },
611     { "Vietnam", 84 },
612     { "Wallis and Futuna Islands", 681 },
613     { "Western Samoa", 685 },
614     { "Yemen", 967 },
615     { "Yugoslavia", 381 },
616     { "Zaire", 243 },
617     { "Zambia", 260 },
618     { "Zimbabwe", 263 }
619 
620 };
621 
getCountryIDtoString(unsigned short id)622 string abstracthook::getCountryIDtoString(unsigned short id) {
623     for(int n = 0; n < Country_table_size; ++n) {
624 	if(Country_table[n].code == id) {
625 	    return Country_table[n].name;
626 	}
627     }
628 
629     return Country_table[0].name;
630 }
631 
getCountryByName(string name)632 unsigned short abstracthook::getCountryByName(string name) {
633     int i;
634     name = up(leadcut(trailcut(name)));
635 
636     for(i = 0; i < Country_table_size; i++)
637 	if(name == up(Country_table[i].name))
638 	    return Country_table[i].code;
639 
640     return 0;
641 }
642 
getSystemTimezone()643 signed char abstracthook::getSystemTimezone() {
644     time_t t = time(0);
645     struct tm *tzone = localtime(&t);
646     int nTimezone = 0;
647 
648 #ifdef HAVE_TM_ZONE
649     nTimezone = -(tzone->tm_gmtoff);
650 #else
651     #ifdef __CYGWIN__
652     nTimezone = _timezone;
653     #else
654     nTimezone = timezone;
655     #endif
656 #endif
657 
658     nTimezone += (tzone->tm_isdst == 1 ? 3600 : 0);
659     nTimezone /= 1800;
660 
661     if(nTimezone > 23) return 23-nTimezone;
662 
663     return (signed char) nTimezone;
664 }
665 
666 static const unsigned char Interests_table_size = 51;
667 static const unsigned char Interests_offset = 100;
668 
669 static const char* const Interests_table[Interests_table_size] = {
670     "Art",
671     "Cars",
672     "Celebrity Fans",
673     "Collections",
674     "Computers",
675     "Culture",
676     "Fitness",
677     "Games",
678     "Hobbies",
679     "ICQ - Help",
680     "Internet",
681     "Lifestyle",
682     "Movies and TV",
683     "Music",
684     "Outdoors",
685     "Parenting",
686     "Pets and Animals",
687     "Religion",
688     "Science",
689     "Skills",
690     "Sports",
691     "Web Design",
692     "Ecology",
693     "News and Media",
694     "Government",
695     "Business",
696     "Mystics",
697     "Travel",
698     "Astronomy",
699     "Space",
700     "Clothing",
701     "Parties",
702     "Women",
703     "Social science",
704     "60's",
705     "70's",
706     "80's",
707     "50's",
708     "Finance and Corporate",
709     "Entertainment",
710     "Consumer Electronics",
711     "Retail Stores",
712     "Health and Beauty",
713     "Media",
714     "Household Products",
715     "Mail Order Catalog",
716     "Business Services",
717     "Audio and Visual",
718     "Sporting and Athletics",
719     "Publishing",
720     "Home Automation"
721 };
722 
getInterestsIDtoString(unsigned char id)723 string abstracthook::getInterestsIDtoString(unsigned char id) {
724     if(id-Interests_offset >= 0 && id-Interests_offset < Interests_table_size) {
725 	return Interests_table[id-Interests_offset];
726     }
727 
728     return "";
729 }
730 
731 static const unsigned short Background_table_size = 8;
732 
733 static const struct {
734     char *name;
735     unsigned short code;
736 
737 } Background_table[Background_table_size] = {
738     { "University", 303 },
739     { "High school", 301 },
740     { "College", 302 },
741     { "Elementary School", 300 },
742     { "Millitary", 304 },
743     { "Other", 399 },
744     { "Past Organization", 306 },
745     { "Past Work Place", 305 }
746 
747 };
748 
getBackgroundIDtoString(unsigned short id)749 string abstracthook::getBackgroundIDtoString(unsigned short id) {
750     for(int n = 0; n < Background_table_size; ++n) {
751 	if(id == Background_table[n].code) {
752 	    return Background_table[n].name;
753 	}
754     }
755 
756     return "";
757 }
758 
getTimezoneIDtoString(signed char id)759 string abstracthook::getTimezoneIDtoString(signed char id) {
760     if(id > 24 || id < -24) {
761 	return "Unspecified";
762     } else {
763 	char buf[32];
764 	snprintf(buf, sizeof(buf), "GMT %s%d:%s", id > 0 ? "-" : "+", abs(id/2), id % 2 == 0 ? "00" : "30");
765 	return buf;
766     }
767 }
768 
getTimezonetoLocaltime(signed char id)769 string abstracthook::getTimezonetoLocaltime(signed char id) {
770     string r;
771 
772     if(id <= 24 && id >= -24) {
773 	time_t rt = time(0) + getSystemTimezone()*1800;
774 	rt -= id*1800;
775 	r = ctime(&rt);
776     }
777 
778     return r;
779 }
780 
781 const unsigned char abstracthook::Language_table_size = 60;
782 
783 const char* const abstracthook::Language_table[Language_table_size] = {
784     "Unspecified",
785     "Arabic",
786     "Bhojpuri",
787     "Bulgarian",
788     "Burmese",
789     "Cantonese",
790     "Catalan",
791     "Chinese",
792     "Croatian",
793     "Czech",
794     "Danish",
795     "Dutch",
796     "English",
797     "Esperanto",
798     "Estonian",
799     "Farsi",
800     "Finnish",
801     "French",
802     "Gaelic",
803     "German",
804     "Greek",
805     "Hebrew",
806     "Hindi",
807     "Hungarian",
808     "Icelandic",
809     "Indonesian",
810     "Italian",
811     "Japanese",
812     "Khmer",
813     "Korean",
814     "Lao",
815     "Latvian",
816     "Lithuanian",
817     "Malay",
818     "Norwegian",
819     "Polish",
820     "Portuguese",
821     "Romanian",
822     "Russian",
823     "Serbian",
824     "Slovak",
825     "Slovenian",
826     "Somali",
827     "Spanish",
828     "Swahili",
829     "Swedish",
830     "Tagalog",
831     "Tatar",
832     "Thai",
833     "Turkish",
834     "Ukrainian",
835     "Urdu",
836     "Vietnamese",
837     "Yiddish",
838     "Yoruba",
839     "Taiwanese",
840     "Afrikaans",
841     "Persian",
842     "Albanian",
843     "Armenian",
844 };
845 
getLanguageIDtoString(unsigned char id)846 string abstracthook::getLanguageIDtoString(unsigned char id) {
847     if (id >= Language_table_size) {
848 	return Language_table[0];
849     } else {
850 	return Language_table[id];
851     }
852 }
853 
854 // ----------------------------------------------------------------------------
855 
gethook(protocolname pname)856 abstracthook &gethook(protocolname pname) {
857     static abstracthook abshook(infocard);
858 
859     switch(pname) {
860 #ifdef BUILD_ICQ
861 	case icq: return ihook;
862 #endif
863 #ifdef BUILD_YAHOO
864 	case yahoo: return yhook;
865 #endif
866 #ifdef BUILD_AIM
867 	case aim: return ahook;
868 #endif
869 #ifdef BUILD_IRC
870 	case irc: return irhook;
871 #endif
872 #ifdef BUILD_JABBER
873 	case jabber: return jhook;
874 #endif
875 #ifdef BUILD_RSS
876 	case rss: return rhook;
877 #endif
878 #ifdef BUILD_LJ
879 	case livejournal: return lhook;
880 #endif
881 #ifdef BUILD_GADU
882 	case gadu: return ghook;
883 #endif
884 #ifdef BUILD_MSN
885 	case msn: return mhook;
886 #endif
887     }
888 
889     return abshook;
890 }
891 
maketm(int hour,int minute,int day,int month,int year)892 struct tm *maketm(int hour, int minute, int day, int month, int year) {
893     static struct tm msgtm;
894     memset(&msgtm, 0, sizeof(msgtm));
895     msgtm.tm_min = minute;
896     msgtm.tm_hour = hour;
897     msgtm.tm_mday = day;
898     msgtm.tm_mon = month-1;
899     msgtm.tm_year = year-1900;
900     return &msgtm;
901 }
902