moved the old Changelog, which only contained log from the old centericq
[centerim.git] / src / icqconf.cc
blob94fab21afcc79c14f254319ddf759a47348e302b
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>
30 #ifdef __sun__
31 #include <sys/statvfs.h>
32 #endif
34 #include "centerim.h"
35 #include "icqconf.h"
36 #include "icqface.h"
37 #include "icqcontacts.h"
38 #include "abstracthook.h"
39 #include "imexternal.h"
40 #include "eventmanager.h"
41 #include "imlogger.h"
42 #include "connwrap.h"
44 icqconf::icqconf() {
45 DEFAULT_TIMESTAMP_FORMAT = "DD.MM.YY hh:mm";
46 DEFAULT_LOGTIMESTAMP_FORMAT = "%R ";
47 SECONDS_TIMESTAMP_FORMAT = "DD.MM.YY hh:mm:ss";
48 SECONDS_LOGTIMESTAMP_FORMAT = "%T ";
50 rs = rscard;
51 rc = rcdark;
52 cm = cmproto;
53 fgroupmode = nogroups;
54 fsortmode = sort_by_status_and_activity;
56 autoaway = autona = 0;
58 hideoffline = antispam = makelog = askaway = logtimestamps =
59 logonline = emacs = proxyssl = proxyconnect = notitles =
60 debug = timestampstothesecond = false;
62 timestampformat = DEFAULT_TIMESTAMP_FORMAT;
63 logtimestampformat = DEFAULT_LOGTIMESTAMP_FORMAT;
65 startoffline = false;
67 savepwd = mailcheck = fenoughdiskspace = true;
69 for(protocolname pname = icq; pname != protocolname_size; pname++) {
70 chatmode[pname] = true;
71 cpconvert[pname] = entersends[pname] = nonimonline[pname] = false;
74 // quick and dirty fix to support .centerim as well as .centericq
75 basedir = (string) getenv("HOME") + "/.centerim/";
76 if ( access(basedir.c_str(), F_OK) != 0 ) {
77 basedir = (string) getenv("HOME") + "/.centericq/";
78 if ( access(basedir.c_str(), F_OK) != 0 ) {
79 basedir = (string) getenv("HOME") + "/.centerim/";
82 screensocketpath = "/var/run/screen";
85 icqconf::~icqconf() {
88 icqconf::imaccount icqconf::getourid(protocolname pname) const {
89 imaccount im;
90 vector<imaccount>::const_iterator i;
92 i = find(accounts.begin(), accounts.end(), pname);
93 im = i == accounts.end() ? imaccount(pname) : *i;
95 return im;
98 icqconf::imserver icqconf::defservers[protocolname_size] = {
99 { "login.icq.com", 5190, 0 },
100 { "scs.msg.yahoo.com", 5050, 0 },
101 { "messenger.hotmail.com", 1863, 0 },
102 { "toc.oscar.aol.com", 9898, 0 },
103 { "irc.oftc.net", 6667, 0 },
104 { "jabber.org", 5222, 5223 },
105 { "", 0, 0 },
106 { "livejournal.com", 80, 0 },
107 { "appmsg.gadu-gadu.pl", 80 }
110 void icqconf::setourid(const imaccount &im) {
111 vector<imaccount>::iterator i;
113 i = find(accounts.begin(), accounts.end(), im.pname);
115 if(i != accounts.end()) {
116 if(im.empty()) {
117 accounts.erase(i);
118 i = accounts.end();
119 } else {
120 *i = im;
122 } else if(!im.empty()) {
123 accounts.push_back(im);
124 i = accounts.end()-1;
127 if(i != accounts.end()) {
128 if(i->server.empty()) {
129 i->server = defservers[i->pname].server;
130 i->port = defservers[i->pname].port;
133 if(!i->port)
134 i->port = defservers[i->pname].port;
136 switch(i->pname) {
137 case jabber:
138 if(i->additional.find("prio") == i->additional.end())
139 i->additional["prio"] = "4";
140 break;
142 case livejournal:
143 if(i->additional.find("importfriends") == i->additional.end())
144 i->additional["importfriends"] = "1";
145 break;
147 case icq:
148 if(i->password.size() > 8)
149 i->password = i->password.substr(0, 8);
150 break;
155 string icqconf::getawaymsg(protocolname pname) const {
156 string r, buf, fname;
157 ifstream f;
159 if(!gethook(pname).getCapabs().count(hookcapab::setaway))
160 return "";
162 fname = conf.getconfigfname("awaymsg-" + getprotocolname(pname));
163 f.open(fname.c_str());
165 if(f.is_open()) {
166 while(!f.eof()) {
167 getstring(f, buf);
168 if(!r.empty()) r += "\n";
169 r += buf;
172 f.close();
175 if(r.empty()) {
176 char buf[512];
178 snprintf(buf, sizeof(buf), _("I do really enjoy the default %s away message of %s %s."),
179 getprotocolname(pname).c_str(), PACKAGE, centerim::version);
181 return buf;
184 return r;
187 void icqconf::setawaymsg(protocolname pname, const string &amsg) {
188 string fname;
189 ofstream f;
191 if(!gethook(pname).getCapabs().count(hookcapab::setaway))
192 return;
194 fname = conf.getconfigfname("awaymsg-" + getprotocolname(pname));
195 f.open(fname.c_str());
197 if(f.is_open()) {
198 f << amsg;
199 f.close();
203 void icqconf::checkdir() {
204 string dname = getdirname();
205 dname.erase(dname.size()-1);
207 if(access(dname.c_str(), F_OK))
208 mkdir(dname.c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
211 void icqconf::load() {
212 loadmainconfig();
213 loadkeys();
214 loadcolors();
215 loadactions();
216 loadcaptcha();
217 external.load();
220 vector<icqconf::keybinding> icqconf::keys;
222 void icqconf::loadkeys() {
223 //int x; not used.
224 string fname = getconfigfname("keybindings"), buf, param;
225 struct keybinding k;
226 ifstream f;
228 keys.clear();
230 if(access(fname.c_str(), F_OK)) {
231 ofstream of(fname.c_str());
233 if(of.is_open()) {
234 of << "# This file contains keybinding configuration for centerim" << endl;
235 of << "# Every line should look like: bind <section> <key> <command>" << endl << endl;
236 of << "bind contact\t?\tinfo" << endl;
237 of << "bind contact\tq\tquit" << endl;
238 of << "bind contact\t<F3>\tchange_status" << endl;
239 of << "bind contact\ts\tchange_status" << endl;
240 of << "bind contact\th\thistory" << endl;
241 of << "bind contact\tf\tfetch_away_message" << endl;
242 of << "bind contact\t<F2>\tuser_menu" << endl;
243 of << "bind contact\tm\tuser_menu" << endl;
244 of << "bind contact\t<F4>\tgeneral_menu" << endl;
245 of << "bind contact\tg\tgeneral_menu" << endl;
246 of << "bind contact\t<F5>\thide_offline" << endl;
247 of << "bind contact\t<F6>\tcontact_external_action" << endl;
248 of << "bind contact\ta\tadd" << endl;
249 of << "bind contact\t<delete> remove" << endl;
250 of << "bind contact\t<enter> compose" << endl;
251 of << "bind contact\tc\tsend_contact" << endl;
252 of << "bind contact\tc\trss_check" << endl;
253 of << "bind contact\tu\tsend_url" << endl;
254 of << "bind contact\tr\trename" << endl;
255 of << "bind contact\tv\tversion" << endl;
256 of << "bind contact\te\tedit" << endl;
257 of << "bind contact\ti\tignore" << endl;
258 of << "bind contact\t\\as\tquickfind" << endl;
259 of << "bind contact\t/\tquickfind" << endl << endl;
260 of << "bind contact\t\\cn\tnext_chat" << endl;
261 of << "bind contact\t\\cb\tprev_chat" << endl;
262 of << "bind contact\t[\tleft_panel_move_left" << endl;
263 of << "bind contact\t]\tleft_panel_move_right" << endl;
264 of << "bind contact\t{\tlog_panel_move_up" << endl;
265 of << "bind contact\t}\tlog_panel_move_down" << endl;
266 of << "bind history\t/\tsearch" << endl;
267 of << "bind history\ts\tsearch" << endl;
268 of << "bind history\tn\tsearch_again" << endl;
269 of << "bind history\t<F2>\tshow_urls" << endl;
270 of << "bind history\t<F9>\tfullscreen" << endl << endl;
271 of << "bind editor\t\\cx\tsend_message" << endl;
272 of << "bind editor\t<esc>\tquit" << endl;
273 of << "bind editor\t\\cp\tmultiple_recipients" << endl;
274 of << "bind editor\t\\co\thistory" << endl;
275 of << "bind editor\t\\cn\tnext_chat" << endl;
276 of << "bind editor\t\\cb\tprev_chat" << endl;
277 of << "bind editor\t\\cv\tout_chat" << endl;
278 of << "bind editor\t\\a?\tinfo" << endl;
279 of << "bind editor\t<F2>\tshow_urls" << endl;
280 of << "bind editor\t<F9>\tfullscreen" << endl << endl;
281 of << "bind editor\t<F4>\tchat_panel_move_up" << endl;
282 of << "bind editor\t<F5>\tchat_panel_move_down" << endl;
283 #ifdef HAVE_LIBOTR
284 of << "bind editor\t<F7>\totr_start_session" << endl;
285 of << "bind editor\t<F8>\totr_end_session" << endl;
286 #endif
287 of << "bind info\t<F2>\tshow_urls" << endl;
288 of << "bind info\t<F6>\tuser_external_action" << endl;
290 of.close();
294 f.open(fname.c_str());
296 if(f.is_open()) {
297 while(!f.eof()) {
298 getstring(f, buf);
300 if(buf.empty() || buf[0] == '#') continue;
302 k.ctrl = false;
303 k.alt = false;
305 param = getword(buf); /* first word is always bind */
307 param = getword(buf); /* read section */
308 if(param == "contact")
309 k.section = section_contact; else
310 if(param == "history")
311 k.section = section_history; else
312 if (param == "editor")
313 k.section = section_editor; else
314 if (param == "info")
315 k.section = section_info;
317 param = getword(buf); /* key */
318 if(param == "\\c<space>" || param == "\\C<space>" || param == "^<space>") {
319 k.ctrl = true;
320 k.key = CTRL(' ');
321 } else if(param == "\\a<enter>" || param == "\\A<enter>" || param == "@<enter>") {
322 k.alt = true;
323 k.key = ALT('\r');
324 } else if(param == "\\a<space>" || param == "\\A<space>" || param == "@<space>") {
325 k.ctrl = true;
326 k.key = ALT(' ');
327 } else if(param[0] == '\\') {
328 if(param[1] == 'c' || param[1] == 'C') {
329 k.ctrl = true;
330 k.key = CTRL(param[2]);
331 } else if(param[1] == 'a' || param[1] == 'A') {
332 k.alt = true;
333 k.key = ALT(param[2]);
334 } else if(param[1] == '\\') {
335 k.key = '\\';
336 } else if(param[1] == '@') {
337 k.key = '@';
338 } else if(param[1] == '^') {
339 k.key = '^';
341 } else if(param[0] == '^') {
342 k.ctrl = true;
343 k.key = CTRL(param[1]);
344 } else if(param[0] == '@') {
345 k.alt = true;
346 k.key = ALT(param[1]);
347 } else if(param == "<delete>")
348 k.key = KEY_DC;
349 else if(param == "<enter>")
350 k.key = '\r';
351 else if(param == "<esc>")
352 k.key = 27;
353 else if(param == "<space>")
354 k.key = ' ';
355 else if(param == "<backspace>")
356 k.key = '\b';
357 else if(param == "<pageup>")
358 k.key = 339;
359 else if(param == "<pagedown>")
360 k.key = 338;
361 else if(param == "<tab>")
362 k.key = 9;
363 else if(param == "<insert>")
364 k.key = 331;
365 else if(param[0] == '<' && param[1] == 'F') {
366 k.alt = true;
367 k.ctrl = true;
368 k.key = KEY_F(param[2]-'0');
369 } else
370 k.key = param[0];
372 param = getword(buf); /* action */
373 if(param == "info") k.action = key_info; else
374 if(param == "remove") k.action = key_remove; else
375 if(param == "quit") k.action = key_quit; else
376 if(param == "change_status") k.action = key_change_status; else
377 if(param == "history") k.action = key_history; else
378 if(param == "next_chat") k.action = key_next_chat; else
379 if(param == "prev_chat") k.action = key_prev_chat; else
380 if(param == "out_chat") k.action = key_out_chat; else
381 if(param == "fetch_away_message") k.action = key_fetch_away_message; else
382 if(param == "user_menu") k.action = key_user_menu; else
383 if(param == "general_menu") k.action = key_general_menu; else
384 if(param == "hide_offline") k.action = key_hide_offline; else
385 if(param == "contact_external_action") k.action = key_contact_external_action; else
386 if(param == "add") k.action = key_add; else
387 if(param == "remove") k.action = key_remove; else
388 if(param == "send_message") k.action = key_send_message; else
389 if(param == "send_contact") k.action = key_send_contact; else
390 if(param == "send_url") k.action = key_send_url; else
391 if(param == "rename") k.action = key_rename; else
392 if(param == "version") k.action = key_version; else
393 if(param == "fullscreen") k.action = key_fullscreen; else
394 if(param == "edit") k.action = key_edit; else
395 if(param == "ignore") k.action = key_ignore; else
396 if(param == "quickfind") k.action = key_quickfind; else
397 if(param == "search") k.action = key_search; else
398 if(param == "compose") k.action = key_compose; else
399 if(param == "search_again") k.action = key_search_again; else
400 if(param == "show_urls") k.action = key_show_urls; else
401 if(param == "rss_check") k.action = key_rss_check; else
402 if(param == "multiple_recipients") k.action = key_multiple_recipients; else
403 if(param == "user_external_action") k.action = key_user_external_action; else
404 if(param == "left_panel_move_left") k.action = key_left_panel_move_left; else
405 if(param == "left_panel_move_right") k.action = key_left_panel_move_right; else
406 if(param == "log_panel_move_up") k.action = key_log_panel_move_up; else
407 if(param == "log_panel_move_down") k.action = key_log_panel_move_down; else
408 if(param == "chat_panel_move_up") k.action = key_chat_panel_move_up; else
409 if(param == "chat_panel_move_down") k.action = key_chat_panel_move_down; else
410 #ifdef HAVE_LIBOTR
411 if(param == "otr_start_session") k.action = key_otr_start_session; else
412 if(param == "otr_end_session") k.action = key_otr_end_session; else
413 #endif
414 continue;
416 keys.push_back(k);
419 f.close();
422 if(face.action2key(key_info, section_contact).empty()) keys.push_back(keybinding()); else
423 if(face.action2key(key_quit, section_contact).empty())
424 if(face.action2key(key_change_status, section_contact).empty())
425 if(face.action2key(key_history, section_contact).empty())
426 if(face.action2key(key_fetch_away_message, section_contact).empty())
427 if(face.action2key(key_user_menu, section_contact).empty())
428 if(face.action2key(key_general_menu, section_contact).empty())
429 if(face.action2key(key_hide_offline, section_contact).empty())
430 if(face.action2key(key_contact_external_action, section_contact).empty())
431 if(face.action2key(key_add, section_contact).empty())
432 if(face.action2key(key_remove, section_contact).empty())
433 if(face.action2key(key_compose, section_contact).empty())
434 if(face.action2key(key_send_contact, section_contact).empty())
435 if(face.action2key(key_rss_check, section_contact).empty())
436 if(face.action2key(key_send_url, section_contact).empty())
437 if(face.action2key(key_rename, section_contact).empty())
438 if(face.action2key(key_version, section_contact).empty())
439 if(face.action2key(key_edit, section_contact).empty())
440 if(face.action2key(key_ignore, section_contact).empty())
441 if(face.action2key(key_quickfind, section_contact).empty())
442 if(face.action2key(key_next_chat, section_contact).empty())
443 if(face.action2key(key_prev_chat, section_contact).empty())
444 if(face.action2key(key_search, section_history).empty())
445 if(face.action2key(key_search_again, section_history).empty())
446 if(face.action2key(key_show_urls, section_history).empty())
447 if(face.action2key(key_fullscreen, section_history).empty())
448 if(face.action2key(key_send_message, section_editor).empty())
449 if(face.action2key(key_quit, section_editor).empty())
450 if(face.action2key(key_multiple_recipients, section_editor).empty())
451 if(face.action2key(key_history, section_editor).empty())
452 if(face.action2key(key_next_chat, section_editor).empty())
453 if(face.action2key(key_prev_chat, section_editor).empty())
454 if(face.action2key(key_out_chat, section_editor).empty())
455 if(face.action2key(key_info, section_editor).empty())
456 if(face.action2key(key_show_urls, section_editor).empty())
457 if(face.action2key(key_fullscreen, section_editor).empty())
458 if(face.action2key(key_show_urls, section_info).empty())
459 if(face.action2key(key_user_external_action, section_info).empty()) {}
463 void icqconf::loadmainconfig() {
464 string fname = getconfigfname("config"), buf, param, rbuf;
465 ifstream f(fname.c_str());
466 imaccount im;
467 protocolname pname;
469 if(f.is_open()) {
470 mailcheck = askaway = false;
471 savepwd = bidi = true;
472 setsmtphost("");
473 setbrowser("");
474 setpeertopeer(0, 65535);
476 while(!f.eof()) {
477 getstring(f, buf);
478 rbuf = buf;
479 param = getword(buf);
481 if(param == "hideoffline") hideoffline = true; else
482 if(param == "emacs") emacs = true; else
483 if(param == "autoaway") autoaway = atol(buf.c_str()); else
484 if(param == "autona") autona = atol(buf.c_str()); else
485 if(param == "antispam") antispam = true; else
486 if(param == "dropauthreq") dropauthreq = true; else
487 if(param == "screenna") screenna = true; else
488 if(param == "screensocketpath") screensocketpath = buf; else
489 if(param == "mailcheck") mailcheck = true; else
490 if(param == "quotemsgs") quote = true; else
491 if(param == "sockshost") setsockshost(buf); else
492 if(param == "socksusername") socksuser = buf; else
493 if(param == "sockspass") sockspass = buf; else
494 if((param == "usegroups") || (param == "group1")) fgroupmode = group1; else
495 if(param == "group2") fgroupmode = group2; else
496 if(param == "protocolormode") cm = icqconf::cmproto; else
497 if(param == "statuscolormode") cm = icqconf::cmstatus; else
498 if(param == "sort_by_status_and_activity") setsortmode(icqconf::sort_by_status_and_activity); else
499 if(param == "sort_by_status_and_name") setsortmode(icqconf::sort_by_status_and_name); else
500 if(param == "sort_by_activity") setsortmode(icqconf::sort_by_activity); else
501 if(param == "sort_by_name") setsortmode(icqconf::sort_by_name); else
502 if(param == "smtp") setsmtphost(buf); else
503 if(param == "browser") setbrowser(browser); else
504 if(param == "http_proxy") sethttpproxyhost(buf); else
505 if(param == "log") makelog = true; else
506 if(param == "proxy_connect") proxyconnect = true; else
507 if(param == "proxy_ssl") proxyssl = true; else
508 if(param == "chatmode") initmultiproto(chatmode, buf, true); else
509 if(param == "entersends") initmultiproto(entersends, buf, true); else
510 if(param == "nonimonline") initmultiproto(nonimonline, buf, false); else
511 if(param == "captcha") usingcaptcha = true; else
512 if(param == "russian" || param == "convert") initmultiproto(cpconvert, buf, false); else
513 if(param == "nobidi") setbidi(false); else
514 if(param == "askaway") askaway = true; else
515 if(param == "askquit") askquit = true; else
516 if(param == "logtimestamps") logtimestamps = true; else
517 if(param == "logonline") logonline = true; else
518 if(param == "fromcharset") fromcharset = buf; else
519 if(param == "tocharset") tocharset = buf; else
520 if(param == "left_panel_width") leftpanelwidth = atol(buf.c_str()); else
521 if(param == "log_panel_height") logpanelheight = atol(buf.c_str()); else
522 if(param == "chat_panel_height") chatpanelheight = atol(buf.c_str()); else
523 if(param == "timestampstothesecond") settimestampstothesecond(true); else
524 if(param == "ptp") {
525 ptpmin = atoi(getword(buf, "-").c_str());
526 ptpmax = atoi(buf.c_str());
527 } else {
528 for(pname = icq; pname != protocolname_size; pname++) {
529 buf = getprotocolname(pname);
530 if(param.substr(0, buf.size()) == buf) {
531 im = getourid(pname);
532 im.read(rbuf);
533 setourid(im);
539 if(fromcharset.empty() && tocharset.empty())
540 for(pname = icq; pname != protocolname_size; pname++) {
541 if(getcpconvert(pname)) {
542 fromcharset = "cp1251";
543 tocharset = "koi8-r";
544 break;
548 setproxy();
549 f.close();
553 void icqconf::save() {
554 string fname = getconfigfname("config"), param;
555 int away, na;
557 if(enoughdiskspace()) {
558 ofstream f(fname.c_str());
560 if(f.is_open()) {
561 if(!getsockshost().empty()) {
562 string user, pass;
563 getsocksuser(user, pass);
564 f << "sockshost\t" << getsockshost() + ":" + i2str(getsocksport()) << endl;
565 f << "socksusername\t" << user << endl;
566 f << "sockspass\t" << pass << endl;
569 getauto(away, na);
571 if(away) f << "autoaway\t" << i2str(away) << endl;
572 if(na) f << "autona\t" << i2str(na) << endl;
573 if(hideoffline) f << "hideoffline" << endl;
574 if(emacs) f << "emacs" << endl;
575 if(getquote()) f << "quotemsgs" << endl;
576 if(getantispam()) f << "antispam" << endl;
577 if(getdropauthreq()) f << "dropauthreq" << endl;
578 if(getusingcaptcha()) f << "captcha" << endl;
579 if(getmailcheck()) f << "mailcheck" << endl;
580 if(getaskaway()) f << "askaway" << endl;
581 if(getscreenna()) f << "screenna" << endl;
582 if(!screensocketpath.empty()) f << "screensocketpath\t" << screensocketpath << endl;
584 param = "";
585 for(protocolname pname = icq; pname != protocolname_size; pname++)
586 if(getchatmode(pname)) param += (string) " " + conf.getprotocolname(pname);
587 if(!param.empty())
588 f << "chatmode" << param << endl;
590 param = "";
591 for(protocolname pname = icq; pname != protocolname_size; pname++)
592 if(getentersends(pname)) param += (string) " " + conf.getprotocolname(pname);
593 if(!param.empty())
594 f << "entersends" << param << endl;
596 param = "";
597 for(protocolname pname = icq; pname != protocolname_size; pname++)
598 if(getnonimonline(pname)) param += (string) " " + conf.getprotocolname(pname);
599 if(!param.empty())
600 f << "nonimonline" << param << endl;
602 param = "";
603 for(protocolname pname = icq; pname != protocolname_size; pname++)
604 if(getcpconvert(pname)) param += (string) " " + conf.getprotocolname(pname);
605 if(!param.empty())
606 f << "convert" << param << endl;
608 param = "";
610 f << "fromcharset\t" << fromcharset << endl;
611 f << "tocharset\t" << tocharset << endl;
613 if(!getbidi()) f << "nobidi" << endl;
614 if(getaskquit()) f << "askquit" << endl;
615 if(logtimestamps) f << "logtimestamps" << endl;
616 if(timestampstothesecond) f << "timestampstothesecond" << endl;
617 if(logonline) f << "logonline" << endl;
619 f << "smtp\t" << getsmtphost() << ":" << getsmtpport() << endl;
620 f << "browser\t" << getbrowser() << endl;
622 if(!gethttpproxyhost().empty())
623 if (!gethttpproxyuser().empty())
624 f << "http_proxy\t" << gethttpproxyuser() << ":" << gethttpproxypasswd() << "@" << gethttpproxyhost() << ":" << gethttpproxyport() << endl;
625 else
626 f << "http_proxy\t" << gethttpproxyhost() << ":" << gethttpproxyport() << endl;
628 f << "ptp\t" << ptpmin << "-" << ptpmax << endl;
630 switch(getgroupmode()) {
631 case group1: f << "group1" << endl; break;
632 case group2: f << "group2" << endl; break;
635 switch(getcolormode()) {
636 case cmproto:
637 f << "protocolormode" << endl;
638 break;
639 case cmstatus:
640 f << "statuscolormode" << endl;
641 break;
644 switch(getsortmode()) {
645 case sort_by_status_and_activity: f << "sort_by_status_and_activity" << endl; break;
646 case sort_by_status_and_name: f << "sort_by_status_and_name" << endl; break;
647 case sort_by_activity: f << "sort_by_activity" << endl; break;
648 case sort_by_name: f << "sort_by_name" << endl; break;
651 if(getmakelog()) f << "log" << endl;
652 if(getproxyconnect()) f << "proxy_connect" << endl;
653 if(getproxyssl()) f << "proxy_ssl" << endl;
655 if(getleftpanelwidth()) f << "left_panel_width\t" << getleftpanelwidth() << endl;
656 if(getlogpanelheight()) f << "log_panel_height\t" << getlogpanelheight() << endl;
657 if(getchatpanelheight()) f << "chat_panel_height\t" << getchatpanelheight() << endl;
659 vector<imaccount>::iterator ia;
660 for(ia = accounts.begin(); ia != accounts.end(); ++ia)
661 ia->write(f);
663 f.close();
668 void icqconf::loadcolors() {
669 string tname = getconfigfname("colorscheme");
671 switch(conf.getregcolor()) {
672 case rcdark:
673 schemer.push(cp_status, "status black/white");
674 schemer.push(cp_dialog_text, "dialog_text black/white");
675 schemer.push(cp_dialog_menu, "dialog_menu black/white");
676 schemer.push(cp_dialog_selected, "dialog_selected white/transparent bold");
677 schemer.push(cp_dialog_highlight, "dialog_highlight red/white");
678 schemer.push(cp_dialog_frame, "dialog_frame blue/white");
679 schemer.push(cp_main_text, "main_text cyan/transparent");
680 schemer.push(cp_main_menu, "main_menu green/transparent");
681 schemer.push(cp_main_selected, "main_selected black/white");
682 schemer.push(cp_main_highlight, "main_highlight yellow/transparent bold");
683 schemer.push(cp_main_frame, "main_frame blue/transparent bold");
684 schemer.push(cp_main_history_incoming, "main_history_incoming yellow/transparent bold");
685 schemer.push(cp_main_history_outgoing, "main_history_outgoing cyan/transparent");
686 schemer.push(cp_clist_icq, "clist_icq green/transparent");
687 schemer.push(cp_clist_yahoo, "clist_yahoo magenta/transparent");
688 schemer.push(cp_clist_infocard, "clist_infocard white/transparent");
689 schemer.push(cp_clist_msn, "clist_msn cyan/transparent");
690 schemer.push(cp_clist_aim, "clist_aim yellow/transparent");
691 schemer.push(cp_clist_irc, "clist_irc blue/transparent");
692 schemer.push(cp_clist_jabber, "clist_jabber red/transparent");
693 schemer.push(cp_clist_rss, "clist_rss white/transparent bold");
694 schemer.push(cp_clist_lj, "clist_lj cyan/transparent bold");
695 schemer.push(cp_clist_gadu, "clist_gg blue/transparent bold");
696 schemer.push(cp_clist_online, "clist_online green/transparent bold");
697 schemer.push(cp_clist_offline, "clist_offline red/transparent bold");
698 schemer.push(cp_clist_away, "clist_away yellow/transparent bold");
699 schemer.push(cp_clist_dnd, "clist_dnd cyan/transparent bold");
700 schemer.push(cp_clist_na, "clist_na blue/transparent bold");
701 schemer.push(cp_clist_free_for_chat, "clist_free_for_chat green/transparent bold");
702 schemer.push(cp_clist_invisible, "clist_invisible grey/transparent bold");
703 schemer.push(cp_clist_not_in_list, "clist_not_in_list white/transparent bold");
704 break;
706 case rcblue:
707 schemer.push(cp_status, "status black/white");
708 schemer.push(cp_dialog_text, "dialog_text black/cyan");
709 schemer.push(cp_dialog_menu, "dialog_menu black/cyan");
710 schemer.push(cp_dialog_selected, "dialog_selected white/black bold");
711 schemer.push(cp_dialog_highlight, "dialog_highlight white/cyan bold");
712 schemer.push(cp_dialog_frame, "dialog_frame black/cyan");
713 schemer.push(cp_main_text, "main_text white/blue");
714 schemer.push(cp_main_menu, "main_menu white/blue");
715 schemer.push(cp_main_selected, "main_selected black/cyan");
716 schemer.push(cp_main_highlight, "main_highlight white/blue bold");
717 schemer.push(cp_main_frame, "main_frame blue/blue bold");
718 schemer.push(cp_main_history_incoming, "main_history_incoming white/blue");
719 schemer.push(cp_main_history_outgoing, "main_history_outgoing white/blue bold");
720 schemer.push(cp_clist_icq, "clist_icq green/blue");
721 schemer.push(cp_clist_yahoo, "clist_yahoo magenta/blue");
722 schemer.push(cp_clist_msn, "clist_msn cyan/blue");
723 schemer.push(cp_clist_infocard, "clist_infocard white/blue");
724 schemer.push(cp_clist_aim, "clist_aim yellow/blue");
725 schemer.push(cp_clist_irc, "clist_irc blue/blue bold");
726 schemer.push(cp_clist_jabber, "clist_jabber red/blue");
727 schemer.push(cp_clist_rss, "clist_rss white/blue bold");
728 schemer.push(cp_clist_lj, "clist_lj cyan/blue bold");
729 schemer.push(cp_clist_gadu, "clist_gg blue/blue bold");
730 schemer.push(cp_clist_online, "clist_online green/transparent bold");
731 schemer.push(cp_clist_offline, "clist_offline red/transparent bold");
732 schemer.push(cp_clist_away, "clist_away yellow/transparent bold");
733 schemer.push(cp_clist_dnd, "clist_dnd cyan/transparent bold");
734 schemer.push(cp_clist_na, "clist_na blue/transparent bold");
735 schemer.push(cp_clist_free_for_chat, "clist_free_for_chat green/transparent bold");
736 schemer.push(cp_clist_invisible, "clist_invisible grey/transparent bold");
737 schemer.push(cp_clist_not_in_list, "clist_not_in_list white/transparent bold");
738 break;
741 if(access(tname.c_str(), F_OK)) {
742 schemer.save(tname);
743 } else {
744 schemer.load(tname);
748 void icqconf::loadsounds() {
749 string tname = getconfigfname("sounds"), buf, suin, skey;
750 int i;
751 icqcontact *c;
752 imevent::imeventtype it;
754 typedef pair<imevent::imeventtype, string> eventsound;
755 vector<eventsound> soundnames;
756 vector<eventsound>::iterator isn;
758 soundnames.push_back(eventsound(imevent::message, "msg"));
759 soundnames.push_back(eventsound(imevent::sms, "sms"));
760 soundnames.push_back(eventsound(imevent::url, "url"));
761 soundnames.push_back(eventsound(imevent::online, "online"));
762 soundnames.push_back(eventsound(imevent::offline, "offline"));
763 soundnames.push_back(eventsound(imevent::email, "email"));
765 for(i = 0; i < clist.count; i++) {
766 c = (icqcontact *) clist.at(i);
768 for(it = imevent::message; it != imevent::imeventtype_size; it++) {
769 c->setsound(it, "");
773 if(access(tname.c_str(), F_OK)) {
774 ofstream fo(tname.c_str());
776 if(fo.is_open()) {
777 fo << "# This file contains sound configuration for centerim" << endl;
778 fo << "# Every line should look like: <id> <event> <command>" << endl << "#" << endl;
780 fo << "# <id>\tid of a contact; can be one of the following" << endl;
781 fo << "# *\tmeans default sound for all the contacts" << endl;
782 fo << "# icq_<uin>\tfor icq contacts (e.g. icq_123)" << endl;
783 fo << "# yahoo_<nickname>\tfor yahoo (e.g. yahoo_thekonst)" << endl;
784 fo << "# .. etc. Similar for the other protocols" << endl << "#" << endl;
786 fo << "# <event>\tcan be: ";
787 for(isn = soundnames.begin(); isn != soundnames.end(); ++isn) {
788 if(isn != soundnames.begin()) fo << ", ";
789 fo << isn->second;
792 fo << endl << "# <command>\tcommand line to be executed to play a sound" << endl << endl;
794 switch(rs) {
795 case rscard:
796 fo << "*\tmsg\tplay " << SHARE_DIR << "/msg.wav" << endl;
797 fo << "*\turl\tplay " << SHARE_DIR << "/url.wav" << endl;
798 fo << "*\temail\tplay " << SHARE_DIR << "/email.wav" << endl;
799 fo << "*\tonline\tplay " << SHARE_DIR << "/online.wav" << endl;
800 fo << "*\toffline\tplay " << SHARE_DIR << "/offline.wav" << endl;
801 fo << "*\tsms\tplay " << SHARE_DIR << "/sms.wav" << endl;
802 break;
804 case rsspeaker:
805 fo << "*\tmsg\t!spk1" << endl;
806 fo << "*\turl\t!spk2" << endl;
807 fo << "*\tsms\t!spk3" << endl;
808 fo << "*\temail\t!spk5" << endl;
809 break;
812 fo.close();
816 ifstream fi(tname.c_str());
817 if(fi.is_open()) {
818 while(!fi.eof()) {
819 getstring(fi, buf);
820 if(buf.empty() || (buf.substr(0, 1) == "#")) continue;
822 suin = getword(buf);
823 skey = getword(buf);
825 it = imevent::imeventtype_size;
827 for(isn = soundnames.begin(); isn != soundnames.end(); ++isn) {
828 if(skey == isn->second) {
829 it = isn->first;
830 break;
834 if(it == imevent::imeventtype_size)
835 continue;
837 c = 0;
839 if(suin != "*") {
840 if((i = suin.find("_")) != -1) {
841 skey = suin.substr(0, i);
842 suin.erase(0, i+1);
844 imcontact ic;
845 protocolname pname;
847 for(pname = icq; pname != protocolname_size && skey != getprotocolname(pname); pname++);
849 if(pname != protocolname_size) {
850 if(suin == "*") {
851 for(i = 0; i < clist.count; i++) {
852 c = (icqcontact *) clist.at(i);
854 if(c->getdesc().pname == pname) c->setsound(it, buf);
856 } else {
857 if(pname == icq) ic = imcontact(strtoul(suin.c_str(), 0, 0), pname);
858 else ic = imcontact(suin, pname);
860 c = clist.get(ic);
864 } else {
865 c = clist.get(contactroot);
868 if(c) c->setsound(it, buf);
871 fi.close();
875 void icqconf::loadactions() {
876 string fname = getconfigfname("actions"), buf, name;
877 ifstream f;
878 bool cont;
880 if(access(fname.c_str(), F_OK)) {
881 buf = getenv("PATH") ? getenv("PATH") : "";
883 ofstream of(fname.c_str());
885 if(of.is_open()) {
886 of << "# This file contains external actions configuration for centerim" << endl;
887 of << "# Every line should look like: <action> <command>" << endl;
888 of << "# Possible actions are: openurl, detectmusic" << endl << endl;
890 of << "openurl \\" << endl;
891 of << " (if test ! -z \"`ps x | grep /" << browser << " | grep -v grep`\"; \\" << endl;
892 of << "\tthen DISPLAY=0:0 " << browser << " -remote 'openURL($url$, new-window)'; \\" << endl;
893 of << "\telse DISPLAY=0:0 " << browser << " \"$url$\"; \\" << endl;
894 of << " fi) >/dev/null 2>&1 &" << endl;
896 of << "detectmusic \\" << endl;
897 of << " if test ! -z \"`ps x | grep orpheus | grep -v grep`\"; \\" << endl;
898 of << "\tthen cat ~/.orpheus/currently_playing; \\" << endl;
899 of << " fi" << endl;
901 of.close();
905 f.open(fname.c_str());
907 if(f.is_open()) {
908 actions.clear();
909 cont = false;
911 while(!f.eof()) {
912 getstring(f, buf);
913 if(!cont) name = getword(buf);
915 if(name == "openurl" || name == "detectmusic") {
916 if(!buf.empty())
917 if(cont = buf.substr(buf.size()-1, 1) == "\\")
918 buf.erase(buf.size()-1, 1);
920 actions[name] += buf;
924 f.close();
928 void icqconf::loadcaptcha() {
929 string fname = getconfigfname("captcha"), buf, entry;
930 ifstream f;
931 vector<string>::const_iterator ic;
933 if(access(fname.c_str(), F_OK)) {
935 ofstream of(fname.c_str());
937 if(of.is_open()) {
938 of << "# This file contains sample configuration for captcha engine." << endl;
939 of << "# Every line should look like: <param> <value>" << endl;
940 of << "# Possible params are: greeting, quest, success, failure, timeout (min)" << endl;
941 of << "# Quest fomat is: quest <question>//<answer>[::answer[...]]" << endl;
942 of << endl;
943 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;
944 of << endl;
945 of << "quest How many legs does a dog have?//4::four" << endl;
946 of << "quest What is the first word of this sentence?//what" << endl;
947 of << "quest What is the sum of 1 and 1?//2::two" << endl;
948 of << "quest What is not a fruit: lettuce, apple or banana?//lettuce" << endl;
949 of << "quest How many fingers are there on one hand?//5::five" << endl;
950 of << "quest How many wheels does a normal bicycle have?//2::two" << endl;
951 of << "quest What colour does a banana have?//yellow::yelow" << endl;
952 of << "quest What does a chicken lay?//eggs::egg" << endl;
953 of << "quest What is the value of PI, accurate to 2 digits?//3.14::3,14" << endl;
954 of << "quest Is a wheel round or not (yes or no)?//yes" << endl;
955 of << endl;
956 of << "success You answered the question correctly, you are now added to my contact list. Thank you for your patience." << endl;
957 of << "failure You answered the question incorrectly, you can try again by answering the next question." << endl;
958 of << "timeout 30" << endl;
959 of.close();
963 f.open(fname.c_str());
965 if(f.is_open()) {
966 while(!f.eof()) {
967 getstring(f, buf);
968 entry = getword(buf);
970 if(entry == "greeting") captchagreet = buf; else
971 if(entry == "success") captchasuccess = buf; else
972 if(entry == "failure") captchafailure = buf; else
973 if(entry == "timeout") captchatimeout = atol(buf.c_str()); else
974 if(entry == "quest") thecaptcha.addquestion(buf);
976 if(thecaptcha.empty()) {
977 usingcaptcha = false;
978 face.log(_("+ ERROR: captcha disabled: no questions found!"));
981 f.close();
985 icqconf::regcolor icqconf::getregcolor() const {
986 return rc;
989 void icqconf::setregcolor(icqconf::regcolor c) {
990 rc = c;
993 icqconf::regsound icqconf::getregsound() const {
994 return rs;
997 void icqconf::setregsound(icqconf::regsound s) {
998 rs = s;
1001 icqconf::colormode icqconf::getcolormode() const {
1002 return cm;
1005 void icqconf::setcolormode(colormode c) {
1006 cm = c;
1009 void icqconf::setauto(int away, int na) {
1010 autoaway = away;
1011 autona = na;
1013 if(away == na)
1014 autoaway = 0;
1017 void icqconf::getauto(int &away, int &na) const {
1018 away = autoaway;
1019 na = autona;
1021 if(away == na)
1022 away = 0;
1025 bool icqconf::getscreenna() const {
1026 return screenna;
1029 void icqconf::setscreenna(bool sna) {
1030 screenna = sna;
1033 string icqconf::getscreensocketpath() const {
1034 return screensocketpath;
1037 void icqconf::setscreensocketpath(string path) {
1038 screensocketpath = path;
1041 void icqconf::setquote(bool use) {
1042 quote = use;
1044 void icqconf::setaskquit(bool faskquit) {
1045 askquit = faskquit;
1048 void icqconf::setsockshost(const string &nsockshost) {
1049 int pos;
1051 if(!nsockshost.empty()) {
1052 if((pos = nsockshost.find(":")) != -1) {
1053 sockshost = nsockshost.substr(0, pos);
1054 socksport = atol(nsockshost.substr(pos+1).c_str());
1055 } else {
1056 sockshost = nsockshost;
1057 socksport = 1080;
1059 } else {
1060 sockshost = "";
1064 string icqconf::getsockshost() const {
1065 return sockshost;
1068 unsigned int icqconf::getsocksport() const {
1069 return socksport;
1072 void icqconf::getsocksuser(string &name, string &pass) const {
1073 name = socksuser;
1074 pass = sockspass;
1077 void icqconf::setsocksuser(const string &name, const string &pass) {
1078 socksuser = name;
1079 sockspass = pass;
1082 void icqconf::setsavepwd(bool ssave) {
1083 savepwd = ssave;
1086 void icqconf::sethideoffline(bool fho) {
1087 hideoffline = fho;
1090 void icqconf::settimestampstothesecond(bool ttts) {
1091 timestampstothesecond = ttts;
1092 if (timestampstothesecond) {
1093 timestampformat = SECONDS_TIMESTAMP_FORMAT;
1094 logtimestampformat = SECONDS_LOGTIMESTAMP_FORMAT;
1095 } else {
1096 timestampformat = DEFAULT_TIMESTAMP_FORMAT;
1097 logtimestampformat = DEFAULT_LOGTIMESTAMP_FORMAT;
1101 void icqconf::setemacs(bool fem) {
1102 emacs = fem;
1105 void icqconf::setantispam(bool fas) {
1106 antispam = fas;
1109 void icqconf::setdropauthreq(bool fas) {
1110 dropauthreq = fas;
1113 void icqconf::setusingcaptcha(bool fas) {
1114 usingcaptcha = fas;
1117 void icqconf::setmailcheck(bool fmc) {
1118 mailcheck = fmc;
1121 void icqconf::setaskaway(bool faskaway) {
1122 askaway = faskaway;
1125 bool icqconf::getchatmode(protocolname pname) {
1126 switch(pname) {
1127 case infocard:
1128 case rss:
1129 return false;
1132 return chatmode[pname];
1135 void icqconf::setchatmode(protocolname pname, bool fchatmode) {
1136 chatmode[pname] = fchatmode;
1139 bool icqconf::getentersends(protocolname pname) {
1140 return entersends[pname];
1143 void icqconf::setentersends(protocolname pname, bool fentersends) {
1144 entersends[pname] = fentersends;
1147 bool icqconf::getnonimonline(protocolname pname) {
1148 return nonimonline[pname];
1151 void icqconf::setnonimonline(protocolname pname, bool fnonimonline) {
1152 nonimonline[pname] = fnonimonline;
1155 bool icqconf::getcpconvert(protocolname pname) const {
1156 return cpconvert[pname];
1159 void icqconf::setcpconvert(protocolname pname, bool fcpconvert) {
1160 cpconvert[pname] = fcpconvert;
1163 string icqconf::execaction(const string &name, const string &param) {
1164 int inpipe[2], outpipe[2], pid, npos;
1165 struct sigaction sact, osact;
1166 string torun = actions[name], out;
1167 fd_set rfds;
1168 char ch;
1170 if(name == "openurl")
1171 while((npos = torun.find("$url$")) != -1)
1172 torun.replace(npos, 5, param);
1174 if(!pipe(inpipe) && !pipe(outpipe)) {
1175 memset(&sact, 0, sizeof(sact));
1176 sigaction(SIGCHLD, &sact, &osact);
1177 pid = fork();
1179 if(!pid) {
1180 dup2(inpipe[1], STDOUT_FILENO);
1181 dup2(outpipe[0], STDIN_FILENO);
1183 close(inpipe[1]);
1184 close(inpipe[0]);
1185 close(outpipe[0]);
1186 close(outpipe[1]);
1188 execl("/bin/sh", "/bin/sh", "-c", torun.c_str(), (char *)NULL );
1189 _exit(0);
1190 } else {
1191 close(outpipe[0]);
1192 close(inpipe[1]);
1194 while(1) {
1195 FD_ZERO(&rfds);
1196 FD_SET(inpipe[0], &rfds);
1198 if(select(inpipe[0]+1, &rfds, 0, 0, 0) < 0) break; else {
1199 if(FD_ISSET(inpipe[0], &rfds)) {
1200 if(read(inpipe[0], &ch, 1) != 1) break; else {
1201 out += ch;
1207 waitpid(pid, 0, 0);
1208 close(inpipe[0]);
1209 close(outpipe[1]);
1212 sigaction(SIGCHLD, &osact, 0);
1215 face.log(_("+ launched the %s action command"), name.c_str());
1216 return out;
1219 string icqconf::getprotocolname(protocolname pname) const {
1220 static const string ptextnames[protocolname_size] = {
1221 "icq", "yahoo", "msn", "aim", "irc", "jab", "rss", "lj", "gg", "infocard"
1224 return ptextnames[pname];
1227 protocolname icqconf::getprotocolbyletter(char letter) const {
1228 switch(letter) {
1229 case 'y': return yahoo;
1230 case 'a': return aim;
1231 case 'i': return irc;
1232 case 'm': return msn;
1233 case 'n': return infocard;
1234 case 'j': return jabber;
1235 case 'r': return rss;
1236 case 'l': return livejournal;
1237 case 'g': return gadu;
1238 case '0':
1239 case '1':
1240 case '2':
1241 case '3':
1242 case '4':
1243 case '5':
1244 case '6':
1245 case '7':
1246 case '8':
1247 case '9': return icq;
1250 return protocolname_size;
1253 string icqconf::getprotocolprefix(protocolname pname) const {
1254 static const string pprefixes[protocolname_size] = {
1255 "", "y", "m", "a", "i", "j", "r", "l", "g", "n"
1258 return pprefixes[pname];
1261 imstatus icqconf::getstatus(protocolname pname) {
1262 if(startoffline)
1263 return offline;
1265 imstatus st = available;
1266 map<string, string>::iterator ia;
1267 imaccount a = getourid(pname);
1269 if((ia = a.additional.find("status")) != a.additional.end()) {
1270 if(!ia->second.empty()) {
1271 for(st = offline; st != imstatus_size && imstatus2char[st] != ia->second[0]; st++);
1272 if(st == imstatus_size) st = available;
1276 return st;
1279 void icqconf::savestatus(protocolname pname, imstatus st) {
1280 imaccount im = getourid(pname);
1281 im.additional["status"] = string(1, imstatus2char[st]);
1282 setourid(im);
1285 int icqconf::getprotcolor(protocolname pname) const {
1286 switch(pname) {
1287 case icq : return getcolor(cp_clist_icq);
1288 case yahoo : return getcolor(cp_clist_yahoo);
1289 case infocard : return getcolor(cp_clist_infocard);
1290 case msn : return getcolor(cp_clist_msn);
1291 case aim : return getcolor(cp_clist_aim);
1292 case irc : return getcolor(cp_clist_irc);
1293 case jabber : return getcolor(cp_clist_jabber);
1294 case rss : return getcolor(cp_clist_rss);
1295 case livejournal : return getcolor(cp_clist_lj);
1296 case gadu : return getcolor(cp_clist_gadu);
1297 default : return getcolor(cp_main_text);
1301 int icqconf::getstatuscolor(imstatus status) const {
1302 switch(status) {
1303 case offline : return getcolor(cp_clist_offline);
1304 case available : return getcolor(cp_clist_online);
1305 case invisible : return getcolor(cp_clist_invisible);
1306 case freeforchat : return getcolor(cp_clist_free_for_chat);
1307 case dontdisturb : return getcolor(cp_clist_dnd);
1308 case occupied : return getcolor(cp_clist_occupied);
1309 case notavail : return getcolor(cp_clist_na);
1310 case outforlunch : return getcolor(cp_clist_na);
1311 case away : return getcolor(cp_clist_away);
1312 default : return getcolor(cp_main_text);
1316 void icqconf::setbidi(bool fbidi) {
1317 bidi = fbidi;
1318 #ifdef USE_FRIBIDI
1319 use_fribidi = bidi;
1320 #endif
1323 void icqconf::commandline(int argc, char **argv) {
1324 int i;
1325 string event, proto, dest, number;
1326 char st = 0;
1328 argv0 = argv[0];
1330 for(i = 1; i < argc; i++) {
1331 string args = argv[i];
1333 if((args == "-a") || (args == "--ascii")) {
1334 kintf_graph = 0;
1336 } else if((args == "-b") || (args == "--basedir")) {
1337 if(argv[++i]) {
1338 basedir = argv[i];
1339 if(basedir.substr(basedir.size()-1) != "/") basedir += "/";
1342 } else if((args == "-B") || (args == "--bind")) {
1343 if(argv[++i]) {
1344 bindhost = argv[i];
1345 cw_setbind(bindhost.c_str());
1348 } else if((args == "-T") || (args == "--no-xtitles")) {
1349 notitles = true;
1351 } else if((args == "-o") || (args == "--offline")) {
1352 startoffline = true;
1354 } else if((args == "-s") || (args == "--send")) {
1355 if(argv[++i]) event = argv[i];
1357 } else if((args == "-p") || (args == "--proto")) {
1358 if(argv[++i]) proto = argv[i];
1360 } else if((args == "-t") || (args == "--to")) {
1361 if(argv[++i]) dest = argv[i];
1363 } else if((args == "-n") || (args == "--number")) {
1364 if(argv[++i]) number = argv[i];
1366 } else if((args == "-S") || (args == "--status")) {
1367 if(argv[++i])
1368 if(strlen(argv[i]))
1369 st = argv[i][0];
1371 } else if((args == "-d") || (args == "--debug")) {
1372 debug = true;
1374 } else if((args == "-v") || (args == "--version")) {
1375 cout << PACKAGE << " " << centerim::version << endl
1376 << "Written by Konstantin Klyagin, 2005. Currently maintained by the CenterIM community." << endl
1377 << "Built-in protocols are:";
1379 for(protocolname pname = icq; pname != protocolname_size; pname++)
1380 if(gethook(pname).enabled()) cout << " " << conf.getprotocolname(pname);
1382 cout << endl << endl
1383 << "This is free software; see the source for copying conditions. There is NO" << endl
1384 << "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." << endl;
1386 exit(0);
1388 } else {
1389 usage();
1390 exit(0);
1394 if(!number.empty()) {
1395 if(event.empty()) event = "sms";
1396 if(proto.empty()) proto = "icq";
1397 dest = "0";
1400 constructevent(event, proto, dest, number);
1401 externalstatuschange(st, proto);
1404 void icqconf::constructevent(const string &event, const string &proto,
1405 const string &dest, const string &number) const {
1407 imevent *ev = 0;
1408 imcontact cdest;
1409 string text, buf;
1410 int pos;
1412 if(event.empty() && dest.empty()) return; else
1413 if(event.empty() || proto.empty() || dest.empty()) {
1414 cout << _("event sending error: not enough parameters") << endl;
1415 exit(1);
1418 while(getline(cin, buf)) {
1419 if(!text.empty()) text += "\n";
1420 text += buf;
1423 if(proto == "icq") {
1424 if(dest.find_first_not_of("0123456789") != -1) {
1425 cout << _("event sending error: only UINs are allowed with icq protocol") << endl;
1426 exit(1);
1428 cdest = imcontact(strtoul(dest.c_str(), 0, 0), icq);
1429 } else {
1430 protocolname pname;
1432 for(pname = icq; pname != protocolname_size; pname++) {
1433 if(getprotocolname(pname) == proto) {
1434 cdest = imcontact(dest, pname);
1435 break;
1439 if(pname == protocolname_size) {
1440 cout << _("event sending error: unknown IM type") << endl;
1441 exit(1);
1445 if(event == "msg") {
1446 ev = new immessage(cdest, imevent::outgoing, text);
1447 } else if(event == "url") {
1448 string url;
1450 if((pos = text.find("\n")) != -1) {
1451 url = text.substr(0, pos);
1452 text.erase(0, pos+1);
1453 } else {
1454 url = text;
1455 text = "";
1458 ev = new imurl(cdest, imevent::outgoing, url, text);
1459 } else if(event == "sms") {
1460 ev = new imsms(cdest, imevent::outgoing, text, number);
1461 } else {
1462 cout << _("event sending error: unknown event type") << endl;
1463 exit(1);
1466 if(ev) {
1467 icqcontact *c = new icqcontact(cdest);
1469 if(access(c->getdirname().c_str(), X_OK)) {
1470 mkdir(c->getdirname().c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
1471 selfsignal(SIGUSR2);
1474 if(!access(c->getdirname().c_str(), X_OK)) {
1475 clist.add(c);
1476 em.store(*ev);
1478 char buf[512];
1479 snprintf(buf, sizeof(buf), _("%s to %s has been put to the queue"),
1480 streventname(ev->gettype()),
1481 number.empty() ? c->getdesc().totext().c_str() : number.c_str());
1483 cout << buf << endl;
1484 } else {
1485 cout << _("event sending error: error creating directory for the contact") << endl;
1486 exit(1);
1489 //delete c;
1490 delete ev;
1492 exit(0);
1496 void icqconf::selfsignal(int signum) const {
1497 int rpid;
1498 ifstream f(conf.getconfigfname("pid").c_str());
1500 if(f.is_open()) {
1501 f >> rpid;
1502 f.close();
1504 if(rpid > 0) {
1505 kill(rpid, signum);
1510 void icqconf::externalstatuschange(char st, const string &proto) const {
1511 imstatus imst;
1512 protocolname pname;
1514 if(st) {
1515 for(pname = icq; pname != protocolname_size; pname++)
1516 if(getprotocolname(pname) == proto)
1517 break;
1519 for(imst = offline; imst != imstatus_size; imst++)
1520 if(imstatus2char[imst] == st)
1521 break;
1523 try {
1524 if(pname != protocolname_size) {
1525 if(imst != imstatus_size) {
1526 string sfname = conf.getconfigfname((string) "status-" + proto);
1527 ofstream sf(sfname.c_str());
1528 if(sf.is_open()) sf << imstatus2char[imst], sf.close();
1530 selfsignal(SIGUSR1);
1531 } else {
1532 throw _("unknown status character was given");
1534 } else {
1535 throw _("unknown IM type");
1537 } catch(char *p) {
1538 cout << _("status change error: ") << p << endl;
1539 exit(1);
1542 exit(0);
1546 void icqconf::usage() const {
1547 cout << PACKAGE << " " << centerim::version << endl;
1549 cout << endl << _("Usage: ") << argv0 << " [OPTION].." << endl;
1551 cout << endl << _("General options:") << endl;
1552 cout << _(" --ascii, -a use ASCII characters for windows and UI controls") << endl;
1553 cout << _(" --basedir, -b <path> set a custom base directory") << endl;
1554 cout << _(" --bind, -B <host/ip> bind a custom local IP") << endl;
1555 cout << _(" --no-xtitles, -T disable xterm titles") << endl;
1556 cout << _(" --offline, -o set all protocols status to offline upon start") << endl;
1557 cout << _(" --debug, -d enables debug info logging") << endl;
1558 cout << _(" --help display this stuff") << endl;
1559 cout << _(" --version, -v show the program version info") << endl;
1561 cout << endl << _("Events sending options:") << endl;
1562 cout << _(" -s, --send <event type> event type; can be msg, sms or url") << endl;
1563 cout << _(" -S, --status <status> change the current IM status. Status; o, _, a, d, n, c, f, i") << endl;
1564 cout << _(" -p, --proto <protocol> protocol type; can be icq, yahoo, msn, aim, irc, jab, rss, lj, gg or infocard") << endl;
1566 cout << _(" -t, --to <destination> destination UIN or nick (depends on protocol)") << endl;
1567 cout << _(" -n, --number <phone#> mobile number to send an event to (sms only)") << endl;
1569 cout << endl << _("Report bugs to http://bugzilla.centerim.org.") << endl;
1572 void icqconf::setproxy() {
1573 if(getproxyconnect()) {
1574 cw_setproxy(gethttpproxyhost().c_str(), gethttpproxyport(),
1575 gethttpproxyuser().c_str(),
1576 gethttpproxypasswd().c_str());
1578 } else {
1579 cw_setproxy(0, 0, 0, 0);
1584 void icqconf::setmakelog(bool slog) {
1585 makelog = slog;
1588 void icqconf::setproxyconnect(bool sproxy) {
1589 proxyconnect = sproxy;
1590 setproxy();
1593 void icqconf::setproxyssl(bool sproxyssl) {
1594 proxyssl = sproxyssl;
1597 void icqconf::setgroupmode(icqconf::groupmode amode) {
1598 fgroupmode = amode;
1601 void icqconf::setsortmode(icqconf::sortmode smode) {
1602 fsortmode = smode;
1603 icqcontacts::setsortmode(smode);
1606 void icqconf::initmultiproto(bool p[], string buf, bool excludenochat) {
1607 string w;
1608 protocolname pname;
1610 for(pname = icq; pname != protocolname_size; pname++)
1611 p[pname] = buf.empty();
1613 while(!(w = getword(buf)).empty()) {
1614 for(pname = icq; pname != protocolname_size; pname++) {
1615 if(getprotocolname(pname) == w) {
1616 if(excludenochat) {
1617 p[pname] = !gethook(pname).getCapabs().count(hookcapab::nochat);
1618 } else {
1619 p[pname] = true;
1621 break;
1627 void icqconf::setbrowser(const string &abrowser) {
1628 if (!abrowser.empty())
1629 browser = abrowser;
1630 else
1631 browser = "mozilla";
1634 void icqconf::setsmtphost(const string &asmtphost) {
1635 int pos;
1637 smtphost = "";
1638 smtpport = 0;
1640 if(!asmtphost.empty()) {
1641 if((pos = asmtphost.find(":")) != -1) {
1642 smtphost = asmtphost.substr(0, pos);
1643 smtpport = atol(asmtphost.substr(pos+1).c_str());
1644 } else {
1645 smtphost = asmtphost;
1646 smtpport = 25;
1650 if(smtphost.empty() || !smtpport) {
1651 smtphost = getsmtphost();
1652 smtpport = getsmtpport();
1656 void icqconf::sethttpproxyhost(const string &ahttpproxyhost) {
1657 int pos, posn;
1659 httpproxyhost = "";
1660 httpproxyport = 0;
1661 httpproxyuser = "";
1662 httpproxypasswd = "";
1664 if(!ahttpproxyhost.empty()) {
1665 if((pos = ahttpproxyhost.find(":")) != -1) {
1666 if ((posn = ahttpproxyhost.find("@")) != -1) {
1667 httpproxyuser = ahttpproxyhost.substr(0, pos);
1668 httpproxypasswd = ahttpproxyhost.substr(pos+1, posn-pos-1);
1669 if((pos = ahttpproxyhost.find(":", posn)) != -1) {
1670 httpproxyhost = ahttpproxyhost.substr(posn+1, pos-posn-1);
1671 httpproxyport = atol(ahttpproxyhost.substr(pos+1).c_str());
1673 } else {
1674 httpproxyhost = ahttpproxyhost.substr(0, pos);
1675 httpproxyport = atol(ahttpproxyhost.substr(pos+1).c_str());
1677 } else {
1678 httpproxyhost = ahttpproxyhost;
1679 httpproxyport = 8080;
1683 setproxy();
1686 string icqconf::getbrowser() const {
1687 return browser.empty() ? "mozilla" : browser;
1690 string icqconf::getsmtphost() const {
1691 return smtphost.empty() ? "localhost" : smtphost;
1694 unsigned int icqconf::getsmtpport() const {
1695 return smtpport ? smtpport : 25;
1698 string icqconf::gethttpproxyhost() const {
1699 return httpproxyhost;
1702 unsigned int icqconf::gethttpproxyport() const {
1703 return httpproxyport ? httpproxyport : 8080;
1706 string icqconf::gethttpproxyuser() const {
1707 return httpproxyuser;
1710 string icqconf::gethttpproxypasswd() const {
1711 return httpproxypasswd;
1714 void icqconf::checkdiskspace() {
1715 fenoughdiskspace = true;
1717 #ifndef __sun__
1718 struct statfs st;
1719 if(!statfs(conf.getdirname().c_str(), &st)) {
1720 #else
1721 struct statvfs st;
1722 if(!statvfs(conf.getdirname().c_str(), &st)) {
1723 #endif
1724 fenoughdiskspace = ((double) st.f_bavail) * st.f_bsize >= 10240;
1728 void icqconf::setcharsets(const string &from, const string &to) {
1729 fromcharset = from;
1730 tocharset = to;
1733 const char *icqconf::getconvertfrom(protocolname pname) const {
1734 if(pname != protocolname_size && !getcpconvert(pname)) return "iso-8859-1";
1735 return fromcharset.c_str();
1738 const char *icqconf::getconvertto(protocolname pname) const {
1739 if(pname != protocolname_size && !getcpconvert(pname)) return "iso-8859-1";
1740 return tocharset.c_str();
1743 // ----------------------------------------------------------------------------
1745 icqconf::imaccount::imaccount() {
1746 uin = port = 0;
1747 pname = infocard;
1750 icqconf::imaccount::imaccount(protocolname apname) {
1751 uin = port = 0;
1752 pname = apname;
1755 bool icqconf::imaccount::empty() const {
1756 return !uin && nickname.empty();
1759 void icqconf::imaccount::write(ofstream &f) {
1760 string prefix = conf.getprotocolname(pname) + "_";
1761 map<string, string>::iterator ia;
1763 f << endl;
1764 if(!nickname.empty()) f << prefix << "nick\t" << nickname << endl;
1765 if(uin) f << prefix << "uin\t" << uin << endl;
1766 if(conf.getsavepwd()) f << prefix << "pass\t" << password << endl;
1767 if(!server.empty()) {
1768 f << prefix << "server\t" << server;
1769 if(port) f << ":" << port;
1770 f << endl;
1773 for(ia = additional.begin(); ia != additional.end(); ++ia)
1774 if(!ia->first.empty() && !ia->second.empty())
1775 f << prefix << ia->first << "\t" << ia->second << endl;
1778 void icqconf::imaccount::read(const string &spec) {
1779 int pos = spec.find("_");
1780 string spname, buf;
1782 if(pos != -1) {
1783 buf = spec;
1784 spname = getword(buf.erase(0, pos+1));
1786 if(spname == "nick") nickname = buf; else
1787 if(spname == "uin") uin = strtoul(buf.c_str(), 0, 0); else
1788 if(spname == "pass") password = buf; else
1789 if(spname == "server") {
1790 if((pos = buf.find(":")) != -1) {
1791 server = buf.substr(0, pos);
1792 port = strtoul(buf.substr(pos+1).c_str(), 0, 0);
1793 } else {
1794 server = buf;
1797 if(pname == icq)
1798 if(server == "icq.mirabilis.com")
1799 server = "";
1801 if(pname == yahoo)
1802 if(server == "scs.yahoo.com")
1803 server = "";
1805 } else {
1806 additional[spname] = buf;
1811 bool icqconf::imaccount::operator == (protocolname apname) const {
1812 return pname == apname;
1815 bool icqconf::imaccount::operator != (protocolname apname) const {
1816 return pname != apname;