Mercurial > hg > nnchat
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 |