changeset 374:bd5638c21834

Improve logging system (traces) There are now two trace logging levels: * tracelog_level = 1: Most messages from the log window are written to disk (LPRINT_LOG) * tracelog_level =2: LPRINT_LOG & LPRINT_DEBUG messages are written to disk The trace file name is set with the "tracelog_file" option.
author Mikael Berthe <mikael@lilotux.net>
date Mon, 25 Jul 2005 21:46:35 +0100
parents af2f8ddf6a1b
children 1fb0a7fe4272
files mcabber/libjabber/jconn.c mcabber/mcabberrc.example mcabber/src/Makefile.am mcabber/src/commands.c mcabber/src/histolog.c mcabber/src/hooks.c mcabber/src/jabglue.c mcabber/src/logprint.h mcabber/src/main.c mcabber/src/screen.c mcabber/src/screen.h mcabber/src/settings.c mcabber/src/utils.c mcabber/src/utils.h
diffstat 14 files changed, 210 insertions(+), 201 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/libjabber/jconn.c	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/libjabber/jconn.c	Mon Jul 25 21:46:35 2005 +0100
@@ -20,7 +20,7 @@
 #include "jabber.h"
 #include "connwrap.h"
 
-#include "../src/utils.h"
+#include "../src/logprint.h"  /* For logging */
 
 /* local macros for launching event handlers */
 #define STATE_EVT(arg) if(j->on_state) { (j->on_state)(j, (arg) ); }
@@ -370,7 +370,8 @@
 	/* Don't disconnect for interrupted system call */
 	if(errno == EINTR) return;
 
-	ut_WriteLog("jab_poll: select returned errno=%d\n", errno);
+	scr_LogPrint(LPRINT_LOGNORM, "jab_poll: select returned errno=%d",
+                     errno);
 	STATE_EVT(JCONN_STATE_OFF);
 	jab_stop(j);
 
--- a/mcabber/mcabberrc.example	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/mcabberrc.example	Mon Jul 25 21:46:35 2005 +0100
@@ -51,10 +51,14 @@
 # See sample script in contrib/ directory.
 #set events_command = /home/mikael/.mcabber/eventcmd
 
-# Debug logging
-# If you want advanced debug, please specify a file here.
-# You can enable debug in main.c before compiling mcabber, too.
-#set debug = /home/mikael/mcabber.log
+# Traces logging
+# If you want advanced traces, please specify a file and a level here.
+# There are currently 2 traceloglog levels:
+#  lvl 1: most events of the log window are written to the file
+#  lvl 2: debug logging (XML, etc.)
+# Default is level 0, no trace logging
+#set tracelog_level = 1
+#set tracelog_file = /home/mikael/mcabber.log
 
 #  Status messages
 # The "message" value will override all others, take care!
--- a/mcabber/src/Makefile.am	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/Makefile.am	Mon Jul 25 21:46:35 2005 +0100
@@ -1,7 +1,7 @@
 bin_PROGRAMS = mcabber
 mcabber_SOURCES = main.c jabglue.c jabglue.h roster.c roster.h \
 		  commands.c commands.h compl.c compl.h \
-		  hbuf.c hbuf.h screen.c screen.h \
+		  hbuf.c hbuf.h screen.c screen.h logprint.h \
 		  settings.c settings.h \
 		  hooks.c hooks.h histolog.c histolog.h \
 		  utf8.c utf8.h utils.c utils.h list.h harddefines.h
--- a/mcabber/src/commands.c	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/commands.c	Mon Jul 25 21:46:35 2005 +0100
@@ -215,13 +215,13 @@
   const char *jid;
       
   if (!current_buddy) {
-    scr_LogPrint("No buddy currently selected.");
+    scr_LogPrint(LPRINT_NORMAL, "No buddy currently selected.");
     return;
   }
 
   jid = CURRENT_JID;
   if (!jid) {
-    scr_LogPrint("No buddy currently selected.");
+    scr_LogPrint(LPRINT_NORMAL, "No buddy currently selected.");
     return;
   }
 
@@ -269,12 +269,12 @@
   curcmd = cmd_get(xpline);
 
   if (!curcmd) {
-    scr_LogPrint("Unrecognized command, sorry.");
+    scr_LogPrint(LPRINT_NORMAL, "Unrecognized command, sorry.");
     if (xpline != line) g_free(xpline);
     return 0;
   }
   if (!curcmd->func) {
-    scr_LogPrint("Not yet implemented, sorry.");
+    scr_LogPrint(LPRINT_NORMAL, "Not yet implemented, sorry.");
     if (xpline != line) g_free(xpline);
     return 0;
   }
@@ -355,19 +355,19 @@
   } else if (!strncasecmp(arg, "search", 6)) {
     char *string = arg+6;
     if (*string && (*string != ' ')) {
-      scr_LogPrint("Unrecognized parameter!");
+      scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
       return;
     }
     while (*string == ' ')
       string++;
     if (!*string) {
-      scr_LogPrint("What name or jid are you looking for?");
+      scr_LogPrint(LPRINT_NORMAL, "What name or jid are you looking for?");
       return;
     }
     scr_RosterSearch(string);
     update_roster = TRUE;
   } else
-    scr_LogPrint("Unrecognized parameter!");
+    scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
 }
 
 static void do_status(char *arg)
@@ -377,7 +377,8 @@
   char *msg;
 
   if (!arg || (*arg == 0)) {
-    scr_LogPrint("Your status is: %c", imstatus2char[jb_getstatus()]);
+    scr_LogPrint(LPRINT_NORMAL, "Your status is: %c",
+                 imstatus2char[jb_getstatus()]);
     return;
   }
 
@@ -396,7 +397,7 @@
   else if (!strncasecmp(arg, "notavail",  len)) st = notavail;
   else if (!strncasecmp(arg, "free",      len)) st = freeforchat;
   else {
-    scr_LogPrint("Unrecognized parameter!");
+    scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
     return;
   }
 
@@ -413,7 +414,7 @@
 {
   char *id, *nick;
   if (!arg || (*arg == 0)) {
-    scr_LogPrint("Wrong usage");
+    scr_LogPrint(LPRINT_NORMAL, "Wrong usage");
     return;
   }
 
@@ -428,7 +429,7 @@
   // FIXME check id =~ jabber id
   // 2nd parameter = optional nickname
   jb_addbuddy(id, nick, NULL);
-  scr_LogPrint("Sent presence notfication request to <%s>", id);
+  scr_LogPrint(LPRINT_LOGNORM, "Sent presence notfication request to <%s>", id);
   g_free(id);
 }
 
@@ -437,7 +438,7 @@
   const char *jid;
 
   if (arg && (*arg)) {
-    scr_LogPrint("Wrong usage");
+    scr_LogPrint(LPRINT_NORMAL, "Wrong usage");
     return;
   }
 
@@ -445,7 +446,7 @@
   jid = buddy_getjid(BUDDATA(current_buddy));
   if (!jid) return;
 
-  scr_LogPrint("Removing <%s>...", jid);
+  scr_LogPrint(LPRINT_LOGNORM, "Removing <%s>...", jid);
   jb_delbuddy(jid);
 }
 
@@ -455,7 +456,7 @@
   guint leave_windowbuddy;
 
   if (!arg || (*arg == 0)) {
-    scr_LogPrint("Missing parameter");
+    scr_LogPrint(LPRINT_NORMAL, "Missing parameter");
     return;
   }
 
@@ -468,7 +469,7 @@
   leave_windowbuddy = (group != BUDDATA(current_buddy));
 
   if (!(buddy_gettype(group) & ROSTER_TYPE_GROUP)) {
-    scr_LogPrint("You need to select a group");
+    scr_LogPrint(LPRINT_NORMAL, "You need to select a group");
     return;
   }
 
@@ -480,7 +481,7 @@
     buddy_setflags(group, ROSTER_FLAG_HIDE,
             !(buddy_getflags(group) & ROSTER_FLAG_HIDE));
   } else {
-    scr_LogPrint("Unrecognized parameter!");
+    scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
     return;
   }
 
@@ -496,13 +497,13 @@
   scr_set_chatmode(TRUE);
 
   if (!current_buddy) {
-    scr_LogPrint("Who are you talking to??");
+    scr_LogPrint(LPRINT_NORMAL, "Who are you talking to??");
     return;
   }
 
   bud = BUDDATA(current_buddy);
   if (!(buddy_gettype(bud) & ROSTER_TYPE_USER)) {
-    scr_LogPrint("This is not a user");
+    scr_LogPrint(LPRINT_NORMAL, "This is not a user");
     return;
   }
 
@@ -517,7 +518,7 @@
 
   if (!strcasecmp(arg, "abort")) {
     if (scr_get_multimode())
-      scr_LogPrint("Leaving multi-line message mode");
+      scr_LogPrint(LPRINT_NORMAL, "Leaving multi-line message mode");
     scr_set_multimode(FALSE);
     return;
   } else if ((!strcasecmp(arg, "begin")) || (!strcasecmp(arg, "verbatim"))) {
@@ -526,36 +527,39 @@
     else
       scr_set_multimode(1);
 
-    scr_LogPrint("Entered multi-line message mode.");
-    scr_LogPrint("Select a buddy and use \"/msay send\" "
+    scr_LogPrint(LPRINT_NORMAL, "Entered multi-line message mode.");
+    scr_LogPrint(LPRINT_NORMAL, "Select a buddy and use \"/msay send\" "
                  "when your message is ready.");
     return;
   } else if (*arg == 0) {
-    scr_LogPrint("Please read the manual before using the /msay command.");
-    scr_LogPrint("(Use /msay begin to enter multi-line mode...)");
+    scr_LogPrint(LPRINT_NORMAL, "Please read the manual before using "
+                 "the /msay command.");
+    scr_LogPrint(LPRINT_NORMAL, "(Use \"/msay begin\" to enter "
+                 "multi-line mode...)");
     return;
   } else if (strcasecmp(arg, "send")) {
-    scr_LogPrint("Unrecognized parameter!");
+    scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
     return;
   }
 
   // send command
 
   if (!scr_get_multimode()) {
-    scr_LogPrint("No message to send.  Use \"/msay begin\" first.");
+    scr_LogPrint(LPRINT_NORMAL, "No message to send.  "
+                 "Use \"/msay begin\" first.");
     return;
   }
 
   scr_set_chatmode(TRUE);
 
   if (!current_buddy) {
-    scr_LogPrint("Who are you talking to??");
+    scr_LogPrint(LPRINT_NORMAL, "Who are you talking to??");
     return;
   }
 
   bud = BUDDATA(current_buddy);
   if (!(buddy_gettype(bud) & ROSTER_TYPE_USER)) {
-    scr_LogPrint("This is not a user");
+    scr_LogPrint(LPRINT_NORMAL, "This is not a user");
     return;
   }
 
@@ -579,15 +583,15 @@
     if (*arg++ == ' ')
       search_dir = -1;
     else
-      scr_LogPrint("Missing parameter");
+      scr_LogPrint(LPRINT_NORMAL, "Missing parameter");
   } else if (!strncasecmp(arg, "search_forward", 14)) {
     arg += 14;
     if (*arg++ == ' ')
       search_dir = 1;
     else
-      scr_LogPrint("Missing parameter");
+      scr_LogPrint(LPRINT_NORMAL, "Missing parameter");
   } else
-    scr_LogPrint("Unrecognized parameter!");
+    scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
 
   if (search_dir) { // It is a string search command
     for ( ; *arg && *arg == ' ' ; arg++)
@@ -640,8 +644,8 @@
     snprintf(buffer, 127, "Type: %s", typestr);
     scr_WriteIncomingMessage(jid, buffer, 0, HBB_PREFIX_INFO);
   } else {
-    if (name) scr_LogPrint("Name: %s", name);
-    scr_LogPrint("Type: %s",
+    if (name) scr_LogPrint(LPRINT_NORMAL, "Name: %s", name);
+    scr_LogPrint(LPRINT_NORMAL, "Type: %s",
             ((type == ROSTER_TYPE_GROUP) ? "group" : "unknown"));
   }
 
@@ -656,7 +660,7 @@
   char *newname, *p;
 
   if (!arg || (*arg == 0)) {
-    scr_LogPrint("Missing parameter");
+    scr_LogPrint(LPRINT_NORMAL, "Missing parameter");
     return;
   }
 
@@ -668,7 +672,7 @@
   type  = buddy_gettype(bud);
 
   if (type & ROSTER_TYPE_GROUP) {
-    scr_LogPrint("You can't rename groups");
+    scr_LogPrint(LPRINT_NORMAL, "You can't rename groups");
     return;
   }
 
@@ -699,7 +703,7 @@
   type = buddy_gettype(bud);
 
   if (type & ROSTER_TYPE_GROUP) {
-    scr_LogPrint("You can't move groups!");
+    scr_LogPrint(LPRINT_NORMAL, "You can't move groups!");
     return;
   }
 
@@ -725,16 +729,16 @@
   
   assign = parse_assigment(arg, &option, &value);
   if (!option) {
-    scr_LogPrint("Huh?");
+    scr_LogPrint(LPRINT_NORMAL, "Huh?");
     return;
   }
   if (!assign) {
     // This is a query
     value = settings_opt_get(option);
     if (value) {
-      scr_LogPrint("%s = [%s]", option, value);
+      scr_LogPrint(LPRINT_NORMAL, "%s = [%s]", option, value);
     } else
-      scr_LogPrint("Option %s is not set", option);
+      scr_LogPrint(LPRINT_NORMAL, "Option %s is not set", option);
     return;
   }
   // Update the option
@@ -755,21 +759,21 @@
   
   assign = parse_assigment(arg, &alias, &value);
   if (!alias) {
-    scr_LogPrint("Huh?");
+    scr_LogPrint(LPRINT_NORMAL, "Huh?");
     return;
   }
   if (!assign) {
     // This is a query
     value = settings_get(SETTINGS_TYPE_ALIAS, alias);
     if (value) {
-      scr_LogPrint("%s = %s", alias, value);
+      scr_LogPrint(LPRINT_NORMAL, "%s = %s", alias, value);
     } else
-      scr_LogPrint("Alias '%s' does not exist", alias);
+      scr_LogPrint(LPRINT_NORMAL, "Alias '%s' does not exist", alias);
     return;
   }
   // Check the alias does not conflict with a registered command
   if (cmd_get(alias)) {
-      scr_LogPrint("'%s' is a reserved word!", alias);
+      scr_LogPrint(LPRINT_NORMAL, "'%s' is a reserved word!", alias);
       return;
   }
   // Update the alias
@@ -794,16 +798,16 @@
   
   assign = parse_assigment(arg, &keycode, &value);
   if (!keycode) {
-    scr_LogPrint("Huh?");
+    scr_LogPrint(LPRINT_NORMAL, "Huh?");
     return;
   }
   if (!assign) {
     // This is a query
     value = settings_get(SETTINGS_TYPE_BINDING, keycode);
     if (value) {
-      scr_LogPrint("Key %s is bound to: %s", keycode, value);
+      scr_LogPrint(LPRINT_NORMAL, "Key %s is bound to: %s", keycode, value);
     } else
-      scr_LogPrint("Key %s is not bound", keycode);
+      scr_LogPrint(LPRINT_NORMAL, "Key %s is not bound", keycode);
     return;
   }
   // Update the key binding
--- a/mcabber/src/histolog.c	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/histolog.c	Mon Jul 25 21:46:35 2005 +0100
@@ -101,7 +101,8 @@
   fp = fopen(filename, "a");
   g_free(filename);
   if (!fp) {
-    scr_LogPrint("Unable to write history (cannot open logfile)");
+    scr_LogPrint(LPRINT_LOGNORM, "Unable to write history "
+                 "(cannot open logfile)");
     return;
   }
 
@@ -109,7 +110,8 @@
   err = fprintf(fp, "%c%c %-18.18s %03d %s\n", type, info, str_ts, len, data);
   fclose(fp);
   if (err < 0) {
-    scr_LogPrint("Error while writing to log file: %s", strerror(errno));
+    scr_LogPrint(LPRINT_LOGNORM, "Error while writing to log file: %s",
+                 strerror(errno));
   }
 }
 
@@ -132,7 +134,7 @@
 
   data = g_new(char, HBB_BLOCKSIZE+32);
   if (!data) {
-    scr_LogPrint("Not enough memory to read history file");
+    scr_LogPrint(LPRINT_LOGNORM, "Not enough memory to read history file");
     return;
   }
 
@@ -146,7 +148,7 @@
   // (it can take a while...)
   if (!fstat(fileno(fp), &bufstat)) {
     if (bufstat.st_size > 524288)
-      scr_LogPrint("Reading <%s> history file...", jid);
+      scr_LogPrint(LPRINT_NORMAL, "Reading <%s> history file...", jid);
   }
 
   /* See write_histo_line() for line format... */
@@ -163,7 +165,8 @@
         ((data[11] != 'T') || (data[20] != 'Z') ||
          (data[21] != ' ') || (data[25] != ' '))) {
       if (!err) {
-        scr_LogPrint("Error in history file format (%s), l.%u", jid, ln);
+        scr_LogPrint(LPRINT_LOGNORM, "Error in history file format (%s), l.%u",
+                     jid, ln);
         err = 1;
       }
       //break;
@@ -177,7 +180,8 @@
     if (((type == 'M') && (info != 'S' && info != 'R')) ||
         ((type == 'I') && (!strchr("OAIFDN", info)))) {
       if (!err) {
-        scr_LogPrint("Error in history file format (%s), l.%u", jid, ln);
+        scr_LogPrint(LPRINT_LOGNORM, "Error in history file format (%s), l.%u",
+                     jid, ln);
         err = 1;
       }
       //break;
@@ -196,7 +200,8 @@
     if (tail >= HBB_BLOCKSIZE+26 + data) {
       // Maybe we will have a parse error on next, because this
       // message is big (maybe too big).
-      scr_LogPrint("A message could be too big in history file...");
+      scr_LogPrint(LPRINT_LOGNORM, "A message could be too big "
+                   "in history file...");
     }
     // Remove last CR (we keep it if the line is empty, too)
     if ((tail > data+26) && (*(tail-1) == '\n'))
@@ -228,7 +233,7 @@
     if (root_dir) {
       int l = strlen(root_dir);
       if (l < 1) {
-        scr_LogPrint("root_dir too short");
+        scr_LogPrint(LPRINT_LOGNORM, "Error: logging dir name too short");
         UseFileLogging = FileLoadLogs = FALSE;
         return;
       }
@@ -251,8 +256,8 @@
     if (checkset_perm(RootDir, TRUE) == -1) {
       // The directory does not actually exists
       g_free(RootDir);
-      scr_LogPrint("ERROR: Cannot access history log directory, "
-                   "logging DISABLED");
+      scr_LogPrint(LPRINT_LOGNORM, "ERROR: Cannot access "
+                   "history log directory, logging DISABLED");
       UseFileLogging = FileLoadLogs = FALSE;
     }
   } else {  // Disable history logging
--- a/mcabber/src/hooks.c	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/hooks.c	Mon Jul 25 21:46:35 2005 +0100
@@ -45,7 +45,7 @@
 
   if (type && !strcmp(type, "error")) {
     message_flags = HBB_PREFIX_ERR | HBB_PREFIX_IN;
-    scr_LogPrint("Error message received from <%s>", jid);
+    scr_LogPrint(LPRINT_LOGNORM, "Error message received from <%s>", jid);
   } else
     message_flags = 0;
 
@@ -79,7 +79,7 @@
 inline void hk_statuschange(const char *jid, time_t timestamp, 
         enum imstatus status, const char *status_msg)
 {
-  scr_LogPrint("Buddy status has changed: [%c>%c] <%s> %s",
+  scr_LogPrint(LPRINT_LOGNORM, "Buddy status has changed: [%c>%c] <%s> %s",
           imstatus2char[roster_getstatus(jid)], imstatus2char[status], jid,
           ((status_msg) ? status_msg : ""));
   roster_setstatus(jid, status, status_msg);
@@ -96,7 +96,7 @@
   if (!msg && (old_status == new_status))
     return;
 
-  scr_LogPrint("Your status has changed:  [%c>%c] %s",
+  scr_LogPrint(LPRINT_LOGNORM, "Your status has changed:  [%c>%c] %s",
           imstatus2char[old_status], imstatus2char[new_status],
           ((msg) ? msg : ""));
   //hlog_write_status(NULL, 0, status);
@@ -156,13 +156,13 @@
   if (!arg_type || !arg_info) return;
 
   if ((pid=fork()) == -1) {
-    scr_LogPrint("Fork error, cannot launch external command.");
+    scr_LogPrint(LPRINT_LOGNORM, "Fork error, cannot launch external command.");
     return;
   }
 
   if (pid == 0) { // child
     if (execl(extcmd, extcmd, arg_type, arg_info, jid, arg_data) == -1) {
-      // ut_WriteLog("Cannot execute external command.\n");
+      // scr_LogPrint(LPRINT_LOGNORM, "Cannot execute external command.");
       exit(1);
     }
   }
--- a/mcabber/src/jabglue.c	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/jabglue.c	Mon Jul 25 21:46:35 2005 +0100
@@ -60,20 +60,9 @@
 void statehandler(jconn, int);
 void packethandler(jconn, jpacket);
 
-void screen_logger(jconn j, int io, const char *buf)
-{
-  scr_LogPrint("%03s: %s", ((io == 0) ? "OUT" : "IN"), buf);
-}
-
-void file_logger(jconn j, int io, const char *buf)
+static void logger(jconn j, int io, const char *buf)
 {
-  ut_WriteLog("%03s: %s\n", ((io == 0) ? "OUT" : "IN"), buf);
-}
-
-void big_logger(jconn j, int io, const char *buf)
-{
-  screen_logger(j, io, buf);
-  file_logger(j, io, buf);
+  scr_LogPrint(LPRINT_DEBUG, "%03s: %s", ((io == 0) ? "OUT" : "IN"), buf);
 }
 
 /*
@@ -145,7 +134,7 @@
   jc = jab_new((char*)jid, (char*)pass, port, ssl);
 
   /* These 3 functions can deal with a NULL jc, no worry... */
-  jab_logger(jc, file_logger);
+  jab_logger(jc, logger);
   jab_packet_handler(jc, &packethandler);
   jab_state_handler(jc, &statehandler);
 
@@ -221,7 +210,7 @@
     }
 
     if (!jc || jc->state == JCONN_STATE_OFF) {
-      scr_LogPrint("Unable to connect to the server");
+      scr_LogPrint(LPRINT_LOGNORM, "Unable to connect to the server");
       online = FALSE;
     }
   }
@@ -384,7 +373,7 @@
 
   // If the current buddy is an agent, unsubscribe from it
   if (roster_gettype(cleanjid) == ROSTER_TYPE_AGENT) {
-    scr_LogPrint("Unregistering from the %s agent", cleanjid);
+    scr_LogPrint(LPRINT_LOGNORM, "Unregistering from the %s agent", cleanjid);
 
     x = jutil_iqnew(JPACKET__SET, NS_REGISTER);
     xmlnode_put_attrib(x, "to", cleanjid);
@@ -560,8 +549,10 @@
   //jidsplit(from, &u, &h, &r);
   // Maybe we should remember the resource?
   if (r)
-    scr_LogPrint("There is an extra part in message (resource?): %s", r);
-  //scr_LogPrint("Msg from <%s>, type=%s", jidtodisp(from), type);
+    scr_LogPrint(LPRINT_NORMAL,
+                 "There is an extra part in message (resource?): %s", r);
+  //scr_LogPrint(LPRINT_NORMAL, "Msg from <%s>, type=%s",
+  //             jidtodisp(from), type);
   */
 
   jid = jidtodisp(from);
@@ -574,12 +565,12 @@
 {
   static int previous_state = -1;
 
-  ut_WriteLog("StateHandler called (state=%d).\n", state);
+  scr_LogPrint(LPRINT_DEBUG, "StateHandler called (state=%d).", state);
 
   switch(state) {
     case JCONN_STATE_OFF:
         if (previous_state != JCONN_STATE_OFF)
-          scr_LogPrint("[Jabber] Not connected to the server");
+          scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Not connected to the server");
 
         online = FALSE;
         mystatus = offline;
@@ -588,21 +579,22 @@
         break;
 
     case JCONN_STATE_CONNECTED:
-        scr_LogPrint("[Jabber] Connected to the server");
+        scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Connected to the server");
         break;
 
     case JCONN_STATE_AUTH:
-        scr_LogPrint("[Jabber] Authenticating to the server");
+        scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Authenticating to the server");
         break;
 
     case JCONN_STATE_ON:
-        scr_LogPrint("[Jabber] Communication with the server established");
+        scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Communication with the server "
+                     "established");
         online = TRUE;
         break;
 
     case JCONN_STATE_CONNECTING:
         if (previous_state != state)
-        scr_LogPrint("[Jabber] Connecting to the server");
+        scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Connecting to the server");
         break;
 
     default:
@@ -679,7 +671,7 @@
           if ((p = xmlnode_get_attrib(packet->x, "id")) != NULL) {
             int iid = atoi(p);
 
-            ut_WriteLog("iid = %d\n", iid);
+            scr_LogPrint(LPRINT_DEBUG, "iid = %d", iid);
             if (iid == s_id) {
               if (!regmode) {
                 if (jstate == STATE_GETAUTH) {
@@ -705,11 +697,11 @@
               if (!x) x = packet->x;
 
               //jhook.gotvcard(ic, x); TODO
-              scr_LogPrint("Got VCARD");
+              scr_LogPrint(LPRINT_LOGNORM, "Got VCARD");
               return;
             } else if (!strcmp(p, "versionreq")) {
               // jhook.gotversion(ic, packet->x); TODO
-              scr_LogPrint("Got version");
+              scr_LogPrint(LPRINT_LOGNORM, "Got version");
               return;
             }
           }
@@ -740,7 +732,7 @@
                     g_free(cleanjid);
                   }
                   if (alias && name && desc) {
-                    scr_LogPrint("Agent: %s / %s / %s / type=%d",
+                    scr_LogPrint(LPRINT_LOGNORM, "Agent: %s / %s / %s / type=%d",
                                  alias, name, desc, atype);
 
                     if (atype == search) {
@@ -773,10 +765,10 @@
 
               if (!strcmp(id, "Agent info")) {
                 // jhook.gotagentinfo(packet->x); TODO
-                scr_LogPrint("Got agent info");
+                scr_LogPrint(LPRINT_LOGNORM, "Got agent info");
               } else if (!strcmp(id, "Lookup")) {
                 // jhook.gotsearchresults(packet->x); TODO
-                scr_LogPrint("Got search results");
+                scr_LogPrint(LPRINT_LOGNORM, "Got search results");
               } else if (!strcmp(id, "Register")) {
                 x = jutil_iqnew(JPACKET__GET, NS_REGISTER);
                 xmlnode_put_attrib(x, "to", from);
@@ -835,7 +827,7 @@
                 */
           }
 #endif
-          scr_LogPrint("Error code from server (%d)", code);
+          scr_LogPrint(LPRINT_LOGNORM, "Error code from server (%d)", code);
 
         }
         break;
@@ -874,17 +866,17 @@
         break;
 
     case JPACKET_S10N:
-        scr_LogPrint("Received (un)subscription packet (type=%s)",
-                ((type) ? type : ""));
+        scr_LogPrint(LPRINT_LOGNORM, "Received (un)subscription packet "
+                     "(type=%s)", ((type) ? type : ""));
 
         if (!strcmp(type, "subscribe")) {
           int isagent;
           r = jidtodisp(from);
           isagent = (roster_gettype(r) & ROSTER_TYPE_AGENT) != 0;
           g_free(r);
-          scr_LogPrint("isagent=%d", isagent); // XXX DBG
+          scr_LogPrint(LPRINT_LOGNORM, "isagent=%d", isagent); // XXX DBG
           if (!isagent) {
-            scr_LogPrint("<%s> wants to subscribe "
+            scr_LogPrint(LPRINT_LOGNORM, "<%s> wants to subscribe "
                          "to your network presence updates", from);
             // FIXME we accept everybody...
             x = jutil_presnew(JPACKET__SUBSCRIBED, from, 0);
@@ -899,7 +891,8 @@
           x = jutil_presnew(JPACKET__UNSUBSCRIBED, from, 0);
           jab_send(jc, x);
           xmlnode_free(x);
-          scr_LogPrint("<%s> has unsubscribed to your presence updates", from);
+          scr_LogPrint(LPRINT_LOGNORM, "<%s> has unsubscribed to "
+                       "your presence updates", from);
         }
         break;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/logprint.h	Mon Jul 25 21:46:35 2005 +0100
@@ -0,0 +1,14 @@
+#ifndef __LOGPRINT_H__
+#define __LOGPRINT_H__ 1
+
+// Flags for scr_LogPrint()
+#define LPRINT_NORMAL   1   // Display in log window
+#define LPRINT_LOG      2   // Log to file (if enabled)
+#define LPRINT_DEBUG    4   // Debug message (log if enabled)
+
+// For convenience...
+#define LPRINT_LOGNORM  (LPRINT_NORMAL|LPRINT_LOG)
+
+void scr_LogPrint(unsigned int flag, const char *fmt, ...);
+
+#endif /* __LOGPRINT_H__ */
--- a/mcabber/src/main.c	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/main.c	Mon Jul 25 21:46:35 2005 +0100
@@ -56,15 +56,15 @@
   resource   = settings_opt_get("resource");
 
   if (!servername) {
-    scr_LogPrint("Server name has not been specified!\n");
+    scr_LogPrint(LPRINT_NORMAL, "Server name has not been specified!");
     return;
   }
   if (!username) {
-    scr_LogPrint("User name has not been specified!\n");
+    scr_LogPrint(LPRINT_NORMAL, "User name has not been specified!");
     return;
   }
   if (!password) {
-    scr_LogPrint("Password has not been specified!\n");
+    scr_LogPrint(LPRINT_NORMAL, "Password has not been specified!");
     return;
   }
   if (!resource)
@@ -76,21 +76,17 @@
   jb_set_priority(settings_opt_get_int("priority"));
 
   /* Connect to server */
-  ut_WriteLog("Connecting to server: %s\n", servername);
-  scr_LogPrint("Connecting to server: %s", servername);
-  if (port) {
-    ut_WriteLog(" using port %d\n", port);
-    scr_LogPrint(" using port %d", port);
-  }
+  scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, "Connecting to server: %s",
+               servername);
+  if (port)
+    scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " using port %d", port);
 
   jid = compose_jid(username, servername, resource);
   jc = jb_connect(jid, port, ssl, password);
   g_free(jid);
 
-  if (!jc) {
-    ut_WriteLog("\tConnection error!!!\n");
-    scr_LogPrint("Error connecting to (%s)\n", servername);
-  }
+  if (!jc)
+    scr_LogPrint(LPRINT_LOGNORM, "Error connecting to (%s)", servername);
 
   jb_reset_keepalive();
 }
@@ -114,7 +110,7 @@
       pid = waitpid (WAIT_ANY, &status, WNOHANG);
     } while (pid > 0);
     //if (pid < 0)
-    //  ut_WriteLog("Error in waitpid: errno=%d\n", errno);
+    //  scr_LogPrint(LPRINT_LOGNORM, "Error in waitpid: errno=%d", errno);
     signal(SIGCHLD, sig_handler);
   } else if (signum == SIGTERM) {
     mcabber_disconnect("Killed by SIGTERM");
@@ -128,9 +124,9 @@
     LastSigtermTime = now;
     signal(SIGINT, sig_handler);
     scr_handle_sigint();
-    scr_LogPrint("Hit Ctrl-C twice to leave mcabber");
+    scr_LogPrint(LPRINT_NORMAL, "Hit Ctrl-C twice to leave mcabber");
   } else {
-    ut_WriteLog("Caught signal: %d\n", signum);
+    scr_LogPrint(LPRINT_LOGNORM, "Caught signal: %d", signum);
   }
 }
 
@@ -186,11 +182,6 @@
 
   credits();
 
-  /* Set this >0 to enable log */
-  /* Note: debug can be enabled via the config file */
-  ut_InitDebug(0, NULL);
-
-  ut_WriteLog("Setting signals handlers...\n");
   signal(SIGTERM, sig_handler);
   signal(SIGINT,  sig_handler);
   signal(SIGCHLD, sig_handler);
@@ -215,19 +206,17 @@
   /* Initialize commands system */
   cmd_init();
 
-  if (configFile)
-    ut_WriteLog("Setting config file: %s\n", configFile);
-
   /* Parsing config file... */
-  ut_WriteLog("Parsing config file...\n");
   ret = cfg_read_file(configFile);
+  /* free() configFile if it has been allocated during options parsing */
   if (configFile) g_free(configFile);
   /* Leave if there was an error in the config. file */
   if (ret)
     exit(EXIT_FAILURE);
 
-  optstring = settings_opt_get("debug");
-  if (optstring) ut_InitDebug(1, optstring);
+  optstring = settings_opt_get("tracelog_file");
+  if (optstring)
+    ut_InitDebug(settings_opt_get_int("tracelog_level"), optstring);
 
   /* If no password is stored, we ask for it before entering
      ncurses mode */
@@ -235,10 +224,10 @@
     ask_password();
 
   /* Initialize N-Curses */
-  ut_WriteLog("Initializing N-Curses...\n");
+  scr_LogPrint(LPRINT_DEBUG, "Initializing N-Curses...");
   scr_InitCurses();
 
-  ut_WriteLog("Drawing main window...\n");
+  scr_LogPrint(LPRINT_DEBUG, "Drawing main window...");
   scr_DrawMainWindow(TRUE);
 
   optval   = (settings_opt_get_int("logging") > 0);
@@ -254,7 +243,7 @@
   if (settings_opt_get("pinginterval"))
     ping = (unsigned int) settings_opt_get_int("pinginterval");
   jb_set_keepalive_delay(ping);
-  ut_WriteLog("Ping interval stablished: %d secs\n", ping);
+  scr_LogPrint(LPRINT_DEBUG, "Ping interval established: %d secs", ping);
 
   if (settings_opt_get_int("hide_offline_buddies") > 0)
     buddylist_set_hide_offline_buddies(TRUE);
@@ -263,10 +252,9 @@
   if (settings_opt_get("password"))
     mcabber_connect();
   else
-    scr_LogPrint("Can't connect: no password supplied");
+    scr_LogPrint(LPRINT_LOGNORM, "Can't connect: no password supplied");
 
-  ut_WriteLog("Entering into main loop...\n\n");
-  ut_WriteLog("Ready to send/receive messages...\n");
+  scr_LogPrint(LPRINT_DEBUG, "Entering into main loop...");
 
   for (ret = 0 ; ret != 255 ; ) {
     key = scr_Getch();
--- a/mcabber/src/screen.c	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/screen.c	Mon Jul 25 21:46:35 2005 +0100
@@ -233,33 +233,38 @@
 
 //  scr_LogPrint(...)
 // Display a message in the log window.
-void scr_LogPrint(const char *fmt, ...)
+void scr_LogPrint(unsigned int flag, const char *fmt, ...)
 {
   time_t timestamp;
-  char *buffer;
+  char *buffer, *b2;
   va_list ap;
 
+  if (!flag) return;
+
   do {
-    buffer = (char *) calloc(1, 1024);
+    buffer = (char *) calloc(1, 1088);
   } while (!buffer);
 
   timestamp = time(NULL);
   strftime(buffer, 64, "[%H:%M:%S] ", localtime(&timestamp));
-  if (Curses)
-    wprintw(logWnd, "\n%s", buffer);
-  else
-    printf("%s", buffer);
-
+  for (b2 = buffer ; *b2 ; b2++)
+    ;
   va_start(ap, fmt);
-  vsnprintf(buffer, 1024, fmt, ap);
+  vsnprintf(b2, 1024, fmt, ap);
   va_end(ap);
 
-  if (Curses) {
-    wprintw(logWnd, "%s", buffer);
-    update_panels();
-    doupdate();
-  } else {
-    printf("%s\n", buffer);
+  if (flag & LPRINT_NORMAL) {
+    if (Curses) {
+      wprintw(logWnd, "\n%s", buffer);
+      update_panels();
+      doupdate();
+    } else {
+      printf("%s\n", buffer);
+    }
+  }
+  if (flag & (LPRINT_LOG|LPRINT_DEBUG)) {
+    strcat(buffer, "\n");
+    ut_WriteLog(flag, buffer);
   }
   free(buffer);
 }
@@ -579,7 +584,7 @@
     inputPanel  = new_panel(inputWnd);
 
     if (utf8_mode)
-      scr_LogPrint("WARNING: UTF-8 not yet supported!");
+      scr_LogPrint(LPRINT_NORMAL, "WARNING: UTF-8 not yet supported!");
   } else {
     // Update panels
     replace_panel(rosterPanel, rosterWnd);
@@ -682,7 +687,7 @@
   // Update offset if necessary
   i = g_list_position(buddylist, current_buddy);
   if (i == -1) { // This is bad
-    scr_LogPrint("Doh! Can't find current selected buddy!!");
+    scr_LogPrint(LPRINT_NORMAL, "Doh! Can't find current selected buddy!!");
     return;
   } else if (i < offset) {
     offset = i;
@@ -920,7 +925,8 @@
   if (nbuddy) {
     set_current_buddy(nbuddy);
     if (chatmode) scr_ShowBuddyWindow();
-  } else scr_LogPrint("Error: nbuddy == NULL");
+  } else
+    scr_LogPrint(LPRINT_LOGNORM, "Error: nbuddy == NULL"); // should not happen
 }
 
 //  scr_RosterJumpAlternate()
@@ -1061,7 +1067,7 @@
     update_panels();
     doupdate();
   } else
-    scr_LogPrint("Search string not found");
+    scr_LogPrint(LPRINT_NORMAL, "Search string not found");
 }
 
 //  scr_set_chatmode()
@@ -1109,7 +1115,7 @@
   static int num;
 
   if (!multimode) {
-    scr_LogPrint("Error: Not in multi-line message mode!");
+    scr_LogPrint(LPRINT_NORMAL, "Error: Not in multi-line message mode!");
     return;
   }
   if (multiline) {
@@ -1117,17 +1123,17 @@
     if (len >= HBB_BLOCKSIZE - 1) {
       // We don't handle single messages with size > HBB_BLOCKSIZE
       // (see hbuf)
-      scr_LogPrint("Your multi-line message is too big, this line has "
-                   "not been added.");
-      scr_LogPrint("Please send this part now...");
+      scr_LogPrint(LPRINT_NORMAL, "Your multi-line message is too big, "
+                   "this line has not been added.");
+      scr_LogPrint(LPRINT_NORMAL, "Please send this part now...");
       return;
     }
     if (num >= MULTILINE_MAX_LINE_NUMBER) {
       // We don't allow too many lines; however the maximum is arbitrary
       // (It should be < 1000 yet)
-      scr_LogPrint("Your message has too many lines, this one has "
-                   "not been added.");
-      scr_LogPrint("Please send this part now...");
+      scr_LogPrint(LPRINT_NORMAL, "Your message has too many lines, "
+                   "this one has not been added.");
+      scr_LogPrint(LPRINT_NORMAL, "Please send this part now...");
       return;
     }
     multiline = g_renew(char, multiline, len);
@@ -1144,7 +1150,8 @@
     } else
       return;
   }
-  scr_LogPrint("Multi-line mode: line #%d added  [%.25s...", num, line);
+  scr_LogPrint(LPRINT_NORMAL, "Multi-line mode: line #%d added  [%.25s...",
+               num, line);
 }
 
 //  scr_cmdhisto_addline()
@@ -1300,7 +1307,7 @@
   int len = strlen(text);
   // Check the line isn't too long
   if (strlen(inputLine) + len >= INPUTLINE_LENGTH) {
-    scr_LogPrint("Cannot insert text, line too long.");
+    scr_LogPrint(LPRINT_LOGNORM, "Cannot insert text, line too long.");
     return;
   }
 
@@ -1339,7 +1346,7 @@
       g_free(xpline);
     }
     if ((!com && (!alias || !completion_started)) || !row) {
-      scr_LogPrint("I cannot complete that...");
+      scr_LogPrint(LPRINT_NORMAL, "I cannot complete that...");
       return;
     }
     if (!alias)
@@ -1605,9 +1612,10 @@
                 return 255;
               g_free(cmd);
             } else {
-              scr_LogPrint("Unknown key=%d", key);
+              scr_LogPrint(LPRINT_NORMAL, "Unknown key=%d", key);
               if (utf8_mode)
-                scr_LogPrint("WARNING: UTF-8 not yet supported!");
+                scr_LogPrint(LPRINT_NORMAL,
+                             "WARNING: UTF-8 not yet supported!");
             }
           }
     }
--- a/mcabber/src/screen.h	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/screen.h	Mon Jul 25 21:46:35 2005 +0100
@@ -4,6 +4,8 @@
 #include <ncurses.h>
 #include <glib.h>
 
+#include "logprint.h"
+
 #define COLOR_GENERAL   3
 #define COLOR_NMSG      4
 #define COLOR_BD_DESSEL 5
@@ -24,14 +26,13 @@
 extern int update_roster;
 
 void scr_InitCurses(void);
+void scr_TerminateCurses(void);
 void scr_DrawMainWindow(unsigned int fullinit);
 void scr_DrawRoster(void);
-void scr_TerminateCurses(void);
 void scr_WriteIncomingMessage(const char *jidfrom, const char *text,
         time_t timestamp, guint prefix);
 void scr_WriteOutgoingMessage(const char *jidto,   const char *text);
 void scr_ShowBuddyWindow(void);
-void scr_LogPrint(const char *fmt, ...);
 inline void scr_set_chatmode(int enable);
 inline void scr_set_multimode(int enable);
 inline int  scr_get_multimode();
--- a/mcabber/src/settings.c	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/settings.c	Mon Jul 25 21:46:35 2005 +0100
@@ -78,7 +78,7 @@
     // Use default config file locations
     char *home = getenv("HOME");
     if (!home) {
-      ut_WriteLog("Can't find home dir!\n");
+      scr_LogPrint(LPRINT_LOG, "Can't find home dir!");
       fprintf(stderr, "Can't find home dir!\n");
       return -1;
     }
@@ -138,14 +138,16 @@
       if (strncmp(line, "set ", 4) &&
           strncmp(line, "bind ", 5) &&
           strncmp(line, "alias ", 6)) {
-        scr_LogPrint("Error in configuration file (l. %d): bad command", ln);
+        scr_LogPrint(LPRINT_LOGNORM,
+                     "Error in configuration file (l. %d): bad command", ln);
         err++;
         continue;
       }
       *(--line) = '/';        // Set the leading '/' to build a command line
       process_command(line);  // Process the command
     } else {
-      scr_LogPrint("Error in configuration file (l. %d): no assignment", ln);
+      scr_LogPrint(LPRINT_LOGNORM,
+                   "Error in configuration file (l. %d): no assignment", ln);
       err++;
     }
   }
--- a/mcabber/src/utils.c	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/utils.c	Mon Jul 25 21:46:35 2005 +0100
@@ -40,7 +40,7 @@
 {
   FILE *fp;
 
-  if (!level) {
+  if (level < 1) {
     DebugEnabled = 0;
     FName = NULL;
     return;
@@ -62,34 +62,23 @@
 
   DebugEnabled = level;
 
-  fp = fopen(FName, "w");
+  fp = fopen(FName, "a");
   if (!fp) return;
-  fprintf(fp, "Debugging mode started...\n"
-	  "-----------------------------------\n");
+  fprintf(fp, "New trace log started.\n"
+	  "----------------------\n");
+  fchmod(fileno(fp), S_IRUSR|S_IWUSR);
   fclose(fp);
 }
 
-void ut_WriteLog(const char *fmt, ...)
+void ut_WriteLog(unsigned int flag, const char *data)
 {
-  FILE *fp = NULL;
-  time_t ahora;
-  va_list ap;
-  char *buffer = NULL;
-
-  if (DebugEnabled && FName) {
-    fp = fopen(FName, "a+");
+  if (!DebugEnabled || !FName) return;
+  
+  if (((DebugEnabled == 2) && (flag & (LPRINT_LOG|LPRINT_DEBUG))) ||
+      ((DebugEnabled == 1) && (flag & LPRINT_LOG))) {
+    FILE *fp = fopen(FName, "a+");
     if (!fp) return;
-    buffer = (char *) calloc(1, 64);
-
-    ahora = time(NULL);
-    strftime(buffer, 64, "[%H:%M:%S] ", localtime(&ahora));
-    fprintf(fp, "%s", buffer);
-
-    va_start(ap, fmt);
-    vfprintf(fp, fmt, ap);
-    va_end(ap);
-
-    free(buffer);
+    fputs(data, fp);
     fclose(fp);
   }
 }
@@ -107,7 +96,7 @@
   if (fd == -1) return -1;
 
   if (buf.st_uid != geteuid()) {
-    scr_LogPrint("Wrong file owner [%s]", name);
+    scr_LogPrint(LPRINT_LOGNORM, "Wrong file owner [%s]", name);
     return 1;
   }
 
@@ -115,17 +104,17 @@
       buf.st_mode & (S_IROTH | S_IWOTH | S_IXOTH)) {
     if (setmode) {
       mode_t newmode = 0;
-      scr_LogPrint("Bad permissions [%s]", name);
+      scr_LogPrint(LPRINT_LOGNORM, "Bad permissions [%s]", name);
       if (S_ISDIR(buf.st_mode))
         newmode |= S_IXUSR;
       newmode |= S_IRUSR | S_IWUSR;
       if (chmod(name, newmode)) {
-        scr_LogPrint("WARNING: Failed to correct permissions!");
+        scr_LogPrint(LPRINT_LOGNORM, "WARNING: Failed to correct permissions!");
         return 1;
       }
-      scr_LogPrint("Permissions have been corrected");
+      scr_LogPrint(LPRINT_LOGNORM, "Permissions have been corrected");
     } else {
-      scr_LogPrint("WARNING: Bad permissions [%s]", name);
+      scr_LogPrint(LPRINT_LOGNORM, "WARNING: Bad permissions [%s]", name);
       return 1;
     }
   }
--- a/mcabber/src/utils.h	Mon Jul 25 19:40:17 2005 +0100
+++ b/mcabber/src/utils.h	Mon Jul 25 21:46:35 2005 +0100
@@ -2,7 +2,7 @@
 #define __UTILS_H__ 1
 
 void ut_InitDebug(unsigned int level, const char *file);
-void ut_WriteLog(const char *fmt, ...);
+void ut_WriteLog(unsigned int flag, const char *data);
 
 int checkset_perm(const char *name, unsigned int setmode);