comparison main.c @ 541:44f67ec5e945

Improve logging facilities. Private chats in query windows are now logged separately. A log file directory can be set in configuration. Room log files are always of format room_%d.ext. Log file extension can be set, default is ".log".
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 11 Nov 2012 18:32:42 +0200
parents ffacb78d9b9f
children d8184a3c241f
comparison
equal deleted inserted replaced
540:658c188101a6 541:44f67ec5e945
19 #include <sys/wait.h> 19 #include <sys/wait.h>
20 #endif 20 #endif
21 21
22 #ifdef __WIN32 22 #ifdef __WIN32
23 #define SET_CONFIG_FILE "nnchat.txt" 23 #define SET_CONFIG_FILE "nnchat.txt"
24 #define SET_DIR_SEPARATOR "\\" 24 #define SET_DIR_SEPARATOR '\\'
25 #else 25 #else
26 #define SET_CONFIG_FILE ".nnchat" 26 #define SET_CONFIG_FILE ".nnchat"
27 #define SET_DIR_SEPARATOR "/" 27 #define SET_DIR_SEPARATOR '/'
28 #endif 28 #endif
29 29
30 #define SET_PROFILE_PREFIX "http://www.newbienudes.com/profile/%s/" 30 #define SET_PROFILE_PREFIX "http://www.newbienudes.com/profile/%s/"
31 #define SET_NICK_SEPARATOR ':' 31 #define SET_NICK_SEPARATOR ':'
32 32
45 *optUserName = NULL, 45 *optUserName = NULL,
46 *optUserNameCmd = NULL, 46 *optUserNameCmd = NULL,
47 *optUserNameEnc = NULL, 47 *optUserNameEnc = NULL,
48 *optPassword = NULL, 48 *optPassword = NULL,
49 *optPasswordCmd = NULL, 49 *optPasswordCmd = NULL,
50 *optLogFilename = NULL, 50 *optLogPath = NULL,
51 *optLogExtension = ".log",
51 *optSite = "NN", 52 *optSite = "NN",
52 *optNickSepStr = NULL; 53 *optNickSepStr = NULL;
53 char optNickSep; 54 char optNickSep;
54 BOOL optDaemon = FALSE; 55 BOOL optDaemon = FALSE;
55 FILE *optLogFile = NULL;
56 BOOL setIgnoreMode = FALSE, 56 BOOL setIgnoreMode = FALSE,
57 optDebug = FALSE, 57 optDebug = FALSE,
58 optLogEnable = FALSE, 58 optLogEnable = FALSE,
59 optOnlyFriendPrv = FALSE; 59 optOnlyFriendPrv = FALSE;
60 60
87 { 0, '?', "help", "Show this help", OPT_NONE }, 87 { 0, '?', "help", "Show this help", OPT_NONE },
88 { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, 88 { 1, 'v', "verbose", "Be more verbose", OPT_NONE },
89 { 2, 'p', "port", "Connect to port", OPT_ARGREQ }, 89 { 2, 'p', "port", "Connect to port", OPT_ARGREQ },
90 { 3, 's', "server", "Server to connect to", OPT_ARGREQ }, 90 { 3, 's', "server", "Server to connect to", OPT_ARGREQ },
91 { 4, 'C', "color", "Initial color in RGB hex 000000", OPT_ARGREQ }, 91 { 4, 'C', "color", "Initial color in RGB hex 000000", OPT_ARGREQ },
92 { 5, 'l', "logfile", "Log filename", OPT_ARGREQ },
93 { 6, 'D', "daemon", "A pseudo-daemon mode for logging", OPT_NONE }, 92 { 6, 'D', "daemon", "A pseudo-daemon mode for logging", OPT_NONE },
94 { 7, 'f', "force-site", "Force site (default: NN)", OPT_ARGREQ }, 93 { 7, 'f', "force-site", "Force site (default: NN)", OPT_ARGREQ },
95 { 8, 'd', "debug", "Enable various debug features", OPT_NONE }, 94 { 8, 'd', "debug", "Enable various debug features", OPT_NONE },
96 95
97 {10, '4', "socks4", "SOCKS4 proxy server", OPT_ARGREQ }, 96 {10, '4', "socks4", "SOCKS4 proxy server", OPT_ARGREQ },
138 THERR("Invalid color argument '%s', should be a RGB hex triplet '000000'.\n", 137 THERR("Invalid color argument '%s', should be a RGB hex triplet '000000'.\n",
139 optArg); 138 optArg);
140 return FALSE; 139 return FALSE;
141 } 140 }
142 THMSG(1, "Using color #%06x\n", optUserColor); 141 THMSG(1, "Using color #%06x\n", optUserColor);
143 break;
144
145 case 5:
146 optLogFilename = optArg;
147 optLogEnable = TRUE;
148 break; 142 break;
149 143
150 case 7: 144 case 7:
151 optSite = optArg; 145 optSite = optArg;
152 break; 146 break;
245 str_get_timestamp(tmpStr, sizeof(tmpStr), "½17½[½11½%H:%M:%S½17½]½0½ "); 239 str_get_timestamp(tmpStr, sizeof(tmpStr), "½17½[½11½%H:%M:%S½17½]½0½ ");
246 } 240 }
247 241
248 buf = th_strdup_vprintf(fmt, ap); 242 buf = th_strdup_vprintf(fmt, ap);
249 243
250 if (optLogFile && (flags & LOG_FILE)) 244 if (win != NULL && win->logFile && (flags & LOG_FILE))
251 { 245 {
252 if (flags & LOG_STAMP) printFile(optLogFile, tmpStr); 246 if (flags & LOG_STAMP) printFile(win->logFile, tmpStr);
253 printFile(optLogFile, buf); 247 printFile(win->logFile, buf);
254 fflush(optLogFile); 248 fflush(win->logFile);
255 } 249 }
256 250
257 if (!optDaemon && (flags & LOG_WINDOW)) 251 if (!optDaemon && (flags & LOG_WINDOW))
258 { 252 {
259 nn_window_t *tmp = (win != NULL) ? win : nnwin_main_window(); 253 nn_window_t *tmp = (win != NULL) ? win : nnwin_main_window();
1330 1324
1331 return FALSE; 1325 return FALSE;
1332 } 1326 }
1333 1327
1334 1328
1335 BOOL nn_log_file_open(void)
1336 {
1337 char *filename;
1338
1339 if (optLogFilename == NULL || !optLogEnable)
1340 return FALSE;
1341
1342 filename = nn_log_parse_filename(optLogFilename, optPort);
1343
1344 if ((optLogFile = fopen(filename, "a")) == NULL)
1345 {
1346 errorMsg("Could not open logfile '%s' for appending!\n", filename);
1347 th_free(filename);
1348 return FALSE;
1349 }
1350
1351 th_free(filename);
1352
1353 return TRUE;
1354 }
1355
1356
1357 void nn_log_file_close(void)
1358 {
1359 if (optLogFile)
1360 {
1361 fclose(optLogFile);
1362 optLogFile = NULL;
1363 }
1364 }
1365
1366
1367 BOOL processUserInput(int c, nn_editbuf_t *editBuf, nn_editstate_t *editState) 1329 BOOL processUserInput(int c, nn_editbuf_t *editBuf, nn_editstate_t *editState)
1368 { 1330 {
1369 // Chat window switching via Meta/Esc-[1..9] 1331 // Chat window switching via Meta/Esc-[1..9]
1370 if (c >= 0x5001 && c <= 0x5009) 1332 if (c >= 0x5001 && c <= 0x5009)
1371 { 1333 {
1520 memset(st, 0, sizeof(nn_editstate_t)); 1482 memset(st, 0, sizeof(nn_editstate_t));
1521 st->insertMode = TRUE; 1483 st->insertMode = TRUE;
1522 st->debugMsg = debugMsg; 1484 st->debugMsg = debugMsg;
1523 } 1485 }
1524 1486
1487
1488 BOOL nn_log_open(nn_window_t *win)
1489 {
1490 char *path = NULL;
1491
1492 if (!optLogEnable)
1493 return FALSE;
1494
1495 th_free(win->logFilename);
1496 win->logFilename = NULL;
1497
1498 if (optLogPath != NULL)
1499 {
1500 char *lt = strrchr(optLogPath, SET_DIR_SEPARATOR);
1501 if (lt == NULL || lt[1] != 0)
1502 path = th_strdup_printf("%s%c", optLogPath, SET_DIR_SEPARATOR);
1503 else
1504 path = th_strdup(optLogPath);
1505 }
1506
1507 if (win->id == NULL)
1508 {
1509 win->logFilename = th_strdup_printf("%sroom_%d%s",
1510 path, optPort, optLogExtension);
1511 }
1512 else
1513 {
1514 size_t pos;
1515 char *cleaned;
1516
1517 if ((cleaned = th_strdup(win->id)) == NULL)
1518 return FALSE;
1519
1520 for (pos = 0; cleaned[pos] != 0; pos++)
1521 {
1522 if (!isalnum(cleaned[pos]))
1523 cleaned[pos] = '_';
1524 }
1525
1526 win->logFilename = th_strdup_printf("%s%s%s", path, cleaned, optLogExtension);
1527 th_free(cleaned);
1528 }
1529
1530 if (win->logFilename == NULL)
1531 goto error;
1532
1533 if ((win->logFile = fopen(win->logFilename, "a")) == NULL)
1534 {
1535 errorMsg("Could not open logfile '%s' for appending!\n", win->logFilename);
1536 goto error;
1537 }
1538
1539 printMsg(win, "Logging to '%s'.\n", win->logFilename);
1540
1541 th_free(path);
1542 return TRUE;
1543
1544 error:
1545 th_free(path);
1546 th_free(win->logFilename);
1547 win->logFilename = NULL;
1548 return FALSE;
1549 }
1550
1551
1552 void nn_log_close(nn_window_t *win)
1553 {
1554 if (win->logFile != NULL)
1555 fclose(win->logFile);
1556 win->logFile = NULL;
1557
1558 th_free(win->logFilename);
1559 win->logFilename = NULL;
1560 }
1561
1562
1525 int main(int argc, char *argv[]) 1563 int main(int argc, char *argv[])
1526 { 1564 {
1527 char *tmpStr; 1565 char *tmpStr;
1528 int index, updateCount = 0; 1566 int index, updateCount = 0;
1529 BOOL argsOK, colorSet = FALSE; 1567 BOOL argsOK, colorSet = FALSE;
1584 th_cfg_add_string(&tmpcfg, "host", &optProxyServer, optProxyServer); 1622 th_cfg_add_string(&tmpcfg, "host", &optProxyServer, optProxyServer);
1585 th_cfg_add_comment(&tmpcfg, "Proxy port, 1080 is the standard SOCKS port"); 1623 th_cfg_add_comment(&tmpcfg, "Proxy port, 1080 is the standard SOCKS port");
1586 th_cfg_add_int(&tmpcfg, "port", &optProxyPort, optProxyPort); 1624 th_cfg_add_int(&tmpcfg, "port", &optProxyPort, optProxyPort);
1587 th_cfg_add_section(&cfg, "proxy", tmpcfg); 1625 th_cfg_add_section(&cfg, "proxy", tmpcfg);
1588 1626
1627
1589 tmpcfg = NULL; 1628 tmpcfg = NULL;
1590 th_cfg_add_comment(&tmpcfg, "Enable logging"); 1629 th_cfg_add_comment(&tmpcfg, "Enable logging");
1591 th_cfg_add_bool(&tmpcfg, "enable", &optLogEnable, optLogEnable); 1630 th_cfg_add_bool(&tmpcfg, "enable", &optLogEnable, optLogEnable);
1592 th_cfg_add_comment(&tmpcfg, "Log filename format"); 1631 th_cfg_add_comment(&tmpcfg, "Log files path");
1593 th_cfg_add_string(&tmpcfg, "filename", &optLogFilename, optLogFilename); 1632 th_cfg_add_string(&tmpcfg, "path", &optLogPath, optLogPath);
1633
1634 th_cfg_add_comment(&tmpcfg, "Log filename extension");
1635 th_cfg_add_string(&tmpcfg, "extension", &optLogExtension, optLogExtension);
1636
1594 th_cfg_add_section(&cfg, "logging", tmpcfg); 1637 th_cfg_add_section(&cfg, "logging", tmpcfg);
1595 1638
1596 // Get home directory path 1639 // Get home directory path
1597 #ifdef __WIN32 1640 #ifdef __WIN32
1598 { 1641 {
1618 #endif 1661 #endif
1619 1662
1620 if (setHomeDir != NULL) 1663 if (setHomeDir != NULL)
1621 { 1664 {
1622 FILE *cfgfile; 1665 FILE *cfgfile;
1623 setConfigFile = th_strdup_printf("%s" SET_DIR_SEPARATOR "%s", setHomeDir, SET_CONFIG_FILE); 1666 setConfigFile = th_strdup_printf("%s%c%s", setHomeDir, SET_DIR_SEPARATOR, SET_CONFIG_FILE);
1624 1667
1625 THMSG(0, "Reading configuration from '%s'.\n", setConfigFile); 1668 THMSG(0, "Reading configuration from '%s'.\n", setConfigFile);
1626 1669
1627 if ((cfgfile = fopen(setConfigFile, "r")) != NULL) 1670 if ((cfgfile = fopen(setConfigFile, "r")) != NULL)
1628 { 1671 {
1629 th_cfg_read(cfgfile, setConfigFile, cfg); 1672 th_cfg_read(cfgfile, setConfigFile, cfg);
1630 fclose(cfgfile); 1673 fclose(cfgfile);
1631 } 1674 }
1632 } 1675 }
1633 1676
1634 if (optNickSepStr) 1677 optNickSep = optNickSepStr ? optNickSepStr[0] : SET_NICK_SEPARATOR;
1635 optNickSep = optNickSepStr[0];
1636 else
1637 optNickSep = SET_NICK_SEPARATOR;
1638
1639 1678
1640 setBrowser = getenv("BROWSER"); 1679 setBrowser = getenv("BROWSER");
1641 if (setBrowser == NULL) 1680 if (setBrowser == NULL)
1642 setBrowser = "firefox"; 1681 setBrowser = "firefox";
1643 1682
1665 // If no idle messages are set, add default 1704 // If no idle messages are set, add default
1666 if (setIdleMessages == NULL) 1705 if (setIdleMessages == NULL)
1667 { 1706 {
1668 th_llist_append(&setIdleMessages, th_strdup(".")); 1707 th_llist_append(&setIdleMessages, th_strdup("."));
1669 } 1708 }
1670
1671 // Open logfile
1672 nn_log_file_open();
1673 1709
1674 // Initialize network 1710 // Initialize network
1675 if (!nn_network_init()) 1711 if (!nn_network_init())
1676 { 1712 {
1677 THERR("Could not initialize network subsystem.\n"); 1713 THERR("Could not initialize network subsystem.\n");
1896 nn_conn_close(conn); 1932 nn_conn_close(conn);
1897 nn_network_close(); 1933 nn_network_close();
1898 1934
1899 THMSG(1, "Connection terminated.\n"); 1935 THMSG(1, "Connection terminated.\n");
1900 1936
1901 nn_log_file_close();
1902
1903 return 0; 1937 return 0;
1904 } 1938 }