#include <curses.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int wait_for_connection(char *interface, int portnr, struct sockaddr_in *clientaddr)
{
int clientaddrlen = sizeof(struct sockaddr_in);
struct sockaddr_in ServerAddr;
int ServerAddrLen = sizeof(ServerAddr);
int ReUseAddr = 1;
int fd = socket(AF_INET, SOCK_STREAM, 0), new_fd;
if (fd == -1)
{
fprintf(stderr, "Could not create socket! Reason: %s\n", strerror(errno));
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&ReUseAddr, sizeof(ReUseAddr)) == -1)
{
fprintf(stderr, "Could not set socket to 'reuse address'! Reason: %s\n", strerror(errno));
return -1;
}
memset((char *)&ServerAddr, '\0', ServerAddrLen);
ServerAddr.sin_family = AF_INET;
if (interface)
{
if (inet_aton(interface, &ServerAddr.sin_addr) == 0)
{
fprintf(stderr, "Could not convert interface address %s!\n", interface);
close(fd);
return -1;
}
}
else
{
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
}
ServerAddr.sin_port = htons(portnr);
if (bind(fd, (struct sockaddr *)&ServerAddr, ServerAddrLen) == -1)
{
fprintf(stderr, "Could not bind socket to interface %s! Reason: %s\n", interface?interface:"(any)", strerror(errno));
close(fd);
return -1;
}
if (listen(fd, 1) == -1)
{
fprintf(stderr, "Could not setup listen queue! Reason: %s\n", strerror(errno));
close(fd);
return -1;
}
new_fd = accept(fd, (struct sockaddr *)clientaddr, &clientaddrlen);
if (new_fd == -1)
{
fprintf(stderr, "Problem accepting new connection! Reason: %s\n", strerror(errno));
close(fd);
return -1;
}
close(fd);
return new_fd;
}
void usage(void)
{
fprintf(stderr, "recvnet v" VERSION ", (C) 2004 by folkert@vanheusden.com\n\n");
fprintf(stderr, "-i interface interface to bind to. default is any\n");
fprintf(stderr, "-p port port to listen on. default is telnet (23)\n");
fprintf(stderr, "-h this help\n");
fprintf(stderr, "-V version information\n");
}
int main(int argc, char *argv[])
{
struct sockaddr_in clientaddr;
int fd;
int portnr=23;
char *interface = NULL;
int c;
while((c = getopt(argc, argv, "i:p:hV")) != -1)
{
switch(c)
{
case 'i':
interface = optarg;
break;
case 'p':
portnr = atoi(optarg);
break;
case 'h':
usage();
return 1;
case 'V':
fprintf(stderr, VERSION ", (C) 2004 by folkert@vanheusden.com\n");
return 1;
}
}
printf("Listening on %s:%d\n", interface?interface:"(any)", portnr);
fd = wait_for_connection(interface, portnr, &clientaddr);
if (fd == -1)
return 1;
/* start curses */
initscr();
/* set terminal to non-cooked mode */
cbreak();
/* enable 8-bit input */
meta(stdscr, TRUE);
/* will take care of this */
noecho();
printw("Connection made with %s:%d\n", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port);
printw("Escape character is '^]'.\n");
refresh();
signal(SIGINT, SIG_IGN);
/* do terminal */
for(;;)
{
fd_set rfds;
int rc;
char buffer[4096 + 1];
FD_ZERO(&rfds);
FD_SET(0, &rfds);
FD_SET(fd, &rfds);
if (select(fd + 1, &rfds, NULL, NULL, NULL) > 0)
{
if (FD_ISSET(0, &rfds))
{
buffer[0] = getch();
/* escapecode? */
if (buffer[0] == 29)
{
/* ... */
endwin();
fprintf(stderr, "\nConnection closed.\n");
break; /* should give some prompt */
}
else
{
/* transmit to other side */
do
{
rc = write(fd, buffer, 1);
}
while(rc == -1 && errno == EINTR);
if (buffer[0] == 10)
wprintw(stdscr, "\n");
else
wprintw(stdscr, "%c", buffer[0]);
}
}
if (FD_ISSET(fd, &rfds))
{
int loop;
do
{
rc = read(fd, buffer, 4096);
}
while(rc == -1 && errno == EINTR);
if (rc == 0)
{
endwin();
fprintf(stderr, "\nConnection closed by foreign host.\n");
break;
}
else if (rc == -1)
{
endwin();
fprintf(stderr, "\nRead error. Reason: %s\n", strerror(errno));
break;
}
buffer[rc] = 0x00;
for(loop=0; loop<rc; loop++)
{
if (buffer[loop] != 13)
wprintw(stdscr, "%c", buffer[loop]);
}
}
refresh();
}
}
close(fd);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1