comparison main.c @ 419:d015ecbd231d

Use C99 style comments, too.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 24 May 2012 07:37:36 +0300
parents 8ca09a6cca09
children 4b7cd24dc943
comparison
equal deleted inserted replaced
418:8ca09a6cca09 419:d015ecbd231d
8 #include "th_args.h" 8 #include "th_args.h"
9 #include "th_config.h" 9 #include "th_config.h"
10 #include <errno.h> 10 #include <errno.h>
11 #include <time.h> 11 #include <time.h>
12 #ifdef __WIN32 12 #ifdef __WIN32
13 /* Undefine because both windows.h and curses.h #define it */ 13 // Undefine because both windows.h and curses.h #define it
14 #undef MOUSE_MOVED 14 #undef MOUSE_MOVED
15 #include <shlwapi.h> 15 #include <shlwapi.h>
16 #else 16 #else
17 #include <sys/wait.h> 17 #include <sys/wait.h>
18 #endif 18 #endif
32 #define SET_DELAY (5) 32 #define SET_DELAY (5)
33 #endif 33 #endif
34 34
35 #define SET_NICK_SEPARATOR ':' 35 #define SET_NICK_SEPARATOR ':'
36 36
37 #define SET_MAX_HISTORY (16) /* Command history length */ 37 #define SET_MAX_HISTORY (16) // Command history length
38 #define SET_KEEPALIVE (15*60) /* Ping/keepalive period in seconds */ 38 #define SET_KEEPALIVE (15*60) // Ping/keepalive period in seconds
39 #define SET_MAX_WINDOWS (32) 39 #define SET_MAX_WINDOWS (32)
40 40
41 41
42 /* Options 42 /* Options
43 */ 43 */
468 BOOL updateMainWin(BOOL force) 468 BOOL updateMainWin(BOOL force)
469 { 469 {
470 int h, offs; 470 int h, offs;
471 qringbuf_t *buf; 471 qringbuf_t *buf;
472 472
473 /* Check pointers */ 473 // Check pointers
474 if (mainWin == NULL || currWin == NULL) 474 if (mainWin == NULL || currWin == NULL)
475 return FALSE; 475 return FALSE;
476 476
477 /* Check if update is forced or if the window is dirty */ 477 // Check if update is forced or if the window is dirty
478 if (!force && !currWin->dirty) 478 if (!force && !currWin->dirty)
479 return FALSE; 479 return FALSE;
480 480
481 /* Compute how many lines from backbuffer fit on the screen */ 481 // Compute how many lines from backbuffer fit on the screen
482 buf = currWin->data; 482 buf = currWin->data;
483 h = getmaxy(mainWin); 483 h = getmaxy(mainWin);
484 484
485 /* Clear and redraw window */ 485 // Clear and redraw window
486 werase(mainWin); 486 werase(mainWin);
487 scrollok(mainWin, 1); 487 scrollok(mainWin, 1);
488 for (offs = buf->size - h - currWin->pos; offs >= 0 && offs < buf->size - currWin->pos && offs < buf->size; offs++) 488 for (offs = buf->size - h - currWin->pos; offs >= 0 && offs < buf->size - currWin->pos && offs < buf->size; offs++)
489 { 489 {
490 if (buf->data[offs] != NULL) 490 if (buf->data[offs] != NULL)
641 int nnproto_parse_user(nn_conn_t *conn) 641 int nnproto_parse_user(nn_conn_t *conn)
642 { 642 {
643 BOOL isMine, isIgnored = FALSE; 643 BOOL isMine, isIgnored = FALSE;
644 char *name, *msg, *t; 644 char *name, *msg, *t;
645 645
646 /* Find start of the message */ 646 // Find start of the message
647 name = conn->ptr; 647 name = conn->ptr;
648 t = nn_conn_buf_strstr(conn, "</USER><MESSAGE>"); 648 t = nn_conn_buf_strstr(conn, "</USER><MESSAGE>");
649 if (!t) return 1; 649 if (!t) return 1;
650 *t = 0; 650 *t = 0;
651 msg = conn->ptr; 651 msg = conn->ptr;
652 652
653 /* Find end of the message */ 653 // Find end of the message
654 t = nn_conn_buf_strstr(conn, "</MESSAGE>"); 654 t = nn_conn_buf_strstr(conn, "</MESSAGE>");
655 if (!t) return 3; 655 if (!t) return 3;
656 *t = 0; 656 *t = 0;
657 657
658 /* Decode message string */ 658 // Decode message string
659 msg = nn_decode_str1(msg); 659 msg = nn_decode_str1(msg);
660 if (!msg) return -1; 660 if (!msg) return -1;
661 661
662 /* Decode username */ 662 // Decode username
663 name = nn_decode_str1(name); 663 name = nn_decode_str1(name);
664 if (!name) 664 if (!name)
665 { 665 {
666 th_free(msg); 666 th_free(msg);
667 return -2; 667 return -2;
671 * that it is not our OWN username! 671 * that it is not our OWN username!
672 */ 672 */
673 isMine = strcmp(name, optUserName) == 0; 673 isMine = strcmp(name, optUserName) == 0;
674 isIgnored = setIgnoreMode && !isMine && checkIgnoreList(name); 674 isIgnored = setIgnoreMode && !isMine && checkIgnoreList(name);
675 675
676 /* Is it a special control message? */ 676 // Is it a special control message?
677 if (*msg == '/') 677 if (*msg == '/')
678 { 678 {
679 /* Ignore room join/leave messages */ 679 // Ignore room join/leave messages
680 if (!optDebug && (strstr(msg, "left the room") || strstr(msg, "joined the room from"))) 680 if (!optDebug && (strstr(msg, "left the room") || strstr(msg, "joined the room from")))
681 goto done; 681 goto done;
682 682
683 t = nn_strip_tags(msg + 1); 683 t = nn_strip_tags(msg + 1);
684 if (!strncmp(t, "BPRV ", 5)) 684 if (!strncmp(t, "BPRV ", 5))
719 th_free(in_name); 719 th_free(in_name);
720 th_free(h); 720 th_free(h);
721 } 721 }
722 else 722 else
723 { 723 {
724 /* It's an action (/me) */ 724 // It's an action (/me)
725 char *h = nn_decode_str2(t); 725 char *h = nn_decode_str2(t);
726 printMsgF(NULL, isIgnored ? LOG_FILE : (LOG_WINDOW | LOG_FILE), 726 printMsgF(NULL, isIgnored ? LOG_FILE : (LOG_WINDOW | LOG_FILE),
727 "½9½* %s½0½\n", h); 727 "½9½* %s½0½\n", h);
728 th_free(h); 728 th_free(h);
729 } 729 }
730 th_free(t); 730 th_free(t);
731 } 731 }
732 else 732 else
733 { 733 {
734 /* It's a normal message */ 734 // It's a normal message
735 char *h; 735 char *h;
736 t = nn_strip_tags(msg); 736 t = nn_strip_tags(msg);
737 h = nn_decode_str2(t); 737 h = nn_decode_str2(t);
738 printMsgF(NULL, isIgnored ? LOG_FILE : (LOG_WINDOW | LOG_FILE), 738 printMsgF(NULL, isIgnored ? LOG_FILE : (LOG_WINDOW | LOG_FILE),
739 "½5½<½%d½%s½5½>½0½ %s\n", isMine ? 14 : 15, name, h); 739 "½5½<½%d½%s½5½>½0½ %s\n", isMine ? 14 : 15, name, h);
885 int nn_handle_input(nn_conn_t *conn, char *buf, size_t bufLen) 885 int nn_handle_input(nn_conn_t *conn, char *buf, size_t bufLen)
886 { 886 {
887 char *tmpStr, tmpBuf[4096]; 887 char *tmpStr, tmpBuf[4096];
888 BOOL result; 888 BOOL result;
889 889
890 /* Trim right */ 890 // Trim right
891 bufLen--; 891 bufLen--;
892 buf[bufLen--] = 0; 892 buf[bufLen--] = 0;
893 while (bufLen > 0 && th_isspace(buf[bufLen])) 893 while (bufLen > 0 && th_isspace(buf[bufLen]))
894 buf[bufLen--] = 0; 894 buf[bufLen--] = 0;
895 895
896 /* Decode completed usernames */ 896 // Decode completed usernames
897 nn_username_decode(buf); 897 nn_username_decode(buf);
898 898
899 /* Check for special user commands */ 899 // Check for special user commands
900 if (*buf == 0) 900 if (*buf == 0)
901 { 901 {
902 return 1; 902 return 1;
903 } 903 }
904 else if (!th_strncasecmp(buf, "/color ", 7)) 904 else if (!th_strncasecmp(buf, "/color ", 7))
905 { 905 {
906 /* Change color */ 906 // Change color
907 int tmpInt; 907 int tmpInt;
908 if ((tmpInt = th_get_hex_triplet(str_trim_left(buf + 7))) < 0) 908 if ((tmpInt = th_get_hex_triplet(str_trim_left(buf + 7))) < 0)
909 { 909 {
910 printMsgQ(currWin, "Invalid color value '%s'\n", buf+7); 910 printMsgQ(currWin, "Invalid color value '%s'\n", buf+7);
911 return 1; 911 return 1;
918 else if (!th_strncasecmp(buf, "/ignore", 7)) 918 else if (!th_strncasecmp(buf, "/ignore", 7))
919 { 919 {
920 char *name = str_trim_left(buf + 7); 920 char *name = str_trim_left(buf + 7);
921 if (strlen(name) > 0) 921 if (strlen(name) > 0)
922 { 922 {
923 /* Add or remove someone to/from ignore */ 923 // Add or remove someone to/from ignore
924 qlist_t *user = th_llist_find_func(setIgnoreList, name, compareUsername); 924 qlist_t *user = th_llist_find_func(setIgnoreList, name, compareUsername);
925 if (user != NULL) 925 if (user != NULL)
926 { 926 {
927 printMsgQ(currWin, "Removed user '%s' from ignore.\n", name); 927 printMsgQ(currWin, "Removed user '%s' from ignore.\n", name);
928 th_llist_delete_node(&setIgnoreList, user); 928 th_llist_delete_node(&setIgnoreList, user);
933 th_llist_append(&setIgnoreList, th_strdup(name)); 933 th_llist_append(&setIgnoreList, th_strdup(name));
934 } 934 }
935 } 935 }
936 else 936 else
937 { 937 {
938 /* Just list whomever is in ignore now */ 938 // Just list whomever is in ignore now
939 qlist_t *user = setIgnoreList; 939 qlist_t *user = setIgnoreList;
940 ssize_t nuser = th_llist_length(setIgnoreList); 940 ssize_t nuser = th_llist_length(setIgnoreList);
941 char *result = th_strdup_printf("Users ignored (%d): ", nuser); 941 char *result = th_strdup_printf("Users ignored (%d): ", nuser);
942 while (user != NULL) 942 while (user != NULL)
943 { 943 {
977 } 977 }
978 return 0; 978 return 0;
979 } 979 }
980 else if (!th_strncasecmp(buf, "/win", 4)) 980 else if (!th_strncasecmp(buf, "/win", 4))
981 { 981 {
982 /* Change color */ 982 // Change color
983 char *tmp = str_trim_left(buf + 4); 983 char *tmp = str_trim_left(buf + 4);
984 if (strlen(tmp) > 0) 984 if (strlen(tmp) > 0)
985 { 985 {
986 int val = atoi(tmp); 986 int val = atoi(tmp);
987 if (val >= 1 && val < SET_MAX_WINDOWS) 987 if (val >= 1 && val < SET_MAX_WINDOWS)
1028 } 1028 }
1029 return 0; 1029 return 0;
1030 } 1030 }
1031 else if (!th_strncasecmp(buf, "/save", 5)) 1031 else if (!th_strncasecmp(buf, "/save", 5))
1032 { 1032 {
1033 /* Save configuration */ 1033 // Save configuration
1034 FILE *cfgfile = fopen(setConfigFile, "w"); 1034 FILE *cfgfile = fopen(setConfigFile, "w");
1035 if (cfgfile == NULL) 1035 if (cfgfile == NULL)
1036 { 1036 {
1037 printMsgQ(currWin, "Could not create configuration to file '%s': %s\n", 1037 printMsgQ(currWin, "Could not create configuration to file '%s': %s\n",
1038 setConfigFile, strerror(errno)); 1038 setConfigFile, strerror(errno));
1045 fclose(cfgfile); 1045 fclose(cfgfile);
1046 return 0; 1046 return 0;
1047 } 1047 }
1048 else if (!th_strncasecmp(buf, "/w ", 3)) 1048 else if (!th_strncasecmp(buf, "/w ", 3))
1049 { 1049 {
1050 /* Open given username's profile via firefox in a new tab */ 1050 // Open given username's profile via firefox in a new tab
1051 char *name = str_trim_left(buf + 3); 1051 char *name = str_trim_left(buf + 3);
1052 1052
1053 printMsg(currWin, "Opening profile for: '%s'\n", name); 1053 printMsg(currWin, "Opening profile for: '%s'\n", name);
1054 1054
1055 tmpStr = nn_encode_str1(name); 1055 tmpStr = nn_encode_str1(name);
1094 #endif 1094 #endif
1095 return 0; 1095 return 0;
1096 } 1096 }
1097 else if (!th_strncasecmp(buf, "/who", 4)) 1097 else if (!th_strncasecmp(buf, "/who", 4))
1098 { 1098 {
1099 /* Alias /who to /listallusers */ 1099 // Alias /who to /listallusers
1100 snprintf(tmpBuf, sizeof(tmpBuf), "/listallusers"); 1100 snprintf(tmpBuf, sizeof(tmpBuf), "/listallusers");
1101 buf = tmpBuf; 1101 buf = tmpBuf;
1102 } 1102 }
1103 1103
1104 if (currWin != chatWindows[0]) 1104 if (currWin != chatWindows[0])
1113 printMsgQ(NULL, "No target set, exiting prv mode.\n"); 1113 printMsgQ(NULL, "No target set, exiting prv mode.\n");
1114 return 1; 1114 return 1;
1115 } 1115 }
1116 } 1116 }
1117 1117
1118 /* Send double-encoded */ 1118 // Send double-encoded
1119 tmpStr = nn_dblencode_str(nn_username_decode(buf)); 1119 tmpStr = nn_dblencode_str(nn_username_decode(buf));
1120 if (tmpStr == 0) return -2; 1120 if (tmpStr == 0) return -2;
1121 result = nn_conn_send_msg(conn, optUserNameEnc, "%s", tmpStr); 1121 result = nn_conn_send_msg(conn, optUserNameEnc, "%s", tmpStr);
1122 th_free(tmpStr); 1122 th_free(tmpStr);
1123 1123
1166 BOOL again = FALSE, hasSeparator = FALSE, newPattern = FALSE, hasSpace = FALSE; 1166 BOOL again = FALSE, hasSeparator = FALSE, newPattern = FALSE, hasSpace = FALSE;
1167 char *str = buf->data; 1167 char *str = buf->data;
1168 int mode = 0; 1168 int mode = 0;
1169 ssize_t endPos, startPos = buf->pos; 1169 ssize_t endPos, startPos = buf->pos;
1170 1170
1171 /* previous word */ 1171 // previous word
1172 if (startPos >= 2 && str[startPos - 1] == ' ' && str[startPos - 2] != ' ') 1172 if (startPos >= 2 && str[startPos - 1] == ' ' && str[startPos - 2] != ' ')
1173 { 1173 {
1174 startPos -= 2; 1174 startPos -= 2;
1175 endPos = startPos; 1175 endPos = startPos;
1176 while (startPos > 0 && str[startPos - 1] != ' ') startPos--; 1176 while (startPos > 0 && str[startPos - 1] != ' ') startPos--;
1177 mode = 1; 1177 mode = 1;
1178 } 1178 }
1179 else 1179 else
1180 /* middle of a word, new pattern */ 1180 // middle of a word, new pattern
1181 if (startPos < buf->len && str[startPos] != ' ') 1181 if (startPos < buf->len && str[startPos] != ' ')
1182 { 1182 {
1183 endPos = startPos; 1183 endPos = startPos;
1184 while (startPos > 0 && str[startPos - 1] != ' ') startPos--; 1184 while (startPos > 0 && str[startPos - 1] != ' ') startPos--;
1185 while (endPos < buf->len - 1 && str[endPos + 1] != ' ') endPos++; 1185 while (endPos < buf->len - 1 && str[endPos + 1] != ' ') endPos++;
1186 newPattern = TRUE; 1186 newPattern = TRUE;
1187 mode = 2; 1187 mode = 2;
1188 } 1188 }
1189 else 1189 else
1190 /* previous word, new pattern */ 1190 // previous word, new pattern
1191 if (startPos >= 1 && str[startPos - 1] != ' ') 1191 if (startPos >= 1 && str[startPos - 1] != ' ')
1192 { 1192 {
1193 startPos -= 1; 1193 startPos -= 1;
1194 endPos = startPos; 1194 endPos = startPos;
1195 while (startPos > 0 && str[startPos - 1] != ' ') startPos--; 1195 while (startPos > 0 && str[startPos - 1] != ' ') startPos--;
1220 if (buf->pos <= buf->len && str[buf->pos] == ' ') 1220 if (buf->pos <= buf->len && str[buf->pos] == ' ')
1221 hasSpace = TRUE; 1221 hasSpace = TRUE;
1222 1222
1223 if (newPattern) 1223 if (newPattern)
1224 { 1224 {
1225 /* Get pattern, check if it matches previous pattern and set 'again' flag */ 1225 // Get pattern, check if it matches previous pattern and set 'again' flag
1226 char *npattern = nn_editbuf_get_string(buf, startPos, endPos); 1226 char *npattern = nn_editbuf_get_string(buf, startPos, endPos);
1227 if (pattern && npattern && th_strcasecmp(npattern, pattern) == 0) 1227 if (pattern && npattern && th_strcasecmp(npattern, pattern) == 0)
1228 again = TRUE; 1228 again = TRUE;
1229 1229
1230 th_free(pattern); 1230 th_free(pattern);
1421 cfgitem_t *tmpcfg; 1421 cfgitem_t *tmpcfg;
1422 char *homeDir = NULL; 1422 char *homeDir = NULL;
1423 1423
1424 memset(histBuf, 0, sizeof(histBuf)); 1424 memset(histBuf, 0, sizeof(histBuf));
1425 1425
1426 /* Initialize */ 1426 // Initialize
1427 th_init("NNChat", "Newbie Nudes chat client", NN_VERSION, 1427 th_init("NNChat", "Newbie Nudes chat client", NN_VERSION,
1428 "Written and designed by Anonymous Finnish Guy (C) 2008-2012", 1428 "Written and designed by Anonymous Finnish Guy (C) 2008-2012",
1429 "This software is freeware, use and distribute as you wish."); 1429 "This software is freeware, use and distribute as you wish.");
1430 th_verbosityLevel = 0; 1430 th_verbosityLevel = 0;
1431 1431
1432 /* Read configuration file */ 1432 // Read configuration file
1433 tmpcfg = NULL; 1433 tmpcfg = NULL;
1434 th_cfg_add_comment(&tmpcfg, "General settings"); 1434 th_cfg_add_comment(&tmpcfg, "General settings");
1435 th_cfg_add_string(&tmpcfg, "username", &optUserName, NULL); 1435 th_cfg_add_string(&tmpcfg, "username", &optUserName, NULL);
1436 th_cfg_add_string(&tmpcfg, "password", &optPassword, NULL); 1436 th_cfg_add_string(&tmpcfg, "password", &optPassword, NULL);
1437 1437
1509 1509
1510 setBrowser = getenv("BROWSER"); 1510 setBrowser = getenv("BROWSER");
1511 if (setBrowser == NULL) 1511 if (setBrowser == NULL)
1512 setBrowser = "firefox"; 1512 setBrowser = "firefox";
1513 1513
1514 /* Parse command line arguments */ 1514 // Parse command line arguments
1515 argsOK = th_args_process(argc, argv, optList, optListN, 1515 argsOK = th_args_process(argc, argv, optList, optListN,
1516 argHandleOpt, argHandleFile, FALSE); 1516 argHandleOpt, argHandleFile, FALSE);
1517 1517
1518 if (optUserNameCmd != NULL) 1518 if (optUserNameCmd != NULL)
1519 { 1519 {
1522 } 1522 }
1523 1523
1524 if (!argsOK) 1524 if (!argsOK)
1525 return -2; 1525 return -2;
1526 1526
1527 /* Allocate userhash */ 1527 // Allocate userhash
1528 if ((nnUsers = nn_userhash_new()) == NULL) 1528 if ((nnUsers = nn_userhash_new()) == NULL)
1529 { 1529 {
1530 THERR("Could not allocate userhash. Fatal error.\n"); 1530 THERR("Could not allocate userhash. Fatal error.\n");
1531 return -105; 1531 return -105;
1532 } 1532 }
1533 1533
1534 /* If no idle messages are set, add default */ 1534 // If no idle messages are set, add default
1535 if (setIdleMessages == NULL) 1535 if (setIdleMessages == NULL)
1536 { 1536 {
1537 th_llist_append(&setIdleMessages, th_strdup(".")); 1537 th_llist_append(&setIdleMessages, th_strdup("."));
1538 } 1538 }
1539 1539
1540 /* Open logfile */ 1540 // Open logfile
1541 logFileOpen(); 1541 logFileOpen();
1542 1542
1543 /* Initialize network */ 1543 // Initialize network
1544 if (!nn_network_init()) 1544 if (!nn_network_init())
1545 { 1545 {
1546 THERR("Could not initialize network subsystem.\n"); 1546 THERR("Could not initialize network subsystem.\n");
1547 goto err_exit; 1547 goto err_exit;
1548 } 1548 }
1549 else 1549 else
1550 networkInit = TRUE; 1550 networkInit = TRUE;
1551 1551
1552 /* Initialize NCurses */ 1552 // Initialize NCurses
1553 if (!optDaemon) 1553 if (!optDaemon)
1554 { 1554 {
1555 if (LINES < 0 || LINES > 1000) LINES = 24; 1555 if (LINES < 0 || LINES > 1000) LINES = 24;
1556 if (COLS < 0 || COLS > 1000) COLS = 80; 1556 if (COLS < 0 || COLS > 1000) COLS = 80;
1557 initscr(); 1557 initscr();
1597 chatWindows[0] = nn_window_new(NULL); 1597 chatWindows[0] = nn_window_new(NULL);
1598 currWin = chatWindows[0]; 1598 currWin = chatWindows[0];
1599 updateStatus(); 1599 updateStatus();
1600 } 1600 }
1601 1601
1602 /* Check if we have username and password */ 1602 // Check if we have username and password
1603 if (cursesInit && (optUserName == NULL || optPassword == NULL)) 1603 if (cursesInit && (optUserName == NULL || optPassword == NULL))
1604 { 1604 {
1605 printWin(editWin, "You can avoid this prompt by issuing '/save' after logging in.\n"); 1605 printWin(editWin, "You can avoid this prompt by issuing '/save' after logging in.\n");
1606 optUserName = promptRequester(editWin, "NN username: ", FALSE); 1606 optUserName = promptRequester(editWin, "NN username: ", FALSE);
1607 optPassword = promptRequester(editWin, "NN password: ", TRUE); 1607 optPassword = promptRequester(editWin, "NN password: ", TRUE);
1611 { 1611 {
1612 errorMsg("Username and/or password not specified.\n"); 1612 errorMsg("Username and/or password not specified.\n");
1613 goto err_exit; 1613 goto err_exit;
1614 } 1614 }
1615 1615
1616 /* Create a connection */ 1616 // Create a connection
1617 conn = nn_conn_new(errorFunc, messageFunc); 1617 conn = nn_conn_new(errorFunc, messageFunc);
1618 if (conn == NULL) 1618 if (conn == NULL)
1619 { 1619 {
1620 errorMsg("Could not create connection structure.\n"); 1620 errorMsg("Could not create connection structure.\n");
1621 goto err_exit; 1621 goto err_exit;
1622 } 1622 }
1623 1623
1624 /* Are we using a proxy? */ 1624 // Are we using a proxy?
1625 if (optProxyType != NN_PROXY_NONE && optProxyServer != NULL) 1625 if (optProxyType != NN_PROXY_NONE && optProxyServer != NULL)
1626 { 1626 {
1627 if (nn_conn_set_proxy(conn, optProxyType, optProxyPort, optProxyServer) != 0) 1627 if (nn_conn_set_proxy(conn, optProxyType, optProxyPort, optProxyServer) != 0)
1628 { 1628 {
1629 errorMsg("Error setting proxy information.\n"); 1629 errorMsg("Error setting proxy information.\n");
1630 goto err_exit; 1630 goto err_exit;
1631 } 1631 }
1632 } 1632 }
1633 1633
1634 /* Okay ... */ 1634 // Okay ...
1635 printMsg(currWin, "Trying to resolve host '%s' ...\n", optServer); 1635 printMsg(currWin, "Trying to resolve host '%s' ...\n", optServer);
1636 conn->host = th_strdup(optServer); 1636 conn->host = th_strdup(optServer);
1637 conn->hst = nn_resolve_host(conn, optServer); 1637 conn->hst = nn_resolve_host(conn, optServer);
1638 if (conn->hst == NULL) 1638 if (conn->hst == NULL)
1639 { 1639 {
1670 } 1670 }
1671 } 1671 }
1672 nn_conn_close(conn); 1672 nn_conn_close(conn);
1673 #endif 1673 #endif
1674 1674
1675 /* Okay, now do the proper connection ... */ 1675 // Okay, now do the proper connection ...
1676 if (nn_conn_open(conn, optPort, NULL) != 0) 1676 if (nn_conn_open(conn, optPort, NULL) != 0)
1677 { 1677 {
1678 errorMsg("Main connection setup failed!\n"); 1678 errorMsg("Main connection setup failed!\n");
1679 goto err_exit; 1679 goto err_exit;
1680 } 1680 }
1681 1681
1682 /* Send login command */ 1682 // Send login command
1683 optUserNameEnc = nn_dblencode_str(optUserName); 1683 optUserNameEnc = nn_dblencode_str(optUserName);
1684 tmpStr = nn_dblencode_str(optSite); 1684 tmpStr = nn_dblencode_str(optSite);
1685 nn_conn_send_msg(conn, optUserNameEnc, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword); 1685 nn_conn_send_msg(conn, optUserNameEnc, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword);
1686 th_free(tmpStr); 1686 th_free(tmpStr);
1687 1687
1688 /* Initialize random numbers */ 1688 // Initialize random numbers
1689 prevTime = time(NULL); 1689 prevTime = time(NULL);
1690 srandom((int) prevTime); 1690 srandom((int) prevTime);
1691 1691
1692 if (cursesInit) 1692 if (cursesInit)
1693 { 1693 {
1694 /* Initialize rest of interactive UI code */ 1694 // Initialize rest of interactive UI code
1695 nn_editbuf_clear(editBuf); 1695 nn_editbuf_clear(editBuf);
1696 1696
1697 /* First update of screen */ 1697 // First update of screen
1698 printEditBuf(editBuf); 1698 printEditBuf(editBuf);
1699 updateStatus(); 1699 updateStatus();
1700 1700
1701 printMsg(NULL, "%s v%s - %s\n", th_prog_name, th_prog_version, th_prog_fullname); 1701 printMsg(NULL, "%s v%s - %s\n", th_prog_name, th_prog_version, th_prog_fullname);
1702 printMsg(NULL, "%s\n", th_prog_author); 1702 printMsg(NULL, "%s\n", th_prog_author);
1703 printMsg(NULL, "%s\n", th_prog_license); 1703 printMsg(NULL, "%s\n", th_prog_license);
1704 } 1704 }
1705 1705
1706 /* Enter mainloop */ 1706 // Enter mainloop
1707 nn_conn_reset(conn); 1707 nn_conn_reset(conn);
1708 while (!isError && !exitProg) 1708 while (!isError && !exitProg)
1709 { 1709 {
1710 nn_conn_reset(conn); 1710 nn_conn_reset(conn);
1711 do { 1711 do {
1713 if (cres == 0 && *(conn->in_ptr - 1) == 0) 1713 if (cres == 0 && *(conn->in_ptr - 1) == 0)
1714 { 1714 {
1715 int result = nn_parse_protocol(conn); 1715 int result = nn_parse_protocol(conn);
1716 if (result > 0) 1716 if (result > 0)
1717 { 1717 {
1718 /* Couldn't handle the message for some reason */ 1718 // Couldn't handle the message for some reason
1719 printMsg(currWin, "Could not handle: %s\n", conn->ptr); 1719 printMsg(currWin, "Could not handle: %s\n", conn->ptr);
1720 } 1720 }
1721 else if (result < 0) 1721 else if (result < 0)
1722 { 1722 {
1723 /* Fatal error, quit */ 1723 // Fatal error, quit
1724 errorMsg("Fatal error with message: %s\n", conn->ptr); 1724 errorMsg("Fatal error with message: %s\n", conn->ptr);
1725 isError = TRUE; 1725 isError = TRUE;
1726 } 1726 }
1727 } 1727 }
1728 else if (cres < 0) 1728 else if (cres < 0)
1733 while (conn->total_bytes > 0 && !isError); 1733 while (conn->total_bytes > 0 && !isError);
1734 1734
1735 if (!nn_conn_check(conn)) 1735 if (!nn_conn_check(conn))
1736 isError = TRUE; 1736 isError = TRUE;
1737 1737
1738 /* Handle user input */ 1738 // Handle user input
1739 if (cursesInit) 1739 if (cursesInit)
1740 { 1740 {
1741 int c, cnt = 0; 1741 int c, cnt = 0;
1742 BOOL update = FALSE, updateMain = FALSE; 1742 BOOL update = FALSE, updateMain = FALSE;
1743 1743
1744 /* Handle several buffered keypresses at once */ 1744 // Handle several buffered keypresses at once
1745 do 1745 do
1746 { 1746 {
1747 c = wgetch(stdscr); 1747 c = wgetch(stdscr);
1748 1748
1749 /* Handle various problematic cases where terminal 1749 /* Handle various problematic cases where terminal
1750 * keycodes do not get properly translated by curses 1750 * keycodes do not get properly translated by curses
1751 */ 1751 */
1752 if (c == 0x1b) 1752 if (c == 0x1b)
1753 { 1753 {
1754 /* ^[O */ 1754 // ^[O
1755 c = wgetch(stdscr); 1755 c = wgetch(stdscr);
1756 if (c == 'O') 1756 if (c == 'O')
1757 { 1757 {
1758 c = wgetch(stdscr); 1758 c = wgetch(stdscr);
1759 switch (c) 1759 switch (c)
1768 if (optDebug) 1768 if (optDebug)
1769 printMsg(currWin, "Unhandled ESC-O key sequence 0x%02x\n", c); 1769 printMsg(currWin, "Unhandled ESC-O key sequence 0x%02x\n", c);
1770 break; 1770 break;
1771 } 1771 }
1772 } 1772 }
1773 /* ^[[ */ 1773 // ^[[
1774 else if (c == '[') 1774 else if (c == '[')
1775 { 1775 {
1776 c = wgetch(stdscr); 1776 c = wgetch(stdscr);
1777 switch (c) 1777 switch (c)
1778 { 1778 {
1809 if (optDebug) 1809 if (optDebug)
1810 printMsg(currWin, "Unhandled ESC-[*~ key sequence 0x%02x\n", c); 1810 printMsg(currWin, "Unhandled ESC-[*~ key sequence 0x%02x\n", c);
1811 c = ERR; 1811 c = ERR;
1812 break; 1812 break;
1813 } 1813 }
1814 /* Get the trailing ~ */ 1814 // Get the trailing ~
1815 if (c != ERR) 1815 if (c != ERR)
1816 wgetch(stdscr); 1816 wgetch(stdscr);
1817 } 1817 }
1818 if (c >= 0x31 && c <= 0x39) 1818 if (c >= 0x31 && c <= 0x39)
1819 { 1819 {
1820 /* Chat window switching via Meta/Esc-[1..9] */ 1820 // Chat window switching via Meta/Esc-[1..9]
1821 int win = c - 0x31; 1821 int win = c - 0x31;
1822 if (win < SET_MAX_WINDOWS && chatWindows[win] != NULL) 1822 if (win < SET_MAX_WINDOWS && chatWindows[win] != NULL)
1823 { 1823 {
1824 currWin = chatWindows[win]; 1824 currWin = chatWindows[win];
1825 update = updateMain = TRUE; 1825 update = updateMain = TRUE;
1833 } 1833 }
1834 } 1834 }
1835 #if defined(__WIN32) && defined(PDCURSES) 1835 #if defined(__WIN32) && defined(PDCURSES)
1836 else if (c >= 0x198 && c <= 0x1a0) 1836 else if (c >= 0x198 && c <= 0x1a0)
1837 { 1837 {
1838 /* Chat window switching via Meta/Esc-[1..9] */ 1838 // Chat window switching via Meta/Esc-[1..9]
1839 int win = c - 0x198; 1839 int win = c - 0x198;
1840 if (win < SET_MAX_WINDOWS && chatWindows[win] != NULL) 1840 if (win < SET_MAX_WINDOWS && chatWindows[win] != NULL)
1841 { 1841 {
1842 currWin = chatWindows[win]; 1842 currWin = chatWindows[win];
1843 update = updateMain = TRUE; 1843 update = updateMain = TRUE;
1864 #endif 1864 #endif
1865 1865
1866 case KEY_ENTER: 1866 case KEY_ENTER:
1867 case '\n': 1867 case '\n':
1868 case '\r': 1868 case '\r':
1869 /* Call the user input handler */ 1869 // Call the user input handler
1870 if (editBuf->len > 0) 1870 if (editBuf->len > 0)
1871 { 1871 {
1872 int result; 1872 int result;
1873 1873
1874 if (histMax > 0) 1874 if (histMax > 0)
1892 errorMsg("Fatal error handling user input: %s\n", editBuf->data); 1892 errorMsg("Fatal error handling user input: %s\n", editBuf->data);
1893 isError = TRUE; 1893 isError = TRUE;
1894 } 1894 }
1895 else 1895 else
1896 { 1896 {
1897 /* Update time value of last sent message for unidle timeouts */ 1897 // Update time value of last sent message for unidle timeouts
1898 prevTime = time(NULL); 1898 prevTime = time(NULL);
1899 } 1899 }
1900 1900
1901 updateMain = update = TRUE; 1901 updateMain = update = TRUE;
1902 } 1902 }
1903 break; 1903 break;
1904 1904
1905 case KEY_UP: /* Backwards in input history */ 1905 case KEY_UP: // Backwards in input history
1906 if (histPos == 0) 1906 if (histPos == 0)
1907 { 1907 {
1908 nn_editbuf_free(histBuf[0]); 1908 nn_editbuf_free(histBuf[0]);
1909 histBuf[0] = nn_editbuf_copy(editBuf); 1909 histBuf[0] = nn_editbuf_copy(editBuf);
1910 } 1910 }
1915 editBuf = nn_editbuf_copy(histBuf[histPos]); 1915 editBuf = nn_editbuf_copy(histBuf[histPos]);
1916 update = TRUE; 1916 update = TRUE;
1917 } 1917 }
1918 break; 1918 break;
1919 1919
1920 case KEY_DOWN: /* Forwards in input history */ 1920 case KEY_DOWN: // Forwards in input history
1921 if (histPos > 0) 1921 if (histPos > 0)
1922 { 1922 {
1923 histPos--; 1923 histPos--;
1924 nn_editbuf_free(editBuf); 1924 nn_editbuf_free(editBuf);
1925 editBuf = nn_editbuf_copy(histBuf[histPos]); 1925 editBuf = nn_editbuf_copy(histBuf[histPos]);
1926 update = TRUE; 1926 update = TRUE;
1927 } 1927 }
1928 break; 1928 break;
1929 1929
1930 case 0x204: /* ctrl+left arrow = Skip words left */ 1930 case 0x204: // ctrl+left arrow = Skip words left
1931 case 0x20b: 1931 case 0x20b:
1932 while (editBuf->pos > 0 && isspace((int) editBuf->data[editBuf->pos - 1])) 1932 while (editBuf->pos > 0 && isspace((int) editBuf->data[editBuf->pos - 1]))
1933 editBuf->pos--; 1933 editBuf->pos--;
1934 while (editBuf->pos > 0 && !isspace((int) editBuf->data[editBuf->pos - 1])) 1934 while (editBuf->pos > 0 && !isspace((int) editBuf->data[editBuf->pos - 1]))
1935 editBuf->pos--; 1935 editBuf->pos--;
1936 update = TRUE; 1936 update = TRUE;
1937 break; 1937 break;
1938 1938
1939 case 0x206: /* ctrl+right arrow = Skip words right */ 1939 case 0x206: // ctrl+right arrow = Skip words right
1940 case 0x210: 1940 case 0x210:
1941 while (editBuf->pos < editBuf->len && isspace((int) editBuf->data[editBuf->pos])) 1941 while (editBuf->pos < editBuf->len && isspace((int) editBuf->data[editBuf->pos]))
1942 editBuf->pos++; 1942 editBuf->pos++;
1943 while (editBuf->pos < editBuf->len && !isspace((int) editBuf->data[editBuf->pos])) 1943 while (editBuf->pos < editBuf->len && !isspace((int) editBuf->data[editBuf->pos]))
1944 editBuf->pos++; 1944 editBuf->pos++;
1968 nn_editbuf_delete(editBuf, editBuf->pos - 1); 1968 nn_editbuf_delete(editBuf, editBuf->pos - 1);
1969 nn_editbuf_setpos(editBuf, editBuf->pos - 1); 1969 nn_editbuf_setpos(editBuf, editBuf->pos - 1);
1970 update = TRUE; 1970 update = TRUE;
1971 break; 1971 break;
1972 1972
1973 case KEY_DC: /* Delete character */ 1973 case KEY_DC: // Delete character
1974 nn_editbuf_delete(editBuf, editBuf->pos); 1974 nn_editbuf_delete(editBuf, editBuf->pos);
1975 update = TRUE; 1975 update = TRUE;
1976 break; 1976 break;
1977 1977
1978 1978
1979 case KEY_IC: /* Ins = Toggle insert / overwrite mode */ 1979 case KEY_IC: // Ins = Toggle insert / overwrite mode
1980 insertMode = !insertMode; 1980 insertMode = !insertMode;
1981 update = TRUE; 1981 update = TRUE;
1982 break; 1982 break;
1983 1983
1984 case KEY_F(1): /* F1 = Print help */ 1984 case KEY_F(1): // F1 = Print help
1985 printHelp(); 1985 printHelp();
1986 updateMain = TRUE; 1986 updateMain = TRUE;
1987 break; 1987 break;
1988 1988
1989 case KEY_F(2): /* F2 = Clear editbuffer */ 1989 case KEY_F(2): // F2 = Clear editbuffer
1990 nn_editbuf_clear(editBuf); 1990 nn_editbuf_clear(editBuf);
1991 update = TRUE; 1991 update = TRUE;
1992 break; 1992 break;
1993 1993
1994 case KEY_F(5): /* F5 = Ignore mode */ 1994 case KEY_F(5): // F5 = Ignore mode
1995 setIgnoreMode = !setIgnoreMode; 1995 setIgnoreMode = !setIgnoreMode;
1996 printMsgQ(currWin, "Ignore mode = %s\n", setIgnoreMode ? "ON" : "OFF"); 1996 printMsgQ(currWin, "Ignore mode = %s\n", setIgnoreMode ? "ON" : "OFF");
1997 break; 1997 break;
1998 1998
1999 #if 0 1999 #if 0
2000 case KEY_F(8): /* F8 = Debug */ 2000 case KEY_F(8): // F8 = Debug
2001 optDebug = !optDebug; 2001 optDebug = !optDebug;
2002 update = TRUE; 2002 update = TRUE;
2003 break; 2003 break;
2004 #endif 2004 #endif
2005 2005
2006 case 0x03: /* ^C = quit */ 2006 case 0x03: // ^C = quit
2007 case KEY_F(9): /* F9 = Quit */ 2007 case KEY_F(9): // F9 = Quit
2008 printMsg(currWin, "Quitting per user request (%d/0x%x).\n", c, c); 2008 printMsg(currWin, "Quitting per user request (%d/0x%x).\n", c, c);
2009 exitProg = TRUE; 2009 exitProg = TRUE;
2010 break; 2010 break;
2011 2011
2012 case 0x09: /* Tab = complete username */ 2012 case 0x09: // Tab = complete username
2013 performTabCompletion(editBuf); 2013 performTabCompletion(editBuf);
2014 update = TRUE; 2014 update = TRUE;
2015 break; 2015 break;
2016 2016
2017 case 0x0c: /* Ctrl + L */ 2017 case 0x0c: // Ctrl + L
2018 updateWindows(); 2018 updateWindows();
2019 update = updateMain = TRUE; 2019 update = updateMain = TRUE;
2020 break; 2020 break;
2021 2021
2022 case KEY_NPAGE: 2022 case KEY_NPAGE:
2023 case KEY_PPAGE: 2023 case KEY_PPAGE:
2024 /* Page Up / Page Down */ 2024 // Page Up / Page Down
2025 if (currWin != NULL) 2025 if (currWin != NULL)
2026 { 2026 {
2027 int oldPos = currWin->pos; 2027 int oldPos = currWin->pos;
2028 2028
2029 currWin->pos += (c == KEY_NPAGE) ? -10 : +10; 2029 currWin->pos += (c == KEY_NPAGE) ? -10 : +10;
2037 updateMain = TRUE; 2037 updateMain = TRUE;
2038 } 2038 }
2039 break; 2039 break;
2040 2040
2041 case ERR: 2041 case ERR:
2042 /* Ignore */ 2042 // Ignore
2043 break; 2043 break;
2044 2044
2045 default: 2045 default:
2046 if (isprint(c) || c == 0xe4 || c == 0xf6 || c == 0xc4 || c == 0xd6) 2046 if (isprint(c) || c == 0xe4 || c == 0xf6 || c == 0xc4 || c == 0xd6)
2047 { 2047 {
2064 2064
2065 updateMainWin(updateMain); 2065 updateMainWin(updateMain);
2066 2066
2067 if (update || firstUpdate) 2067 if (update || firstUpdate)
2068 { 2068 {
2069 /* Update edit line */ 2069 // Update edit line
2070 updateStatus(); 2070 updateStatus();
2071 printEditBuf(editBuf); 2071 printEditBuf(editBuf);
2072 firstUpdate = FALSE; /* a nasty hack ... */ 2072 firstUpdate = FALSE; // a nasty hack ...
2073 } 2073 }
2074 2074
2075 } /* cursesInit */ 2075 } // cursesInit
2076 2076
2077 if (++updateCount > 10) 2077 if (++updateCount > 10)
2078 { 2078 {
2079 time_t tmpTime = time(NULL); 2079 time_t tmpTime = time(NULL);
2080 if (tmpTime - prevTime > SET_KEEPALIVE) 2080 if (tmpTime - prevTime > SET_KEEPALIVE)
2096 updateCount = 0; 2096 updateCount = 0;
2097 } 2097 }
2098 2098
2099 } 2099 }
2100 2100
2101 /* Shutdown */ 2101 // Shutdown
2102 err_exit: 2102 err_exit:
2103 th_cfg_free(cfg); 2103 th_cfg_free(cfg);
2104 th_free(homeDir); 2104 th_free(homeDir);
2105 th_llist_free_func(setIdleMessages, th_free); 2105 th_llist_free_func(setIdleMessages, th_free);
2106 nn_userhash_free(nnUsers); 2106 nn_userhash_free(nnUsers);