aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <frankhwei536@gmail.com>2014-07-14 22:31:04 -0400
committerFranklin Wei <frankhwei536@gmail.com>2014-07-14 22:31:04 -0400
commit3b104903087460158fd79c9cae27ada2d4dc103e (patch)
tree0d928355a981d37e2e72186828deebdae537150b
parentf10cfb8bd77327b73da570730dee794d83b5c6ad (diff)
downloadwargames-server-3b104903087460158fd79c9cae27ada2d4dc103e.zip
wargames-server-3b104903087460158fd79c9cae27ada2d4dc103e.tar.gz
wargames-server-3b104903087460158fd79c9cae27ada2d4dc103e.tar.bz2
wargames-server-3b104903087460158fd79c9cae27ada2d4dc103e.tar.xz
Added some features to telnet server
-rw-r--r--server.c117
-rw-r--r--util.c14
-rw-r--r--util.h11
3 files changed, 135 insertions, 7 deletions
diff --git a/server.c b/server.c
index 629d976..290739e 100644
--- a/server.c
+++ b/server.c
@@ -19,6 +19,7 @@
*/
#include "joshua.h"
+#include "util.h"
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
@@ -29,10 +30,11 @@
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
-
+#define DEFAULT_PORT 23
int server_socket;
uint16_t port;
int pipes[FD_SETSIZE][2];
+struct connection_data_t connection_data[FD_SETSIZE];
int make_server_socket(uint16_t port)
{
int sock;
@@ -40,7 +42,7 @@ int make_server_socket(uint16_t port)
sock=socket(AF_INET, SOCK_STREAM, 0);
if(sock<0)
{
- printf("error creating socket.\n");
+ printf("error opening socket.\n");
return -1;
}
name.sin_family=AF_INET;
@@ -56,7 +58,7 @@ int make_server_socket(uint16_t port)
}
int process_data(int fd)
{
- char buf[1024];
+ unsigned char buf[1024];
memset(buf, 0, sizeof(buf));
int ret=read(fd, buf, sizeof(buf));
char ctrl_c[]={0xff, 0xf4, 0xff, 0xfd, 0x06, 0x00};
@@ -78,7 +80,91 @@ int process_data(int fd)
else
{
printf("Client sends: %s\n", buf);
- write(pipes[fd][1], buf, strlen(buf));
+ if(strlen(buf)>0)
+ {
+ if(buf[0]==0xff)
+ {
+ printf("String is command.\n");
+ printf("Hex dump: ");
+ for(int i=0;buf[i];++i)
+ {
+ printf("%d ", buf[i]);
+ }
+ if(strlen(buf)<2)
+ {
+ printf("Bad command (length<3).\n");
+ return 0; /* not a fatal error */
+ }
+ unsigned char cmd=buf[1];
+#define WILL 251
+#define WONT 252
+#define DO 253
+#define DONT 254
+#define SB 250
+#define SE 240
+#define AYT 246
+#define NAWS 31
+ unsigned char opt=(strlen(buf)==2)?0:buf[2];
+ unsigned char nop[2]={0xff, 241};
+ switch(cmd)
+ {
+ case AYT:
+ /* respond with IAC NOP */
+ write(fd, nop, 2);
+ break;
+ case WILL:
+ case DO:
+ if(cmd==NAWS)
+ {
+ printf("Client offers NAWS\n");
+ }
+ else if(cmd==1)
+ {
+ printf("Client offers echo.\n");
+ }
+ break;
+ case WONT:
+ case DONT:
+ if(cmd==NAWS)
+ {
+ printf("Client denies NAWS.\n");
+ }
+ else if(cmd==1)
+ {
+ printf("Client denies echo.\n");
+ }
+ break;
+ default:
+ printf("Unknown command.\n");
+ break;
+ }
+ if(cmd==SB)
+ {
+ if(opt==NAWS)
+ {
+ if(strlen(buf)>=9)
+ {
+ uint16_t width, height;
+ uint8_t width_hi, width_lo, height_hi, height_lo;
+ width_hi=buf[3];
+ width_lo=buf[4];
+ height_hi=buf[5];
+ height_lo=buf[6];
+ width=(width_hi<<8)|width_lo;
+ height=(height_hi<<8)|height_lo;
+ connection_data[fd].know_termsize=(width==0 || height==0)?0:1; /* if any dimension is zero, unknown */
+ connection_data[fd].term_height=height;
+ connection_data[fd].term_width=width;
+ printf("Client window is %dx%d\n", width, height);
+ }
+ }
+ }
+ }
+ else
+ {
+ write(pipes[fd][1], buf, strlen(buf));
+ }
+ }
return 0;
}
}
@@ -88,14 +174,29 @@ void serv_cleanup()
fflush(stdout);
shutdown(server_socket, SHUT_RDWR);
}
+void setup_new_connection(int fd)
+{
+ unsigned char will_naws[]={0xff, 251, 31};
+ write(fd, will_naws, sizeof(will_naws));
+ memset(&connection_data[fd], 0, sizeof(struct connection_data_t));
+}
int main(int argc, char* argv[])
{
if(argc!=2)
{
- printf("Usage: %s PORT\n", argv[0]);
- return 2;
+ printf("Listening on default port: %d\n", DEFAULT_PORT);
+ port=DEFAULT_PORT;
+ }
+ else
+ {
+ int port2=atoi(argv[1]);
+ if(port2<0 || port2>65535)
+ {
+ printf("Port out of range.\n");
+ return 2;
+ }
+ port=atoi(argv[1]);
}
- port=atoi(argv[1]);
printf("Initializing server on port %u...\n", port);
signal(SIGINT, &serv_cleanup);
int sock=make_server_socket(port);
@@ -144,6 +245,8 @@ int main(int argc, char* argv[])
pid_t pid=fork();
if(pid==0) /* child */
{
+ /* set up the connection */
+ setup_new_connection(new);
be_joshua(new);
printf("Client exits\n");
shutdown(new, SHUT_RDWR);
diff --git a/util.c b/util.c
index 9539b46..c27981a 100644
--- a/util.c
+++ b/util.c
@@ -69,6 +69,7 @@ void refresh(void)
}
int getnstr(char* buf, int max)
{
+ echo_on();
memset(buf, 0, max);
int ret=read(pipes[out_fd][0], buf, max);
if(ret!=0)
@@ -81,4 +82,17 @@ int getnstr(char* buf, int max)
if(ret<0)
return ERR;
return OK;
+ echo_off();
+}
+void echo_off(void)
+{
+ unsigned char echo_off[]={0xff, 254, 1};
+ write(out_fd, echo_off, 3);
+ fsync(out_fd);
+}
+void echo_on(void)
+{
+ unsigned char echo_on[]={0xff, 253, 1};
+ write(out_fd, echo_on, 3);
+ fsync(out_fd);
}
diff --git a/util.h b/util.h
index 5f7e170..6b824fd 100644
--- a/util.h
+++ b/util.h
@@ -19,12 +19,23 @@
*/
#define SLEEP_TIME 5000
+#include <stdint.h>
+#include <stdlib.h>
+struct connection_data_t {
+ int naws_enable:1;
+ int know_termsize:1;
+ uint16_t term_height;
+ uint16_t term_width;
+};
+extern struct connection_data_t connection_data[FD_SETSIZE];
void allLower(char*);
void print_string(const char*);
void remove_punct(char*);
void refresh(void);
void clear(void);
int getnstr(char*, int);
+void echo_off(void);
+void echo_on(void);
#define ERR 1
#define OK 0
extern int out_fd;