/* * A network client for interacting with KDB. * * Dan Aloni , 2006 (c) * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include struct termios orig_tty; void sigint(int s) { tcsetattr(STDIN_FILENO, TCSANOW, &orig_tty); } void disable_icanon(void) { struct termios tty; tcgetattr(STDIN_FILENO, &tty); orig_tty = tty; tty.c_lflag &= ~ICANON; tty.c_lflag &= ~ECHO; tty.c_iflag &= ~ICRNL; tcsetattr(STDIN_FILENO, TCSANOW, &tty); signal(SIGINT, sigint); } int main(int argc, char *argv[]) { int sock_fd; int ret; int flag; int stdin_fd = STDIN_FILENO; char in_char; struct sockaddr_in listening_address = { .sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(9353), }; struct sockaddr_in remote_address = { .sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(6665), }; struct pollfd ufds[2]; if (argc < 2) return -1; remote_address.sin_addr.s_addr = inet_addr(argv[1]); printf("netkdb to %s, SIGINT will exit\n", inet_ntoa(remote_address.sin_addr)); sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock_fd < 0) { printf("socket creation failed\n"); return -1; } flag = 1; ret = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); if (ret <0) { return -1; } ret = bind(sock_fd, (struct sockaddr *)&listening_address, sizeof(listening_address)); if (ret < 0) { printf("bind failed\n"); return -1; } ufds[0].fd = sock_fd; ufds[0].events = POLLIN; ufds[1].fd = stdin_fd; ufds[1].events = POLLIN; disable_icanon(); while (1) { ufds[0].revents = 0; ufds[1].revents = 0; ret = poll(ufds, 2, 1000); if (ret < 0) break; if (ufds[1].revents) { ret = read(stdin_fd, &in_char, 1); if (ret == 0) break; /* translate backspace to what kdb is expecting */ if (in_char == 127) { in_char = 8; } ret = sendto(sock_fd, &in_char, 1, 0, (struct sockaddr *)&remote_address, sizeof(remote_address)); if (ret < 0) { fprintf(stderr, "sendto() failed\n"); break; } } if (ufds[0].revents) { struct sockaddr_in source; socklen_t socklen = sizeof(remote_address); char buf[0x1000]; ret = recvfrom(sock_fd, buf, sizeof(buf), 0, (struct sockaddr *)&source, &socklen); if (ret < 0) { fprintf(stderr, "recvfrom() failed\n"); break; } if (source.sin_addr.s_addr == remote_address.sin_addr.s_addr) { write(STDOUT_FILENO, buf, ret); } } } tcsetattr(STDIN_FILENO, TCSANOW, &orig_tty); return 0; }