connwrap - initialize gnutls session in cw_connect
[centerim.git] / src / icqconf.cc
blobaa6650c3cd4420aae82d8f51ceed0458c1c56cf3
1 /*
3 * centerim configuration handling routines
4 * $Id: icqconf.cc,v 1.143 2005/09/02 15:20:59 konst Exp $
6 * Copyright (C) 2001-2004 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 <sys/types.h>
26 #include <sys/wait.h>
27 #include <dirent.h>
28 #include <fstream>
31 #if defined(__sun__) || defined(__NetBSD__) || defined(__sgi__)
32 #include <sys/statvfs.h>
33 #endif
35 #include "centerim.h"
36 #include "icqconf.h"
37 #include "icqface.h"
38 #include "icqcontacts.h"
39 #include "abstracthook.h"
40 #include "imexternal.h"
41 #include "eventmanager.h"
42 #include "imlogger.h"
43 #include "connwrap.h"
45 icqconf* icqconf::self=NULL;
47 icqconf* icqconf::instance()
49 if(!self){
50 self=new icqconf();
53 return self;
56 icqconf::icqconf() {
57 DEFAULT_TIMESTAMP_FORMAT = "DD.MM.YY hh:mm";
58 DEFAULT_LOGTIMESTAMP_FORMAT = "%R ";
59 SECONDS_TIMESTAMP_FORMAT = "DD.MM.YY hh:mm:ss";
60 SECONDS_LOGTIMESTAMP_FORMAT = "%T ";
62 rs = rscard;
63 rc = rcdark;
64 cm = cmproto;
65 fgroupmode = nogroups;
66 fsortmode = sort_by_status_and_activity;
68 autoaway = autona = 0;
70 hideoffline = antispam = makelog = askaway = logtimestamps =
71 logonline = emacs = proxyssl = proxyconnect = notitles =
72 debug = timestampstothesecond = vi = autoawayx = false;
74 timestampformat = DEFAULT_TIMESTAMP_FORMAT;
75 logtimestampformat = DEFAULT_LOGTIMESTAMP_FORMAT;
77 startoffline = false;
79 savepwd = mailcheck = fenoughdiskspace = true;
81 for(protocolname pname = icq; pname != protocolname_size; pname++) {
82 chatmode[pname] = true;
83 cpconvert[pname] = entersends[pname] = nonimonline[pname] = false;
86 // quick and dirty fix to support .centerim as well as .centericq
87 char *home = getenv("HOME");
88 if( home != NULL ) {
89 basedir = string(home) + "/.centerim/";
90 if ( access(basedir.c_str(), F_OK) != 0 ) {
91 basedir = string(home) + "/.centericq/";
92 if ( access(basedir.c_str(), F_OK) != 0 ) {
93 basedir = string(home) + "/.centerim/";
97 screensocketpath = "/var/run/screen";
99 defaultAuthMessage = "Please accept my authorization to add you to my contact list.";
102 icqconf::~icqconf() {
103 if(self)
104 delete self;
107 icqconf::imaccount icqconf::getourid(protocolname pname) const {
108 imaccount im;
109 vector<imaccount>::const_iterator i;
111 i = find(accounts.begin(), accounts.end(), pname);
112 im = i == accounts.end() ? imaccount(pname) : *i;
114 return im;
117 icqconf::imserver icqconf::defservers[protocolname_size] = {
118 { "login.icq.com", 5190, 0 },
119 { "scs.msg.yahoo.com", 5050, 0 },
120 { "messenger.hotmail.com", 1863, 0 },
121 { "toc.oscar.aol.com", 9898, 0 },
122 { "irc.oftc.net", 6667, 0 },
123 { "jabber.org", 5222, 5223 },
124 { "", 0, 0 },
125 { "livejournal.com", 80, 0 },
126 { "appmsg.gadu-gadu.pl", 80 }
129 void icqconf::setourid(const imaccount &im) {
130 vector<imaccount>::iterator i;
132 i = find(accounts.begin(), accounts.end(), im.pname);
134 if(i != accounts.end()) {
135 if(im.empty()) {
136 accounts.erase(i);
137 i = accounts.end();
138 } else {
139 *i = im;
141 } else if(!im.empty()) {
142 accounts.push_back(im);
143 i = accounts.end()-1;
146 if(i != accounts.end()) {
147 if(i->server.empty()) {
148 i->server = defservers[i->pname].server;
149 i->port = defservers[i->pname].port;
152 if(!i->port)
153 i->port = defservers[i->pname].port;
155 switch(i->pname) {
156 case jabber:
157 if(i->additional.find("prio") == i->additional.end())
158 i->additional["prio"] = "4";
159 #ifdef HAVE_UNAME
160 if(i->additional.find("osinfo") == i->additional.end())
161 i->additional["osinfo"] = "1";
162 #endif
163 break;
165 case yahoo:
166 if (i->additional.find("ssl") == i->additional.end())
167 i->additional["ssl"] = "1";
168 break;
170 case livejournal:
171 if(i->additional.find("importfriends") == i->additional.end())
172 i->additional["importfriends"] = "1";
173 break;
175 case icq:
176 if(i->password.size() > 8)
177 i->password = i->password.substr(0, 8);
178 break;
183 string icqconf::getawaymsg(protocolname pname) const {
184 string r, buf, fname;
185 ifstream f;
187 if(!gethook(pname).getCapabs().count(hookcapab::setaway))
188 return "";
190 fname = conf->getconfigfname("awaymsg-" + getprotocolname(pname));
191 f.open(fname.c_str());
193 if(f.is_open()) {
194 while(!f.eof()) {
195 getstring(f, buf);
196 if(!r.empty()) r += "\n";
197 r += buf;
200 f.close();
203 if(r.empty()) {
204 char buf[512];
206 snprintf(buf, sizeof(buf), _("I do really enjoy the default %s away message of %s %s."),
207 getprotocolname(pname).c_str(), PACKAGE, centerim::version);
209 return buf;
212 return r;
215 void icqconf::setawaymsg(protocolname pname, const string &amsg) {
216 string fname;
217 ofstream f;
219 if(!gethook(pname).getCapabs().count(hookcapab::setaway))
220 return;
222 fname = conf->getconfigfname("awaymsg-" + getprotocolname(pname));
223 f.open(fname.c_str());
225 if(f.is_open()) {
226 f << amsg;
227 f.close();
231 string icqconf::getextstatus(protocolname pname, imstatus status) const {
232 string r, buf, fname;
233 ifstream f;
235 if(!gethook(pname).getCapabs().count(hookcapab::setextstatus))
236 return "";
238 fname = conf->getconfigfname("extmsg-" + getprotocolname(pname) + "-" + imstatus2char[status]);
239 f.open(fname.c_str());
241 if(f.is_open()) {
242 while(!f.eof()) {
243 getstring(f, buf);
244 if(!r.empty()) r += "\n";
245 r += buf;
248 f.close();
251 if(r.empty()) {
252 return "";
255 return r;
258 void icqconf::setextstatus(protocolname pname, const string &amsg, imstatus status) {
259 string fname;
260 ofstream f;
262 if(!gethook(pname).getCapabs().count(hookcapab::setextstatus))
263 return;
265 fname = conf->getconfigfname("extmsg-" + getprotocolname(pname) + "-" + imstatus2char[status]);
266 f.open(fname.c_str());
268 if(f.is_open()) {
269 f << amsg;
270 f.close();
274 void icqconf::checkdir() {
275 string dname = getdirname();
276 dname.erase(dname.size()-1);
277 const char * dirstr = dname.c_str();
278 // The proper rights for the ~/.centerim-directory
279 const mode_t proper_rights = S_IRUSR | S_IWUSR | S_IXUSR;
281 if(access(dirstr, F_OK) == 0) {
282 // Directory allready exists check the permissions of the directory.
283 struct stat dir_stat;
284 if ( stat(dirstr, &dir_stat) == 0 &&
285 (dir_stat.st_mode & ~proper_rights) != 0 ) {
286 DIR *pDir = NULL;
287 // group / other have some kind of permissions for this directory
288 // as mr Picard would have said: compensate!
289 chmod (dirstr, proper_rights);
292 else{
293 // create the ~/.centerim directory since
294 // ~/.centerim / ~/.centericq does not exist.
295 mkdir(dname.c_str(), proper_rights);
299 void icqconf::load() {
300 loadmainconfig();
301 loadkeys();
302 loadcolors();
303 loadactions();
304 loadcaptcha();
305 external.load();
308 vector<icqconf::keybinding> icqconf::keys;
310 void icqconf::loadkeys() {
311 //int x; not used.
312 string fname = getconfigfname("keybindings"), buf, param;
313 struct keybinding k;
314 ifstream f;
316 keys.clear();
318 if(access(fname.c_str(), F_OK)) {
319 ofstream of(fname.c_str());
321 if(of.is_open()) {
322 of << "# This file contains keybinding configuration for centerim" << endl;
323 of << "# Every line should look like: bind <section> <key> <command>" << endl << endl;
324 of << "bind contact\t?\tinfo" << endl;
325 of << "bind contact\tq\tquit" << endl;
326 of << "bind contact\t<F3>\tchange_status" << endl;
327 of << "bind contact\ts\tchange_status" << endl;
328 of << "bind contact\th\thistory" << endl;
329 of << "bind contact\tf\tfetch_away_message" << endl;
330 of << "bind contact\t<F2>\tuser_menu" << endl;
331 of << "bind contact\tm\tuser_menu" << endl;
332 of << "bind contact\t<F4>\tgeneral_menu" << endl;
333 of << "bind contact\tg\tgeneral_menu" << endl;
334 of << "bind contact\t<F5>\thide_offline" << endl;
335 of << "bind contact\t<F6>\tcontact_external_action" << endl;
336 of << "bind contact\ta\tadd" << endl;
337 of << "bind contact\t<delete> remove" << endl;
338 of << "bind contact\t<enter> compose" << endl;
339 of << "bind contact\tc\tsend_contact" << endl;
340 of << "bind contact\tc\trss_check" << endl;
341 of << "bind contact\tu\tsend_url" << endl;
342 of << "bind contact\tr\trename" << endl;
343 of << "bind contact\tv\tversion" << endl;
344 of << "bind contact\te\tedit" << endl;
345 of << "bind contact\ti\tignore" << endl;
346 of << "bind contact\t\\as\tquickfind" << endl;
347 of << "bind contact\t/\tquickfind" << endl << endl;
348 of << "bind contact\t\\cn\tnext_chat" << endl;
349 of << "bind contact\t\\cb\tprev_chat" << endl;
350 of << "bind contact\t[\tleft_panel_move_left" << endl;
351 of << "bind contact\t]\tleft_panel_move_right" << endl;
352 of << "bind contact\t{\tlog_panel_move_up" << endl;
353 of << "bind contact\t}\tlog_panel_move_down" << endl;
354 of << "bind history\t/\tsearch" << endl;
355 of << "bind history\ts\tsearch" << endl;
356 of << "bind history\tn\tsearch_again" << endl;
357 of << "bind history\t<F2>\tshow_urls" << endl;
358 of << "bind history\t<F9>\tfullscreen" << endl << endl;
359 of << "bind editor\t\\cx\tsend_message" << endl;
360 of << "bind editor\t<esc>\tquit" << endl;
361 of << "bind editor\t\\cp\tmultiple_recipients" << endl;
362 of << "bind editor\t\\co\thistory" << endl;
363 of << "bind editor\t\\cn\tnext_chat" << endl;
364 of << "bind editor\t\\cb\tprev_chat" << endl;
365 of << "bind editor\t\\cv\tout_chat" << endl;
366 of << "bind editor\t\\a?\tinfo" << endl;
367 of << "bind editor\t<F2>\tshow_urls" << endl;
368 of << "bind editor\t<F9>\tfullscreen" << endl << endl;
369 of << "bind editor\t<F4>\tchat_panel_move_up" << endl;
370 of << "bind editor\t<F5>\tchat_panel_move_down" << endl;
371 #ifdef HAVE_LIBOTR
372 of << "bind editor\t<F7>\totr_start_session" << endl;
373 of << "bind editor\t<F8>\totr_end_session" << endl;
374 #endif
375 of << "bind info\t<F2>\tshow_urls" << endl;
376 of << "bind info\t<F6>\tuser_external_action" << endl;
378 of.close();
382 f.open(fname.c_str());
384 if(f.is_open()) {
385 while(!f.eof()) {
386 getstring(f, buf);
388 if(buf.empty() || buf[0] == '#') continue;
390 k.ctrl = false;
391 k.alt = false;
393 param = getword(buf); /* first word is always bind */
395 param = getword(buf); /* read section */
396 if(param == "contact")
397 k.section = section_contact; else
398 if(param == "history")
399 k.section = section_history; else
400 if (param == "editor")
401 k.section = section_editor; else
402 if (param == "info")
403 k.section = section_info;
405 param = getword(buf); /* key */
406 if(param == "\\c<space>" || param == "\\C<space>" || param == "^<space>") {
407 k.ctrl = true;
408 k.key = CTRL(' ');
409 } else if(param == "\\a<enter>" || param == "\\A<enter>" || param == "@<enter>") {
410 k.alt = true;
411 k.key = ALT('\r');
412 } else if(param == "\\a<space>" || param == "\\A<space>" || param == "@<space>") {
413 k.ctrl = true;
414 k.key = ALT(' ');
415 } else if(param[0] == '\\') {
416 if(param[1] == 'c' || param[1] == 'C') {
417 k.ctrl = true;
418 k.key = CTRL(param[2]);
419 } else if(param[1] == 'a' || param[1] == 'A') {
420 k.alt = true;
421 k.key = ALT(param[2]);
422 } else if(param[1] == '\\') {
423 k.key = '\\';
424 } else if(param[1] == '@') {
425 k.key = '@';
426 } else if(param[1] == '^') {
427 k.key = '^';
429 } else if(param[0] == '^') {
430 k.ctrl = true;
431 k.key = CTRL(param[1]);
432 } else if(param[0] == '@') {
433 k.alt = true;
434 k.key = ALT(param[1]);
435 } else if(param == "<delete>")
436 k.key = KEY_DC;
437 else if(param == "<enter>")
438 k.key = '\r';
439 else if(param == "<esc>")
440 k.key = 27;
441 else if(param == "<space>")
442 k.key = ' ';
443 else if(param == "<backspace>")
444 k.key = '\b';
445 else if(param == "<pageup>")
446 k.key = 339;
447 else if(param == "<pagedown>")
448 k.key = 338;
449 else if(param == "<tab>")
450 k.key = 9;
451 else if(param == "<insert>")
452 k.key = 331;
453 else if(param[0] == '<' && param[1] == 'F') {
454 k.alt = true;
455 k.ctrl = true;
456 k.key = KEY_F(param[2]-'0');
457 } else
458 k.key = param[0];
460 param = getword(buf); /* action */
461 if(param == "info") k.action = key_info; else
462 if(param == "remove") k.action = key_remove; else
463 if(param == "quit") k.action = key_quit; else
464 if(param == "change_status") k.action = key_change_status; else
465 if(param == "history") k.action = key_history; else
466 if(param == "next_chat") k.action = key_next_chat; else
467 if(param == "prev_chat") k.action = key_prev_chat; else
468 if(param == "out_chat") k.action = key_out_chat; else
469 if(param == "fetch_away_message") k.action = key_fetch_away_message; else
470 if(param == "user_menu") k.action = key_user_menu; else
471 if(param == "general_menu") k.action = key_general_menu; else
472 if(param == "hide_offline") k.action = key_hide_offline; else
473 if(param == "contact_external_action") k.action = key_contact_external_action; else
474 if(param == "add") k.action = key_add; else
475 if(param == "remove") k.action = key_remove; else
476 if(param == "send_message") k.action = key_send_message; else
477 if(param == "send_contact") k.action = key_send_contact; else
478 if(param == "send_url") k.action = key_send_url; else
479 if(param == "rename") k.action = key_rename; else
480 if(param == "version") k.action = key_version; else
481 if(param == "fullscreen") k.action = key_fullscreen; else
482 if(param == "edit") k.action = key_edit; else
483 if(param == "ignore") k.action = key_ignore; else
484 if(param == "quickfind") k.action = key_quickfind; else
485 if(param == "search") k.action = key_search; else
486 if(param == "compose") k.action = key_compose; else
487 if(param == "search_again") k.action = key_search_again; else
488 if(param == "show_urls") k.action = key_show_urls; else
489 if(param == "rss_check") k.action = key_rss_check; else
490 if(param == "multiple_recipients") k.action = key_multiple_recipients; else
491 if(param == "user_external_action") k.action = key_user_external_action; else
492 if(param == "left_panel_move_left") k.action = key_left_panel_move_left; else
493 if(param == "left_panel_move_right") k.action = key_left_panel_move_right; else
494 if(param == "log_panel_move_up") k.action = key_log_panel_move_up; else
495 if(param == "log_panel_move_down") k.action = key_log_panel_move_down; else
496 if(param == "chat_panel_move_up") k.action = key_chat_panel_move_up; else
497 if(param == "chat_panel_move_down") k.action = key_chat_panel_move_down; else
498 #ifdef HAVE_LIBOTR
499 if(param == "otr_start_session") k.action = key_otr_start_session; else
500 if(param == "otr_end_session") k.action = key_otr_end_session; else
501 #endif
502 continue;
504 keys.push_back(k);
507 f.close();
510 if(face.action2key(key_info, section_contact).empty()) keys.push_back(keybinding()); else
511 if(face.action2key(key_quit, section_contact).empty())
512 if(face.action2key(key_change_status, section_contact).empty())
513 if(face.action2key(key_history, section_contact).empty())
514 if(face.action2key(key_fetch_away_message, section_contact).empty())
515 if(face.action2key(key_user_menu, section_contact).empty())
516 if(face.action2key(key_general_menu, section_contact).empty())
517 if(face.action2key(key_hide_offline, section_contact).empty())
518 if(face.action2key(key_contact_external_action, section_contact).empty())
519 if(face.action2key(key_add, section_contact).empty())
520 if(face.action2key(key_remove, section_contact).empty())
521 if(face.action2key(key_compose, section_contact).empty())
522 if(face.action2key(key_send_contact, section_contact).empty())
523 if(face.action2key(key_rss_check, section_contact).empty())
524 if(face.action2key(key_send_url, section_contact).empty())
525 if(face.action2key(key_rename, section_contact).empty())
526 if(face.action2key(key_version, section_contact).empty())
527 if(face.action2key(key_edit, section_contact).empty())
528 if(face.action2key(key_ignore, section_contact).empty())
529 if(face.action2key(key_quickfind, section_contact).empty())
530 if(face.action2key(key_next_chat, section_contact).empty())
531 if(face.action2key(key_prev_chat, section_contact).empty())
532 if(face.action2key(key_search, section_history).empty())
533 if(face.action2key(key_search_again, section_history).empty())
534 if(face.action2key(key_show_urls, section_history).empty())
535 if(face.action2key(key_fullscreen, section_history).empty())
536 if(face.action2key(key_send_message, section_editor).empty())
537 if(face.action2key(key_quit, section_editor).empty())
538 if(face.action2key(key_multiple_recipients, section_editor).empty())
539 if(face.action2key(key_history, section_editor).empty())
540 if(face.action2key(key_next_chat, section_editor).empty())
541 if(face.action2key(key_prev_chat, section_editor).empty())
542 if(face.action2key(key_out_chat, section_editor).empty())
543 if(face.action2key(key_info, section_editor).empty())
544 if(face.action2key(key_show_urls, section_editor).empty())
545 if(face.action2key(key_fullscreen, section_editor).empty())
546 if(face.action2key(key_show_urls, section_info).empty())
547 if(face.action2key(key_user_external_action, section_info).empty()) {}
551 void icqconf::loadmainconfig() {
552 string fname = getconfigfname("config"), buf, param, rbuf;
553 ifstream f(fname.c_str());
554 imaccount im;
555 protocolname pname;
557 if(f.is_open()) {
558 mailcheck = askaway = false;
559 savepwd = bidi = true;
560 setsmtphost("");
561 setbrowser("");
562 setpeertopeer(0, 65535);
564 while(!f.eof()) {
565 getstring(f, buf);
566 rbuf = buf;
567 param = getword(buf);
569 if(param == "hideoffline") hideoffline = true; else
570 if(param == "emacs") emacs = true; else
571 if(param == "vi") vi = true; else
572 if(param == "autoaway") autoaway = atol(buf.c_str()); else
573 if(param == "autona") autona = atol(buf.c_str()); else
574 if(param == "auto_away_na_x") autoawayx = true; else
575 if(param == "antispam") antispam = true; else
576 if(param == "showopenedchats") setshowopenedchats(true); else
577 if(param == "dropauthreq") dropauthreq = true; else
578 if(param == "screenna") screenna = true; else
579 if(param == "screensocketpath") screensocketpath = buf; else
580 if(param == "mailcheck") mailcheck = true; else
581 if(param == "quotemsgs") quote = true; else
582 if(param == "sockshost") setsockshost(buf); else
583 if(param == "socksusername") socksuser = buf; else
584 if(param == "sockspass") sockspass = buf; else
585 if((param == "usegroups") || (param == "group1")) fgroupmode = group1; else
586 if(param == "group2") fgroupmode = group2; else
587 if(param == "protocolormode") cm = icqconf::cmproto; else
588 if(param == "statuscolormode") cm = icqconf::cmstatus; else
589 if(param == "sort_by_status_and_activity") setsortmode(icqconf::sort_by_status_and_activity); else
590 if(param == "sort_by_status_and_name") setsortmode(icqconf::sort_by_status_and_name); else
591 if(param == "sort_by_activity") setsortmode(icqconf::sort_by_activity); else
592 if(param == "sort_by_name") setsortmode(icqconf::sort_by_name); else
593 if(param == "smtp") setsmtphost(buf); else
594 if(param == "browser") setbrowser(buf); else
595 if(param == "http_proxy") sethttpproxyhost(buf); else
596 if(param == "log") makelog = true; else
597 if(param == "proxy_connect") proxyconnect = true; else
598 if(param == "proxy_ssl") proxyssl = true; else
599 if(param == "chatmode") initmultiproto(chatmode, buf, true); else
600 if(param == "entersends") initmultiproto(entersends, buf, true); else
601 if(param == "nonimonline") initmultiproto(nonimonline, buf, false); else
602 if(param == "captcha") usingcaptcha = true; else
603 if(param == "russian" || param == "convert") initmultiproto(cpconvert, buf, false); else
604 if(param == "nobidi") setbidi(false); else
605 if(param == "askaway") askaway = true; else
606 if(param == "askquit") askquit = true; else
607 if(param == "logtimestamps") logtimestamps = true; else
608 if(param == "logonline") logonline = true; else
609 if(param == "fromcharset") fromcharset = buf; else
610 if(param == "tocharset") tocharset = buf; else
611 if(param == "left_panel_width") leftpanelwidth = atol(buf.c_str()); else
612 if(param == "log_panel_height") logpanelheight = atol(buf.c_str()); else
613 if(param == "chat_panel_height") chatpanelheight = atol(buf.c_str()); else
614 if(param == "timestampstothesecond") settimestampstothesecond(true); else
615 if(param == "defaultauthmessage") defaultAuthMessage = buf; else
616 if(param == "ptp") {
617 ptpmin = atoi(getword(buf, "-").c_str());
618 ptpmax = atoi(buf.c_str());
619 } else {
620 for(pname = icq; pname != protocolname_size; pname++) {
621 buf = getprotocolname(pname);
622 if(param.substr(0, buf.size()) == buf) {
623 im = getourid(pname);
624 im.read(rbuf);
625 setourid(im);
631 if(fromcharset.empty() && tocharset.empty())
632 for(pname = icq; pname != protocolname_size; pname++) {
633 if(getcpconvert(pname)) {
634 fromcharset = "cp1251";
635 tocharset = "koi8-r";
636 break;
640 setproxy();
641 f.close();
645 void icqconf::save() {
646 string fname = getconfigfname("config"), param;
647 int away, na;
648 bool usex = false;
650 if(enoughdiskspace()) {
651 ofstream f(fname.c_str());
653 if(f.is_open()) {
654 if(!getsockshost().empty()) {
655 string user, pass;
656 getsocksuser(user, pass);
657 f << "sockshost\t" << getsockshost() + ":" + i2str(getsocksport()) << endl;
658 f << "socksusername\t" << user << endl;
659 f << "sockspass\t" << pass << endl;
662 getauto(away, na, usex);
664 if(away) f << "autoaway\t" << i2str(away) << endl;
665 if(na) f << "autona\t" << i2str(na) << endl;
666 if(autoawayx) f << "auto_away_na_x" << endl;
667 if(hideoffline) f << "hideoffline" << endl;
668 if(emacs) f << "emacs" << endl;
669 if(getquote()) f << "quotemsgs" << endl;
670 if(vi) f << "vi" << endl;
671 if(getantispam()) f << "antispam" << endl;
672 if(getshowopenedchats()) f << "showopenedchats" << endl;
673 if(getdropauthreq()) f << "dropauthreq" << endl;
674 if(getusingcaptcha()) f << "captcha" << endl;
675 if(getmailcheck()) f << "mailcheck" << endl;
676 if(getaskaway()) f << "askaway" << endl;
677 if(getscreenna()) f << "screenna" << endl;
678 if(!screensocketpath.empty()) f << "screensocketpath\t" << screensocketpath << endl;
680 param = "";
681 for(protocolname pname = icq; pname != protocolname_size; pname++)
682 if(getchatmode(pname)) param += (string) " " + conf->getprotocolname(pname);
683 if(!param.empty())
684 f << "chatmode" << param << endl;
686 param = "";
687 for(protocolname pname = icq; pname != protocolname_size; pname++)
688 if(getentersends(pname)) param += (string) " " + conf->getprotocolname(pname);
689 if(!param.empty())
690 f << "entersends" << param << endl;
692 param = "";
693 for(protocolname pname = icq; pname != protocolname_size; pname++)
694 if(getnonimonline(pname)) param += (string) " " + conf->getprotocolname(pname);
695 if(!param.empty())
696 f << "nonimonline" << param << endl;
698 param = "";
699 for(protocolname pname = icq; pname != protocolname_size; pname++)
700 if(getcpconvert(pname)) param += (string) " " + conf->getprotocolname(pname);
701 if(!param.empty())
702 f << "convert" << param << endl;
704 param = "";
706 f << "fromcharset\t" << fromcharset << endl;
707 f << "tocharset\t" << tocharset << endl;
709 if(!getbidi()) f << "nobidi" << endl;
710 if(getaskquit()) f << "askquit" << endl;
711 if(logtimestamps) f << "logtimestamps" << endl;
712 if(timestampstothesecond) f << "timestampstothesecond" << endl;
713 if(logonline) f << "logonline" << endl;
715 f << "smtp\t" << getsmtphost() << ":" << getsmtpport() << endl;
716 f << "browser\t" << getbrowser() << endl;
718 if(!gethttpproxyhost().empty())
719 if (!gethttpproxyuser().empty())
720 f << "http_proxy\t" << gethttpproxyuser() << ":" << gethttpproxypasswd() << "@" << gethttpproxyhost() << ":" << gethttpproxyport() << endl;
721 else
722 f << "http_proxy\t" << gethttpproxyhost() << ":" << gethttpproxyport() << endl;
724 f << "ptp\t" << ptpmin << "-" << ptpmax << endl;
726 switch(getgroupmode()) {
727 case group1: f << "group1" << endl; break;
728 case group2: f << "group2" << endl; break;
731 switch(getcolormode()) {
732 case cmproto:
733 f << "protocolormode" << endl;
734 break;
735 case cmstatus:
736 f << "statuscolormode" << endl;
737 break;
740 switch(getsortmode()) {
741 case sort_by_status_and_activity: f << "sort_by_status_and_activity" << endl; break;
742 case sort_by_status_and_name: f << "sort_by_status_and_name" << endl; break;
743 case sort_by_activity: f << "sort_by_activity" << endl; break;
744 case sort_by_name: f << "sort_by_name" << endl; break;
747 if(getmakelog()) f << "log" << endl;
748 if(getproxyconnect()) f << "proxy_connect" << endl;
749 if(getproxyssl()) f << "proxy_ssl" << endl;
751 if(getleftpanelwidth()) f << "left_panel_width\t" << getleftpanelwidth() << endl;
752 if(getlogpanelheight()) f << "log_panel_height\t" << getlogpanelheight() << endl;
753 if(getchatpanelheight()) f << "chat_panel_height\t" << getchatpanelheight() << endl;
755 f << "defaultauthmessage\t" << getDefaultAuthMessage() << endl;
757 vector<imaccount>::iterator ia;
758 for(ia = accounts.begin(); ia != accounts.end(); ++ia)
759 ia->write(f);
761 f.close();
766 void icqconf::loadcolors() {
767 string tname = getconfigfname("colorscheme");
769 switch(conf->getregcolor()) {
770 case rcdark:
771 schemer.push(cp_status, "status black/white");
772 schemer.push(cp_dialog_text, "dialog_text black/white");
773 schemer.push(cp_dialog_menu, "dialog_menu black/white");
774 schemer.push(cp_dialog_selected, "dialog_selected white/transparent bold");
775 schemer.push(cp_dialog_highlight, "dialog_highlight red/white");
776 schemer.push(cp_dialog_frame, "dialog_frame blue/white");
777 schemer.push(cp_main_text, "main_text cyan/transparent");
778 schemer.push(cp_main_menu, "main_menu green/transparent");
779 schemer.push(cp_main_selected, "main_selected black/white");
780 schemer.push(cp_main_highlight, "main_highlight yellow/transparent bold");
781 schemer.push(cp_main_frame, "main_frame blue/transparent bold");
782 schemer.push(cp_main_history_incoming, "main_history_incoming yellow/transparent bold");
783 schemer.push(cp_main_history_outgoing, "main_history_outgoing cyan/transparent");
784 schemer.push(cp_clist_icq, "clist_icq green/transparent");
785 schemer.push(cp_clist_yahoo, "clist_yahoo magenta/transparent");
786 schemer.push(cp_clist_infocard, "clist_infocard white/transparent");
787 schemer.push(cp_clist_msn, "clist_msn cyan/transparent");
788 schemer.push(cp_clist_aim, "clist_aim yellow/transparent");
789 schemer.push(cp_clist_irc, "clist_irc blue/transparent");
790 schemer.push(cp_clist_jabber, "clist_jabber red/transparent");
791 schemer.push(cp_clist_rss, "clist_rss white/transparent bold");
792 schemer.push(cp_clist_lj, "clist_lj cyan/transparent bold");
793 schemer.push(cp_clist_gadu, "clist_gg blue/transparent bold");
794 schemer.push(cp_clist_online, "clist_online green/transparent bold");
795 schemer.push(cp_clist_offline, "clist_offline red/transparent bold");
796 schemer.push(cp_clist_away, "clist_away yellow/transparent bold");
797 schemer.push(cp_clist_dnd, "clist_dnd cyan/transparent bold");
798 schemer.push(cp_clist_na, "clist_na blue/transparent bold");
799 schemer.push(cp_clist_free_for_chat, "clist_free_for_chat green/transparent bold");
800 schemer.push(cp_clist_invisible, "clist_invisible grey/transparent bold");
801 schemer.push(cp_clist_not_in_list, "clist_not_in_list white/transparent bold");
802 schemer.push(cp_clist_unread, "clist_unread red/transparent bold");
803 break;
805 case rcblue:
806 schemer.push(cp_status, "status black/white");
807 schemer.push(cp_dialog_text, "dialog_text black/cyan");
808 schemer.push(cp_dialog_menu, "dialog_menu black/cyan");
809 schemer.push(cp_dialog_selected, "dialog_selected white/black bold");
810 schemer.push(cp_dialog_highlight, "dialog_highlight white/cyan bold");
811 schemer.push(cp_dialog_frame, "dialog_frame black/cyan");
812 schemer.push(cp_main_text, "main_text white/blue");
813 schemer.push(cp_main_menu, "main_menu white/blue");
814 schemer.push(cp_main_selected, "main_selected black/cyan");
815 schemer.push(cp_main_highlight, "main_highlight white/blue bold");
816 schemer.push(cp_main_frame, "main_frame blue/blue bold");
817 schemer.push(cp_main_history_incoming, "main_history_incoming white/blue");
818 schemer.push(cp_main_history_outgoing, "main_history_outgoing white/blue bold");
819 schemer.push(cp_clist_icq, "clist_icq green/blue");
820 schemer.push(cp_clist_yahoo, "clist_yahoo magenta/blue");
821 schemer.push(cp_clist_msn, "clist_msn cyan/blue");
822 schemer.push(cp_clist_infocard, "clist_infocard white/blue");
823 schemer.push(cp_clist_aim, "clist_aim yellow/blue");
824 schemer.push(cp_clist_irc, "clist_irc blue/blue bold");
825 schemer.push(cp_clist_jabber, "clist_jabber red/blue");
826 schemer.push(cp_clist_rss, "clist_rss white/blue bold");
827 schemer.push(cp_clist_lj, "clist_lj cyan/blue bold");
828 schemer.push(cp_clist_gadu, "clist_gg blue/blue bold");
829 schemer.push(cp_clist_online, "clist_online green/transparent bold");
830 schemer.push(cp_clist_offline, "clist_offline red/transparent bold");
831 schemer.push(cp_clist_away, "clist_away yellow/transparent bold");
832 schemer.push(cp_clist_dnd, "clist_dnd cyan/transparent bold");
833 schemer.push(cp_clist_na, "clist_na blue/transparent bold");
834 schemer.push(cp_clist_free_for_chat, "clist_free_for_chat green/transparent bold");
835 schemer.push(cp_clist_invisible, "clist_invisible grey/transparent bold");
836 schemer.push(cp_clist_not_in_list, "clist_not_in_list white/transparent bold");
837 schemer.push(cp_clist_unread, "clist_unread black/blue bold");
838 break;
841 if(access(tname.c_str(), F_OK)) {
842 schemer.save(tname);
843 } else {
844 schemer.load(tname);
848 void icqconf::loadsounds() {
849 string tname = getconfigfname("sounds"), buf, suin, skey;
850 int i;
851 icqcontact *c;
852 imevent::imeventtype it;
854 typedef pair<imevent::imeventtype, string> eventsound;
855 vector<eventsound> soundnames;
856 vector<eventsound>::iterator isn;
858 soundnames.push_back(eventsound(imevent::message, "msg"));
859 soundnames.push_back(eventsound(imevent::sms, "sms"));
860 soundnames.push_back(eventsound(imevent::url, "url"));
861 soundnames.push_back(eventsound(imevent::online, "online"));
862 soundnames.push_back(eventsound(imevent::offline, "offline"));
863 soundnames.push_back(eventsound(imevent::email, "email"));
865 for(i = 0; i < clist.count; i++) {
866 c = (icqcontact *) clist.at(i);
868 for(it = imevent::message; it != imevent::imeventtype_size; it++) {
869 c->setsound(it, "");
873 if(access(tname.c_str(), F_OK)) {
874 ofstream fo(tname.c_str());
876 if(fo.is_open()) {
877 fo << "# This file contains sound configuration for centerim" << endl;
878 fo << "# Every line should look like: <id> <event> <command>" << endl << "#" << endl;
880 fo << "# <id>\tid of a contact; can be one of the following" << endl;
881 fo << "# *\tmeans default sound for all the contacts" << endl;
882 fo << "# icq_<uin>\tfor icq contacts (e.g. icq_123)" << endl;
883 fo << "# yahoo_<nickname>\tfor yahoo (e.g. yahoo_thekonst)" << endl;
884 fo << "# .. etc. Similar for the other protocols" << endl << "#" << endl;
886 fo << "# <event>\tcan be: ";
887 for(isn = soundnames.begin(); isn != soundnames.end(); ++isn) {
888 if(isn != soundnames.begin()) fo << ", ";
889 fo << isn->second;
892 fo << endl << "# <command>\tcommand line to be executed to play a sound" << endl << endl;
894 switch(rs) {
895 case rscard:
896 fo << "*\tmsg\taplay " << SHARE_DIR << "/msg.wav" << endl;
897 fo << "*\turl\taplay " << SHARE_DIR << "/url.wav" << endl;
898 fo << "*\temail\taplay " << SHARE_DIR << "/email.wav" << endl;
899 fo << "*\tonline\taplay " << SHARE_DIR << "/online.wav" << endl;
900 fo << "*\toffline\taplay " << SHARE_DIR << "/offline.wav" << endl;
901 fo << "*\tsms\taplay " << SHARE_DIR << "/sms.wav" << endl;
902 break;
904 case rsspeaker:
905 fo << "*\tmsg\t!spk1" << endl;
906 fo << "*\turl\t!spk2" << endl;
907 fo << "*\tsms\t!spk3" << endl;
908 fo << "*\temail\t!spk5" << endl;
909 break;
912 fo.close();
916 ifstream fi(tname.c_str());
917 if(fi.is_open()) {
918 while(!fi.eof()) {
919 getstring(fi, buf);
920 if(buf.empty() || (buf.substr(0, 1) == "#")) continue;
922 suin = getword(buf);
923 skey = getword(buf);
925 it = imevent::imeventtype_size;
927 for(isn = soundnames.begin(); isn != soundnames.end(); ++isn) {
928 if(skey == isn->second) {
929 it = isn->first;
930 break;
934 if(it == imevent::imeventtype_size)
935 continue;
937 c = 0;
939 if(suin != "*") {
940 if((i = suin.find("_")) != -1) {
941 skey = suin.substr(0, i);
942 suin.erase(0, i+1);
944 imcontact ic;
945 protocolname pname;
947 for(pname = icq; pname != protocolname_size && skey != getprotocolname(pname); pname++);
949 if(pname != protocolname_size) {
950 if(suin == "*") {
951 for(i = 0; i < clist.count; i++) {
952 c = (icqcontact *) clist.at(i);
954 if(c->getdesc().pname == pname) c->setsound(it, buf);
956 } else {
957 if(pname == icq) ic = imcontact(strtoul(suin.c_str(), 0, 0), pname);
958 else ic = imcontact(suin, pname);
960 c = clist.get(ic);
964 } else {
965 c = clist.get(contactroot);
968 if(c) c->setsound(it, buf);
971 fi.close();
975 void icqconf::loadactions() {
976 string fname = getconfigfname("actions"), buf, name;
977 ifstream f;
978 bool cont;
980 if(access(fname.c_str(), F_OK)) {
981 buf = getenv("PATH") ? getenv("PATH") : "";
983 ofstream of(fname.c_str());
985 if(of.is_open()) {
986 of << "# This file contains external actions configuration for centerim" << endl;
987 of << "# Every line should look like: <action> <command>" << endl;
988 of << "# Possible actions are: openurl, detectmusic" << endl << endl;
990 of << "openurl \\" << endl;
991 of << " (if test ! -z \"`ps x | grep /" << browser << " | grep -v grep`\"; \\" << endl;
992 of << "\tthen DISPLAY=0:0 " << browser << " -remote 'openURL($url$, new-window)'; \\" << endl;
993 of << "\telse DISPLAY=0:0 " << browser << " '$url$'; \\" << endl;
994 of << " fi) >/dev/null 2>&1 &" << endl;
996 of << "detectmusic \\" << endl;
997 of << " if test ! -z \"`ps x | grep orpheus | grep -v grep`\"; \\" << endl;
998 of << "\tthen cat ~/.orpheus/currently_playing; \\" << endl;
999 of << " fi" << endl;
1001 of.close();
1005 f.open(fname.c_str());
1007 if(f.is_open()) {
1008 actions.clear();
1009 cont = false;
1011 while(!f.eof()) {
1012 getstring(f, buf);
1013 if(!cont) name = getword(buf);
1015 if(name == "openurl" || name == "detectmusic") {
1016 if(!buf.empty())
1017 if(cont = buf.substr(buf.size()-1, 1) == "\\")
1018 buf.erase(buf.size()-1, 1);
1020 actions[name] += buf;
1024 f.close();
1028 void icqconf::loadcaptcha() {
1029 string fname = getconfigfname("captcha"), buf, entry;
1030 ifstream f;
1031 vector<string>::const_iterator ic;
1033 if(access(fname.c_str(), F_OK)) {
1035 ofstream of(fname.c_str());
1037 if(of.is_open()) {
1038 of << "# This file contains sample configuration for captcha engine." << endl;
1039 of << "# Every line should look like: <param> <value>" << endl;
1040 of << "# Possible params are: greeting, quest, success, failure, timeout (min)" << endl;
1041 of << "# Quest fomat is: quest <question>//<answer>[::answer[...]]" << endl;
1042 of << endl;
1043 of << "greeting I'm using a test to determine if you are a computer or not. If you would please answer the question correctly, you will be added to my contact list automatically." << endl;
1044 of << endl;
1045 of << "quest How many legs does a dog have?//4::four" << endl;
1046 of << "quest What is the first word of this sentence?//what" << endl;
1047 of << "quest What is the sum of 1 and 1?//2::two" << endl;
1048 of << "quest What is not a fruit: lettuce, apple or banana?//lettuce" << endl;
1049 of << "quest How many fingers are there on one hand?//5::five" << endl;
1050 of << "quest How many wheels does a normal bicycle have?//2::two" << endl;
1051 of << "quest What colour does a banana have?//yellow::yelow" << endl;
1052 of << "quest What does a chicken lay?//eggs::egg" << endl;
1053 of << "quest What is the value of PI, accurate to 2 digits?//3.14::3,14" << endl;
1054 of << "quest Is a wheel round or not (yes or no)?//yes" << endl;
1055 of << endl;
1056 of << "success You answered the question correctly, you are now added to my contact list. Thank you for your patience." << endl;
1057 of << "failure You answered the question incorrectly, you can try again by answering the next question." << endl;
1058 of << "timeout 30" << endl;
1059 of.close();
1063 f.open(fname.c_str());
1065 if(f.is_open()) {
1066 while(!f.eof()) {
1067 getstring(f, buf);
1068 entry = getword(buf);
1070 if(entry == "greeting") captchagreet = buf; else
1071 if(entry == "success") captchasuccess = buf; else
1072 if(entry == "failure") captchafailure = buf; else
1073 if(entry == "timeout") captchatimeout = atol(buf.c_str()); else
1074 if(entry == "quest") thecaptcha.addquestion(buf);
1076 if(thecaptcha.empty()) {
1077 usingcaptcha = false;
1078 face.log(_("+ ERROR: captcha disabled: no questions found!"));
1081 f.close();
1085 icqconf::regcolor icqconf::getregcolor() const {
1086 return rc;
1089 void icqconf::setregcolor(icqconf::regcolor c) {
1090 rc = c;
1093 icqconf::regsound icqconf::getregsound() const {
1094 return rs;
1097 void icqconf::setregsound(icqconf::regsound s) {
1098 rs = s;
1101 icqconf::colormode icqconf::getcolormode() const {
1102 return cm;
1105 void icqconf::setcolormode(colormode c) {
1106 cm = c;
1109 void icqconf::setauto(int away, int na, bool usex) {
1110 autoaway = away;
1111 autona = na;
1112 autoawayx = usex;
1114 if(away == na)
1115 autoaway = 0;
1118 void icqconf::getauto(int &away, int &na, bool& usex) const {
1119 away = autoaway;
1120 na = autona;
1121 usex = autoawayx;
1123 if(away == na)
1124 away = 0;
1127 bool icqconf::getscreenna() const {
1128 return screenna;
1131 void icqconf::setscreenna(bool sna) {
1132 screenna = sna;
1135 string icqconf::getscreensocketpath() const {
1136 return screensocketpath;
1139 void icqconf::setscreensocketpath(string path) {
1140 screensocketpath = path;
1143 void icqconf::setquote(bool use) {
1144 quote = use;
1146 void icqconf::setaskquit(bool faskquit) {
1147 askquit = faskquit;
1150 void icqconf::setsockshost(const string &nsockshost) {
1151 int pos;
1153 if(!nsockshost.empty()) {
1154 if((pos = nsockshost.find(":")) != -1) {
1155 sockshost = nsockshost.substr(0, pos);
1156 socksport = atol(nsockshost.substr(pos+1).c_str());
1157 } else {
1158 sockshost = nsockshost;
1159 socksport = 1080;
1161 } else {
1162 sockshost = "";
1166 string icqconf::getsockshost() const {
1167 return sockshost;
1170 unsigned int icqconf::getsocksport() const {
1171 return socksport;
1174 void icqconf::getsocksuser(string &name, string &pass) const {
1175 name = socksuser;
1176 pass = sockspass;
1179 void icqconf::setsocksuser(const string &name, const string &pass) {
1180 socksuser = name;
1181 sockspass = pass;
1184 void icqconf::setsavepwd(bool ssave) {
1185 savepwd = ssave;
1188 void icqconf::sethideoffline(bool fho) {
1189 hideoffline = fho;
1192 void icqconf::settimestampstothesecond(bool ttts) {
1193 timestampstothesecond = ttts;
1194 if (timestampstothesecond) {
1195 timestampformat = SECONDS_TIMESTAMP_FORMAT;
1196 logtimestampformat = SECONDS_LOGTIMESTAMP_FORMAT;
1197 } else {
1198 timestampformat = DEFAULT_TIMESTAMP_FORMAT;
1199 logtimestampformat = DEFAULT_LOGTIMESTAMP_FORMAT;
1203 void icqconf::setemacs(bool fem) {
1204 emacs = fem;
1207 void icqconf::setvi(bool b) {
1208 vi = b;
1211 void icqconf::setantispam(bool fas) {
1212 antispam = fas;
1215 void icqconf::setshowopenedchats(bool fsoc)
1217 showopenedchats = fsoc;
1220 void icqconf::setdropauthreq(bool fas) {
1221 dropauthreq = fas;
1224 void icqconf::setusingcaptcha(bool fas) {
1225 usingcaptcha = fas;
1228 void icqconf::setmailcheck(bool fmc) {
1229 mailcheck = fmc;
1232 void icqconf::setaskaway(bool faskaway) {
1233 askaway = faskaway;
1236 bool icqconf::getchatmode(protocolname pname) {
1237 switch(pname) {
1238 case infocard:
1239 case rss:
1240 return false;
1243 return chatmode[pname];
1246 void icqconf::setchatmode(protocolname pname, bool fchatmode) {
1247 chatmode[pname] = fchatmode;
1250 bool icqconf::getentersends(protocolname pname) {
1251 return entersends[pname];
1254 void icqconf::setentersends(protocolname pname, bool fentersends) {
1255 entersends[pname] = fentersends;
1258 bool icqconf::getnonimonline(protocolname pname) {
1259 return nonimonline[pname];
1262 void icqconf::setnonimonline(protocolname pname, bool fnonimonline) {
1263 nonimonline[pname] = fnonimonline;
1266 bool icqconf::getcpconvert(protocolname pname) const {
1267 return cpconvert[pname];
1270 void icqconf::setcpconvert(protocolname pname, bool fcpconvert) {
1271 cpconvert[pname] = fcpconvert;
1274 string icqconf::execaction(const string &name, const string &param) {
1275 int inpipe[2], outpipe[2], pid, npos;
1276 struct sigaction sact, osact;
1277 string torun = actions[name], out;
1278 fd_set rfds;
1279 char ch;
1281 if(name == "openurl")
1283 string url = param;
1284 int pos = 0, fnd = -1;
1286 char enc[4];
1288 while( ((fnd = url.find("'", pos)) != -1) || ((fnd = url.find("\"", pos)) != -1) ) {
1289 snprintf(enc, 4, "%%%02X", url[fnd]);
1290 url.replace(fnd, 1, enc);
1291 pos = fnd+3;
1294 while((npos = torun.find("$url$")) != -1)
1295 torun.replace(npos, 5, url);
1298 if(!pipe(inpipe) && !pipe(outpipe)) {
1299 memset(&sact, 0, sizeof(sact));
1300 sigaction(SIGCHLD, &sact, &osact);
1301 pid = fork();
1303 if(!pid) {
1304 dup2(inpipe[1], STDOUT_FILENO);
1305 dup2(outpipe[0], STDIN_FILENO);
1307 close(inpipe[1]);
1308 close(inpipe[0]);
1309 close(outpipe[0]);
1310 close(outpipe[1]);
1312 execl("/bin/sh", "/bin/sh", "-c", torun.c_str(), (char *)NULL );
1313 _exit(0);
1314 } else {
1315 close(outpipe[0]);
1316 close(inpipe[1]);
1318 while(1) {
1319 FD_ZERO(&rfds);
1320 FD_SET(inpipe[0], &rfds);
1322 if(select(inpipe[0]+1, &rfds, 0, 0, 0) < 0) break; else {
1323 if(FD_ISSET(inpipe[0], &rfds)) {
1324 if(read(inpipe[0], &ch, 1) != 1) break; else {
1325 out += ch;
1331 waitpid(pid, 0, 0);
1332 close(inpipe[0]);
1333 close(outpipe[1]);
1336 sigaction(SIGCHLD, &osact, 0);
1338 face.log(_("+ launched the %s action command"), name.c_str());
1339 return out;
1342 string icqconf::getprotocolname(protocolname pname) const {
1343 static const string ptextnames[protocolname_size] = {
1344 "icq", "yahoo", "msn", "aim", "irc", "jab", "rss", "lj", "gg", "infocard"
1347 return ptextnames[pname];
1350 protocolname icqconf::getprotocolbyletter(char letter) const {
1351 switch(letter) {
1352 case 'y': return yahoo;
1353 case 'a': return aim;
1354 case 'i': return irc;
1355 case 'm': return msn;
1356 case 'n': return infocard;
1357 case 'j': return jabber;
1358 case 'r': return rss;
1359 case 'l': return livejournal;
1360 case 'g': return gadu;
1361 case '0':
1362 case '1':
1363 case '2':
1364 case '3':
1365 case '4':
1366 case '5':
1367 case '6':
1368 case '7':
1369 case '8':
1370 case '9': return icq;
1373 return protocolname_size;
1376 string icqconf::getprotocolprefix(protocolname pname) const {
1377 static const string pprefixes[protocolname_size] = {
1378 "", "y", "m", "a", "i", "j", "r", "l", "g", "n"
1381 return pprefixes[pname];
1384 imstatus icqconf::getstatus(protocolname pname) {
1385 if(startoffline)
1386 return offline;
1388 imstatus st = available;
1389 map<string, string>::iterator ia;
1390 imaccount a = getourid(pname);
1392 if((ia = a.additional.find("status")) != a.additional.end()) {
1393 if(!ia->second.empty()) {
1394 for(st = offline; st != imstatus_size && imstatus2char[st] != ia->second[0]; st++);
1395 if(st == imstatus_size) st = available;
1399 return st;
1402 void icqconf::savestatus(protocolname pname, imstatus st) {
1403 imaccount im = getourid(pname);
1404 im.additional["status"] = string(1, imstatus2char[st]);
1405 setourid(im);
1408 void icqconf::setavatar(protocolname pname, const string &ava) {
1409 imaccount im = getourid(pname);
1410 im.additional["avatar"] = ava;
1411 setourid(im);
1414 int icqconf::getprotcolor(protocolname pname) const {
1415 switch(pname) {
1416 case icq : return getcolor(cp_clist_icq);
1417 case yahoo : return getcolor(cp_clist_yahoo);
1418 case infocard : return getcolor(cp_clist_infocard);
1419 case msn : return getcolor(cp_clist_msn);
1420 case aim : return getcolor(cp_clist_aim);
1421 case irc : return getcolor(cp_clist_irc);
1422 case jabber : return getcolor(cp_clist_jabber);
1423 case rss : return getcolor(cp_clist_rss);
1424 case livejournal : return getcolor(cp_clist_lj);
1425 case gadu : return getcolor(cp_clist_gadu);
1426 default : return getcolor(cp_main_text);
1430 int icqconf::getstatuscolor(imstatus status) const {
1431 switch(status) {
1432 case offline : return getcolor(cp_clist_offline);
1433 case available : return getcolor(cp_clist_online);
1434 case invisible : return getcolor(cp_clist_invisible);
1435 case freeforchat : return getcolor(cp_clist_free_for_chat);
1436 case dontdisturb : return getcolor(cp_clist_dnd);
1437 case occupied : return getcolor(cp_clist_occupied);
1438 case notavail : return getcolor(cp_clist_na);
1439 case outforlunch : return getcolor(cp_clist_na);
1440 case away : return getcolor(cp_clist_away);
1441 default : return getcolor(cp_main_text);
1445 void icqconf::setbidi(bool fbidi) {
1446 bidi = fbidi;
1447 #ifdef USE_FRIBIDI
1448 use_fribidi = bidi;
1449 #endif
1452 void icqconf::commandline(int argc, char **argv) {
1453 int i;
1454 string event, proto, dest, number;
1455 char st = 0;
1457 argv0 = argv[0];
1459 for(i = 1; i < argc; i++) {
1460 string args = argv[i];
1462 if((args == "-a") || (args == "--ascii")) {
1463 kintf_graph = 0;
1465 } else if((args == "-b") || (args == "--basedir")) {
1466 if(argv[++i]) {
1467 basedir = argv[i];
1468 if(basedir.substr(basedir.size()-1) != "/") basedir += "/";
1471 } else if((args == "-B") || (args == "--bind")) {
1472 if(argv[++i]) {
1473 bindhost = argv[i];
1474 cw_setbind(bindhost.c_str());
1477 } else if((args == "-T") || (args == "--no-xtitles")) {
1478 notitles = true;
1480 } else if((args == "-o") || (args == "--offline")) {
1481 startoffline = true;
1483 } else if((args == "-s") || (args == "--send")) {
1484 if(argv[++i]) event = argv[i];
1486 } else if((args == "-p") || (args == "--proto")) {
1487 if(argv[++i]) proto = argv[i];
1489 } else if((args == "-t") || (args == "--to")) {
1490 if(argv[++i]) dest = argv[i];
1492 } else if((args == "-n") || (args == "--number")) {
1493 if(argv[++i]) number = argv[i];
1495 } else if((args == "-S") || (args == "--status")) {
1496 if(argv[++i])
1497 if(strlen(argv[i]))
1498 st = argv[i][0];
1500 } else if((args == "-d") || (args == "--debug")) {
1501 debug = true;
1503 } else if((args == "-v") || (args == "--version")) {
1504 cout << PACKAGE << " " << centerim::version << endl
1505 << "Written by Konstantin Klyagin, 2005. Currently maintained by the CenterIM community." << endl
1506 << "Built-in protocols are:";
1508 for(protocolname pname = icq; pname != protocolname_size; pname++)
1509 if(gethook(pname).enabled()) cout << " " << conf->getprotocolname(pname);
1511 cout << endl << endl
1512 << "This is free software; see the source for copying conditions. There is NO" << endl
1513 << "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." << endl;
1515 exit(0);
1517 } else {
1518 usage();
1519 exit(0);
1523 if(!number.empty()) {
1524 if(event.empty()) event = "sms";
1525 if(proto.empty()) proto = "icq";
1526 dest = "0";
1529 constructevent(event, proto, dest, number);
1530 externalstatuschange(st, proto);
1533 void icqconf::constructevent(const string &event, const string &proto,
1534 const string &dest, const string &number) const {
1536 imevent *ev = 0;
1537 imcontact cdest;
1538 string text, buf;
1539 int pos;
1541 if(event.empty() && dest.empty()) return; else
1542 if(event.empty() || proto.empty() || dest.empty()) {
1543 cout << _("event sending error: not enough parameters") << endl;
1544 exit(1);
1547 while(getline(cin, buf)) {
1548 if(!text.empty()) text += "\n";
1549 text += buf;
1552 if(proto == "icq") {
1553 if(dest.find_first_not_of("0123456789") != -1) {
1554 cout << _("event sending error: only UINs are allowed with icq protocol") << endl;
1555 exit(1);
1557 cdest = imcontact(strtoul(dest.c_str(), 0, 0), icq);
1558 } else {
1559 protocolname pname;
1561 for(pname = icq; pname != protocolname_size; pname++) {
1562 if(getprotocolname(pname) == proto) {
1563 cdest = imcontact(dest, pname);
1564 break;
1568 if(pname == protocolname_size) {
1569 cout << _("event sending error: unknown IM type") << endl;
1570 exit(1);
1574 if(event == "msg") {
1575 ev = new immessage(cdest, imevent::outgoing, text);
1576 } else if(event == "url") {
1577 string url;
1579 if((pos = text.find("\n")) != -1) {
1580 url = text.substr(0, pos);
1581 text.erase(0, pos+1);
1582 } else {
1583 url = text;
1584 text = "";
1587 ev = new imurl(cdest, imevent::outgoing, url, text);
1588 } else if(event == "sms") {
1589 ev = new imsms(cdest, imevent::outgoing, text, number);
1590 } else {
1591 cout << _("event sending error: unknown event type") << endl;
1592 exit(1);
1595 if(ev) {
1596 icqcontact *c = new icqcontact(cdest);
1598 if(access(c->getdirname().c_str(), X_OK)) {
1599 mkdir(c->getdirname().c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
1600 selfsignal(SIGUSR2);
1603 if(!access(c->getdirname().c_str(), X_OK)) {
1604 clist.add(c);
1605 em.store(*ev);
1607 char buf[512];
1608 snprintf(buf, sizeof(buf), _("%s to %s has been put to the queue"),
1609 streventname(ev->gettype()),
1610 number.empty() ? c->getdesc().totext().c_str() : number.c_str());
1612 cout << buf << endl;
1613 } else {
1614 cout << _("event sending error: error creating directory for the contact") << endl;
1615 exit(1);
1618 //delete c;
1619 delete ev;
1621 exit(0);
1625 void icqconf::selfsignal(int signum) const {
1626 int rpid;
1627 ifstream f(conf->getconfigfname("pid").c_str());
1629 if(f.is_open()) {
1630 f >> rpid;
1631 f.close();
1633 if(rpid > 0) {
1634 kill(rpid, signum);
1639 void icqconf::externalstatuschange(char st, const string &proto) const {
1640 imstatus imst;
1641 protocolname pname;
1643 if(st) {
1644 for(pname = icq; pname != protocolname_size; pname++)
1645 if(getprotocolname(pname) == proto)
1646 break;
1648 for(imst = offline; imst != imstatus_size; imst++)
1649 if(imstatus2char[imst] == st)
1650 break;
1652 try {
1653 if(pname != protocolname_size) {
1654 if(imst != imstatus_size) {
1655 string sfname = conf->getconfigfname((string) "status-" + proto);
1656 ofstream sf(sfname.c_str());
1657 if(sf.is_open()) sf << imstatus2char[imst], sf.close();
1659 selfsignal(SIGUSR1);
1660 } else {
1661 throw _("unknown status character was given");
1663 } else {
1664 throw _("unknown IM type");
1666 } catch(char *p) {
1667 cout << _("status change error: ") << p << endl;
1668 exit(1);
1671 exit(0);
1675 void icqconf::usage() const {
1676 cout << PACKAGE << " " << centerim::version << endl;
1678 cout << endl << _("Usage: ") << argv0 << _(" [OPTION]...") << endl;
1680 cout << endl << _("General options:") << endl;
1681 cout << _(" --ascii, -a use ASCII characters for windows and UI controls") << endl;
1682 cout << _(" --basedir, -b <path> set a custom base directory") << endl;
1683 cout << _(" --bind, -B <host/ip> bind a custom local IP") << endl;
1684 cout << _(" --no-xtitles, -T disable xterm titles") << endl;
1685 cout << _(" --offline, -o set all protocols status to offline upon start") << endl;
1686 cout << _(" --debug, -d enables debug info logging") << endl;
1687 cout << _(" --help display this stuff") << endl;
1688 cout << _(" --version, -v show the program version info") << endl;
1690 cout << endl << _("Events sending options:") << endl;
1691 cout << _(" -s, --send <event type> event type; can be msg, sms or url") << endl;
1692 cout << _(" -S, --status <status> change the current IM status. Status; o, _, a, d, n, c, f, i") << endl;
1693 cout << _(" -p, --proto <protocol> protocol type; can be icq, yahoo, msn, aim, irc, jab, rss, lj, gg or infocard") << endl;
1695 cout << _(" -t, --to <destination> destination UIN or nick (depends on protocol)") << endl;
1696 cout << _(" -n, --number <phone#> mobile number to send an event to (sms only)") << endl;
1698 cout << endl << _("Report bugs to http://bugzilla.centerim.org/.") << endl;
1701 void icqconf::setproxy() {
1702 if(getproxyconnect()) {
1703 cw_setproxy(gethttpproxyhost().c_str(), gethttpproxyport(),
1704 gethttpproxyuser().c_str(),
1705 gethttpproxypasswd().c_str());
1707 } else {
1708 cw_setproxy(0, 0, 0, 0);
1713 void icqconf::setmakelog(bool slog) {
1714 makelog = slog;
1717 void icqconf::setproxyconnect(bool sproxy) {
1718 proxyconnect = sproxy;
1719 setproxy();
1722 void icqconf::setproxyssl(bool sproxyssl) {
1723 proxyssl = sproxyssl;
1726 void icqconf::setgroupmode(icqconf::groupmode amode) {
1727 fgroupmode = amode;
1730 void icqconf::setsortmode(icqconf::sortmode smode) {
1731 fsortmode = smode;
1732 icqcontacts::setsortmode(smode);
1735 void icqconf::initmultiproto(bool p[], string buf, bool excludenochat) {
1736 string w;
1737 protocolname pname;
1739 for(pname = icq; pname != protocolname_size; pname++)
1740 p[pname] = buf.empty();
1742 while(!(w = getword(buf)).empty()) {
1743 for(pname = icq; pname != protocolname_size; pname++) {
1744 if(getprotocolname(pname) == w) {
1745 if(excludenochat) {
1746 p[pname] = !gethook(pname).getCapabs().count(hookcapab::nochat);
1747 } else {
1748 p[pname] = true;
1750 break;
1756 void icqconf::setbrowser(const string &abrowser) {
1757 if (!abrowser.empty())
1758 browser = abrowser;
1759 else
1760 browser = "mozilla";
1763 void icqconf::setsmtphost(const string &asmtphost) {
1764 int pos;
1766 smtphost = "";
1767 smtpport = 0;
1769 if(!asmtphost.empty()) {
1770 if((pos = asmtphost.find(":")) != -1) {
1771 smtphost = asmtphost.substr(0, pos);
1772 smtpport = atol(asmtphost.substr(pos+1).c_str());
1773 } else {
1774 smtphost = asmtphost;
1775 smtpport = 25;
1779 if(smtphost.empty() || !smtpport) {
1780 smtphost = getsmtphost();
1781 smtpport = getsmtpport();
1785 void icqconf::sethttpproxyhost(const string &ahttpproxyhost) {
1786 int pos, posn;
1788 httpproxyhost = "";
1789 httpproxyport = 0;
1790 httpproxyuser = "";
1791 httpproxypasswd = "";
1793 if(!ahttpproxyhost.empty()) {
1794 if((pos = ahttpproxyhost.find(":")) != -1) {
1795 if ((posn = ahttpproxyhost.find("@")) != -1) {
1796 httpproxyuser = ahttpproxyhost.substr(0, pos);
1797 httpproxypasswd = ahttpproxyhost.substr(pos+1, posn-pos-1);
1798 if((pos = ahttpproxyhost.find(":", posn)) != -1) {
1799 httpproxyhost = ahttpproxyhost.substr(posn+1, pos-posn-1);
1800 httpproxyport = atol(ahttpproxyhost.substr(pos+1).c_str());
1802 } else {
1803 httpproxyhost = ahttpproxyhost.substr(0, pos);
1804 httpproxyport = atol(ahttpproxyhost.substr(pos+1).c_str());
1806 } else {
1807 httpproxyhost = ahttpproxyhost;
1808 httpproxyport = 8080;
1812 setproxy();
1815 string icqconf::getbrowser() const {
1816 return browser.empty() ? "mozilla" : browser;
1819 string icqconf::getsmtphost() const {
1820 return smtphost.empty() ? "localhost" : smtphost;
1823 unsigned int icqconf::getsmtpport() const {
1824 return smtpport ? smtpport : 25;
1827 string icqconf::gethttpproxyhost() const {
1828 return httpproxyhost;
1831 unsigned int icqconf::gethttpproxyport() const {
1832 return httpproxyport ? httpproxyport : 8080;
1835 string icqconf::gethttpproxyuser() const {
1836 return httpproxyuser;
1839 string icqconf::gethttpproxypasswd() const {
1840 return httpproxypasswd;
1843 void icqconf::checkdiskspace() {
1844 fenoughdiskspace = true;
1846 #if !(defined(__sun__) || defined(__NetBSD__) || defined(__sgi__))
1847 struct statfs st;
1848 if(!statfs(conf->getdirname().c_str(), &st)) {
1849 #else
1850 struct statvfs st;
1851 if(!statvfs(conf->getdirname().c_str(), &st)) {
1852 #endif
1853 fenoughdiskspace = ((double) st.f_bavail) * st.f_bsize >= 10240;
1857 void icqconf::setcharsets(const string &from, const string &to) {
1858 fromcharset = from;
1859 tocharset = to;
1862 const char *icqconf::getconvertfrom(protocolname pname) const {
1863 if(pname != protocolname_size && !getcpconvert(pname)) return "iso-8859-1";
1864 return fromcharset.c_str();
1867 const char *icqconf::getconvertto(protocolname pname) const {
1868 if(pname != protocolname_size && !getcpconvert(pname)) return "iso-8859-1";
1869 return tocharset.c_str();
1872 // ----------------------------------------------------------------------------
1874 icqconf::imaccount::imaccount() {
1875 uin = port = 0;
1876 pname = infocard;
1879 icqconf::imaccount::imaccount(protocolname apname) {
1880 uin = port = 0;
1881 pname = apname;
1884 bool icqconf::imaccount::empty() const {
1885 return !uin && nickname.empty();
1888 void icqconf::imaccount::write(ofstream &f) {
1889 string prefix = conf->getprotocolname(pname) + "_";
1890 map<string, string>::iterator ia;
1892 f << endl;
1893 if(!nickname.empty()) f << prefix << "nick\t" << nickname << endl;
1894 if(uin) f << prefix << "uin\t" << uin << endl;
1895 if(conf->getsavepwd()) f << prefix << "pass\t" << password << endl;
1896 if(!server.empty()) {
1897 f << prefix << "server\t" << server;
1898 if(port) f << ":" << port;
1899 f << endl;
1902 for(ia = additional.begin(); ia != additional.end(); ++ia)
1903 if(!ia->first.empty() && !ia->second.empty())
1904 f << prefix << ia->first << "\t" << ia->second << endl;
1907 void icqconf::imaccount::read(const string &spec) {
1908 int pos = spec.find("_");
1909 string spname, buf;
1911 if(pos != -1) {
1912 buf = spec;
1913 spname = getword(buf.erase(0, pos+1));
1915 if(spname == "nick") nickname = buf; else
1916 if(spname == "uin") uin = strtoul(buf.c_str(), 0, 0); else
1917 if(spname == "pass") password = buf; else
1918 if(spname == "server") {
1919 if((pos = buf.find(":")) != -1) {
1920 server = buf.substr(0, pos);
1921 port = strtoul(buf.substr(pos+1).c_str(), 0, 0);
1922 } else {
1923 server = buf;
1926 if(pname == icq)
1927 if(server == "icq.mirabilis.com")
1928 server = "";
1930 if(pname == yahoo)
1931 if(server == "scs.yahoo.com")
1932 server = "";
1934 } else {
1935 additional[spname] = buf;
1940 bool icqconf::imaccount::operator == (protocolname apname) const {
1941 return pname == apname;
1944 bool icqconf::imaccount::operator != (protocolname apname) const {
1945 return pname != apname;