comparison nnchat.c @ 68:3ab7751fdad1

MingW compatibility, with one ugly kludge.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 14 Nov 2008 07:15:57 +0200
parents 4086088e95dc
children 79982b0aad97
comparison
equal deleted inserted replaced
67:4086088e95dc 68:3ab7751fdad1
8 #include "th_args.h" 8 #include "th_args.h"
9 #include <string.h> 9 #include <string.h>
10 #include <errno.h> 10 #include <errno.h>
11 #include <time.h> 11 #include <time.h>
12 #ifdef __WIN32 12 #ifdef __WIN32
13 #define usleep(t) Sleep((t) / 1000)
14 /* Undefine because both windows.h and curses.h #define it */
15 #undef MOUSE_MOVED
16 #endif
13 #include <curses.h> 17 #include <curses.h>
14 #else
15 #include <ncurses.h>
16 #endif
17 18
18 19
19 #define SET_MAX_BACKBUF (1024) 20 #define SET_MAX_BACKBUF (1024)
20 #define SET_MAX_HISTORY (16) 21 #define SET_MAX_HISTORY (16)
21 #define SET_DELAY (15) 22 #define SET_DELAY (15)
54 }; 55 };
55 56
56 const int optListN = (sizeof(optList) / sizeof(optList[0])); 57 const int optListN = (sizeof(optList) / sizeof(optList[0]));
57 58
58 59
59 void argShowHelp()
60 {
61 th_args_help(stdout, optList, optListN, th_prog_name,
62 "[options] <username> <password>");
63 }
64
65
66 int getColor(char *str) 60 int getColor(char *str)
67 { 61 {
68 char *p = str; 62 char *p = str;
69 int len, val = 0; 63 int len, val = 0;
70 64
80 } 74 }
81 75
82 return (len == 6) ? val : -1; 76 return (len == 6) ? val : -1;
83 } 77 }
84 78
79
80 void argShowHelp()
81 {
82 th_args_help(stdout, optList, optListN, th_prog_name,
83 "[options] <username> <password>");
84 }
85
86
85 BOOL argHandleOpt(const int optN, char *optArg, char *currArg) 87 BOOL argHandleOpt(const int optN, char *optArg, char *currArg)
86 { 88 {
87 switch (optN) { 89 switch (optN) {
88 case 0: 90 case 0:
89 argShowHelp(); 91 argShowHelp();
145 } 147 }
146 148
147 return TRUE; 149 return TRUE;
148 } 150 }
149 151
152 #ifdef __WIN32
153 const char *hstrerror(int err)
154 {
155 static char buf[64];
156 snprintf(buf, sizeof(buf), "Error #%d", err);
157 return buf;
158 }
159
160 int getSocketErrno(void)
161 {
162 return WSAGetLastError();
163 }
164
165 const char *getSocketErrStr(int err)
166 {
167 static char buf[64];
168 snprintf(buf, sizeof(buf), "Error #%d", err);
169 return buf;
170 }
171 #else
172 int getSocketErrno(void)
173 {
174 return errno;
175 }
176
177 const char *getSocketErrStr(int err)
178 {
179 return strerror(err);
180 }
181 #endif
150 182
151 void updateStatus(BOOL insertMode) 183 void updateStatus(BOOL insertMode)
152 { 184 {
153 char tmpStr[128] = ""; 185 char tmpStr[128] = "";
154 time_t timeStamp; 186 time_t timeStamp;
571 struct hostent *tmpHost; 603 struct hostent *tmpHost;
572 BOOL argsOK, isError = FALSE, 604 BOOL argsOK, isError = FALSE,
573 exitProg = FALSE, 605 exitProg = FALSE,
574 colorSet = FALSE, 606 colorSet = FALSE,
575 cursesInit = FALSE, 607 cursesInit = FALSE,
608 #if __WIN32
609 networkInit = FALSE,
610 #endif
576 insertMode = TRUE; 611 insertMode = TRUE;
577 struct timeval tv; 612 struct timeval tv;
578 fd_set sockfds; 613 fd_set sockfds;
579 char *tmpStr; 614 char *tmpStr;
580 editbuf_t *editBuf = newBuf(SET_BUFSIZE); 615 editbuf_t *editBuf = newBuf(SET_BUFSIZE);
601 636
602 if (!argsOK) 637 if (!argsOK)
603 return -2; 638 return -2;
604 639
605 640
641 /* Open logfile */
642 if (optLogFilename) {
643 THMSG(1, "Opening logfile '%s'\n", optLogFilename);
644
645 if ((optLogFile = fopen(optLogFilename, "a")) == NULL) {
646 THERR("Could not open logfile for appending!\n");
647 return -9;
648 }
649 }
650
606 #ifdef __WIN32 651 #ifdef __WIN32
607 { 652 {
608 /* Initialize WinSock, if needed */ 653 /* Initialize WinSock, if needed */
609 WSADATA wsaData; 654 WSADATA wsaData;
610 int err = WSAStartup(0x0200, &wsaData); 655 int err = WSAStartup(0x0101, &wsaData);
611 if (err != 0) { 656 if (err != 0) {
612 THERR("Could not initialize WinSock DLL: %d\n", err); 657 THERR("Could not initialize WinSock DLL: %d\n", err);
613 return -3; 658 goto err_exit;
614 } 659 }
660 networkInit = TRUE;
615 #endif 661 #endif
616 662
617 /* Open logfile */
618 if (optLogFilename) {
619 THMSG(1, "Opening logfile '%s'\n", optLogFilename);
620
621 if ((optLogFile = fopen(optLogFilename, "a")) == NULL) {
622 THERR("Could not open logfile for appending!\n");
623 return -9;
624 }
625 }
626
627 /* Okay ... */ 663 /* Okay ... */
628 THMSG(1, "Trying to resolve host '%s' ...\n", optServer); 664 THMSG(1, "Trying to resolve host '%s' ...\n", optServer);
629 tmpHost = gethostbyname(optServer); 665 tmpHost = gethostbyname(optServer);
630 if (tmpHost == NULL) { 666 if (tmpHost == NULL) {
631 THERR("Could not resolve hostname: %s.\n", 667 THERR("Could not resolve hostname: %s.\n",
632 hstrerror(h_errno)); 668 hstrerror(h_errno));
633 return -3; 669 goto err_exit;
634 } 670 }
635 THMSG(2, "True hostname: %s\n", tmpHost->h_name); 671 THMSG(2, "True hostname: %s\n", tmpHost->h_name);
672
636 673
637 #if 0 674 #if 0
638 /* To emulate the official client, we first make a request for 675 /* To emulate the official client, we first make a request for
639 * policy file, even though we don't use it for anything... 676 * policy file, even though we don't use it for anything...
640 */ 677 */
669 sendUserMsg(tmpSocket, optUserName2, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword); 706 sendUserMsg(tmpSocket, optUserName2, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword);
670 th_free(tmpStr); 707 th_free(tmpStr);
671 708
672 /* Initialize NCurses */ 709 /* Initialize NCurses */
673 if (!optDaemon) { 710 if (!optDaemon) {
711 if (LINES < 0 || LINES > 1000) LINES = 24;
712 if (COLS < 0 || COLS > 1000) COLS = 80;
713 LINES=24;
674 initscr(); 714 initscr();
675 raw(); 715 raw();
676 keypad(stdscr, TRUE); 716 keypad(stdscr, TRUE);
677 noecho(); 717 noecho();
678 meta(stdscr, TRUE); 718 meta(stdscr, TRUE);
708 clearBuf(editBuf); 748 clearBuf(editBuf);
709 printEditBuf("", editBuf); 749 printEditBuf("", editBuf);
710 updateStatus(insertMode); 750 updateStatus(insertMode);
711 } 751 }
712 752
713
714 /* Enter mainloop */ 753 /* Enter mainloop */
715 FD_ZERO(&sockfds); 754 FD_ZERO(&sockfds);
716 FD_SET(tmpSocket, &sockfds); 755 FD_SET(tmpSocket, &sockfds);
717 756
718 while (!isError && !exitProg) { 757 while (!isError && !exitProg) {
722 /* Check for incoming data from the server */ 761 /* Check for incoming data from the server */
723 tv.tv_sec = 0; 762 tv.tv_sec = 0;
724 tv.tv_usec = SET_DELAY_USEC; 763 tv.tv_usec = SET_DELAY_USEC;
725 tmpfds = sockfds; 764 tmpfds = sockfds;
726 if ((result = select(tmpSocket+1, &tmpfds, NULL, NULL, &tv)) == -1) { 765 if ((result = select(tmpSocket+1, &tmpfds, NULL, NULL, &tv)) == -1) {
727 if (errno != EINTR && errno != ERESTART) { 766 int res = getSocketErrno();
728 printMsg("Error occured in select(sockfds): %d, %s\n", errno, strerror(errno)); 767 if (res != EINTR) {
768 printMsg("Error occured in select(sockfds): %d, %s\n",
769 res, getSocketErrStr(res));
729 isError = TRUE; 770 isError = TRUE;
730 } 771 }
731 } else if (FD_ISSET(tmpSocket, &tmpfds)) { 772 } else if (FD_ISSET(tmpSocket, &tmpfds)) {
732 ssize_t gotBuf; 773 ssize_t gotBuf;
733 char tmpBuf[8192]; 774 char tmpBuf[8192];
734 char *bufPtr = tmpBuf; 775 char *bufPtr = tmpBuf;
735 gotBuf = recv(tmpSocket, tmpBuf, sizeof(tmpBuf), 0); 776 gotBuf = recv(tmpSocket, tmpBuf, sizeof(tmpBuf), 0);
736 777
737 if (gotBuf < 0) { 778 if (gotBuf < 0) {
738 printMsg("Error in recv: %s\n", strerror(errno)); 779 int res = getSocketErrno();
780 printMsg("Error in recv: %d, %s\n", res, getSocketErrStr(res));
739 isError = TRUE; 781 isError = TRUE;
740 } else if (gotBuf == 0) { 782 } else if (gotBuf == 0) {
741 printMsg("Server closed connection.\n"); 783 printMsg("Server closed connection.\n");
742 isError = TRUE; 784 isError = TRUE;
743 } else { 785 } else {
953 995
954 th_free(optUserName2); 996 th_free(optUserName2);
955 997
956 closeConnection(tmpSocket); 998 closeConnection(tmpSocket);
957 999
1000 #ifdef __WIN32
1001 if (networkInit)
1002 WSACleanup();
1003 #endif
1004
958 THMSG(1, "Connection terminated.\n"); 1005 THMSG(1, "Connection terminated.\n");
959 1006
960 if (optLogFile) { 1007 if (optLogFile) {
961 THMSG(1, "Closing logfile.\n"); 1008 THMSG(1, "Closing logfile.\n");
962 fclose(optLogFile); 1009 fclose(optLogFile);
963 } 1010 }
964 1011
965 return 0; 1012 return 0;
966 } 1013 }
1014
1015 #ifdef __WIN32
1016 /* This is a really weird kludge ... */
1017 }
1018 #endif