1 /*
2 *
3 * centerim configuration handling routines
4 * $Id: icqconf.cc,v 1.143 2005/09/02 15:20:59 konst Exp $
5 *
6 * Copyright (C) 2001-2004 by Konstantin Klyagin <k@thekonst.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 *
23 */
24
25 #include <sys/types.h>
26 #include <sys/wait.h>
27 #include <dirent.h>
28 #include <fstream>
29
30
31 #if defined(__sun__) || defined(__NetBSD__) || defined(__sgi__)
32 #include <sys/statvfs.h>
33 #endif
34
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"
44
45 icqconf* icqconf::self=NULL;
46
instance()47 icqconf* icqconf::instance()
48 {
49 if(!self){
50 self=new icqconf();
51 }
52
53 return self;
54 }
55
icqconf()56 icqconf::icqconf() : showopenedchats(false), quote(false), dropauthreq(false),
57 usingcaptcha(false), screenna(false), askquit(false), bidi(false)
58 {
59 DEFAULT_TIMESTAMP_FORMAT = "DD.MM.YY hh:mm";
60 DEFAULT_LOGTIMESTAMP_FORMAT = "%R ";
61 SECONDS_TIMESTAMP_FORMAT = "DD.MM.YY hh:mm:ss";
62 SECONDS_LOGTIMESTAMP_FORMAT = "%T ";
63
64 rs = rscard;
65 rc = rcdark;
66 cm = cmproto;
67 fgroupmode = nogroups;
68 fsortmode = sort_by_status_and_activity;
69
70 autoaway = autona = 0;
71
72 hideoffline = antispam = makelog = askaway = logtimestamps =
73 logonline = emacs = proxyssl = proxyconnect = notitles =
74 debug = timestampstothesecond = vi = autoawayx = false;
75
76 timestampformat = DEFAULT_TIMESTAMP_FORMAT;
77 logtimestampformat = DEFAULT_LOGTIMESTAMP_FORMAT;
78
79 startoffline = false;
80
81 savepwd = mailcheck = fenoughdiskspace = true;
82
83 for(protocolname pname = icq; pname != protocolname_size; pname++) {
84 chatmode[pname] = true;
85 cpconvert[pname] = entersends[pname] = nonimonline[pname] = false;
86 }
87
88 // quick and dirty fix to support .centerim as well as .centericq
89 char *home = getenv("HOME");
90 if( home != NULL ) {
91 basedir = string(home) + "/.centerim/";
92 if ( access(basedir.c_str(), F_OK) != 0 ) {
93 basedir = string(home) + "/.centericq/";
94 if ( access(basedir.c_str(), F_OK) != 0 ) {
95 basedir = string(home) + "/.centerim/";
96 }
97 }
98 }
99 screensocketpath = "/var/run/screen";
100
101 defaultAuthMessage = "Please accept my authorization to add you to my contact list.";
102 }
103
~icqconf()104 icqconf::~icqconf() {
105 if(self)
106 delete self;
107 }
108
getourid(protocolname pname) const109 icqconf::imaccount icqconf::getourid(protocolname pname) const {
110 imaccount im;
111 vector<imaccount>::const_iterator i;
112
113 i = find(accounts.begin(), accounts.end(), pname);
114 im = i == accounts.end() ? imaccount(pname) : *i;
115
116 return im;
117 }
118
119 icqconf::imserver icqconf::defservers[protocolname_size] = {
120 { "login.icq.com", 5190, 0 },
121 { "scs.msg.yahoo.com", 5050, 0 },
122 { "messenger.hotmail.com", 1863, 0 },
123 { "toc.oscar.aol.com", 9898, 0 },
124 { "irc.oftc.net", 6667, 0 },
125 { "jabber.org", 5222, 5223 },
126 { "", 0, 0 },
127 { "livejournal.com", 80, 0 },
128 { "appmsg.gadu-gadu.pl", 80 }
129 };
130
setourid(const imaccount & im)131 void icqconf::setourid(const imaccount &im) {
132 vector<imaccount>::iterator i;
133
134 i = find(accounts.begin(), accounts.end(), im.pname);
135
136 if(i != accounts.end()) {
137 if(im.empty()) {
138 accounts.erase(i);
139 i = accounts.end();
140 } else {
141 *i = im;
142 }
143 } else if(!im.empty()) {
144 accounts.push_back(im);
145 i = accounts.end()-1;
146 }
147
148 if(i != accounts.end()) {
149 if(i->server.empty()) {
150 i->server = defservers[i->pname].server;
151 i->port = defservers[i->pname].port;
152 }
153
154 if(!i->port)
155 i->port = defservers[i->pname].port;
156
157 switch(i->pname) {
158 case jabber:
159 if(i->additional.find("prio") == i->additional.end())
160 i->additional["prio"] = "4";
161 #ifdef HAVE_UNAME
162 if(i->additional.find("osinfo") == i->additional.end())
163 i->additional["osinfo"] = "1";
164 #endif
165 break;
166
167 case yahoo:
168 if (i->additional.find("ssl") == i->additional.end())
169 i->additional["ssl"] = "1";
170 break;
171
172 case livejournal:
173 if(i->additional.find("importfriends") == i->additional.end())
174 i->additional["importfriends"] = "1";
175 break;
176
177 case icq:
178 if(i->password.size() > 8)
179 i->password = i->password.substr(0, 8);
180 break;
181 }
182 }
183 }
184
getawaymsg(protocolname pname) const185 string icqconf::getawaymsg(protocolname pname) const {
186 string r, buf, fname;
187 ifstream f;
188
189 if(!gethook(pname).getCapabs().count(hookcapab::setaway))
190 return "";
191
192 fname = conf->getconfigfname("awaymsg-" + getprotocolname(pname));
193 f.open(fname.c_str());
194
195 if(f.is_open()) {
196 while(!f.eof()) {
197 getstring(f, buf);
198 if(!r.empty()) r += "\n";
199 r += buf;
200 }
201
202 f.close();
203 }
204
205 if(r.empty()) {
206 char buf[512];
207
208 snprintf(buf, sizeof(buf), _("I do really enjoy the default %s away message of %s %s."),
209 getprotocolname(pname).c_str(), PACKAGE, centerim::version);
210
211 return buf;
212 }
213
214 return r;
215 }
216
setawaymsg(protocolname pname,const string & amsg)217 void icqconf::setawaymsg(protocolname pname, const string &amsg) {
218 string fname;
219 ofstream f;
220
221 if(!gethook(pname).getCapabs().count(hookcapab::setaway))
222 return;
223
224 fname = conf->getconfigfname("awaymsg-" + getprotocolname(pname));
225 f.open(fname.c_str());
226
227 if(f.is_open()) {
228 f << amsg;
229 f.close();
230 }
231 }
232
getextstatus(protocolname pname,imstatus status) const233 string icqconf::getextstatus(protocolname pname, imstatus status) const {
234 string r, buf, fname;
235 ifstream f;
236
237 if(!gethook(pname).getCapabs().count(hookcapab::setextstatus))
238 return "";
239
240 fname = conf->getconfigfname("extmsg-" + getprotocolname(pname) + "-" + imstatus2char[status]);
241 f.open(fname.c_str());
242
243 if(f.is_open()) {
244 while(!f.eof()) {
245 getstring(f, buf);
246 if(!r.empty()) r += "\n";
247 r += buf;
248 }
249
250 f.close();
251 }
252
253 if(r.empty()) {
254 return "";
255 }
256
257 return r;
258 }
259
setextstatus(protocolname pname,const string & amsg,imstatus status)260 void icqconf::setextstatus(protocolname pname, const string &amsg, imstatus status) {
261 string fname;
262 ofstream f;
263
264 if(!gethook(pname).getCapabs().count(hookcapab::setextstatus))
265 return;
266
267 fname = conf->getconfigfname("extmsg-" + getprotocolname(pname) + "-" + imstatus2char[status]);
268 f.open(fname.c_str());
269
270 if(f.is_open()) {
271 f << amsg;
272 f.close();
273 }
274 }
275
checkdir()276 void icqconf::checkdir() {
277 string dname = getdirname();
278 dname.erase(dname.size()-1);
279 const char * dirstr = dname.c_str();
280 // The proper rights for the ~/.centerim-directory
281 const mode_t proper_rights = S_IRUSR | S_IWUSR | S_IXUSR;
282
283 if(access(dirstr, F_OK) == 0) {
284 // Directory allready exists check the permissions of the directory.
285 struct stat dir_stat;
286 if ( stat(dirstr, &dir_stat) == 0 &&
287 (dir_stat.st_mode & ~proper_rights) != 0 ) {
288 DIR *pDir = NULL;
289 // group / other have some kind of permissions for this directory
290 // as mr Picard would have said: compensate!
291 chmod (dirstr, proper_rights);
292 }
293 }
294 else{
295 // create the ~/.centerim directory since
296 // ~/.centerim / ~/.centericq does not exist.
297 mkdir(dname.c_str(), proper_rights);
298 }
299 }
300
load()301 void icqconf::load() {
302 loadmainconfig();
303 loadkeys();
304 loadcolors();
305 loadactions();
306 loadcaptcha();
307 external.load();
308 }
309
310 vector<icqconf::keybinding> icqconf::keys;
311
loadkeys()312 void icqconf::loadkeys() {
313 //int x; not used.
314 string fname = getconfigfname("keybindings"), buf, param;
315 struct keybinding k;
316 ifstream f;
317
318 keys.clear();
319
320 if(access(fname.c_str(), F_OK)) {
321 ofstream of(fname.c_str());
322
323 if(of.is_open()) {
324 of << "# This file contains keybinding configuration for centerim" << endl;
325 of << "# Every line should look like: bind <section> <key> <command>" << endl << endl;
326 of << "bind contact\t?\tinfo" << endl;
327 of << "bind contact\tq\tquit" << endl;
328 of << "bind contact\t<F3>\tchange_status" << endl;
329 of << "bind contact\ts\tchange_status" << endl;
330 of << "bind contact\th\thistory" << endl;
331 of << "bind contact\tf\tfetch_away_message" << endl;
332 of << "bind contact\t<F2>\tuser_menu" << endl;
333 of << "bind contact\tm\tuser_menu" << endl;
334 of << "bind contact\t<F4>\tgeneral_menu" << endl;
335 of << "bind contact\tg\tgeneral_menu" << endl;
336 of << "bind contact\t<F5>\thide_offline" << endl;
337 of << "bind contact\t<F6>\tcontact_external_action" << endl;
338 of << "bind contact\ta\tadd" << endl;
339 of << "bind contact\t<delete> remove" << endl;
340 of << "bind contact\t<enter> compose" << endl;
341 of << "bind contact\tc\tsend_contact" << endl;
342 of << "bind contact\tc\trss_check" << endl;
343 of << "bind contact\tu\tsend_url" << endl;
344 of << "bind contact\tr\trename" << endl;
345 of << "bind contact\tv\tversion" << endl;
346 of << "bind contact\te\tedit" << endl;
347 of << "bind contact\ti\tignore" << endl;
348 of << "bind contact\t\\as\tquickfind" << endl;
349 of << "bind contact\t/\tquickfind" << endl << endl;
350 of << "bind contact\t\\cn\tnext_chat" << endl;
351 of << "bind contact\t\\cb\tprev_chat" << endl;
352 of << "bind contact\t[\tleft_panel_move_left" << endl;
353 of << "bind contact\t]\tleft_panel_move_right" << endl;
354 of << "bind contact\t{\tlog_panel_move_up" << endl;
355 of << "bind contact\t}\tlog_panel_move_down" << endl;
356 of << "bind history\t/\tsearch" << endl;
357 of << "bind history\ts\tsearch" << endl;
358 of << "bind history\tn\tsearch_again" << endl;
359 of << "bind history\t<F2>\tshow_urls" << endl;
360 of << "bind history\t<F9>\tfullscreen" << endl << endl;
361 of << "bind editor\t\\cx\tsend_message" << endl;
362 of << "bind editor\t<esc>\tquit" << endl;
363 of << "bind editor\t\\cp\tmultiple_recipients" << endl;
364 of << "bind editor\t\\co\thistory" << endl;
365 of << "bind editor\t\\cn\tnext_chat" << endl;
366 of << "bind editor\t\\cb\tprev_chat" << endl;
367 of << "bind editor\t\\cv\tout_chat" << endl;
368 of << "bind editor\t\\a?\tinfo" << endl;
369 of << "bind editor\t<F2>\tshow_urls" << endl;
370 of << "bind editor\t<F9>\tfullscreen" << endl << endl;
371 of << "bind editor\t<F4>\tchat_panel_move_up" << endl;
372 of << "bind editor\t<F5>\tchat_panel_move_down" << endl;
373 #ifdef HAVE_LIBOTR
374 of << "bind editor\t<F7>\totr_start_session" << endl;
375 of << "bind editor\t<F8>\totr_end_session" << endl;
376 #endif
377 of << "bind info\t<F2>\tshow_urls" << endl;
378 of << "bind info\t<F6>\tuser_external_action" << endl;
379
380 of.close();
381 }
382 }
383
384 f.open(fname.c_str());
385
386 if(f.is_open()) {
387 while(!f.eof()) {
388 getstring(f, buf);
389
390 if(buf.empty() || buf[0] == '#') continue;
391
392 k.ctrl = false;
393 k.alt = false;
394
395 param = getword(buf); /* first word is always bind */
396
397 param = getword(buf); /* read section */
398 if(param == "contact")
399 k.section = section_contact; else
400 if(param == "history")
401 k.section = section_history; else
402 if (param == "editor")
403 k.section = section_editor; else
404 if (param == "info")
405 k.section = section_info;
406
407 param = getword(buf); /* key */
408 if(param == "\\c<space>" || param == "\\C<space>" || param == "^<space>") {
409 k.ctrl = true;
410 k.key = CTRL(' ');
411 } else if(param == "\\a<enter>" || param == "\\A<enter>" || param == "@<enter>") {
412 k.alt = true;
413 k.key = ALT('\r');
414 } else if(param == "\\a<space>" || param == "\\A<space>" || param == "@<space>") {
415 k.ctrl = true;
416 k.key = ALT(' ');
417 } else if(param[0] == '\\') {
418 if(param[1] == 'c' || param[1] == 'C') {
419 k.ctrl = true;
420 k.key = CTRL(param[2]);
421 } else if(param[1] == 'a' || param[1] == 'A') {
422 k.alt = true;
423 k.key = ALT(param[2]);
424 } else if(param[1] == '\\') {
425 k.key = '\\';
426 } else if(param[1] == '@') {
427 k.key = '@';
428 } else if(param[1] == '^') {
429 k.key = '^';
430 }
431 } else if(param[0] == '^') {
432 k.ctrl = true;
433 k.key = CTRL(param[1]);
434 } else if(param[0] == '@') {
435 k.alt = true;
436 k.key = ALT(param[1]);
437 } else if(param == "<delete>")
438 k.key = KEY_DC;
439 else if(param == "<enter>")
440 k.key = '\r';
441 else if(param == "<esc>")
442 k.key = 27;
443 else if(param == "<space>")
444 k.key = ' ';
445 else if(param == "<backspace>")
446 k.key = '\b';
447 else if(param == "<pageup>")
448 k.key = 339;
449 else if(param == "<pagedown>")
450 k.key = 338;
451 else if(param == "<tab>")
452 k.key = 9;
453 else if(param == "<insert>")
454 k.key = 331;
455 else if(param[0] == '<' && param[1] == 'F') {
456 k.alt = true;
457 k.ctrl = true;
458 k.key = KEY_F(param[2]-'0');
459 } else
460 k.key = param[0];
461
462 param = getword(buf); /* action */
463 if(param == "info") k.action = key_info; else
464 if(param == "remove") k.action = key_remove; else
465 if(param == "quit") k.action = key_quit; else
466 if(param == "change_status") k.action = key_change_status; else
467 if(param == "history") k.action = key_history; else
468 if(param == "next_chat") k.action = key_next_chat; else
469 if(param == "prev_chat") k.action = key_prev_chat; else
470 if(param == "out_chat") k.action = key_out_chat; else
471 if(param == "fetch_away_message") k.action = key_fetch_away_message; else
472 if(param == "user_menu") k.action = key_user_menu; else
473 if(param == "general_menu") k.action = key_general_menu; else
474 if(param == "hide_offline") k.action = key_hide_offline; else
475 if(param == "contact_external_action") k.action = key_contact_external_action; else
476 if(param == "add") k.action = key_add; else
477 if(param == "remove") k.action = key_remove; else
478 if(param == "send_message") k.action = key_send_message; else
479 if(param == "send_contact") k.action = key_send_contact; else
480 if(param == "send_url") k.action = key_send_url; else
481 if(param == "rename") k.action = key_rename; else
482 if(param == "version") k.action = key_version; else
483 if(param == "fullscreen") k.action = key_fullscreen; else
484 if(param == "edit") k.action = key_edit; else
485 if(param == "ignore") k.action = key_ignore; else
486 if(param == "quickfind") k.action = key_quickfind; else
487 if(param == "search") k.action = key_search; else
488 if(param == "compose") k.action = key_compose; else
489 if(param == "search_again") k.action = key_search_again; else
490 if(param == "show_urls") k.action = key_show_urls; else
491 if(param == "rss_check") k.action = key_rss_check; else
492 if(param == "multiple_recipients") k.action = key_multiple_recipients; else
493 if(param == "user_external_action") k.action = key_user_external_action; else
494 if(param == "left_panel_move_left") k.action = key_left_panel_move_left; else
495 if(param == "left_panel_move_right") k.action = key_left_panel_move_right; else
496 if(param == "log_panel_move_up") k.action = key_log_panel_move_up; else
497 if(param == "log_panel_move_down") k.action = key_log_panel_move_down; else
498 if(param == "chat_panel_move_up") k.action = key_chat_panel_move_up; else
499 if(param == "chat_panel_move_down") k.action = key_chat_panel_move_down; else
500 #ifdef HAVE_LIBOTR
501 if(param == "otr_start_session") k.action = key_otr_start_session; else
502 if(param == "otr_end_session") k.action = key_otr_end_session; else
503 #endif
504 continue;
505
506 keys.push_back(k);
507 }
508
509 f.close();
510 }
511 /*
512 if(face.action2key(key_info, section_contact).empty()) keys.push_back(keybinding()); else
513 if(face.action2key(key_quit, section_contact).empty())
514 if(face.action2key(key_change_status, section_contact).empty())
515 if(face.action2key(key_history, section_contact).empty())
516 if(face.action2key(key_fetch_away_message, section_contact).empty())
517 if(face.action2key(key_user_menu, section_contact).empty())
518 if(face.action2key(key_general_menu, section_contact).empty())
519 if(face.action2key(key_hide_offline, section_contact).empty())
520 if(face.action2key(key_contact_external_action, section_contact).empty())
521 if(face.action2key(key_add, section_contact).empty())
522 if(face.action2key(key_remove, section_contact).empty())
523 if(face.action2key(key_compose, section_contact).empty())
524 if(face.action2key(key_send_contact, section_contact).empty())
525 if(face.action2key(key_rss_check, section_contact).empty())
526 if(face.action2key(key_send_url, section_contact).empty())
527 if(face.action2key(key_rename, section_contact).empty())
528 if(face.action2key(key_version, section_contact).empty())
529 if(face.action2key(key_edit, section_contact).empty())
530 if(face.action2key(key_ignore, section_contact).empty())
531 if(face.action2key(key_quickfind, section_contact).empty())
532 if(face.action2key(key_next_chat, section_contact).empty())
533 if(face.action2key(key_prev_chat, section_contact).empty())
534 if(face.action2key(key_search, section_history).empty())
535 if(face.action2key(key_search_again, section_history).empty())
536 if(face.action2key(key_show_urls, section_history).empty())
537 if(face.action2key(key_fullscreen, section_history).empty())
538 if(face.action2key(key_send_message, section_editor).empty())
539 if(face.action2key(key_quit, section_editor).empty())
540 if(face.action2key(key_multiple_recipients, section_editor).empty())
541 if(face.action2key(key_history, section_editor).empty())
542 if(face.action2key(key_next_chat, section_editor).empty())
543 if(face.action2key(key_prev_chat, section_editor).empty())
544 if(face.action2key(key_out_chat, section_editor).empty())
545 if(face.action2key(key_info, section_editor).empty())
546 if(face.action2key(key_show_urls, section_editor).empty())
547 if(face.action2key(key_fullscreen, section_editor).empty())
548 if(face.action2key(key_show_urls, section_info).empty())
549 if(face.action2key(key_user_external_action, section_info).empty()) {}
550 */
551 }
552
loadmainconfig()553 void icqconf::loadmainconfig() {
554 string fname = getconfigfname("config"), buf, param, rbuf;
555 ifstream f(fname.c_str());
556 imaccount im;
557 protocolname pname;
558
559 if(f.is_open()) {
560 mailcheck = askaway = false;
561 savepwd = bidi = true;
562 setsmtphost("");
563 setbrowser("");
564 setpeertopeer(0, 65535);
565
566 while(!f.eof()) {
567 getstring(f, buf);
568 rbuf = buf;
569 param = getword(buf);
570
571 if(param == "hideoffline") hideoffline = true; else
572 if(param == "emacs") emacs = true; else
573 if(param == "vi") vi = true; else
574 if(param == "autoaway") autoaway = atol(buf.c_str()); else
575 if(param == "autona") autona = atol(buf.c_str()); else
576 if(param == "auto_away_na_x") autoawayx = true; else
577 if(param == "antispam") antispam = true; else
578 if(param == "showopenedchats") setshowopenedchats(true); else
579 if(param == "dropauthreq") dropauthreq = true; else
580 if(param == "screenna") screenna = true; else
581 if(param == "screensocketpath") screensocketpath = buf; else
582 if(param == "mailcheck") mailcheck = true; else
583 if(param == "quotemsgs") quote = true; else
584 if(param == "sockshost") setsockshost(buf); else
585 if(param == "socksusername") socksuser = buf; else
586 if(param == "sockspass") sockspass = buf; else
587 if((param == "usegroups") || (param == "group1")) fgroupmode = group1; else
588 if(param == "group2") fgroupmode = group2; else
589 if(param == "protocolormode") cm = icqconf::cmproto; else
590 if(param == "statuscolormode") cm = icqconf::cmstatus; else
591 if(param == "sort_by_status_and_activity") setsortmode(icqconf::sort_by_status_and_activity); else
592 if(param == "sort_by_status_and_name") setsortmode(icqconf::sort_by_status_and_name); else
593 if(param == "sort_by_activity") setsortmode(icqconf::sort_by_activity); else
594 if(param == "sort_by_name") setsortmode(icqconf::sort_by_name); else
595 if(param == "smtp") setsmtphost(buf); else
596 if(param == "browser") setbrowser(buf); else
597 if(param == "http_proxy") sethttpproxyhost(buf); else
598 if(param == "log") makelog = true; else
599 if(param == "proxy_connect") proxyconnect = true; else
600 if(param == "proxy_ssl") proxyssl = true; else
601 if(param == "chatmode") initmultiproto(chatmode, buf, true); else
602 if(param == "entersends") initmultiproto(entersends, buf, true); else
603 if(param == "nonimonline") initmultiproto(nonimonline, buf, false); else
604 if(param == "captcha") usingcaptcha = true; else
605 if(param == "russian" || param == "convert") initmultiproto(cpconvert, buf, false); else
606 if(param == "nobidi") setbidi(false); else
607 if(param == "askaway") askaway = true; else
608 if(param == "askquit") askquit = true; else
609 if(param == "logtimestamps") logtimestamps = true; else
610 if(param == "logonline") logonline = true; else
611 if(param == "fromcharset") fromcharset = buf; else
612 if(param == "tocharset") tocharset = buf; else
613 if(param == "left_panel_width") leftpanelwidth = atol(buf.c_str()); else
614 if(param == "log_panel_height") logpanelheight = atol(buf.c_str()); else
615 if(param == "chat_panel_height") chatpanelheight = atol(buf.c_str()); else
616 if(param == "timestampstothesecond") settimestampstothesecond(true); else
617 if(param == "defaultauthmessage") defaultAuthMessage = buf; else
618 if(param == "ptp") {
619 ptpmin = atoi(getword(buf, "-").c_str());
620 ptpmax = atoi(buf.c_str());
621 } else {
622 for(pname = icq; pname != protocolname_size; pname++) {
623 buf = getprotocolname(pname);
624 if(param.substr(0, buf.size()) == buf) {
625 im = getourid(pname);
626 im.read(rbuf);
627 setourid(im);
628 }
629 }
630 }
631 }
632
633 if(fromcharset.empty() && tocharset.empty())
634 for(pname = icq; pname != protocolname_size; pname++) {
635 if(getcpconvert(pname)) {
636 fromcharset = "cp1251";
637 tocharset = "koi8-r";
638 break;
639 }
640 }
641
642 setproxy();
643 f.close();
644 }
645 }
646
save()647 void icqconf::save() {
648 string fname = getconfigfname("config"), param;
649 int away, na;
650 bool usex = false;
651
652 if(enoughdiskspace()) {
653 ofstream f(fname.c_str());
654
655 if(f.is_open()) {
656 if(!getsockshost().empty()) {
657 string user, pass;
658 getsocksuser(user, pass);
659 f << "sockshost\t" << getsockshost() + ":" + i2str(getsocksport()) << endl;
660 f << "socksusername\t" << user << endl;
661 f << "sockspass\t" << pass << endl;
662 }
663
664 getauto(away, na, usex);
665
666 if(away) f << "autoaway\t" << i2str(away) << endl;
667 if(na) f << "autona\t" << i2str(na) << endl;
668 if(autoawayx) f << "auto_away_na_x" << endl;
669 if(hideoffline) f << "hideoffline" << endl;
670 if(emacs) f << "emacs" << endl;
671 if(getquote()) f << "quotemsgs" << endl;
672 if(vi) f << "vi" << endl;
673 if(getantispam()) f << "antispam" << endl;
674 if(getshowopenedchats()) f << "showopenedchats" << endl;
675 if(getdropauthreq()) f << "dropauthreq" << endl;
676 if(getusingcaptcha()) f << "captcha" << endl;
677 if(getmailcheck()) f << "mailcheck" << endl;
678 if(getaskaway()) f << "askaway" << endl;
679 if(getscreenna()) f << "screenna" << endl;
680 if(!screensocketpath.empty()) f << "screensocketpath\t" << screensocketpath << endl;
681
682 param = "";
683 for(protocolname pname = icq; pname != protocolname_size; pname++)
684 if(getchatmode(pname)) param += (string) " " + conf->getprotocolname(pname);
685 if(!param.empty())
686 f << "chatmode" << param << endl;
687
688 param = "";
689 for(protocolname pname = icq; pname != protocolname_size; pname++)
690 if(getentersends(pname)) param += (string) " " + conf->getprotocolname(pname);
691 if(!param.empty())
692 f << "entersends" << param << endl;
693
694 param = "";
695 for(protocolname pname = icq; pname != protocolname_size; pname++)
696 if(getnonimonline(pname)) param += (string) " " + conf->getprotocolname(pname);
697 if(!param.empty())
698 f << "nonimonline" << param << endl;
699
700 param = "";
701 for(protocolname pname = icq; pname != protocolname_size; pname++)
702 if(getcpconvert(pname)) param += (string) " " + conf->getprotocolname(pname);
703 if(!param.empty())
704 f << "convert" << param << endl;
705
706 param = "";
707
708 f << "fromcharset\t" << fromcharset << endl;
709 f << "tocharset\t" << tocharset << endl;
710
711 if(!getbidi()) f << "nobidi" << endl;
712 if(getaskquit()) f << "askquit" << endl;
713 if(logtimestamps) f << "logtimestamps" << endl;
714 if(timestampstothesecond) f << "timestampstothesecond" << endl;
715 if(logonline) f << "logonline" << endl;
716
717 f << "smtp\t" << getsmtphost() << ":" << getsmtpport() << endl;
718 f << "browser\t" << getbrowser() << endl;
719
720 if(!gethttpproxyhost().empty())
721 if (!gethttpproxyuser().empty())
722 f << "http_proxy\t" << gethttpproxyuser() << ":" << gethttpproxypasswd() << "@" << gethttpproxyhost() << ":" << gethttpproxyport() << endl;
723 else
724 f << "http_proxy\t" << gethttpproxyhost() << ":" << gethttpproxyport() << endl;
725
726 f << "ptp\t" << ptpmin << "-" << ptpmax << endl;
727
728 switch(getgroupmode()) {
729 case group1: f << "group1" << endl; break;
730 case group2: f << "group2" << endl; break;
731 }
732
733 switch(getcolormode()) {
734 case cmproto:
735 f << "protocolormode" << endl;
736 break;
737 case cmstatus:
738 f << "statuscolormode" << endl;
739 break;
740 }
741
742 switch(getsortmode()) {
743 case sort_by_status_and_activity: f << "sort_by_status_and_activity" << endl; break;
744 case sort_by_status_and_name: f << "sort_by_status_and_name" << endl; break;
745 case sort_by_activity: f << "sort_by_activity" << endl; break;
746 case sort_by_name: f << "sort_by_name" << endl; break;
747 }
748
749 if(getmakelog()) f << "log" << endl;
750 if(getproxyconnect()) f << "proxy_connect" << endl;
751 if(getproxyssl()) f << "proxy_ssl" << endl;
752
753 if(getleftpanelwidth()) f << "left_panel_width\t" << getleftpanelwidth() << endl;
754 if(getlogpanelheight()) f << "log_panel_height\t" << getlogpanelheight() << endl;
755 if(getchatpanelheight()) f << "chat_panel_height\t" << getchatpanelheight() << endl;
756
757 f << "defaultauthmessage\t" << getDefaultAuthMessage() << endl;
758
759 vector<imaccount>::iterator ia;
760 for(ia = accounts.begin(); ia != accounts.end(); ++ia)
761 ia->write(f);
762
763 f.close();
764 }
765 }
766 }
767
loadcolors()768 void icqconf::loadcolors() {
769 string tname = getconfigfname("colorscheme");
770
771 switch(conf->getregcolor()) {
772 case rcdark:
773 schemer.push(cp_status, "status black/white");
774 schemer.push(cp_dialog_text, "dialog_text black/white");
775 schemer.push(cp_dialog_menu, "dialog_menu black/white");
776 schemer.push(cp_dialog_selected, "dialog_selected white/transparent bold");
777 schemer.push(cp_dialog_highlight, "dialog_highlight red/white");
778 schemer.push(cp_dialog_frame, "dialog_frame blue/white");
779 schemer.push(cp_main_text, "main_text cyan/transparent");
780 schemer.push(cp_main_menu, "main_menu green/transparent");
781 schemer.push(cp_main_selected, "main_selected black/white");
782 schemer.push(cp_main_highlight, "main_highlight yellow/transparent bold");
783 schemer.push(cp_main_frame, "main_frame blue/transparent bold");
784 schemer.push(cp_main_history_incoming, "main_history_incoming yellow/transparent bold");
785 schemer.push(cp_main_history_outgoing, "main_history_outgoing cyan/transparent");
786 schemer.push(cp_clist_icq, "clist_icq green/transparent");
787 schemer.push(cp_clist_yahoo, "clist_yahoo magenta/transparent");
788 schemer.push(cp_clist_infocard, "clist_infocard white/transparent");
789 schemer.push(cp_clist_msn, "clist_msn cyan/transparent");
790 schemer.push(cp_clist_aim, "clist_aim yellow/transparent");
791 schemer.push(cp_clist_irc, "clist_irc blue/transparent");
792 schemer.push(cp_clist_jabber, "clist_jabber red/transparent");
793 schemer.push(cp_clist_rss, "clist_rss white/transparent bold");
794 schemer.push(cp_clist_lj, "clist_lj cyan/transparent bold");
795 schemer.push(cp_clist_gadu, "clist_gg blue/transparent bold");
796 schemer.push(cp_clist_online, "clist_online green/transparent bold");
797 schemer.push(cp_clist_offline, "clist_offline red/transparent bold");
798 schemer.push(cp_clist_away, "clist_away yellow/transparent bold");
799 schemer.push(cp_clist_dnd, "clist_dnd cyan/transparent bold");
800 schemer.push(cp_clist_na, "clist_na blue/transparent bold");
801 schemer.push(cp_clist_free_for_chat, "clist_free_for_chat green/transparent bold");
802 schemer.push(cp_clist_invisible, "clist_invisible grey/transparent bold");
803 schemer.push(cp_clist_not_in_list, "clist_not_in_list white/transparent bold");
804 schemer.push(cp_clist_unread, "clist_unread red/transparent bold");
805 break;
806
807 case rcblue:
808 schemer.push(cp_status, "status black/white");
809 schemer.push(cp_dialog_text, "dialog_text black/cyan");
810 schemer.push(cp_dialog_menu, "dialog_menu black/cyan");
811 schemer.push(cp_dialog_selected, "dialog_selected white/black bold");
812 schemer.push(cp_dialog_highlight, "dialog_highlight white/cyan bold");
813 schemer.push(cp_dialog_frame, "dialog_frame black/cyan");
814 schemer.push(cp_main_text, "main_text white/blue");
815 schemer.push(cp_main_menu, "main_menu white/blue");
816 schemer.push(cp_main_selected, "main_selected black/cyan");
817 schemer.push(cp_main_highlight, "main_highlight white/blue bold");
818 schemer.push(cp_main_frame, "main_frame blue/blue bold");
819 schemer.push(cp_main_history_incoming, "main_history_incoming white/blue");
820 schemer.push(cp_main_history_outgoing, "main_history_outgoing white/blue bold");
821 schemer.push(cp_clist_icq, "clist_icq green/blue");
822 schemer.push(cp_clist_yahoo, "clist_yahoo magenta/blue");
823 schemer.push(cp_clist_msn, "clist_msn cyan/blue");
824 schemer.push(cp_clist_infocard, "clist_infocard white/blue");
825 schemer.push(cp_clist_aim, "clist_aim yellow/blue");
826 schemer.push(cp_clist_irc, "clist_irc blue/blue bold");
827 schemer.push(cp_clist_jabber, "clist_jabber red/blue");
828 schemer.push(cp_clist_rss, "clist_rss white/blue bold");
829 schemer.push(cp_clist_lj, "clist_lj cyan/blue bold");
830 schemer.push(cp_clist_gadu, "clist_gg blue/blue bold");
831 schemer.push(cp_clist_online, "clist_online green/transparent bold");
832 schemer.push(cp_clist_offline, "clist_offline red/transparent bold");
833 schemer.push(cp_clist_away, "clist_away yellow/transparent bold");
834 schemer.push(cp_clist_dnd, "clist_dnd cyan/transparent bold");
835 schemer.push(cp_clist_na, "clist_na blue/transparent bold");
836 schemer.push(cp_clist_free_for_chat, "clist_free_for_chat green/transparent bold");
837 schemer.push(cp_clist_invisible, "clist_invisible grey/transparent bold");
838 schemer.push(cp_clist_not_in_list, "clist_not_in_list white/transparent bold");
839 schemer.push(cp_clist_unread, "clist_unread black/blue bold");
840 break;
841 }
842
843 if(access(tname.c_str(), F_OK)) {
844 schemer.save(tname);
845 } else {
846 schemer.load(tname);
847 }
848 }
849
loadsounds()850 void icqconf::loadsounds() {
851 string tname = getconfigfname("sounds"), buf, suin, skey;
852 int i;
853 icqcontact *c;
854 imevent::imeventtype it;
855
856 typedef pair<imevent::imeventtype, string> eventsound;
857 vector<eventsound> soundnames;
858 vector<eventsound>::iterator isn;
859
860 soundnames.push_back(eventsound(imevent::message, "msg"));
861 soundnames.push_back(eventsound(imevent::sms, "sms"));
862 soundnames.push_back(eventsound(imevent::url, "url"));
863 soundnames.push_back(eventsound(imevent::online, "online"));
864 soundnames.push_back(eventsound(imevent::offline, "offline"));
865 soundnames.push_back(eventsound(imevent::email, "email"));
866
867 for(i = 0; i < clist.count; i++) {
868 c = (icqcontact *) clist.at(i);
869
870 for(it = imevent::message; it != imevent::imeventtype_size; it++) {
871 c->setsound(it, "");
872 }
873 }
874
875 if(access(tname.c_str(), F_OK)) {
876 ofstream fo(tname.c_str());
877
878 if(fo.is_open()) {
879 fo << "# This file contains sound configuration for centerim" << endl;
880 fo << "# Every line should look like: <id> <event> <command>" << endl << "#" << endl;
881
882 fo << "# <id>\tid of a contact; can be one of the following" << endl;
883 fo << "# *\tmeans default sound for all the contacts" << endl;
884 fo << "# icq_<uin>\tfor icq contacts (e.g. icq_123)" << endl;
885 fo << "# yahoo_<nickname>\tfor yahoo (e.g. yahoo_thekonst)" << endl;
886 fo << "# .. etc. Similar for the other protocols" << endl << "#" << endl;
887
888 fo << "# <event>\tcan be: ";
889 for(isn = soundnames.begin(); isn != soundnames.end(); ++isn) {
890 if(isn != soundnames.begin()) fo << ", ";
891 fo << isn->second;
892 }
893
894 fo << endl << "# <command>\tcommand line to be executed to play a sound" << endl << endl;
895
896 switch(rs) {
897 case rscard:
898 fo << "*\tmsg\taplay " << SHARE_DIR << "/msg.wav" << endl;
899 fo << "*\turl\taplay " << SHARE_DIR << "/url.wav" << endl;
900 fo << "*\temail\taplay " << SHARE_DIR << "/email.wav" << endl;
901 fo << "*\tonline\taplay " << SHARE_DIR << "/online.wav" << endl;
902 fo << "*\toffline\taplay " << SHARE_DIR << "/offline.wav" << endl;
903 fo << "*\tsms\taplay " << SHARE_DIR << "/sms.wav" << endl;
904 break;
905
906 case rsspeaker:
907 fo << "*\tmsg\t!spk1" << endl;
908 fo << "*\turl\t!spk2" << endl;
909 fo << "*\tsms\t!spk3" << endl;
910 fo << "*\temail\t!spk5" << endl;
911 break;
912 }
913
914 fo.close();
915 }
916 }
917
918 ifstream fi(tname.c_str());
919 if(fi.is_open()) {
920 while(!fi.eof()) {
921 getstring(fi, buf);
922 if(buf.empty() || (buf.substr(0, 1) == "#")) continue;
923
924 suin = getword(buf);
925 skey = getword(buf);
926
927 it = imevent::imeventtype_size;
928
929 for(isn = soundnames.begin(); isn != soundnames.end(); ++isn) {
930 if(skey == isn->second) {
931 it = isn->first;
932 break;
933 }
934 }
935
936 if(it == imevent::imeventtype_size)
937 continue;
938
939 c = 0;
940
941 if(suin != "*") {
942 if((i = suin.find("_")) != -1) {
943 skey = suin.substr(0, i);
944 suin.erase(0, i+1);
945
946 imcontact ic;
947 protocolname pname;
948
949 for(pname = icq; pname != protocolname_size && skey != getprotocolname(pname); pname++);
950
951 if(pname != protocolname_size) {
952 if(suin == "*") {
953 for(i = 0; i < clist.count; i++) {
954 c = (icqcontact *) clist.at(i);
955
956 if(c->getdesc().pname == pname) c->setsound(it, buf);
957 }
958 } else {
959 if(pname == icq) ic = imcontact(strtoul(suin.c_str(), 0, 0), pname);
960 else ic = imcontact(suin, pname);
961
962 c = clist.get(ic);
963 }
964 }
965 }
966 } else {
967 c = clist.get(contactroot);
968 }
969
970 if(c) c->setsound(it, buf);
971 }
972
973 fi.close();
974 }
975 }
976
loadactions()977 void icqconf::loadactions() {
978 string fname = getconfigfname("actions"), buf, name;
979 ifstream f;
980 bool cont;
981
982 if(access(fname.c_str(), F_OK)) {
983 buf = getenv("PATH") ? getenv("PATH") : "";
984
985 ofstream of(fname.c_str());
986
987 if(of.is_open()) {
988 of << "# This file contains external actions configuration for centerim" << endl;
989 of << "# Every line should look like: <action> <command>" << endl;
990 of << "# Possible actions are: openurl, detectmusic" << endl << endl;
991
992 of << "openurl \\" << endl;
993 of << " (if test ! -z \"`ps x | grep /" << browser << " | grep -v grep`\"; \\" << endl;
994 of << "\tthen DISPLAY=0:0 " << browser << " -remote 'openURL($url$, new-window)'; \\" << endl;
995 of << "\telse DISPLAY=0:0 " << browser << " '$url$'; \\" << endl;
996 of << " fi) >/dev/null 2>&1 &" << endl;
997
998 of << "detectmusic \\" << endl;
999 of << " if test ! -z \"`ps x | grep orpheus | grep -v grep`\"; \\" << endl;
1000 of << "\tthen cat ~/.orpheus/currently_playing; \\" << endl;
1001 of << " fi" << endl;
1002
1003 of.close();
1004 }
1005 }
1006
1007 f.open(fname.c_str());
1008
1009 if(f.is_open()) {
1010 actions.clear();
1011 cont = false;
1012
1013 while(!f.eof()) {
1014 getstring(f, buf);
1015 if(!cont) name = getword(buf);
1016
1017 if(name == "openurl" || name == "detectmusic") {
1018 if(!buf.empty())
1019 if(cont = buf.substr(buf.size()-1, 1) == "\\")
1020 buf.erase(buf.size()-1, 1);
1021
1022 actions[name] += buf;
1023 }
1024 }
1025
1026 f.close();
1027 }
1028 }
1029
loadcaptcha()1030 void icqconf::loadcaptcha() {
1031 string fname = getconfigfname("captcha"), buf, entry;
1032 ifstream f;
1033 vector<string>::const_iterator ic;
1034
1035 if(access(fname.c_str(), F_OK)) {
1036
1037 ofstream of(fname.c_str());
1038
1039 if(of.is_open()) {
1040 of << "# This file contains sample configuration for captcha engine." << endl;
1041 of << "# Every line should look like: <param> <value>" << endl;
1042 of << "# Possible params are: greeting, quest, success, failure, timeout (min)" << endl;
1043 of << "# Quest fomat is: quest <question>//<answer>[::answer[...]]" << endl;
1044 of << endl;
1045 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;
1046 of << endl;
1047 of << "quest How many legs does a dog have?//4::four" << endl;
1048 of << "quest What is the first word of this sentence?//what" << endl;
1049 of << "quest What is the sum of 1 and 1?//2::two" << endl;
1050 of << "quest What is not a fruit: lettuce, apple or banana?//lettuce" << endl;
1051 of << "quest How many fingers are there on one hand?//5::five" << endl;
1052 of << "quest How many wheels does a normal bicycle have?//2::two" << endl;
1053 of << "quest What colour does a banana have?//yellow::yelow" << endl;
1054 of << "quest What does a chicken lay?//eggs::egg" << endl;
1055 of << "quest What is the value of PI, accurate to 2 digits?//3.14::3,14" << endl;
1056 of << "quest Is a wheel round or not (yes or no)?//yes" << endl;
1057 of << endl;
1058 of << "success You answered the question correctly, you are now added to my contact list. Thank you for your patience." << endl;
1059 of << "failure You answered the question incorrectly, you can try again by answering the next question." << endl;
1060 of << "timeout 30" << endl;
1061 of.close();
1062 }
1063 }
1064
1065 f.open(fname.c_str());
1066
1067 if(f.is_open()) {
1068 while(!f.eof()) {
1069 getstring(f, buf);
1070 entry = getword(buf);
1071
1072 if(entry == "greeting") captchagreet = buf; else
1073 if(entry == "success") captchasuccess = buf; else
1074 if(entry == "failure") captchafailure = buf; else
1075 if(entry == "timeout") captchatimeout = atol(buf.c_str()); else
1076 if(entry == "quest") thecaptcha.addquestion(buf);
1077 }
1078 if(thecaptcha.empty()) {
1079 usingcaptcha = false;
1080 face.log(_("+ ERROR: captcha disabled: no questions found!"));
1081 }
1082
1083 f.close();
1084 }
1085 }
1086
getregcolor() const1087 icqconf::regcolor icqconf::getregcolor() const {
1088 return rc;
1089 }
1090
setregcolor(icqconf::regcolor c)1091 void icqconf::setregcolor(icqconf::regcolor c) {
1092 rc = c;
1093 }
1094
getregsound() const1095 icqconf::regsound icqconf::getregsound() const {
1096 return rs;
1097 }
1098
setregsound(icqconf::regsound s)1099 void icqconf::setregsound(icqconf::regsound s) {
1100 rs = s;
1101 }
1102
getcolormode() const1103 icqconf::colormode icqconf::getcolormode() const {
1104 return cm;
1105 }
1106
setcolormode(colormode c)1107 void icqconf::setcolormode(colormode c) {
1108 cm = c;
1109 }
1110
setauto(int away,int na,bool usex)1111 void icqconf::setauto(int away, int na, bool usex) {
1112 autoaway = away;
1113 autona = na;
1114 autoawayx = usex;
1115
1116 if(away == na)
1117 autoaway = 0;
1118 }
1119
getauto(int & away,int & na,bool & usex) const1120 void icqconf::getauto(int &away, int &na, bool& usex) const {
1121 away = autoaway;
1122 na = autona;
1123 usex = autoawayx;
1124
1125 if(away == na)
1126 away = 0;
1127 }
1128
getscreenna() const1129 bool icqconf::getscreenna() const {
1130 return screenna;
1131 }
1132
setscreenna(bool sna)1133 void icqconf::setscreenna(bool sna) {
1134 screenna = sna;
1135 }
1136
getscreensocketpath() const1137 string icqconf::getscreensocketpath() const {
1138 return screensocketpath;
1139 }
1140
setscreensocketpath(string path)1141 void icqconf::setscreensocketpath(string path) {
1142 screensocketpath = path;
1143 }
1144
setquote(bool use)1145 void icqconf::setquote(bool use) {
1146 quote = use;
1147 }
setaskquit(bool faskquit)1148 void icqconf::setaskquit(bool faskquit) {
1149 askquit = faskquit;
1150 }
1151
setsockshost(const string & nsockshost)1152 void icqconf::setsockshost(const string &nsockshost) {
1153 int pos;
1154
1155 if(!nsockshost.empty()) {
1156 if((pos = nsockshost.find(":")) != -1) {
1157 sockshost = nsockshost.substr(0, pos);
1158 socksport = atol(nsockshost.substr(pos+1).c_str());
1159 } else {
1160 sockshost = nsockshost;
1161 socksport = 1080;
1162 }
1163 } else {
1164 sockshost = "";
1165 }
1166 }
1167
getsockshost() const1168 string icqconf::getsockshost() const {
1169 return sockshost;
1170 }
1171
getsocksport() const1172 unsigned int icqconf::getsocksport() const {
1173 return socksport;
1174 }
1175
getsocksuser(string & name,string & pass) const1176 void icqconf::getsocksuser(string &name, string &pass) const {
1177 name = socksuser;
1178 pass = sockspass;
1179 }
1180
setsocksuser(const string & name,const string & pass)1181 void icqconf::setsocksuser(const string &name, const string &pass) {
1182 socksuser = name;
1183 sockspass = pass;
1184 }
1185
setsavepwd(bool ssave)1186 void icqconf::setsavepwd(bool ssave) {
1187 savepwd = ssave;
1188 }
1189
sethideoffline(bool fho)1190 void icqconf::sethideoffline(bool fho) {
1191 hideoffline = fho;
1192 }
1193
settimestampstothesecond(bool ttts)1194 void icqconf::settimestampstothesecond(bool ttts) {
1195 timestampstothesecond = ttts;
1196 if (timestampstothesecond) {
1197 timestampformat = SECONDS_TIMESTAMP_FORMAT;
1198 logtimestampformat = SECONDS_LOGTIMESTAMP_FORMAT;
1199 } else {
1200 timestampformat = DEFAULT_TIMESTAMP_FORMAT;
1201 logtimestampformat = DEFAULT_LOGTIMESTAMP_FORMAT;
1202 }
1203 }
1204
setemacs(bool fem)1205 void icqconf::setemacs(bool fem) {
1206 emacs = fem;
1207 }
1208
setvi(bool b)1209 void icqconf::setvi(bool b) {
1210 vi = b;
1211 }
1212
setantispam(bool fas)1213 void icqconf::setantispam(bool fas) {
1214 antispam = fas;
1215 }
1216
setshowopenedchats(bool fsoc)1217 void icqconf::setshowopenedchats(bool fsoc)
1218 {
1219 showopenedchats = fsoc;
1220 }
1221
setdropauthreq(bool fas)1222 void icqconf::setdropauthreq(bool fas) {
1223 dropauthreq = fas;
1224 }
1225
setusingcaptcha(bool fas)1226 void icqconf::setusingcaptcha(bool fas) {
1227 usingcaptcha = fas;
1228 }
1229
setmailcheck(bool fmc)1230 void icqconf::setmailcheck(bool fmc) {
1231 mailcheck = fmc;
1232 }
1233
setaskaway(bool faskaway)1234 void icqconf::setaskaway(bool faskaway) {
1235 askaway = faskaway;
1236 }
1237
getchatmode(protocolname pname)1238 bool icqconf::getchatmode(protocolname pname) {
1239 switch(pname) {
1240 case infocard:
1241 case rss:
1242 return false;
1243 }
1244
1245 return chatmode[pname];
1246 }
1247
setchatmode(protocolname pname,bool fchatmode)1248 void icqconf::setchatmode(protocolname pname, bool fchatmode) {
1249 chatmode[pname] = fchatmode;
1250 }
1251
getentersends(protocolname pname)1252 bool icqconf::getentersends(protocolname pname) {
1253 return entersends[pname];
1254 }
1255
setentersends(protocolname pname,bool fentersends)1256 void icqconf::setentersends(protocolname pname, bool fentersends) {
1257 entersends[pname] = fentersends;
1258 }
1259
getnonimonline(protocolname pname)1260 bool icqconf::getnonimonline(protocolname pname) {
1261 return nonimonline[pname];
1262 }
1263
setnonimonline(protocolname pname,bool fnonimonline)1264 void icqconf::setnonimonline(protocolname pname, bool fnonimonline) {
1265 nonimonline[pname] = fnonimonline;
1266 }
1267
getcpconvert(protocolname pname) const1268 bool icqconf::getcpconvert(protocolname pname) const {
1269 return cpconvert[pname];
1270 }
1271
setcpconvert(protocolname pname,bool fcpconvert)1272 void icqconf::setcpconvert(protocolname pname, bool fcpconvert) {
1273 cpconvert[pname] = fcpconvert;
1274 }
1275
execaction(const string & name,const string & param)1276 string icqconf::execaction(const string &name, const string ¶m) {
1277 int inpipe[2], outpipe[2], pid, npos;
1278 struct sigaction sact, osact;
1279 string torun = actions[name], out;
1280 fd_set rfds;
1281 char ch;
1282
1283 if(name == "openurl")
1284 {
1285 string url = param;
1286 int pos = 0, fnd = -1;
1287
1288 char enc[4];
1289
1290 while( ((fnd = url.find("'", pos)) != -1) || ((fnd = url.find("\"", pos)) != -1) ) {
1291 snprintf(enc, 4, "%%%02X", url[fnd]);
1292 url.replace(fnd, 1, enc);
1293 pos = fnd+3;
1294 }
1295
1296 while((npos = torun.find("$url$")) != -1)
1297 torun.replace(npos, 5, url);
1298 }
1299
1300 if(!pipe(inpipe) && !pipe(outpipe)) {
1301 memset(&sact, 0, sizeof(sact));
1302 sigaction(SIGCHLD, &sact, &osact);
1303 pid = fork();
1304
1305 if(!pid) {
1306 dup2(inpipe[1], STDOUT_FILENO);
1307 dup2(outpipe[0], STDIN_FILENO);
1308
1309 close(inpipe[1]);
1310 close(inpipe[0]);
1311 close(outpipe[0]);
1312 close(outpipe[1]);
1313
1314 execl("/bin/sh", "/bin/sh", "-c", torun.c_str(), (char *)NULL );
1315 _exit(0);
1316 } else {
1317 close(outpipe[0]);
1318 close(inpipe[1]);
1319
1320 while(1) {
1321 FD_ZERO(&rfds);
1322 FD_SET(inpipe[0], &rfds);
1323
1324 if(select(inpipe[0]+1, &rfds, 0, 0, 0) < 0) break; else {
1325 if(FD_ISSET(inpipe[0], &rfds)) {
1326 if(read(inpipe[0], &ch, 1) != 1) break; else {
1327 out += ch;
1328 }
1329 }
1330 }
1331 }
1332
1333 waitpid(pid, 0, 0);
1334 close(inpipe[0]);
1335 close(outpipe[1]);
1336 }
1337
1338 sigaction(SIGCHLD, &osact, 0);
1339 }
1340 face.log(_("+ launched the %s action command"), name.c_str());
1341 return out;
1342 }
1343
getprotocolname(protocolname pname) const1344 string icqconf::getprotocolname(protocolname pname) const {
1345 static const string ptextnames[protocolname_size] = {
1346 "icq", "yahoo", "msn", "aim", "irc", "jab", "rss", "lj", "gg", "infocard"
1347 };
1348
1349 return ptextnames[pname];
1350 }
1351
getprotocolbyletter(char letter) const1352 protocolname icqconf::getprotocolbyletter(char letter) const {
1353 switch(letter) {
1354 case 'y': return yahoo;
1355 case 'a': return aim;
1356 case 'i': return irc;
1357 case 'm': return msn;
1358 case 'n': return infocard;
1359 case 'j': return jabber;
1360 case 'r': return rss;
1361 case 'l': return livejournal;
1362 case 'g': return gadu;
1363 case '0':
1364 case '1':
1365 case '2':
1366 case '3':
1367 case '4':
1368 case '5':
1369 case '6':
1370 case '7':
1371 case '8':
1372 case '9': return icq;
1373 }
1374
1375 return protocolname_size;
1376 }
1377
getprotocolprefix(protocolname pname) const1378 string icqconf::getprotocolprefix(protocolname pname) const {
1379 static const string pprefixes[protocolname_size] = {
1380 "", "y", "m", "a", "i", "j", "r", "l", "g", "n"
1381 };
1382
1383 return pprefixes[pname];
1384 }
1385
getstatus(protocolname pname)1386 imstatus icqconf::getstatus(protocolname pname) {
1387 if(startoffline)
1388 return offline;
1389
1390 imstatus st = available;
1391 map<string, string>::iterator ia;
1392 imaccount a = getourid(pname);
1393
1394 if((ia = a.additional.find("status")) != a.additional.end()) {
1395 if(!ia->second.empty()) {
1396 for(st = offline; st != imstatus_size && imstatus2char[st] != ia->second[0]; st++);
1397 if(st == imstatus_size) st = available;
1398 }
1399 }
1400
1401 return st;
1402 }
1403
savestatus(protocolname pname,imstatus st)1404 void icqconf::savestatus(protocolname pname, imstatus st) {
1405 imaccount im = getourid(pname);
1406 im.additional["status"] = string(1, imstatus2char[st]);
1407 setourid(im);
1408 }
1409
setavatar(protocolname pname,const string & ava)1410 void icqconf::setavatar(protocolname pname, const string &ava) {
1411 imaccount im = getourid(pname);
1412 im.additional["avatar"] = ava;
1413 setourid(im);
1414 }
1415
getprotcolor(protocolname pname) const1416 int icqconf::getprotcolor(protocolname pname) const {
1417 switch(pname) {
1418 case icq : return getcolor(cp_clist_icq);
1419 case yahoo : return getcolor(cp_clist_yahoo);
1420 case infocard : return getcolor(cp_clist_infocard);
1421 case msn : return getcolor(cp_clist_msn);
1422 case aim : return getcolor(cp_clist_aim);
1423 case irc : return getcolor(cp_clist_irc);
1424 case jabber : return getcolor(cp_clist_jabber);
1425 case rss : return getcolor(cp_clist_rss);
1426 case livejournal : return getcolor(cp_clist_lj);
1427 case gadu : return getcolor(cp_clist_gadu);
1428 default : return getcolor(cp_main_text);
1429 }
1430 }
1431
getstatuscolor(imstatus status) const1432 int icqconf::getstatuscolor(imstatus status) const {
1433 switch(status) {
1434 case offline : return getcolor(cp_clist_offline);
1435 case available : return getcolor(cp_clist_online);
1436 case invisible : return getcolor(cp_clist_invisible);
1437 case freeforchat : return getcolor(cp_clist_free_for_chat);
1438 case dontdisturb : return getcolor(cp_clist_dnd);
1439 case occupied : return getcolor(cp_clist_occupied);
1440 case notavail : return getcolor(cp_clist_na);
1441 case outforlunch : return getcolor(cp_clist_na);
1442 case away : return getcolor(cp_clist_away);
1443 default : return getcolor(cp_main_text);
1444 }
1445 }
1446
setbidi(bool fbidi)1447 void icqconf::setbidi(bool fbidi) {
1448 bidi = fbidi;
1449 #ifdef USE_FRIBIDI
1450 use_fribidi = bidi;
1451 #endif
1452 }
1453
commandline(int argc,char ** argv)1454 void icqconf::commandline(int argc, char **argv) {
1455 int i;
1456 string event, proto, dest, number;
1457 char st = 0;
1458
1459 argv0 = argv[0];
1460
1461 for(i = 1; i < argc; i++) {
1462 string args = argv[i];
1463
1464 if((args == "-a") || (args == "--ascii")) {
1465 kintf_graph = 0;
1466
1467 } else if((args == "-b") || (args == "--basedir")) {
1468 if(argv[++i]) {
1469 basedir = argv[i];
1470 if(basedir.substr(basedir.size()-1) != "/") basedir += "/";
1471 }
1472
1473 } else if((args == "-B") || (args == "--bind")) {
1474 if(argv[++i]) {
1475 bindhost = argv[i];
1476 cw_setbind(bindhost.c_str());
1477 }
1478
1479 } else if((args == "-T") || (args == "--no-xtitles")) {
1480 notitles = true;
1481
1482 } else if((args == "-o") || (args == "--offline")) {
1483 startoffline = true;
1484
1485 } else if((args == "-s") || (args == "--send")) {
1486 if(argv[++i]) event = argv[i];
1487
1488 } else if((args == "-p") || (args == "--proto")) {
1489 if(argv[++i]) proto = argv[i];
1490
1491 } else if((args == "-t") || (args == "--to")) {
1492 if(argv[++i]) dest = argv[i];
1493
1494 } else if((args == "-n") || (args == "--number")) {
1495 if(argv[++i]) number = argv[i];
1496
1497 } else if((args == "-S") || (args == "--status")) {
1498 if(argv[++i])
1499 if(strlen(argv[i]))
1500 st = argv[i][0];
1501
1502 } else if((args == "-d") || (args == "--debug")) {
1503 debug = true;
1504
1505 } else if((args == "-v") || (args == "--version")) {
1506 cout << PACKAGE << " " << centerim::version << endl
1507 << "Written by Konstantin Klyagin, 2005. Currently maintained by the CenterIM community." << endl
1508 << "Built-in protocols are:";
1509
1510 for(protocolname pname = icq; pname != protocolname_size; pname++)
1511 if(gethook(pname).enabled()) cout << " " << conf->getprotocolname(pname);
1512
1513 cout << endl << endl
1514 << "This is free software; see the source for copying conditions. There is NO" << endl
1515 << "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." << endl;
1516
1517 exit(0);
1518
1519 } else {
1520 usage();
1521 exit(0);
1522 }
1523 }
1524
1525 if(!number.empty()) {
1526 if(event.empty()) event = "sms";
1527 if(proto.empty()) proto = "icq";
1528 dest = "0";
1529 }
1530
1531 constructevent(event, proto, dest, number);
1532 externalstatuschange(st, proto);
1533 }
1534
constructevent(const string & event,const string & proto,const string & dest,const string & number) const1535 void icqconf::constructevent(const string &event, const string &proto,
1536 const string &dest, const string &number) const {
1537
1538 imevent *ev = 0;
1539 imcontact cdest;
1540 string text, buf;
1541 int pos;
1542
1543 if(event.empty() && dest.empty()) return; else
1544 if(event.empty() || proto.empty() || dest.empty()) {
1545 cout << _("event sending error: not enough parameters") << endl;
1546 exit(1);
1547 }
1548
1549 while(getline(cin, buf)) {
1550 if(!text.empty()) text += "\n";
1551 text += buf;
1552 }
1553
1554 if(proto == "icq") {
1555 if(dest.find_first_not_of("0123456789") != -1) {
1556 cout << _("event sending error: only UINs are allowed with icq protocol") << endl;
1557 exit(1);
1558 }
1559 cdest = imcontact(strtoul(dest.c_str(), 0, 0), icq);
1560 } else {
1561 protocolname pname;
1562
1563 for(pname = icq; pname != protocolname_size; pname++) {
1564 if(getprotocolname(pname) == proto) {
1565 cdest = imcontact(dest, pname);
1566 break;
1567 }
1568 }
1569
1570 if(pname == protocolname_size) {
1571 cout << _("event sending error: unknown IM type") << endl;
1572 exit(1);
1573 }
1574 }
1575
1576 if(event == "msg") {
1577 ev = new immessage(cdest, imevent::outgoing, text);
1578 } else if(event == "url") {
1579 string url;
1580
1581 if((pos = text.find("\n")) != -1) {
1582 url = text.substr(0, pos);
1583 text.erase(0, pos+1);
1584 } else {
1585 url = text;
1586 text = "";
1587 }
1588
1589 ev = new imurl(cdest, imevent::outgoing, url, text);
1590 } else if(event == "sms") {
1591 ev = new imsms(cdest, imevent::outgoing, text, number);
1592 } else {
1593 cout << _("event sending error: unknown event type") << endl;
1594 exit(1);
1595 }
1596
1597 if(ev) {
1598 icqcontact *c = new icqcontact(cdest);
1599
1600 if(access(c->getdirname().c_str(), X_OK)) {
1601 mkdir(c->getdirname().c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
1602 selfsignal(SIGUSR2);
1603 }
1604
1605 if(!access(c->getdirname().c_str(), X_OK)) {
1606 clist.add(c);
1607 em.store(*ev);
1608
1609 char buf[512];
1610 snprintf(buf, sizeof(buf), _("%s to %s has been put to the queue"),
1611 streventname(ev->gettype()),
1612 number.empty() ? c->getdesc().totext().c_str() : number.c_str());
1613
1614 cout << buf << endl;
1615 } else {
1616 cout << _("event sending error: error creating directory for the contact") << endl;
1617 exit(1);
1618 }
1619
1620 //delete c;
1621 delete ev;
1622
1623 exit(0);
1624 }
1625 }
1626
selfsignal(int signum) const1627 void icqconf::selfsignal(int signum) const {
1628 int rpid;
1629 ifstream f(conf->getconfigfname("pid").c_str());
1630
1631 if(f.is_open()) {
1632 f >> rpid;
1633 f.close();
1634
1635 if(rpid > 0) {
1636 kill(rpid, signum);
1637 }
1638 }
1639 }
1640
externalstatuschange(char st,const string & proto) const1641 void icqconf::externalstatuschange(char st, const string &proto) const {
1642 imstatus imst;
1643 protocolname pname;
1644
1645 if(st) {
1646 for(pname = icq; pname != protocolname_size; pname++)
1647 if(getprotocolname(pname) == proto)
1648 break;
1649
1650 for(imst = offline; imst != imstatus_size; imst++)
1651 if(imstatus2char[imst] == st)
1652 break;
1653
1654 try {
1655 if(pname != protocolname_size) {
1656 if(imst != imstatus_size) {
1657 string sfname = conf->getconfigfname((string) "status-" + proto);
1658 ofstream sf(sfname.c_str());
1659 if(sf.is_open()) sf << imstatus2char[imst], sf.close();
1660
1661 selfsignal(SIGUSR1);
1662 } else {
1663 throw _("unknown status character was given");
1664 }
1665 } else {
1666 throw _("unknown IM type");
1667 }
1668 } catch(char *p) {
1669 cout << _("status change error: ") << p << endl;
1670 exit(1);
1671 }
1672
1673 exit(0);
1674 }
1675 }
1676
usage() const1677 void icqconf::usage() const {
1678 cout << PACKAGE << " " << centerim::version << endl;
1679
1680 cout << endl << _("Usage: ") << argv0 << _(" [OPTION]...") << endl;
1681
1682 cout << endl << _("General options:") << endl;
1683 cout << _(" --ascii, -a use ASCII characters for windows and UI controls") << endl;
1684 cout << _(" --basedir, -b <path> set a custom base directory") << endl;
1685 cout << _(" --bind, -B <host/ip> bind a custom local IP") << endl;
1686 cout << _(" --no-xtitles, -T disable xterm titles") << endl;
1687 cout << _(" --offline, -o set all protocols status to offline upon start") << endl;
1688 cout << _(" --debug, -d enables debug info logging") << endl;
1689 cout << _(" --help display this stuff") << endl;
1690 cout << _(" --version, -v show the program version info") << endl;
1691
1692 cout << endl << _("Events sending options:") << endl;
1693 cout << _(" -s, --send <event type> event type; can be msg, sms or url") << endl;
1694 cout << _(" -S, --status <status> change the current IM status. Status; o, _, a, d, n, c, f, i") << endl;
1695 cout << _(" -p, --proto <protocol> protocol type; can be icq, yahoo, msn, aim, irc, jab, rss, lj, gg or infocard") << endl;
1696
1697 cout << _(" -t, --to <destination> destination UIN or nick (depends on protocol)") << endl;
1698 cout << _(" -n, --number <phone#> mobile number to send an event to (sms only)") << endl;
1699
1700 cout << endl << _("Report bugs to http://bugzilla.centerim.org/.") << endl;
1701 }
1702
setproxy()1703 void icqconf::setproxy() {
1704 if(getproxyconnect()) {
1705 cw_setproxy(gethttpproxyhost().c_str(), gethttpproxyport(),
1706 gethttpproxyuser().c_str(),
1707 gethttpproxypasswd().c_str());
1708
1709 } else {
1710 cw_setproxy(0, 0, 0, 0);
1711
1712 }
1713 }
1714
setmakelog(bool slog)1715 void icqconf::setmakelog(bool slog) {
1716 makelog = slog;
1717 }
1718
setproxyconnect(bool sproxy)1719 void icqconf::setproxyconnect(bool sproxy) {
1720 proxyconnect = sproxy;
1721 setproxy();
1722 }
1723
setproxyssl(bool sproxyssl)1724 void icqconf::setproxyssl(bool sproxyssl) {
1725 proxyssl = sproxyssl;
1726 }
1727
setgroupmode(icqconf::groupmode amode)1728 void icqconf::setgroupmode(icqconf::groupmode amode) {
1729 fgroupmode = amode;
1730 }
1731
setsortmode(icqconf::sortmode smode)1732 void icqconf::setsortmode(icqconf::sortmode smode) {
1733 fsortmode = smode;
1734 icqcontacts::setsortmode(smode);
1735 }
1736
initmultiproto(bool p[],string buf,bool excludenochat)1737 void icqconf::initmultiproto(bool p[], string buf, bool excludenochat) {
1738 string w;
1739 protocolname pname;
1740
1741 for(pname = icq; pname != protocolname_size; pname++)
1742 p[pname] = buf.empty();
1743
1744 while(!(w = getword(buf)).empty()) {
1745 for(pname = icq; pname != protocolname_size; pname++) {
1746 if(getprotocolname(pname) == w) {
1747 if(excludenochat) {
1748 p[pname] = !gethook(pname).getCapabs().count(hookcapab::nochat);
1749 } else {
1750 p[pname] = true;
1751 }
1752 break;
1753 }
1754 }
1755 }
1756 }
1757
setbrowser(const string & abrowser)1758 void icqconf::setbrowser(const string &abrowser) {
1759 if (!abrowser.empty())
1760 browser = abrowser;
1761 else
1762 browser = "mozilla";
1763 }
1764
setsmtphost(const string & asmtphost)1765 void icqconf::setsmtphost(const string &asmtphost) {
1766 int pos;
1767
1768 smtphost = "";
1769 smtpport = 0;
1770
1771 if(!asmtphost.empty()) {
1772 if((pos = asmtphost.find(":")) != -1) {
1773 smtphost = asmtphost.substr(0, pos);
1774 smtpport = atol(asmtphost.substr(pos+1).c_str());
1775 } else {
1776 smtphost = asmtphost;
1777 smtpport = 25;
1778 }
1779 }
1780
1781 if(smtphost.empty() || !smtpport) {
1782 smtphost = getsmtphost();
1783 smtpport = getsmtpport();
1784 }
1785 }
1786
sethttpproxyhost(const string & ahttpproxyhost)1787 void icqconf::sethttpproxyhost(const string &ahttpproxyhost) {
1788 int pos, posn;
1789
1790 httpproxyhost = "";
1791 httpproxyport = 0;
1792 httpproxyuser = "";
1793 httpproxypasswd = "";
1794
1795 if(!ahttpproxyhost.empty()) {
1796 if((pos = ahttpproxyhost.find(":")) != -1) {
1797 if ((posn = ahttpproxyhost.find("@")) != -1) {
1798 httpproxyuser = ahttpproxyhost.substr(0, pos);
1799 httpproxypasswd = ahttpproxyhost.substr(pos+1, posn-pos-1);
1800 if((pos = ahttpproxyhost.find(":", posn)) != -1) {
1801 httpproxyhost = ahttpproxyhost.substr(posn+1, pos-posn-1);
1802 httpproxyport = atol(ahttpproxyhost.substr(pos+1).c_str());
1803 }
1804 } else {
1805 httpproxyhost = ahttpproxyhost.substr(0, pos);
1806 httpproxyport = atol(ahttpproxyhost.substr(pos+1).c_str());
1807 }
1808 } else {
1809 httpproxyhost = ahttpproxyhost;
1810 httpproxyport = 8080;
1811 }
1812 }
1813
1814 setproxy();
1815 }
1816
getbrowser() const1817 string icqconf::getbrowser() const {
1818 return browser.empty() ? "mozilla" : browser;
1819 }
1820
getsmtphost() const1821 string icqconf::getsmtphost() const {
1822 return smtphost.empty() ? "localhost" : smtphost;
1823 }
1824
getsmtpport() const1825 unsigned int icqconf::getsmtpport() const {
1826 return smtpport ? smtpport : 25;
1827 }
1828
gethttpproxyhost() const1829 string icqconf::gethttpproxyhost() const {
1830 return httpproxyhost;
1831 }
1832
gethttpproxyport() const1833 unsigned int icqconf::gethttpproxyport() const {
1834 return httpproxyport ? httpproxyport : 8080;
1835 }
1836
gethttpproxyuser() const1837 string icqconf::gethttpproxyuser() const {
1838 return httpproxyuser;
1839 }
1840
gethttpproxypasswd() const1841 string icqconf::gethttpproxypasswd() const {
1842 return httpproxypasswd;
1843 }
1844
checkdiskspace()1845 void icqconf::checkdiskspace() {
1846 fenoughdiskspace = true;
1847
1848 #if !(defined(__sun__) || defined(__NetBSD__) || defined(__sgi__))
1849 struct statfs st;
1850 if(!statfs(conf->getdirname().c_str(), &st)) {
1851 #else
1852 struct statvfs st;
1853 if(!statvfs(conf->getdirname().c_str(), &st)) {
1854 #endif
1855 fenoughdiskspace = ((double) st.f_bavail) * st.f_bsize >= 10240;
1856 }
1857 }
1858
1859 void icqconf::setcharsets(const string &from, const string &to) {
1860 fromcharset = from;
1861 tocharset = to;
1862 }
1863
1864 const char *icqconf::getconvertfrom(protocolname pname) const {
1865 if(pname != protocolname_size && !getcpconvert(pname)) return "iso-8859-1";
1866 return fromcharset.c_str();
1867 }
1868
1869 const char *icqconf::getconvertto(protocolname pname) const {
1870 if(pname != protocolname_size && !getcpconvert(pname)) return "iso-8859-1";
1871 return tocharset.c_str();
1872 }
1873
1874 // ----------------------------------------------------------------------------
1875
1876 icqconf::imaccount::imaccount() {
1877 uin = port = 0;
1878 pname = infocard;
1879 }
1880
1881 icqconf::imaccount::imaccount(protocolname apname) {
1882 uin = port = 0;
1883 pname = apname;
1884 }
1885
1886 bool icqconf::imaccount::empty() const {
1887 return !uin && nickname.empty();
1888 }
1889
1890 void icqconf::imaccount::write(ofstream &f) {
1891 string prefix = conf->getprotocolname(pname) + "_";
1892 map<string, string>::iterator ia;
1893
1894 f << endl;
1895 if(!nickname.empty()) f << prefix << "nick\t" << nickname << endl;
1896 if(uin) f << prefix << "uin\t" << uin << endl;
1897 if(conf->getsavepwd()) f << prefix << "pass\t" << password << endl;
1898 if(!server.empty()) {
1899 f << prefix << "server\t" << server;
1900 if(port) f << ":" << port;
1901 f << endl;
1902 }
1903
1904 for(ia = additional.begin(); ia != additional.end(); ++ia)
1905 if(!ia->first.empty() && !ia->second.empty())
1906 f << prefix << ia->first << "\t" << ia->second << endl;
1907 }
1908
1909 void icqconf::imaccount::read(const string &spec) {
1910 int pos = spec.find("_");
1911 string spname, buf;
1912
1913 if(pos != -1) {
1914 buf = spec;
1915 spname = getword(buf.erase(0, pos+1));
1916
1917 if(spname == "nick") nickname = buf; else
1918 if(spname == "uin") uin = strtoul(buf.c_str(), 0, 0); else
1919 if(spname == "pass") password = buf; else
1920 if(spname == "server") {
1921 if((pos = buf.find(":")) != -1) {
1922 server = buf.substr(0, pos);
1923 port = strtoul(buf.substr(pos+1).c_str(), 0, 0);
1924 } else {
1925 server = buf;
1926 }
1927
1928 if(pname == icq)
1929 if(server == "icq.mirabilis.com")
1930 server = "";
1931
1932 if(pname == yahoo)
1933 if(server == "scs.yahoo.com")
1934 server = "";
1935
1936 } else {
1937 additional[spname] = buf;
1938 }
1939 }
1940 }
1941
1942 bool icqconf::imaccount::operator == (protocolname apname) const {
1943 return pname == apname;
1944 }
1945
1946 bool icqconf::imaccount::operator != (protocolname apname) const {
1947 return pname != apname;
1948 }
1949