comparison nnchat.c @ 13:86fe5f0d1a85

Cleanups; Added probing connection (requesting some policy crap) to emulate the official client.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 24 Mar 2008 08:02:05 +0000
parents df23968f0c6a
children 50d8396e7417
comparison
equal deleted inserted replaced
12:df23968f0c6a 13:86fe5f0d1a85
42 { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, 42 { 1, 'v', "verbose", "Be more verbose", OPT_NONE },
43 { 2, 'p', "port", "Connect to port", OPT_ARGREQ }, 43 { 2, 'p', "port", "Connect to port", OPT_ARGREQ },
44 { 3, 's', "server", "Server to connect to", OPT_ARGREQ }, 44 { 3, 's', "server", "Server to connect to", OPT_ARGREQ },
45 { 4, 'C', "color", "Initial color in RGB hex 000000", OPT_ARGREQ }, 45 { 4, 'C', "color", "Initial color in RGB hex 000000", OPT_ARGREQ },
46 { 5, 'l', "logfile", "Log filename", OPT_ARGREQ }, 46 { 5, 'l', "logfile", "Log filename", OPT_ARGREQ },
47 /*
48 { 6, 'p', "plaintext", "Use plaintext logging", OPT_NONE },
49 */
50 }; 47 };
51 48
52 const int optListN = (sizeof(optList) / sizeof(optarg_t)); 49 const int optListN = (sizeof(optList) / sizeof(optarg_t));
53 50
54 51
482 if (!strncmp(str, "FAILURE", 7)) { 479 if (!strncmp(str, "FAILURE", 7)) {
483 printMsg("Login failure.\n"); 480 printMsg("Login failure.\n");
484 return -2; 481 return -2;
485 } else if (!strncmp(str, "SUCCESS", 7)) { 482 } else if (!strncmp(str, "SUCCESS", 7)) {
486 printMsg("Login success.\n"); 483 printMsg("Login success.\n");
487 sendUserMsg(sock, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); 484 sendUserMsg(sock, optUserName2, "%%2FRequestUserList");
488 return 0; 485 return 0;
489 } else 486 } else
490 return 1; 487 return 1;
491 } 488 }
492 489
619 return -1; 616 return -1;
620 } 617 }
621 } 618 }
622 619
623 620
621 int openConnection(struct in_addr *addr, int port)
622 {
623 struct sockaddr_in tmpAddr;
624 int sock = -1;
625
626 tmpAddr.sin_family = AF_INET;
627 tmpAddr.sin_port = htons(port);
628 tmpAddr.sin_addr = *addr;
629
630 THMSG(1, "Connecting to %s:%d ...\n",
631 inet_ntoa(tmpAddr.sin_addr), port);
632
633 if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
634 THERR("Could not open socket: %s\n", strerror(errno));
635 return -2;
636 }
637
638 THMSG(2, "Using socket %d.\n", sock);
639
640 if (connect(sock, (struct sockaddr *) &tmpAddr, sizeof(tmpAddr)) == -1) {
641 THERR("Could not connect: %s\n", strerror(errno));
642 return -5;
643 }
644
645 return sock;
646 }
647
648
649 void closeConnection(int sock)
650 {
651 if (sock >= 0) {
652 #ifdef __WIN32
653 closesocket(sock);
654 #else
655 close(sock);
656 #endif
657 }
658 }
659
660
624 int main(int argc, char *argv[]) 661 int main(int argc, char *argv[])
625 { 662 {
626 int tmpSocket; 663 int tmpSocket;
627 struct hostent *tmpHost; 664 struct hostent *tmpHost;
628 struct sockaddr_in tmpAddr; 665 BOOL exitProg = FALSE, colorSet = FALSE;
629 BOOL exitProg = FALSE; 666 struct timeval tv;
667 fd_set sockfds;
668 fd_set inputfds;
669 char *tmpStr;
630 670
631 /* Initialize */ 671 /* Initialize */
632 th_init("NNChat", "Newbie Nudes chat client", "0.3", 672 th_init("NNChat", "Newbie Nudes chat client", "0.3",
633 "Written and designed by Anonymous Finnish Guy (C) 2008", 673 "Written and designed by Anonymous Finnish Guy (C) 2008",
634 "This software is freeware, use and distribute as you wish."); 674 "This software is freeware, use and distribute as you wish.");
672 hstrerror(h_errno)); 712 hstrerror(h_errno));
673 return -3; 713 return -3;
674 } 714 }
675 THMSG(2, "True hostname: %s\n", tmpHost->h_name); 715 THMSG(2, "True hostname: %s\n", tmpHost->h_name);
676 716
677 tmpAddr.sin_family = AF_INET; 717 /* To emulate the official client, we first make a fake connection ... */
678 tmpAddr.sin_port = htons(optPort); 718 if ((tmpSocket = openConnection((struct in_addr *) tmpHost->h_addr, optPort)) < 0) {
679 tmpAddr.sin_addr = *((struct in_addr *) tmpHost->h_addr); 719 THERR("Fakeprobe connection setup failed!\n");
680 720 goto err_exit;
681 THMSG(1, "Connecting to %s:%d ...\n", 721 }
682 inet_ntoa(tmpAddr.sin_addr), optPort); 722
683 723 tmpStr = "<policy-file-request/>";
684 if ((tmpSocket = socket(PF_INET, SOCK_STREAM, 0)) == -1) { 724 if (sendToSocket(tmpSocket, tmpStr, strlen(tmpStr) + 1) < 0) {
685 THERR("Could not open socket: %s\n", strerror(errno)); 725 THERR("Failed to send fakeprobe.\n");
686 return -2; 726 goto err_exit;
687 } 727 } else {
688 728 ssize_t gotBuf;
689 THMSG(2, "Using socket %d.\n", tmpSocket); 729 char tmpBuf[4096];
690 730 gotBuf = recv(tmpSocket, tmpBuf, sizeof(tmpBuf), 0);
691 if (connect(tmpSocket, (struct sockaddr *) &tmpAddr, sizeof(tmpAddr)) == -1) { 731 tmpBuf[gotBuf-1] = 0;
692 THERR("Could not connect: %s\n", strerror(errno)); 732 THMSG(2, "Probe got: %s\n", tmpBuf);
693 return -5; 733 closeConnection(tmpSocket);
694 } 734 }
695 735
736 /* Okay, now do the proper connection ... */
737 if ((tmpSocket = openConnection((struct in_addr *) tmpHost->h_addr, optPort)) < 0) {
738 THERR("Main connection setup failed!\n");
739 goto err_exit;
740 }
741
696 THMSG(1, "Connected, logging in as '%s'.\n", optUserName); 742 THMSG(1, "Connected, logging in as '%s'.\n", optUserName);
697 optUserName2 = encodeStr1(optUserName); 743 optUserName2 = encodeStr1(optUserName);
698 744
699 sendUserMsg(tmpSocket, optUserName2, "%%2Flogin%%20%%2Dsite%%20NN%%20%%2Dpassword%%20%s", optPassword); 745 sendUserMsg(tmpSocket, optUserName2, "%%2Flogin%%20%%2Dsite%%20NN%%20%%2Dpassword%%20%s", optPassword);
700 746
701 struct timeval tv;
702 fd_set sockfds;
703 fd_set inputfds;
704
705
706 FD_ZERO(&inputfds); 747 FD_ZERO(&inputfds);
707 FD_SET(0, &inputfds); 748 FD_SET(0, &inputfds);
708
709 FD_ZERO(&sockfds); 749 FD_ZERO(&sockfds);
710 FD_SET(tmpSocket, &sockfds); 750 FD_SET(tmpSocket, &sockfds);
711 751
712 while (!exitProg) { 752 while (!exitProg) {
713 ssize_t gotBuf; 753 ssize_t gotBuf;
769 exitProg = TRUE; 809 exitProg = TRUE;
770 } 810 }
771 } 811 }
772 } 812 }
773 813
814 if (!colorSet) {
815 colorSet = TRUE;
816 sendUserMsg(tmpSocket, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor);
817 }
818
774 fflush(stdout); 819 fflush(stdout);
775 fflush(stderr); 820 fflush(stderr);
776 } 821 }
777 822
778 /* .. */ 823 /* Shotdiwn */
824 err_exit:
779 th_free(optUserName2); 825 th_free(optUserName2);
780 826
827 closeConnection(tmpSocket);
828
781 #ifdef __WIN32 829 #ifdef __WIN32
782 closesocket(tmpSocket);
783 WSACleanup(); 830 WSACleanup();
784 #else
785 close(tmpSocket);
786 #endif 831 #endif
832
833 THMSG(1, "Connection terminated.\n");
787 834
788 if (optLogFile) { 835 if (optLogFile) {
789 THMSG(1, "Closing logfile.\n"); 836 THMSG(1, "Closing logfile.\n");
790 fclose(optLogFile); 837 fclose(optLogFile);
791 } 838 }
792 839
793 THMSG(1, "Connection terminated.\n");
794 840
795 return 0; 841 return 0;
796 } 842 }