connwrap - initialize gnutls session in cw_connect
[centerim.git] / src / hooks / abstracthook.cc
blob5f4c049c23bde3d23bb54cbad78ebdd49466a921
1 /*
3 * centerim IM protocol abstraction class
4 * $Id: abstracthook.cc,v 1.58 2004/11/09 23:49:59 konst Exp $
6 * Copyright (C) 2001,2002,2003 by Konstantin Klyagin <k@thekonst.net>
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.
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.
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
25 #include "abstracthook.h"
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"
38 #include "icqface.h"
40 #include "md5.h"
42 #include <time.h>
44 #define NOTIFBUF 512
46 time_t timer_current = time(0);
48 abstracthook::abstracthook(protocolname aproto)
49 : proto(aproto), searchdest(0)
50 { }
52 abstracthook::~abstracthook() {
55 void abstracthook::init() {
58 void abstracthook::connect() {
61 void abstracthook::disconnect() {
64 void abstracthook::exectimers() {
67 void abstracthook::main() {
70 void abstracthook::setautostatus(imstatus st) {
73 void abstracthook::restorestatus() {
74 setautostatus(manualstatus);
77 void abstracthook::setstatus(imstatus st) {
78 setautostatus(manualstatus = st);
80 for(protocolname pname = icq; pname != protocolname_size; pname++) {
81 if(&gethook(pname) == this) {
82 conf->savestatus(pname, manualstatus);
83 break;
88 void abstracthook::getsockets(fd_set &rfds, fd_set &wfds, fd_set &efds, int &hsocket) const {
91 bool abstracthook::isoursocket(fd_set &rfds, fd_set &wfds, fd_set &efds) const {
92 return false;
95 bool abstracthook::online() const {
96 return false;
99 bool abstracthook::logged() const {
100 return false;
103 bool abstracthook::isconnecting() const {
104 return false;
107 bool abstracthook::enabled() const {
108 return false;
111 bool abstracthook::send(const imevent &ev) {
112 return false;
115 void abstracthook::sendnewuser(const imcontact &c) {
118 imstatus abstracthook::getstatus() const {
119 return offline;
122 bool abstracthook::isdirectopen(const imcontact &c) const {
123 return false;
126 void abstracthook::removeuser(const imcontact &ic) {
129 void abstracthook::requestinfo(const imcontact &c) {
132 void abstracthook::lookup(const imsearchparams &params, verticalmenu &dest) {
135 void abstracthook::stoplookup() {
136 searchdest = 0;
139 void abstracthook::requestawaymsg(const imcontact &c) {
142 void abstracthook::ouridchanged(const icqconf::imaccount &ia) {
145 void abstracthook::requestversion(const imcontact &c) {
148 void abstracthook::ping(const imcontact &c) {
151 bool abstracthook::knowntransfer(const imfile &fr) const {
152 return false;
155 void abstracthook::replytransfer(const imfile &fr, bool accept, const string &localpath) {
158 void abstracthook::aborttransfer(const imfile &fr) {
161 void abstracthook::conferencecreate(const imcontact &confid,
162 const vector<imcontact> &lst) {
165 vector<string> abstracthook::getservices(servicetype::enumeration st) const {
166 return vector<string>();
169 vector<pair< string, string> > abstracthook::getsearchparameters(const string &agentname) const {
170 return vector<pair<string, string> >();
173 vector<pair<string, string> > abstracthook::getregparameters(const string &agentname) const {
174 return vector<pair<string, string> >();
177 void abstracthook::updatecontact(icqcontact *c) {
180 void abstracthook::renamegroup(const string &oldname, const string &newname) {
183 string abstracthook::rushtmlconv(const string &tdir, const string &text, bool rus) {
184 int pos;
185 string r = rus ? rusconv(tdir, text) : text;
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;
199 pos++;
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++;
226 return r;
229 string abstracthook::ruscrlfconv(const string &tdir, const string &text) {
230 string r = rusconv(tdir, text);
231 int pos;
233 for(pos = 0; (pos = r.find("\r")) != -1; pos++) {
234 r.erase(pos, 1);
237 return r;
240 string abstracthook::rusconv(const string &tdir, const string &text) {
241 string r;
243 if(!conf->getcpconvert(proto) && tdir.find("u") == -1)
244 return text;
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;
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
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
278 unsigned char c;
279 string::const_iterator i;
280 unsigned char *table = 0;
282 if(tdir == "kw") table = kw; else
283 if(tdir == "wk") table = wk;
285 if(table) {
286 r = "";
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;
295 #endif
297 return r;
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];
306 md5_init(&state);
307 md5_append(&state, (md5_byte_t *) text.c_str(), text.size());
308 md5_finish(&state, digest);
310 for(int i = 0; i < 16; i++) {
311 sprintf(buf, "%02x", digest[i]);
312 r += buf;
315 return r;
318 void abstracthook::requestfromfound(const imcontact &ic) {
319 vector<icqcontact *>::const_iterator ig = foundguys.begin();
321 while(ig != foundguys.end()) {
322 if((*ig)->getdesc() == ic) {
323 icqcontact *rc = clist.get(ic);
324 if(!rc) rc = clist.get(contactroot);
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());
334 break;
337 ++ig;
341 bool abstracthook::regconnect(const string &aserv) {
342 return false;
345 bool abstracthook::regattempt(unsigned int &auin, const string &apassword, const string &email) {
346 return false;
349 void abstracthook::log(logevent ev, ...) {
350 va_list ap;
351 char buf[NOTIFBUF];
352 static map<logevent, string> lst;
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");
365 va_start(ap, ev);
366 vsnprintf(buf, NOTIFBUF, lst[ev].c_str(), ap);
367 va_end(ap);
369 face.log((string) "+ [" + conf->getprotocolname(proto) + "] " + buf);
370 face.xtermtitle((string) "[" + conf->getprotocolname(proto) + "] " + buf);
373 const unsigned short abstracthook::Country_table_size = 243;
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 }
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;
629 return Country_table[0].name;
632 unsigned short abstracthook::getCountryByName(string name) {
633 int i;
634 name = up(leadcut(trailcut(name)));
636 for(i = 0; i < Country_table_size; i++)
637 if(name == up(Country_table[i].name))
638 return Country_table[i].code;
640 return 0;
643 signed char abstracthook::getSystemTimezone() {
644 time_t t = time(0);
645 struct tm *tzone = localtime(&t);
646 int nTimezone = 0;
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
658 nTimezone += (tzone->tm_isdst == 1 ? 3600 : 0);
659 nTimezone /= 1800;
661 if(nTimezone > 23) return 23-nTimezone;
663 return (signed char) nTimezone;
666 static const unsigned char Interests_table_size = 51;
667 static const unsigned char Interests_offset = 100;
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"
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];
728 return "";
731 static const unsigned short Background_table_size = 8;
733 static const struct {
734 char *name;
735 unsigned short code;
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 }
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;
756 return "";
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;
769 string abstracthook::getTimezonetoLocaltime(signed char id) {
770 string r;
772 if(id <= 24 && id >= -24) {
773 time_t rt = time(0) + getSystemTimezone()*1800;
774 rt -= id*1800;
775 r = ctime(&rt);
778 return r;
781 const unsigned char abstracthook::Language_table_size = 60;
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",
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];
854 // ----------------------------------------------------------------------------
856 abstracthook &gethook(protocolname pname) {
857 static abstracthook abshook(infocard);
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
889 return abshook;
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;