root/climm/src/file_util.c

Revision 2859, 67.8 kB (checked in by kuhlmann, 6 months ago)

make sure server's contact is initialized (causes segfault on initial setup)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /* $Id$ */
2 /* Copyright: This file may be distributed under version 2 of the GPL licence. */
3
4 #include "climm.h"
5 #include <stdarg.h>
6 #include <assert.h>
7 #include <ctype.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #if HAVE_SYS_TYPES_H
11 #include <sys/types.h>
12 #endif
13 #if HAVE_SYS_STAT_H
14 #include <sys/stat.h>
15 #endif
16 #if HAVE_UNISTD_H
17 #include <unistd.h>
18 #endif
19 #if HAVE_NETINET_IN_H
20 #include <netinet/in.h>
21 #endif
22 #if HAVE_TERMIOS_H
23 #include <termios.h>
24 #endif
25 #if HAVE_ARPA_INET_H
26 #include <arpa/inet.h>
27 #endif
28
29 #include "buildmark.h"
30 #include "util_ui.h"
31 #include "file_util.h"
32 #include "util_alias.h"
33 #include "util_tabs.h"
34 #include "contact.h"
35 #include "oscar_dc.h"
36 #include "util.h"
37 #include "conv.h"
38 #include "cmd_user.h"
39 #include "preferences.h"
40 #include "util_io.h"
41 #include "remote.h"
42 #include "oscar_base.h" /* IcqToStatus */
43 #include "connection.h"
44 #include "util_parse.h"
45 #include "util_rl.h"
46
47 /****/
48 #define USER_PROMPT "%4c%b%p%d://%1c%b%n%3c/%2c%b%s%8c %t%7c%b>%6c%r%7c%b<%6c%b%a%7c%b>"
49 /*#define USER_PROMPT "%n@%p:%s %t>%r<%a>"*/
50 #define USER_PROMPT_STRFTIME "%c"
51
52 #define WAND1 " \xb7 \xb7 "
53 #define WAND2 "\xb7 o \xb7"
54 #define WAND3 " \xb7 \\ "
55 #define WAND4 "    \\"
56
57 Server *PrefNewConnection (UDWORD servertype, const char *user, const char *passwd)
58 {
59     Server *serv = NULL;
60     Contact *cont;
61    
62     if (servertype == TYPE_SERVER)
63     {
64         serv = ServerC (servertype);
65        
66         serv->flags |= CONN_AUTOLOGIN;
67         serv->pref_server = strdup ("login.icq.com");
68         serv->pref_port = 5190;
69         serv->pref_status = ims_online;
70         serv->pref_version = 8;
71         s_repl (&serv->screen, user);
72         serv->oscar_uin = atoi (user);
73         serv->pref_passwd = passwd ? strdup (passwd) : NULL;
74        
75         serv->conn->server  = strdup (serv->pref_server);
76         serv->conn->port    = serv->pref_port;
77         serv->passwd  = passwd ? strdup (passwd) : NULL;
78         serv->status  = ims_online;
79
80         serv->contacts = ContactGroupC (serv, 0, s_sprintf ("contacts-icq8-%s", user));
81         OptSetVal (&serv->copts, CO_IGNORE, 0);
82        
83         cont = ContactUIN (serv, 82274703);
84         ContactCreate (serv, cont);
85         ContactAddAlias (cont, "climm");
86         ContactAddAlias (cont, "Tadu");
87         OptSetStr (&cont->copts, CO_COLORINCOMING, OptC2S ("red bold"));
88         OptSetStr (&cont->copts, CO_COLORMESSAGE, OptC2S ("red bold"));
89         rl_print ("\n");
90         rl_printf (i18n (2381, "I'll add the author of climm to your contact list for your convenience. Don't abuse this opportunity - please use the help command and make a serious attempt to read the man pages and the FAQ before asking questions.\n"));
91         rl_print ("\n");
92     }
93 #ifdef ENABLE_XMPP
94     else if (servertype == TYPE_XMPP_SERVER)
95     {
96         const char *serverpart = strchr (user, '@') + 1;
97    
98         serv = ServerC (servertype);
99        
100         serv->flags |= CONN_AUTOLOGIN;
101         if (!strcmp (serverpart, "gmail.com") || !strcmp (serverpart, "gmail.com"))
102             serv->pref_server = strdup ("talk.google.com");
103         else
104             serv->pref_server = strdup (serverpart);
105         serv->pref_port = 5222;
106         serv->pref_status = ims_online;
107         serv->pref_version = 8;
108         s_repl (&serv->screen, user);
109         serv->pref_passwd = passwd ? strdup (passwd) : NULL;
110        
111         serv->conn->server  = strdup (serv->pref_server);
112         serv->conn->port    = serv->pref_port;
113         serv->passwd  = passwd ? strdup (passwd) : NULL;
114         serv->status  = ims_online;
115
116         serv->contacts = ContactGroupC (serv, 0, s_sprintf ("contacts-xmpp-%s", user));
117         OptSetVal (&serv->copts, CO_IGNORE, 0);
118        
119         cont = ContactScreen (serv, "RKuhlmann@gmail.com");
120         ContactCreate (serv, cont);
121         ContactAddAlias (cont, "climm");
122         ContactAddAlias (cont, "Tadu");
123         OptSetStr (&cont->copts, CO_COLORINCOMING, OptC2S ("red bold"));
124         OptSetStr (&cont->copts, CO_COLORMESSAGE, OptC2S ("red bold"));
125         rl_print ("\n");
126         rl_printf (i18n (2381, "I'll add the author of climm to your contact list for your convenience. Don't abuse this opportunity - please use the help command and make a serious attempt to read the man pages and the FAQ before asking questions.\n"));
127         rl_print ("\n");
128     }
129 #endif
130 #ifdef ENABLE_MSN
131     else if (servertype == TYPE_MSN_SERVER)
132     {
133         serv = ServerC (servertype);
134        
135         serv->flags |= CONN_AUTOLOGIN;
136         serv->pref_server = strdup (strchr (user, '@') + 1);
137         serv->pref_port = 42;
138         serv->pref_status = ims_online;
139         serv->pref_version = 8;
140         s_repl (&serv->screen, user);
141         serv->pref_passwd = passwd ? strdup (passwd) : NULL;
142        
143         serv->conn->server  = strdup (serv->pref_server);
144         serv->conn->port    = serv->pref_port;
145         serv->passwd  = passwd ? strdup (passwd) : NULL;
146         serv->status  = ims_online;
147
148         serv->contacts = ContactGroupC (serv, 0, s_sprintf ("contacts-msn-%s", user));
149         OptSetVal (&serv->copts, CO_IGNORE, 0);
150     }
151 #endif
152     serv->conn->cont = ContactScreen (serv, serv->screen);
153     return serv;
154 }
155
156 void Initialize_RC_File ()
157 {
158     strc_t line;
159     Server *conn;
160     char *user = NULL;
161     char *passwd;
162     char *t;
163     UDWORD servertype = 0;
164    
165     prG->away_time = default_away_time;
166
167     rl_print ("\n");
168     rl_print (i18n (2612, "No valid user account found. The setup wizard will guide you through the process of setting one up.\n"));
169     rl_print (i18n (2613, "You first need to enter a user account you want to use. This climm supports the following chat protocols:\n"));
170     rl_print ("  *  ");
171     rl_printf (i18n (2614, "%s, enter i.e. %s\n"), "ICQ", "12345678");
172 #ifdef ENABLE_XMPP
173     rl_print ("  *  ");
174     rl_printf (i18n (2614, "%s, enter i.e. %s\n"), "XMPP (Jabber, Google Talk)", "example@gmail.com");
175 #endif
176 #ifdef ENABLE_MSN
177     rl_print ("  *  ");
178     rl_printf (i18n (2614, "%s, enter i.e. %s\n"), "MSN", "fool@hotmale.net");
179 #endif
180     while (1)
181     {
182         servertype = 0;
183         while (!servertype)
184         {
185             rl_printf ("%s ", i18n (2615, "User account ID:"));
186             fflush (stdout);
187             ReadLineTtyUnset ();
188             line = UtilIOReadline (stdin);
189             ReadLineTtySet ();
190            
191             if (!line || !line->len)
192             {
193                 if (!user)
194                     continue;
195                 break;
196             }
197
198 #ifdef ENABLE_XMPP
199             if (is_valid_xmpp_name (line->txt))
200                 servertype = TYPE_XMPP_SERVER;
201             else
202 #endif
203             if (is_valid_icq_name (line->txt))
204                 servertype = TYPE_SERVER;
205             else
206 #ifdef ENABLE_MSN
207             if (is_valid_msn_name (line->txt))
208                 servertype = TYPE_MSN_SERVER;
209             else
210 #endif
211                 rl_printf (i18n (2616, "Cannot parse %s as a valid user ID. Try again!\n"), line->txt);
212         }
213         if (user && !servertype)
214             break;
215
216         user = strdup (line->txt);
217        
218         rl_print ("\n");
219         rl_printf (i18n (2617, "Next you can allow climm to store your password for %s account %s. Enter nothing to not save the password.\n"),
220             ConnectionServerType (servertype), user);
221        
222         rl_printf ("%s ", i18n (1795, "Password:"));
223         fflush (stdout);
224         line = UtilIOReadline (stdin);
225         rl_print ("\n");
226
227         passwd = line && line->len ? strdup (c_out (line->txt)) : NULL;
228         conn = PrefNewConnection (servertype, user, passwd);
229         conn->flags |= CONN_WIZARD;
230         free (user);
231         s_free (passwd);
232         rl_print (i18n (2618, "You may add more user accounts now. Enter nothing to not add more accounts.\n"));
233     }
234
235     rl_print (i18n (1784, "If you are firewalled, you may need to use a SOCKS5 server. If you do, please enter its hostname or IP address. Otherwise, or if unsure, just press return.\n"));
236     rl_printf ("%s ", i18n (1094, "SOCKS5 server:"));
237     fflush (stdout);
238     ReadLineTtyUnset ();
239     line = UtilIOReadline (stdin);
240     if (line && line->len)
241     {
242         if (strchr (line->txt, ':'))
243         {
244             char *tmp = strdup (line->txt);
245             t = strchr (tmp, ':');
246             OptSetVal (&prG->copts, CO_S5PORT, atoi (t + 1));
247             *t = '\0';
248             OptSetStr (&prG->copts, CO_S5HOST, tmp);
249             free (tmp);
250         }
251         else
252         {
253             UWORD p = 0;
254             OptSetStr (&prG->copts, CO_S5HOST, line->txt);
255             rl_print (i18n (1786, "I also need the port the socks server listens on. If unsure, press return for the default port.\n"));
256             rl_printf ("%s ", i18n (1095, "SOCKS5 port:"));
257             fflush (stdout);
258             line = UtilIOReadline (stdin);
259             if (line)
260                 sscanf (line->txt, "%hu", &p);
261             if (!p)
262                 p = 1080;
263             OptSetVal (&prG->copts, CO_S5PORT, p);
264         }
265         OptSetVal (&prG->copts, CO_S5USE, 1);
266
267         rl_print ("\n");
268         rl_print (i18n (1787, "You probably need to authenticate yourself to the socks server. If so, you need to enter the user name the administrator of the socks server gave you. Otherwise, just press return.\n"));
269         rl_printf ("%s ", i18n (1096, "SOCKS5 user name:"));
270         fflush (stdout);
271         line = UtilIOReadline (stdin);
272         if (line && line->len)
273         {
274             OptSetStr (&prG->copts, CO_S5NAME, line->txt);
275             rl_print (i18n (1788, "Now I also need the password for this user.\n"));
276             rl_printf ("%s ", i18n (1097, "SOCKS5 password:"));
277             fflush (stdout);
278             line = UtilIOReadline (stdin);
279             if (line && line->len)
280                 OptSetStr (&prG->copts, CO_S5PASS, line->txt);
281         }
282     }
283     rl_print ("\n");
284     ReadLineTtySet ();
285
286     rl_print (i18n (1791, "Setup wizard finished. Congratulations!\n"));
287     rl_print ("\n");
288    
289     {
290         char *tmp = strdup (PrefUserDir (prG));
291         if (tmp[strlen (tmp) - 1] == '/')
292             tmp[strlen (tmp) - 1] = '\0';
293         mkdir (tmp, 0700);
294         free (tmp);
295     }
296 #ifdef ENABLE_REMOTECONTROL
297     OptSetVal (&prG->copts, CO_SCRIPT, 1);
298     OptSetStr (&prG->copts, CO_SCRIPT_PATH, "scripting");
299 #endif
300
301     prG->prompt    = strdup (USER_PROMPT);
302     prG->prompt_strftime = strdup (USER_PROMPT_STRFTIME);
303     prG->logplace  = strdup ("history" _OS_PATHSEPSTR);
304     prG->chat      = 49;
305     prG->autoupdate = AUTOUPDATE_CURRENT;
306     prG->status = ims_online;
307     prG->flags = FLAG_DELBS | FLAG_AUTOSAVE;
308 #ifdef ANSI_TERM
309     prG->flags |= FLAG_COLOR;
310 #endif
311
312     OptSetVal (&prG->copts, CO_LOGMESS,    1);
313     OptSetVal (&prG->copts, CO_LOGONOFF,   1);
314     OptSetVal (&prG->copts, CO_LOGCHANGE,  1);
315     OptSetVal (&prG->copts, CO_SHOWONOFF,  1);
316     OptSetVal (&prG->copts, CO_SHOWCHANGE, 1);
317     OptSetVal (&prG->copts, CO_AUTOAUTO,   0);
318     OptSetVal (&prG->copts, CO_WANTSBL,    1);
319     OptSetVal (&prG->copts, CO_PEEKME,     0);
320     OptSetVal (&prG->copts, CO_REVEALTIME, 600);
321
322     OptSetStr (&prG->copts, CO_AUTODND,  i18n (1929, "User is dnd [Auto-Message]"));
323     OptSetStr (&prG->copts, CO_AUTOAWAY, i18n (1010, "User is away [Auto-Message]"));
324     OptSetStr (&prG->copts, CO_AUTONA,   i18n (1011, "User is not available [Auto-Message]"));
325     OptSetStr (&prG->copts, CO_AUTOOCC,  i18n (1012, "User is occupied [Auto-Message]"));
326     OptSetStr (&prG->copts, CO_AUTOFFC,  i18n (2055, "User is ffc and wants to chat about everything."));
327
328     Save_RC ();
329 }
330
331 #define PrefParse(x)          switch (1) { case 1: if (!(par = s_parse (&args))) { rl_printf (i18n (2123, "%sSyntax error%s: Too few arguments: %s\n"), COLERROR, COLNONE, s_qquote (line->txt)); continue; } x = par->txt; }
332 #define PrefParseInt(i)       switch (1) { case 1: if (!s_parseint (&args, &i))  { rl_printf (i18n (2124, "%sSyntax error%s: Not an integer: %s\n"), COLERROR, COLNONE, s_qquote (line->txt)); continue; }}
333 #define ERROR continue;
334
335 /*
336  * Reads in a configuration file.
337  */
338 int Read_RC_File (FILE *rcf)
339 {
340     char *tmp = NULL, *tmp2 = NULL, *cmd = NULL;
341     strc_t line, par;
342     const char *args, *p;
343     Contact *cont = NULL, *lastcont = NULL;
344     Server *serv = NULL, *oldserv = NULL, *tserv;
345     ContactGroup *cg = NULL;
346     int section, dep = 0;
347     val_t v;
348     UDWORD uin, i, j;
349     UWORD flags;
350     UBYTE enc = ENC_LATIN1, format = 0;
351
352     for (section = 0; (line = UtilIOReadline (rcf)); )
353     {
354         if (!line->len || (line->txt[0] == '#'))
355             continue;
356         args = ConvFrom (line, enc)->txt;
357         if (*args == '[')
358         {
359             if (!strcasecmp (args, "[General]"))
360                 section = 0;
361             else if (!strcasecmp (args, "[Contacts]"))
362                 section = 1;
363             else if (!strcasecmp (args, "[Strings]"))
364                 section = 2;
365             else if (!strcasecmp (args, "[Connection]") || !strcasecmp (args, "[Server]"))
366             {
367                 section = 3;
368                 oldserv = serv;
369                 serv = NULL;
370             }
371             else if (!strcasecmp (args, "[Group]"))
372             {
373                 section = 4;
374                 cg = ContactGroupC (NULL, 0, NULL);
375                 OptSetVal (&cg->copts, CO_IGNORE, 0);
376                 if ((serv = ServerNr (0)))
377                     cg->serv = serv;
378                 cont = NULL;
379             }
380             else
381             {
382                 rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
383                 rl_printf (i18n (1659, "Unknown section '%s' in configuration file."), args);
384                 rl_print ("\n");
385                 section = -1;
386             }
387             continue;
388         }
389         switch (section)
390         {
391             case -1:
392                 rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
393                 rl_print  (i18n (1675, "Ignored line:"));
394                 rl_printf (" %s\n", args);
395                 break;
396             case 0:
397                 if (!(par = s_parse (&args)))
398                     continue;
399                 cmd = par->txt;
400
401                 if (!strcasecmp (cmd, "encoding"))
402                 {
403                     int which, what;
404                     PrefParse (cmd);
405                    
406                     if (!strcasecmp (cmd, "remote"))
407                         which = 1;
408                     else if (!strcasecmp (cmd, "local"))
409                         which = 2;
410                     else if (!strcasecmp (cmd, "file"))
411                         which = 3;
412                     else
413                         ERROR;
414                    
415                     PrefParse (cmd);
416                     if (!strcasecmp (cmd, "auto"))
417                         continue;
418                     else if (!strcasecmp (cmd, "utf8"))
419                     {   what = ConvEnc ("UTF-8");        dep = 1; }
420                     else if (!strcasecmp (cmd, "latin1"))
421                     {   what = ConvEnc ("ISO-8859-1");   dep = 2; }
422                     else if (!strcasecmp (cmd, "latin9"))
423                     {   what = ConvEnc ("ISO-8859-15");  dep = 3; }
424                     else if (!strcasecmp (cmd, "koi8"))
425                     {   what = ConvEnc ("KOI8-U");       dep = 4; }
426                     else if (!strcasecmp (cmd, "win1251"))
427                     {   what = ConvEnc ("CP-1251");      dep = 5; }
428                     else if (!strcasecmp (cmd, "euc"))
429                     {   what = ConvEnc ("EUC-JP");       dep = 6; }
430                     else if (!strcasecmp (cmd, "sjis"))
431                     {   what = ConvEnc ("SHIFT-JIS");    dep = 7; }
432                     else
433                         what = ConvEnc (cmd);
434
435                     if (!what)
436                     {
437                         rl_printf ("%s%s%s ", COLERROR, i18n (2251, "Error:"), COLNONE);
438                         rl_printf (i18n (2216, "This climm doesn't know the '%s' encoding.\n"), cmd);
439                         ERROR;
440                     }
441                     if (what & ENC_FERR)
442                     {
443                         if ((what & ~ENC_FLAGS) != ENC_UTF8)
444                         {
445                             if ((which == 3 && (what ^ prG->enc_loc) & ~ENC_FLAGS)
446                                 || (which == 2 && (what ^ enc) & ~ENC_FLAGS))
447                                 rl_printf ("%s%s%s ", COLERROR, i18n (2251, "Error:"), COLNONE);
448                             else
449                                 rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
450                             rl_printf (i18n (2217, "This climm can't convert between '%s' and unicode.\n"), cmd);
451                         }
452                         what &= ~ENC_FLAGS;
453                     }
454                     if (which == 1)
455                     {
456                         OptSetVal (&prG->copts, CO_ENCODING, what);
457                         OptSetStr (&prG->copts, CO_ENCODINGSTR, ConvEncName (what));
458                         dep = 17;
459                     }
460                     else if (which == 2)
461                     {
462                         if (ENC (enc_loc) != what)
463                             prG->locale_broken = 2;
464                         prG->enc_loc = what;
465                     }
466                     else
467                     {
468                         if (what != ENC_UTF8)
469                             dep = 13;
470                         enc = what;
471                     }
472                 }
473                 else if (!strcasecmp (cmd, "format"))
474                 {
475                     PrefParseInt (i);
476                     format = i;
477                     if (format > 3)
478                     {
479                         rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
480                         rl_printf (i18n (2457, "Unknown configuration file format version %d.\n"), format);
481                         return 0;
482                     }
483                     if (format >= 2)
484                         enc = ENC_UTF8;
485                     if (format < 3)
486                         dep = 45;
487                 }
488 #ifdef ENABLE_TCL
489                 else if (!strcasecmp (cmd, "tclscript"))
490                 {
491                     PrefParse (tmp);
492                     TCLPrefAppend (TCL_FILE, tmp);
493                 }
494                 else if (!strcasecmp (cmd, "tcl"))
495                 {
496                     PrefParse (tmp);
497                     TCLPrefAppend (TCL_CMD, tmp);
498                 }
499 #endif
500                 else if (!strcasecmp (cmd, "receivescript") || !strcasecmp (cmd, "event"))
501                 {
502                     if (!strcasecmp (cmd, "receivescript"))
503                         dep = 8;
504                     if (!(par = s_parse (&args)))
505                     {
506                         dep = 9;
507                         prG->event_cmd = NULL;
508                         continue;
509                     }
510                     tmp = par->txt;
511                     if (!strcmp (tmp, "off") || !strcmp (tmp, i18n (1086, "off")) || !*tmp)
512                         prG->event_cmd = NULL;
513                     else
514                     {
515                         prG->event_cmd = strdup (tmp);
516 #ifndef MSGEXEC
517                         rl_printf (COLERROR "%s" COLNONE " ", i18n (1619, "Warning:"));
518                         rl_printf (i18n (1817, "The event scripting feature is disabled.\n"));
519 #endif
520                     }
521                 }
522                 else if (!strcasecmp (cmd, "s5_use"))
523                 {
524                     PrefParseInt (i);
525                     OptSetVal (&prG->copts, CO_S5USE, i ? 1 : 0);
526                     dep = 55;
527                 }
528                 else if (!strcasecmp (cmd, "s5_host"))
529                 {
530                     PrefParse (tmp);
531                     OptSetStr (&prG->copts, CO_S5HOST, tmp);
532                     dep = 55;
533                 }
534                 else if (!strcasecmp (cmd, "s5_port"))
535                 {
536                     PrefParseInt (i);
537                     OptSetVal (&prG->copts, CO_S5PORT, i);
538                     dep = 55;
539                 }
540                 else if (!strcasecmp (cmd, "s5_auth"))
541                 {
542                     PrefParseInt (i);
543                     dep = 55;
544                 }
545                 else if (!strcasecmp (cmd, "s5_name"))
546                 {
547                     PrefParse (tmp);
548                     OptSetStr (&prG->copts, CO_S5NAME, tmp);
549                     dep = 55;
550                 }
551                 else if (!strcasecmp (cmd, "s5_pass"))
552                 {
553                     PrefParse (tmp);
554                     OptSetStr (&prG->copts, CO_S5PASS, tmp);
555                     dep = 55;
556                 }
557                 else if (!strcasecmp (cmd, "verbose"))
558                 {
559                     PrefParseInt (i);
560                     if (!prG->verbose)
561                         prG->verbose = i;
562                 }
563                 else if (!strcasecmp (cmd, "logplace"))
564                 {
565                     PrefParse (tmp);
566                     if (!prG->logplace) /* don't overwrite command line arg */
567                         prG->logplace = strdup (tmp);
568                 }
569                 else if (!strcasecmp (cmd, "chat"))
570                 {
571                     PrefParseInt (i);
572                     prG->chat = i;
573                 }
574                 else if (!strcasecmp (cmd, "prompt_strftime"))
575                 {
576                     PrefParse (tmp);
577                     prG->prompt_strftime = strdup (tmp);
578                 }
579                 else if (!strcasecmp (cmd, "autoupdate"))
580                 {
581                     PrefParseInt (i);
582                     prG->autoupdate = i;
583                 }
584                 else if (!strcasecmp (cmd, "color") || !strcasecmp (cmd, "colour"))
585                 {
586                     dep = 235;
587
588                     PrefParse (tmp);
589
590                     if (!strcasecmp (tmp, "scheme"))
591                     {
592                         PrefParseInt (i);
593                         OptImport (&prG->copts, PrefSetColorScheme (1 + ((i + 3) % 4)));
594                     }
595                     else
596                         OptImport (&prG->copts, s_sprintf ("color%s %s", tmp, s_quote (args)));
597                 }
598                 else if (!strcasecmp (cmd, "linebreaktype"))
599                 {
600                     PrefParseInt (i);
601
602                     prG->flags &= ~FLAG_LIBR_BR & ~FLAG_LIBR_INT;
603                     if (!i || i == 3)
604                         prG->flags |= FLAG_LIBR_BR;
605                     if (i & 2)
606                         prG->flags |= FLAG_LIBR_INT;
607                 }
608                 else if (!strcasecmp (cmd, "auto"))
609                 {
610                     if (!(par = s_parse (&args)))
611                     {
612                         dep = 10;
613                         prG->flags |= FLAG_AUTOREPLY;
614                         continue;
615                     }
616                     tmp = par->txt;
617                    
618                     if (!strcasecmp (tmp, "on"))
619                         prG->flags |= FLAG_AUTOREPLY;
620                     else if (!strcasecmp (tmp, "off"))
621                         prG->flags &= ~FLAG_AUTOREPLY;
622                     else if (!strcasecmp (tmp, "away"))
623                     {
624                         PrefParse (tmp);
625                         OptSetStr (&prG->copts, CO_AUTOAWAY, tmp);
626                         dep = 1;
627                     }
628                     else if (!strcasecmp (tmp, "na"))
629                     {
630                         PrefParse (tmp);
631                         OptSetStr (&prG->copts, CO_AUTONA, tmp);
632                         dep = 1;
633                     }
634                     else if (!strcasecmp (tmp, "dnd"))
635                     {
636                         PrefParse (tmp);
637                         OptSetStr (&prG->copts, CO_AUTODND, tmp);
638                         dep = 1;
639                     }
640                     else if (!strcasecmp (tmp, "occ"))
641                     {
642                         PrefParse (tmp);
643                         OptSetStr (&prG->copts, CO_AUTOOCC, tmp);
644                         dep = 1;
645                     }
646                     else if (!strcasecmp (tmp, "inv"))
647                     {
648                         PrefParse (tmp);
649                         dep = 1;
650                     }
651                     else if (!strcasecmp (tmp, "ffc"))
652                     {
653                         PrefParse (tmp);
654                         OptSetStr (&prG->copts, CO_AUTOFFC, tmp);
655                         dep = 1;
656                     }
657                     else
658                         ERROR;
659                 }
660                 else if (!strcasecmp (cmd, "sound"))
661                 {
662                     if (!(par = s_parse (&args)))
663                     {
664                         prG->sound = SFLAG_BEEP;
665                         dep = 11;
666                         continue;
667                     }
668                     tmp = par->txt;
669                     if (!strcasecmp (tmp, "on") || !strcasecmp (tmp, "beep"))
670                         prG->sound = SFLAG_BEEP;
671                     else if (!strcasecmp (tmp, "event"))
672                         prG->sound = SFLAG_EVENT;
673                     else
674                         prG->sound = 0;
675                 }
676                 else if (!strcasecmp (cmd, "soundonline"))
677                     dep = 12;
678                 else if (!strcasecmp (cmd, "soundoffline"))
679                     dep = 13;
680                 else if (!strcasecmp (cmd, "auto_away"))
681                 {
682                     PrefParseInt (i);
683                     prG->away_time = i;
684                 }
685                 else if (!strcasecmp (cmd, "screen_width"))
686                 {
687                     PrefParseInt (i);
688                     prG->screen = i;
689                 }
690                 else if (!strcasecmp (cmd, "tab"))
691                 {
692                     dep = 234;
693                     PrefParse (tmp);
694                     rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
695                     rl_printf (i18n (2458, "Can't tab spool %s; type \"%sopt %s tabspool 1%s\" manually.\n"),
696                               s_qquote (tmp), COLQUOTE, tmp, COLNONE);
697                 }
698                 else if (!strcasecmp (cmd, "set"))
699                 {
700                     int which = 0;
701                    
702                     PrefParse (cmd);
703
704                     if (!strcasecmp (cmd, "color") || !strcasecmp (cmd, "colour"))
705                         which = FLAG_COLOR;
706                     else if (!strcasecmp (cmd, "hermit"))
707                         which = FLAG_DEP_HERMIT;
708                     else if (!strcasecmp (cmd, "delbs"))
709                         which = FLAG_DELBS;
710                     else if (!strcasecmp (cmd, "russian"))
711                         which = FLAG_DEP_CONVRUSS;
712                     else if (!strcasecmp (cmd, "japanese"))
713                         which = FLAG_DEP_CONVEUC;
714                     else if (!strcasecmp (cmd, "funny"))
715                         which = FLAG_FUNNY;
716                     else if (!strcasecmp (cmd, "log"))
717                         which = FLAG_DEP_LOG;
718                     else if (!strcasecmp (cmd, "loglevel"))
719                         which = -1;
720                     else if (!strcasecmp (cmd, "logonoff"))
721                         which = FLAG_DEP_LOG_ONOFF;
722                     else if (!strcasecmp (cmd, "auto"))
723                         which = FLAG_AUTOREPLY;
724                     else if (!strcasecmp (cmd, "uinprompt"))
725                         which = FLAG_UINPROMPT;
726                     else if (!strcasecmp (cmd, "prompt"))
727                         which = -9;
728                     else if (!strcasecmp (cmd, "autosave"))
729                         which = FLAG_AUTOSAVE;
730                     else if (!strcasecmp (cmd, "autofinger"))
731                         which = FLAG_AUTOFINGER;
732                     else if (!strcasecmp (cmd, "linebreak"))
733                         which = -2;
734                     else if (!strcasecmp (cmd, "tabs"))
735                         which = -3;
736                     else if (!strcasecmp (cmd, "silent"))
737                         which = -4;
738                     else if (!strcasecmp (cmd, "webaware"))
739                         which = -5;
740                     else if (!strcasecmp (cmd, "hideip"))
741                         which = -6;
742                     else if (!strcasecmp (cmd, "dcauth"))
743                         which = -7;
744                     else if (!strcasecmp (cmd, "dccont"))
745                         which = -8;
746                     else
747                         ERROR;
748                     if (which > 0)
749                     {
750                         PrefParse (cmd);
751                         if (!strcasecmp (cmd, "on"))
752                         {
753                             if (which == FLAG_DEP_CONVRUSS)
754                             {
755                                 OptSetVal (&prG->copts, CO_ENCODING, ENC_WIN1251);
756                                 OptSetStr (&prG->copts, CO_ENCODINGSTR, ConvEncName (ENC_WIN1251));
757                                 dep = 14;
758                             }
759                             else if (which == FLAG_DEP_CONVEUC)
760                             {
761                                 dep = 15;
762                                 OptSetVal (&prG->copts, CO_ENCODING, ENC_SJIS);
763                                 OptSetStr (&prG->copts, CO_ENCODINGSTR, ConvEncName (ENC_SJIS));
764 #ifndef ENABLE_ICONV
765                                 rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
766                                 rl_print (i18n (2215, "This climm can't convert between SJIS or EUC and unicode.\n"));
767 #endif
768                             }
769                             else if (which == FLAG_DEP_LOG)
770                             {
771                                 dep = 16;
772                                 OptSetVal (&prG->copts, CO_LOGMESS, 1);
773                             }
774                             else if (which == FLAG_DEP_LOG_ONOFF)
775                             {
776                                 dep = 17;
777                                 OptSetVal (&prG->copts, CO_LOGONOFF, 1);
778                                 OptSetVal (&prG->copts, CO_LOGCHANGE, 1);
779                             }
780                             else if (which == FLAG_DEP_HERMIT)
781                             {
782                                 dep = 18;
783                                 OptSetVal (&prG->copts, CO_IGNORE, 1);
784                             }
785                             else
786                                 prG->flags |= which;
787                         }
788                         else if (!strcasecmp (cmd, "off"))
789                             prG->flags &= ~which;
790                         else
791                             ERROR;
792                     }
793                     else if (which == -1)
794                     {
795                         PrefParseInt (i);
796
797                         if (i)
798                         {
799                             OptSetVal (&prG->copts, CO_LOGMESS, 1);
800                         }
801                         if (i & 2)
802                         {
803                             OptSetVal (&prG->copts, CO_LOGONOFF, 1);
804                             OptSetVal (&prG->copts, CO_LOGCHANGE, 1);
805                         }
806                         dep = 16;
807                     }
808                     else if (which == -2)
809                     {
810                         PrefParse (cmd);
811
812                         prG->flags &= ~FLAG_LIBR_BR & ~FLAG_LIBR_INT;
813                         if (!strcasecmp (cmd, "break"))
814                             prG->flags |= FLAG_LIBR_BR;
815                         else if (!strcasecmp (cmd, "simple"))
816                             ;
817                         else if (!strcasecmp (cmd, "indent"))
818                             prG->flags |= FLAG_LIBR_INT;
819                         else if (!strcasecmp (cmd, "smart"))
820                             prG->flags |= FLAG_LIBR_BR | FLAG_LIBR_INT;
821                         else
822                             ERROR;
823                     }
824                     else if (which == -3)
825                     {
826                         dep = 8374;
827                     }
828                     else if (which == -4)
829                     {
830                         PrefParse (cmd);
831                        
832                         if (!strcasecmp (cmd, "on"))
833                             OptSetVal (&prG->copts, CO_SHOWCHANGE, 0);
834                         else if (!strcasecmp (cmd, "complete"))
835                         {
836                             OptSetVal (&prG->copts, CO_SHOWCHANGE, 0);
837                             OptSetVal (&prG->copts, CO_SHOWONOFF, 0);
838                         }
839                         dep = 18;
840                     }
841                     else if (which == -5)
842                     {
843                         OptSetVal (&prG->copts, CO_WEBAWARE, 1);
844                         dep = 3247;
845                     }
846                     else if (which == -6)
847                     {
848                         OptSetVal (&prG->copts, CO_HIDEIP, 1);
849                         dep = 2345;
850                     }
851                     else if (which == -7)
852                     {
853                         OptSetVal (&prG->copts, CO_DCAUTH, 1);
854                         dep = 3274;
855                     }
856                     else if (which == -8)
857                     {
858                         OptSetVal (&prG->copts, CO_DCCONT, 1);
859                         dep = 8723;
860                     }
861                     else if (which == -9)
862                     {
863                         PrefParse (cmd);
864
865                         prG->flags &= ~FLAG_USERPROMPT & ~FLAG_UINPROMPT;
866                         if (!strcasecmp (cmd, "user"))
867                             prG->flags |= FLAG_USERPROMPT;
868                         else if (!strcasecmp (cmd, "uin"))
869                             prG->flags |= FLAG_UINPROMPT;
870                         else if (!strcasecmp (cmd, "simple"))
871                             ;
872                         else
873                             ERROR;
874                     }
875                 }
876                 else if (!strcasecmp (cmd, "options"))
877                 {
878                     if (OptImport (&prG->copts, args))
879                         ERROR;
880                 }
881                 else
882                 {
883                     rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
884                     rl_printf (i18n (1188, "Unrecognized command '%s' in configuration file, ignored."), cmd);
885                     rl_print ("\n");
886                 }
887                 break;
888             case 1:
889                 if (format > 1)
890                     continue;
891
892                 flags = 0;
893                
894                 for (p = args; *p && *p != '#'; p++)
895                 {
896                     if (!*p || *p == '#' || isdigit ((int) *p))
897                         break;
898
899                     switch (*p)
900                     {
901                         case '*':
902                             flags |= CO_INTIMATE;
903                             flags &= ~(CO_HIDEFROM & CO_BOOLMASK);
904                             continue;
905                         case '^':
906                             flags |= CO_IGNORE;
907                             continue;
908                         case '~':
909                             flags |= CO_HIDEFROM;
910                             flags &= ~(CO_INTIMATE & CO_BOOLMASK);
911                             continue;
912                         case ' ':
913                         case '-':
914                             continue;
915                     }
916                     break;
917                 }
918
919                 if (!*p || *p == '#' )
920                     continue;
921                
922                 args = p;
923
924                 if (isdigit ((int)*p))
925                 {
926                     PrefParseInt (uin);
927                     PrefParse (cmd);
928                 }
929                 else
930                 {
931                     if (!lastcont)     /* ignore noise */
932                     {
933                         dep = 1;
934                         continue;
935                     }
936                     uin = lastcont->uin;
937                     PrefParse (cmd);
938                 }
939                
940                 for (i = j = 0; (tserv = ServerNr (i)); i++)
941                 {
942                     if ((cont = ContactFindUIN (tserv->contacts, uin)))
943                     {
944                         j = 1;
945                         ContactAddAlias (cont, cmd);
946                         OptSetVal (&cont->copts, flags, 1); /* FIXME */
947                     }
948                 }
949                 if (!j)
950                 {
951                     dep = 19;
952                     tserv = ServerNr (0);
953                     if (!tserv)
954                         break;
955                     if (!(cont = ContactFindUIN (tserv->contacts, uin)))
956                     {
957                         rl_printf ("%s%s%s %s\n", COLERROR, i18n (1619, "Warning:"), COLNONE,
958                                    i18n (2118, "Out of memory.\n"));
959                         section = -1;
960                         break;
961                     }
962                     ContactCreate (tserv, cont);
963                     ContactAddAlias (cont, cmd);
964                     OptSetVal (&cont->copts, flags, 1); /* FIXME */
965                 }
966                 break;
967             case 2:
968                 PrefParse (cmd);
969
970                 if (!strcasecmp (cmd, "alter"))
971                 {
972                     PrefParse (tmp);
973                     tmp = strdup (tmp);
974                     PrefParse (tmp2);
975                     tmp2 = strdup (s_quote (tmp2));
976                    
977                     CmdUser (cmd = strdup (s_sprintf ("\\alias %s %s", tmp2, tmp)));
978
979                     free (cmd);
980                     free (tmp);
981                     free (tmp2);
982                 }
983                 else if (!strcasecmp (cmd, "alias"))
984                 {
985                     char autoexpand = FALSE;
986                     if (s_parsekey (&args, "auto") || s_parsekey (&args, "autoexpand"))
987                         autoexpand = TRUE;
988                     PrefParse (tmp);
989                     tmp = strdup (s_quote (tmp));
990                     PrefParse (tmp2);
991                     tmp2 = strdup (tmp2);
992
993                     CmdUser (cmd = strdup (s_sprintf ("\\alias %s%s%s%s %s",
994                         autoexpand ? "autoexpand " : "",
995                         *tmp == '"' ? "" : "\"", tmp, *tmp == '"' ? "" : "\"", tmp2)));
996                    
997                     free (cmd);
998                     free (tmp);
999                     free (tmp2);
1000                 }
1001                 else if (!strcasecmp (cmd, "prompt"))
1002                 {
1003                     PrefParse (cmd);
1004                     prG->prompt = strdup (cmd);
1005                 }
1006                 else
1007                 {
1008                     rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1009                     rl_printf (i18n (1188, "Unrecognized command '%s' in configuration file, ignored."), cmd);
1010                     rl_print ("\n");
1011                 }
1012                 break;
1013             case 301:
1014                 PrefParse (cmd);
1015                 if (!strcasecmp (cmd, "status"))
1016                 {
1017                     status_t ii;
1018                     if (!OptGetVal (&oldserv->copts, CO_OSCAR_DC_MODE, &v))
1019                         v = 16+3;
1020                     if (!ContactStatus (&args, &ii))
1021                     {
1022                         PrefParseInt (i);
1023                         ii = IcqToStatus (i);
1024                     }
1025                     v = (v & ~15) + ii;
1026                     OptSetVal (&oldserv->copts, CO_OSCAR_DC_MODE, v);
1027                 }
1028                 else if (!strcasecmp (cmd, "port"))
1029                 {
1030                     PrefParseInt (i);
1031                     OptSetVal (&oldserv->copts, CO_OSCAR_DC_PORT, i);
1032                 }
1033                 break;
1034             case 302:
1035                 PrefParse (cmd);
1036                 if (!strcasecmp (cmd, "server"))
1037                 {
1038                     PrefParse (tmp);
1039                     OptSetStr (&prG->copts, CO_SCRIPT_PATH, tmp);
1040                 }
1041                 break;
1042             case 3:
1043                 PrefParse (cmd);
1044                 if (!serv && strcasecmp (cmd, "type"))
1045                 {
1046                     dep = 42;
1047                     serv = ServerC (TYPEF_ANY_SERVER);
1048                 }
1049
1050                 if (!strcasecmp (cmd, "type"))
1051                 {
1052                     UDWORD newtype = 0;
1053
1054                     PrefParse (cmd);
1055                     if (!strcasecmp (cmd, "server"))
1056                     {
1057                         newtype = TYPE_SERVER;
1058                         dep = 20;
1059                     }
1060                     else if (!strcasecmp (cmd, "peer"))
1061                     {
1062                         dep = 45;
1063                         if (!oldserv)
1064                             ERROR;
1065                         if (s_parsekey (&args, "auto"))
1066                             OptSetVal (&oldserv->copts, CO_OSCAR_DC_MODE, 32+3);
1067                         else
1068                             OptSetVal (&oldserv->copts, CO_OSCAR_DC_MODE, 16+3);
1069                         section = 301;
1070                         break;
1071                     }
1072                     else if (!strcasecmp (cmd, "remote"))
1073                     {
1074                         dep = 45;
1075                         OptSetVal (&prG->copts, CO_SCRIPT, 1);
1076                         section = 302;
1077                         break;
1078                     }
1079                     else if (!(newtype = ConnectionServerNType (cmd, 0)))
1080                         ERROR;
1081                    
1082                     serv = ServerC (newtype);
1083                    
1084                     if ((par = s_parse (&args)))
1085                     {
1086                         if (!strcasecmp (par->txt, "auto"))
1087                             serv->flags |= CONN_AUTOLOGIN;
1088                     }
1089                 }
1090                 else if (serv && !strcasecmp (cmd, "version"))
1091                 {
1092                     PrefParseInt (i);
1093
1094                     serv->pref_version = i;
1095                     if (serv->type == TYPEF_ANY_SERVER)
1096                     {
1097                         serv->type = TYPE_SERVER;
1098                         dep = 43;
1099                     }
1100                 }
1101                 else if (serv && (!strcasecmp (cmd, "server") || !strcasecmp (cmd, "host")))
1102                 {
1103                     PrefParse (tmp);
1104                     s_repl (&serv->pref_server, tmp);
1105                 }
1106                 else if (serv && !strcasecmp (cmd, "port"))
1107                 {
1108                     PrefParseInt (i);
1109                     serv->pref_port = i;
1110                 }
1111                 else if (serv && !strcasecmp (cmd, "uin"))
1112                 {
1113                     PrefParseInt (i);
1114                     s_repl (&serv->screen, s_sprintf ("%lu", UD2UL (i)));
1115                     dep = 77;
1116                 }
1117                 else if (serv && !strcasecmp (cmd, "screen"))
1118                 {
1119                     PrefParse (tmp);
1120                     s_repl (&serv->screen, tmp);
1121                 }
1122                 else if (serv && !strcasecmp (cmd, "password"))
1123                 {
1124                     PrefParse (tmp);
1125                     s_repl (&serv->pref_passwd, tmp);
1126                 }
1127                 else if (serv && !strcasecmp (cmd, "status"))
1128                 {
1129                     if (!ContactStatus (&args, &serv->pref_status))
1130                     {
1131                         PrefParseInt (i);
1132                         serv->pref_status = IcqToStatus (i);
1133                     }
1134                 }
1135                 else if (!strcasecmp (cmd, "options"))
1136                 {
1137                     if (OptImport (&serv->copts, args))
1138                         ERROR;
1139                 }
1140                 else
1141                 {
1142                     rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1143                     rl_printf (i18n (1188, "Unrecognized command '%s' in configuration file, ignored."), cmd);
1144                     rl_print ("\n");
1145                 }
1146                 break;
1147             case 4: /* contact groups */
1148                 if (format > 1) /* contacts are in seperate file now */
1149                     continue;
1150
1151                 PrefParse (cmd);
1152                 if (!strcasecmp (cmd, "label") && !cg->used)
1153                 {
1154                     Server *serv = NULL;
1155                     PrefParse (tmp);
1156                     s_repl (&cg->name, tmp);
1157                     if (!strncmp (cg->name, "contacts-", 9))
1158                     {
1159                         UWORD type;
1160                         if ((type = ConnectionServerNType (cg->name + 9, '-')))
1161                         {
1162                             int len = strlen (ConnectionServerType (type));
1163                             serv = ServerFindScreen (type, cg->name + len + 10);
1164                             if (serv)
1165                             {
1166                                 if (serv->contacts && serv->contacts != cg) /* Duplicate! */
1167                                 {
1168                                     ContactGroupD (cg);
1169                                     cg = serv->contacts;
1170                                 }
1171                                 else
1172                                 {
1173                                     cg->serv = serv;
1174                                     cg->serv->contacts = cg;
1175                                 }
1176                             }
1177                         }
1178                     }
1179                     if (!cg->serv)
1180                         if ((serv = ServerNr (0)))
1181                             cg->serv = serv;
1182                 }
1183                 else if (!strcasecmp (cmd, "id") && !cg->used)
1184                 {
1185                     PrefParseInt (i);
1186                     cg->id = i;
1187                 }
1188                 else if (!strcasecmp (cmd, "server") && !cg->used)
1189                 {
1190                     Server *serv;
1191                     UWORD type;
1192                    
1193                     PrefParse (tmp);
1194                     if (!(type = ConnectionServerNType (tmp, 0)))
1195                         ERROR;
1196                    
1197                     PrefParse (tmp);
1198                    
1199                     if ((serv = ServerFindScreen (type, tmp)))
1200                         cg->serv = serv;
1201                 }
1202                 else if (!cg->serv)
1203                 {
1204                     rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1205                     rl_printf (i18n (2460, "Contact group %s (id %s%d%s) not associated to server connection.\n"),
1206                               s_wordquote (cg->name ? cg->name : ""), COLQUOTE, cg->id, COLNONE);
1207                 }
1208                 else if (!strcasecmp (cmd, "entry"))
1209                 {
1210                     UDWORD uin;
1211                    
1212                     PrefParseInt (i);
1213                     PrefParseInt (uin);
1214                    
1215                     if (!(cont = ContactFindUIN (cg->serv->contacts, uin)))
1216                         break;
1217                     ContactCreate (cg->serv, cont);
1218                     if (cont && cg != cg->serv->contacts)
1219                         ContactAdd (cg, cont);
1220                 }
1221                 else
1222                 {
1223                     rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1224                     rl_printf (i18n (1188, "Unrecognized command '%s' in configuration file, ignored."), cmd);
1225                     rl_print ("\n");
1226                 }
1227                 break;
1228         }
1229     }
1230    
1231     if (!prG->logplace)
1232         prG->logplace = strdup ("history" _OS_PATHSEPSTR);
1233    
1234     if (!prG->chat)
1235         prG->chat = 49;
1236
1237     if (!prG->prompt)
1238         prG->prompt = strdup (USER_PROMPT);
1239
1240     if (!prG->prompt_strftime)
1241         prG->prompt_strftime = strdup (USER_PROMPT_STRFTIME);
1242
1243     for (i = 0; (serv = ServerNr (i)); i++)
1244     {
1245         serv->conn->port = serv->pref_port;
1246         s_repl (&serv->conn->server, serv->pref_server);
1247         s_repl (&serv->passwd, serv->pref_passwd);
1248         serv->status = serv->pref_status;
1249         if (format < 2 && !serv->contacts)
1250         {
1251             serv->contacts = cg = ContactGroupC (serv, 0, s_sprintf ("contacts-%s-%s", ConnectionServerType (serv->type), serv->screen));
1252             for (i = 0; (cont = ContactIndex (NULL, i)); i++)
1253                 ContactCreate (serv, cont);
1254             dep = 21;
1255         }
1256     }
1257
1258 #ifdef ENABLE_REMOTECONTROL
1259     if (!OptGetVal (&prG->copts, CO_SCRIPT, &v))
1260     {
1261         OptSetVal (&prG->copts, CO_SCRIPT, 1);
1262         dep = 22;
1263     }
1264 #endif
1265                            
1266     if (dep || !format)
1267     {
1268         rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1269         rl_printf (i18n (2461, "Deprecated syntax found in configuration file '%s'!\n    Please update or \"save\" the configuration file and check for changes.\n"), prG->rcfile);
1270         rl_printf ("FIXME: dep %d\n", dep);
1271     }
1272     fclose (rcf);
1273     return format;
1274 }
1275
1276
1277 /*
1278  * Reads in a status file.
1279  */
1280 void PrefReadStat (FILE *stf)
1281 {
1282     char *cmd = NULL;
1283     const char *args;
1284     Contact *cont = NULL;
1285     Server *serv = NULL;
1286     ContactGroup *cg = NULL;
1287     int section, dep = 0;
1288     UDWORD i;
1289     strc_t par, line;
1290     UBYTE format = 0;
1291     UDWORD uinconts = 0;
1292     Contact *uincont[20];
1293
1294     for (section = 0; (line = UtilIOReadline (stf)); )
1295     {
1296         if (!line->len || (line->txt[0] == '#'))
1297             continue;
1298         args = ConvFrom (line, ENC_UTF8)->txt;
1299         if (format && *args == '[')
1300         {
1301             if (!strcasecmp (args, "[Group]"))
1302             {
1303                 section = 4;
1304                 cg = ContactGroupC (NULL, 0, NULL);
1305                 OptSetVal (&cg->copts, CO_IGNORE, 0);
1306                 if ((serv = ServerNr (0)))
1307                     cg->serv = serv;
1308             }
1309             else if (!strcasecmp (args, "[Contacts]"))
1310             {
1311                 if (format == 1)
1312                     section = 5;
1313                 else
1314                     section = 6;
1315                 serv = NULL;
1316             }
1317             else
1318             {
1319                 rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1320                 rl_printf (i18n (1659, "Unknown section '%s' in configuration file."), args);
1321                 rl_print ("\n");
1322                 section = -1;
1323             }
1324             continue;
1325         }
1326         switch (section)
1327         {
1328             case -1:
1329                 rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1330                 rl_print  (i18n (1675, "Ignored line:"));
1331                 rl_printf (" %s\n", args);
1332                 break;
1333             case 0:
1334                 PrefParse (cmd);
1335                 if (!strcasecmp (cmd, "format"))
1336                 {
1337                     PrefParseInt (i);
1338                     format = i;
1339                     if (format > 3)
1340                     {
1341                         rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1342                         rl_printf (i18n (2457, "Unknown configuration file format version %d.\n"), format);
1343                         return;
1344                     }
1345                 }
1346                 else
1347                 {
1348                     rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1349                     rl_printf (i18n (1188, "Unrecognized command '%s' in configuration file, ignored."), cmd);
1350                     rl_print ("\n");
1351                 }
1352                 break;
1353             case 4: /* contact groups */
1354                 PrefParse (cmd);
1355                 if (!strcasecmp (cmd, "label") && !cg->used)
1356                 {
1357                     PrefParse (cmd);
1358                     s_repl (&cg->name, cmd);
1359                     if (!strncmp (cg->name, "contacts-", 9))
1360                     {
1361                         UWORD type;
1362                         int len;
1363                        
1364                         if (!(type = ConnectionServerNType (cg->name + 9, '-')))
1365                             break;
1366
1367                         len = strlen (ConnectionServerType (type));
1368                         if ((serv = ServerFindScreen (type, cg->name + 10 + len)))
1369                         {
1370                             if (serv->contacts && serv->contacts != cg)
1371                             {
1372                                 ContactGroupD (cg);
1373                                 cg = serv->contacts;
1374                             }
1375                             else
1376                             {
1377                                 serv->contacts = cg;
1378                                 cg->serv = serv;
1379                             }
1380                         }
1381                     }
1382                     if (!cg->serv)
1383                         cg->serv = ServerNr (0);
1384                 }
1385                 else if (!strcasecmp (cmd, "id") && !cg->used)
1386                 {
1387                     PrefParseInt (i);
1388                     cg->id = i;
1389                 }
1390                 else if (!strcasecmp (cmd, "server") && !cg->used)
1391                 {
1392                     UWORD type;
1393                    
1394                     PrefParse (cmd);
1395                     if (!(type = ConnectionServerNType (cmd, 0)))
1396                         ERROR;
1397                    
1398                     PrefParse (cmd);
1399                     if ((serv = ServerFindScreen (type, cmd)))
1400                         cg->serv = serv;
1401                 }
1402                 else if (!strcasecmp (cmd, "options"))
1403                 {
1404                     if (OptImport (&cg->copts, args))
1405                         ERROR;
1406                 }
1407                 else if (cg->serv && !strcasecmp (cmd, "entry"))
1408                 {
1409                     if (format < 3)
1410                         PrefParseInt (i);
1411                     PrefParse (cmd);
1412                    
1413                     if (!cg->serv->contacts)
1414                     {
1415                         cg->serv->contacts = ContactGroupC (NULL, 0, s_sprintf ("contacts-%s-%s", ConnectionServerType (cg->serv->type), cmd));
1416                         OptSetVal (&cg->serv->copts, CO_IGNORE, 0);
1417                         cg->serv->contacts->serv = cg->serv;
1418                     }
1419                    
1420                     if (format == 1)
1421                         cont = ContactFindUIN (cg->serv->contacts, atol (cmd));
1422                     else
1423                         cont = ContactScreen (cg->serv, cmd);
1424                    
1425                     if (!cont)
1426                     {
1427                         rl_printf ("%s%s%s %s\n", COLERROR, i18n (1619, "Warning:"), COLNONE,
1428                                    i18n (2118, "Out of memory.\n"));
1429                         ERROR;
1430                     }
1431                     ContactCreate (cg->serv, cont);
1432
1433                     if (cg != cg->serv->contacts)
1434                     {
1435                         if (!ContactHas (cg, cont))
1436                             ContactAdd (cg, cont);
1437                         if (cont->group == cg->serv->contacts)
1438                             cont->group = cg;
1439                     }
1440
1441                     while ((par = s_parse (&args)))
1442                         ContactAddAlias (cont, par->txt);
1443                 }
1444                 else
1445                 {
1446                     rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1447                     rl_printf (i18n (1188, "Unrecognized command '%s' in configuration file, ignored."), cmd);
1448                     rl_print ("\n");
1449                 }
1450                 break;
1451             case 5:
1452                 PrefParse (cmd);
1453                 if (!strcasecmp (cmd, "entry"))
1454                 {
1455                     UDWORD uin;
1456                    
1457                     PrefParseInt (uin);
1458                     PrefParse (cmd);
1459                    
1460                     for (i = uinconts = 0; (serv = ServerNr (i)); i++)
1461                     {
1462                         if (serv->contacts && uinconts < 20
1463                             && (cont = ContactFindUIN (serv->contacts, uin)))
1464                         {
1465                             uincont[uinconts++] = cont;
1466                             ContactAddAlias (cont, cmd);
1467                         }
1468                     }
1469                     while ((par = s_parse (&args)))
1470                     {
1471                         for (i = 0; i < uinconts; i++)
1472                             ContactAddAlias (uincont[i], par->txt);
1473                     }
1474                 }
1475                 else if (!strcasecmp (cmd, "options"))
1476                 {
1477                     for (i = 0; i < uinconts; i++)
1478                         OptImport (&uincont[i]->copts, args);
1479                 }
1480                 else
1481                 {
1482                     rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1483                     rl_printf (i18n (1188, "Unrecognized command '%s' in configuration file, ignored."), cmd);
1484                     rl_print ("\n");
1485                 }
1486                 break;
1487             case 6:
1488                 PrefParse (cmd);
1489                 if (!strcasecmp (cmd, "server"))
1490                 {
1491                     UWORD type;
1492                    
1493                     PrefParse (cmd);
1494                     if (!(type = ConnectionServerNType (cmd, 0)))
1495                         ERROR;
1496
1497                     PrefParse (cmd);
1498                     if (!(serv = ServerFindScreen (type, cmd)))
1499                         ERROR;
1500                     cont = NULL;
1501                     if (!serv->contacts)
1502                     {
1503                         serv->contacts = ContactGroupC (serv, 0, s_sprintf ("contacts-%s-%s", ConnectionServerType (serv->type), serv->screen));
1504                         OptSetVal (&serv->copts, CO_IGNORE, 0);
1505                         serv->contacts->serv = serv;
1506                     }
1507                 }
1508                 else if (serv && !strcasecmp (cmd, "entry"))
1509                 {
1510                     UDWORD id;
1511                    
1512                     if (format < 3)
1513                         PrefParseInt (id);
1514                     PrefParse (cmd);
1515                    
1516                     cont = ContactScreen (serv, cmd);
1517                     if (!cont)
1518                         ERROR;
1519                     ContactCreate (serv, cont);
1520                    
1521                     while ((par = s_parse (&args)))
1522                         ContactAddAlias (cont, par->txt);
1523                 }
1524                 else if (serv && !strcasecmp (cmd, "options"))
1525                 {
1526                     if (cont)
1527                         OptImport (&cont->copts, args);
1528                     else
1529                         OptImport (&serv->copts, args);
1530                 }
1531                 else
1532                 {
1533                     rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE);
1534                     rl_printf (i18n (1188, "Unrecognized command '%s' in configuration file, ignored."), cmd);
1535                     rl_print ("\n");
1536                 }
1537                 break;
1538         }
1539     }
1540    
1541     for (i = 0; (serv = ServerNr (i)); i++)
1542     {
1543         if (!serv->contacts)
1544         {
1545             serv->contacts = cg = ContactGroupC (serv, 0, s_sprintf ("contacts-%s-%s", ConnectionServerType (serv->type), serv->screen));
1546             OptSetVal (&cg->copts, CO_IGNORE, 0);
1547             dep = 21;
1548         }
1549         if (!serv->conn->cont)
1550             serv->conn->cont = ContactScreen (serv, serv->screen);
1551     }
1552
1553     if (dep || !format)
1554     {
1555         rl_printf (i18n (1818, "Warning: Deprecated syntax found in configuration file '%s'!\n    Please update or \"save\" the configuration file and check for changes.\n"), prG->statfile);
1556         rl_printf ("FIXME: dep %d\n", dep);
1557     }
1558     fclose (stf);
1559 }
1560
1561 int PrefWriteStatusFile (void)
1562 {
1563     FILE *stf;
1564     char *stfn, *stfo;
1565     time_t t;
1566     int i, k, rc;
1567     Contact *cont;
1568     Server *ss;
1569     ContactGroup *cg;
1570
1571     if (!prG->statfile)
1572         prG->statfile = strdup (s_sprintf ("%sstatus", PrefUserDir (prG)));
1573     rl_printf (i18n (2048, "Saving preferences to %s.\n"), prG->statfile);
1574     stfn = strdup (s_sprintf ("%s.##", prG->statfile));
1575     stf = fopen (stfn, "w");
1576     if (!stf)
1577     {
1578         int rc = errno;
1579         if (rc == ENOENT)
1580         {
1581             char *tmp = strdup (PrefUserDir (prG));
1582             if (tmp[strlen (tmp) - 1] == '/')
1583                 tmp[strlen (tmp) - 1] = '\0';
1584             rl_printf (i18n (2047, "Creating directory %s.\n"), tmp);
1585             k = mkdir (tmp, 0700);
1586             if (!k)
1587                 stf = fopen (stfn, "w");
1588             if (!stf)
1589                 rc = errno;
1590             free (tmp);
1591         }
1592         if (!stf)
1593             rl_printf (i18n (1872, "failed: %s (%d)\n"), strerror (rc), rc);
1594     }
1595     if (!stf)
1596     {
1597         s_free (stfn);
1598         return -1;
1599     }
1600
1601     t = time (NULL);
1602     fprintf (stf, "# This file was generated by climm " CLIMM_VERSION " of %s %s\n", __TIME__, __DATE__);
1603     fprintf (stf, "# This file was generated on %s\n", ctime (&t));
1604     fprintf (stf, "format 3\n\n");
1605
1606     fprintf (stf, "\n# The contact list section.\n");
1607     for (k = 0; (ss = ServerNr (k)); k++)
1608     {
1609         if (!ss->oscar_uin && (ss->type & TYPEF_HAVEUIN))
1610             continue;
1611
1612         fprintf (stf, "[Contacts]\n");
1613         fprintf (stf, "server %s %s\n", ConnectionServerType (ss->type), ss->screen);
1614         fprintf (stf, "%s\n", OptString (&ss->copts));
1615
1616         for (i = 0; (cont = ContactIndex (0, i)); i++)
1617         {
1618             if (cont->group && cont->group->serv == ss)
1619             {
1620                 ContactAlias *alias;
1621                 fprintf (stf, "entry %s ", s_quote (cont->screen));
1622                 fprintf (stf, "%s", s_quote (cont->nick));
1623                 for (alias = cont->alias; alias; alias = alias->more)
1624                     fprintf (stf, " %s", s_quote (alias->alias));
1625                 fprintf (stf, "\n%s", OptString (&cont->copts));
1626             }
1627         }
1628         fprintf (stf, "\n");
1629     }
1630    
1631     fprintf (stf, "# Contact groups.");
1632     for (k = 1; (cg = ContactGroupIndex (k)); k++)
1633     {
1634         if (!cg->serv || cg->serv->contacts == cg)
1635             continue;
1636
1637         fprintf (stf, "\n[Group]\n");
1638         fprintf (stf, "server %s %s\n", ConnectionServerType (cg->serv->type), cg->serv->screen);
1639         fprintf (stf, "label %s\n", s_quote (cg->name));
1640         fprintf (stf, "id %d\n", cg->id);
1641         fprintf (stf, "%s", OptString (&cg->copts));
1642
1643         for (i = 0; (cont = ContactIndex (cg, i)); i++)
1644             fprintf (stf, "entry %s\n", s_quote (cont->screen));
1645     }
1646
1647     if (fclose (stf))
1648     {
1649         s_free (stfn);
1650         return -1;
1651     }
1652    
1653     stfo = strdup (s_sprintf ("%s.old", prG->statfile));
1654     rename (prG->statfile, stfo);
1655     s_free (stfo);
1656    
1657     rc = rename (stfn, prG->statfile);
1658     s_free (stfn);
1659     return rc;
1660 }
1661
1662 int PrefWriteConfFile (void)
1663 {
1664     FILE *rcf;
1665     char *rcfn, *rcfo;
1666     time_t t;
1667     int k, rc;
1668     Server *ss;
1669 #ifdef ENABLE_TCL
1670     tcl_pref_p tpref;
1671 #endif
1672
1673     if (!prG->rcfile)
1674         prG->rcfile = strdup (s_sprintf ("%sclimmrc", PrefUserDir (prG)));
1675     rl_printf (i18n (2048, "Saving preferences to %s.\n"), prG->rcfile);
1676     rcfn = strdup (s_sprintf ("%s.##", prG->rcfile));
1677     rcf = fopen (rcfn, "w");
1678     if (!rcf)
1679     {
1680         int rc = errno;
1681         if (rc == ENOENT)
1682         {
1683             char *tmp = strdup (PrefUserDir (prG));
1684             if (tmp[strlen (tmp) - 1] == '/')
1685                 tmp[strlen (tmp) - 1] = '\0';
1686             rl_printf (i18n (2047, "Creating directory %s.\n"), tmp);
1687             k = mkdir (tmp, 0700);
1688             if (!k)
1689                 rcf = fopen (rcfn, "w");
1690             if (!rcf)
1691                 rc = errno;
1692             free (tmp);
1693         }
1694         if (!rcf)
1695             rl_printf (i18n (1872, "failed: %s (%d)\n"), strerror (rc), rc);
1696     }
1697     if (!rcf)
1698     {
1699         s_free (rcfn);
1700         return -1;
1701     }
1702
1703     t = time (NULL);
1704     fprintf (rcf, "# This file was generated by climm " CLIMM_VERSION " of %s %s\n", __TIME__, __DATE__);
1705     fprintf (rcf, "# This file was generated on %s\n", ctime (&t));
1706
1707     fprintf (rcf, "encoding file UTF-8 # do not modify\n");
1708     fprintf (rcf, "# Local character encodings: auto, ISO-8859-1, KOI8-u, ...\n");
1709     fprintf (rcf, "# Setting this explicitly will render climm unable to determine character widths.\n");
1710     fprintf (rcf, "%sencoding local %s%s\n",
1711              prG->enc_loc & ENC_FLAGS ? "# " : "", s_quote (ConvEncName (prG->enc_loc)),
1712              prG->enc_loc & ENC_FLAGS ? "" : " # please set your locale correctly instead");
1713     fprintf (rcf, "format 3\n\n");
1714
1715     for (k = 0; (ss = ServerNr (k)); k++)
1716     {
1717         if (!strcmp (ConnectionServerType (ss->type), "unknown"))
1718             continue;
1719
1720         fprintf (rcf, "[Server]\n");
1721         fprintf (rcf, "type %s%s\n",  ConnectionServerType (ss->type),
1722                                       ss->flags & CONN_AUTOLOGIN ? " auto" : "");
1723         fprintf (rcf, "version %d\n", ss->pref_version);
1724         if (ss->pref_server)
1725             fprintf (rcf, "host %s\n",   s_quote (ss->pref_server));
1726         if (ss->pref_port && ss->pref_port != -1)
1727             fprintf (rcf, "port %lu\n",    UD2UL (ss->pref_port));
1728         fprintf (rcf, "screen %s\n",   s_quote (ss->screen));
1729         if (ss->pref_passwd)
1730             fprintf (rcf, "password %s\n", s_quote (ss->pref_passwd));
1731         else
1732             fprintf (rcf, "# password\n");
1733         if (ss->pref_status || !k)
1734             fprintf (rcf, "status %s\n",  ContactStatusStr (ss->pref_status));
1735         fprintf (rcf, "%s", OptString (&ss->copts));
1736         fprintf (rcf, "\n");
1737     }
1738
1739     fprintf (rcf, "\n[General]\n");
1740     fprintf (rcf, "\n#in seconds\nauto_away %lu\n", UD2UL (prG->away_time));
1741     fprintf (rcf, "\n#For dumb terminals that don't wrap set this.");
1742     fprintf (rcf, "\nScreen_Width %d\n", prG->screen);
1743     fprintf (rcf, "verbose %lu\n\n", UD2UL (prG->verbose));
1744
1745 #ifdef ENABLE_TCL
1746     tpref = prG->tclscript;
1747     while (tpref)
1748     {
1749         fprintf (rcf, "%s \"%s\"\n", tpref->type == TCL_FILE ? "tclscript" : "tcl",
1750                         tpref->file);
1751         tpref = tpref->next;
1752     }
1753     fprintf (rcf, "\n");
1754 #endif
1755
1756     fprintf (rcf, "# Set some simple options.\n");
1757     fprintf (rcf, "set delbs      %s # if a DEL char is supposed to be backspace\n",
1758                     prG->flags & FLAG_DELBS     ? "on " : "off");
1759     fprintf (rcf, "set funny      %s # if you want funny messages\n",
1760                     prG->flags & FLAG_FUNNY     ? "on " : "off");
1761     fprintf (rcf, "set color      %s # if you want colored messages\n",
1762                     prG->flags & FLAG_COLOR     ? "on " : "off");
1763     fprintf (rcf, "set auto       %s # if automatic responses are to be sent\n",
1764                     prG->flags & FLAG_AUTOREPLY ? "on " : "off");
1765     fprintf (rcf, "set prompt  %s # type of prompt (user, uin, simple)\n",
1766                     prG->flags & FLAG_USERPROMPT ? "user " :
1767                     prG->flags & FLAG_UINPROMPT ? "uin " : "simple");
1768     fprintf (rcf, "set autosave   %s # whether the climmrc should be automatically saved on exit\n",
1769                     prG->flags & FLAG_AUTOSAVE ? "on " : "off");
1770     fprintf (rcf, "set autofinger %s # whether new UINs should be fingered automatically\n",
1771                     prG->flags & FLAG_AUTOFINGER ? "on " : "off");
1772     fprintf (rcf, "set linebreak  %s # the line break type to be used (simple, break, indent, smart)\n",
1773                     prG->flags & FLAG_LIBR_INT
1774                     ? prG->flags & FLAG_LIBR_BR ? "smart " : "indent"
1775                     : prG->flags & FLAG_LIBR_BR ? "break " : "simple");
1776     fprintf (rcf, "\n");
1777    
1778     fprintf (rcf, "%s\n\n", OptString (&prG->copts));
1779
1780     fprintf (rcf, "chat %d          # random chat group; -1 to disable, 49 for climm\n",
1781                   prG->chat);
1782
1783     fprintf (rcf, "autoupdate %d    # level of automatic preference updates\n\n",
1784                   prG->autoupdate);
1785
1786     fprintf (rcf, "logplace %s      # the file or (distinct files in) dir to log to\n\n",
1787                   prG->logplace ? s_quote (prG->logplace) : "");
1788
1789     fprintf (rcf, "sound %s # on=beep,off,event\n",
1790                   prG->sound & SFLAG_BEEP  ? "beep " :
1791                   prG->sound & SFLAG_EVENT ? "event" : "off  ");
1792
1793     fprintf (rcf, "event %s\n\n", prG->event_cmd && *prG->event_cmd ? s_quote (prG->event_cmd) : "off");
1794
1795     fprintf (rcf, "prompt_strftime \"%s\"          # format for time prompt option %%T. man strftime\n",
1796                    prG->prompt_strftime);
1797
1798     fprintf (rcf, "\n# The strings section - runtime redefinable strings.\n");
1799     fprintf (rcf, "[Strings]\n");
1800     fprintf (rcf, "# The user prompt.\n");
1801
1802     fprintf (rcf, "prompt %s          # user prompt. for prompt template see manual\n",
1803                    s_quote (prG->prompt));
1804
1805     fprintf (rcf, "# The aliases.\n");
1806     {
1807         const alias_t *node;
1808         for (node = AliasList (); node; node = node->next)
1809         {
1810             const char *tmp = s_quote (node->command);
1811             fprintf (rcf, "alias %s%s%s%s", node->autoexpand ? "autoexpand " : "",
1812                 *tmp == '"' ? "" : "\"", tmp, *tmp == '"' ? "" : "\"");
1813             fprintf (rcf, " %s\n", s_quote (node->replace));
1814         }
1815     }
1816     fprintf (rcf, "\n");
1817
1818     if (fclose (rcf))
1819     {
1820         s_free (rcfn);
1821         return -1;
1822     }
1823    
1824     rcfo = strdup (s_sprintf ("%s.old", prG->rcfile));
1825     rename (prG->rcfile, rcfo);
1826     s_free (rcfo);
1827    
1828     rc = rename (rcfn, prG->rcfile);
1829     s_free (rcfn);
1830     return rc;
1831 }
1832
1833 int Save_RC ()
1834 {
1835     return PrefWriteConfFile () | PrefWriteStatusFile ();
1836 }
Note: See TracBrowser for help on using the browser.