summaryrefslogtreecommitdiff
path: root/src/downserver
diff options
context:
space:
mode:
authororoborus <oroborus@0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e>2008-09-03 19:41:33 +0000
committeroroborus <oroborus@0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e>2008-09-03 19:41:33 +0000
commitfb449850a6895b5b82ee545fcb35a04d565c6d56 (patch)
tree0689495086c1c69929dddbc4a65626705131de96 /src/downserver
parentc8a8b08db7889eaa34f0b52b5a4d9487358b0d88 (diff)
- server si dokaze stahnut arenu z downServera
( este to nie je poriadne otestovane ) git-svn-id: http://opensvn.csie.org/tuxanci_ng@273 0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e
Diffstat (limited to 'src/downserver')
-rwxr-xr-xsrc/downserver/Makefile14
-rw-r--r--src/downserver/arena.conf5
-rw-r--r--src/downserver/downServer.c376
3 files changed, 395 insertions, 0 deletions
diff --git a/src/downserver/Makefile b/src/downserver/Makefile
new file mode 100755
index 0000000..df15b12
--- /dev/null
+++ b/src/downserver/Makefile
@@ -0,0 +1,14 @@
+
+#CC = /usr/local/gcc/bin/gcc
+CC = gcc
+
+CFLAGS = -g -O0 -std=c99 -D_GNU_SOURCE=1 -I../base -I../net
+LIBS =
+
+FILES = ../base/list.o ../base/textFile.o ../base/buffer.o ../net/tcp.o
+
+downServer: downServer.c $(FILES)
+ $(CC) $(CFLAGS) $(LIBS) -o downServer downServer.c $(FILES)
+
+clean:
+ rm -rf *.o *.c~ *.h~ Makefile~
diff --git a/src/downserver/arena.conf b/src/downserver/arena.conf
new file mode 100644
index 0000000..c936e19
--- /dev/null
+++ b/src/downserver/arena.conf
@@ -0,0 +1,5 @@
+/home/dusan/projectTuxanci/tuxanci_ng/data/arena/for_a_good_night.zip FAGN
+/home/dusan/projectTuxanci/tuxanci_ng/data/arena/night_workshift.zip NW
+/home/dusan/projectTuxanci/tuxanci_ng/data/arena/in_a_captivity_of_8-bit.zip IACO8B
+/home/dusan/projectTuxanci/tuxanci_ng/data/arena/construction_site.zip CS
+
diff --git a/src/downserver/downServer.c b/src/downserver/downServer.c
new file mode 100644
index 0000000..ae1c314
--- /dev/null
+++ b/src/downserver/downServer.c
@@ -0,0 +1,376 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include "list.h"
+#include "tcp.h"
+#include "buffer.h"
+#include "textFile.h"
+
+#define CLIENT_LIMIT_BUFFER (4096+256)
+
+#define STR_PATH_SIZE 4096
+#define STR_ARENA_NET_NAME_SIZE 256
+#define BUFFER_SEND_FILE_SIZE 4096
+
+#define NET_STATUS_OK 0
+#define NET_STATUS_ZOMBIE 1
+
+#define BUFFER_SIZE 256
+#define PROTO_SIZE 256
+
+static sock_tcp_t *sock_server_tcp;
+static list_t *listClient;
+static textFile_t *configFile;
+
+typedef struct
+{
+ int status;
+
+ FILE *file;
+ int fileSize;
+ int fileOffset;
+
+ sock_tcp_t *socket;
+ buffer_t *recvBuffer;
+ buffer_t *sendBuffer;
+} client_t;
+
+static client_t* newClient(sock_tcp_t *sock)
+{
+ client_t *new;
+
+ new = malloc( sizeof(client_t) );
+ new->socket = sock;
+ new->status = NET_STATUS_OK;
+ new->file = NULL;
+ new->recvBuffer = newBuffer(CLIENT_LIMIT_BUFFER);
+ new->sendBuffer = newBuffer(CLIENT_LIMIT_BUFFER);
+
+ return new;
+}
+
+static void destroyClient(client_t *client)
+{
+ if( client->file != NULL )fclose(client->file);
+ closeTcpSocket(client->socket);
+ destroyBuffer(client->recvBuffer);
+ destroyBuffer(client->sendBuffer);
+ free(client);
+}
+
+int getFileSize(char *s)
+{
+ struct stat buf;
+
+ if( lstat(s, &buf) < 0 )
+ {
+ return -1;
+ }
+
+ return buf.st_size;
+}
+
+static char* getFileFromArenaNetName(char *s)
+{
+ int i;
+
+ for( i = 0 ; i < configFile->text->count ; i++ )
+ {
+ char path[STR_PATH_SIZE];
+ char arena[STR_ARENA_NET_NAME_SIZE];
+ char *line;
+ int len;
+
+ line = configFile->text->list[i];
+
+ sscanf(line, "%s %s", path, arena);
+ len = strlen(arena);
+
+ if( strncmp(arena, s, len) == 0 )
+ {
+ return strdup(path);
+ }
+ }
+
+ return NULL;
+}
+
+static void proto_getarena(client_t *client, char *msg)
+{
+ char msg_out[PROTO_SIZE];
+ char *path;
+
+ path = getFileFromArenaNetName(msg);
+
+ if( path != NULL )
+ {
+ client->file = fopen(path, "rb");
+ client->fileSize = getFileSize(path);
+ client->fileOffset = 0;
+ free(path);
+
+ if( client->file == NULL || client->fileSize < 0 )
+ {
+ client->file = NULL;
+ client->fileSize = 0;
+ sprintf(msg_out, "ERR server has a problem !\n");
+ }
+ else
+ {
+ sprintf(msg_out, "OK %d\n", client->fileSize);
+ }
+ }
+ else
+ {
+ sprintf(msg_out, "ERR arena not found\n");
+ }
+
+ addBuffer(client->sendBuffer, msg_out, strlen(msg_out));
+}
+
+static void doProto(client_t *client, char *msg)
+{
+ printf("hmm msg = %s\n", msg);
+
+ if( strncmp(msg, "GETARENA", 8) == 0 && client->file == NULL )
+ {
+ proto_getarena(client, msg+9);
+ }
+}
+
+static int initDownServer(char *ip, int port)
+{
+ sock_server_tcp = bindTcpSocket(ip, port, PROTO_TCPv4);
+
+ listClient = newList();
+
+ configFile = loadTextFile("arena.conf");
+
+ return 0;
+}
+
+static void eventNewClient(sock_tcp_t *server_sock)
+{
+ sock_tcp_t *sock;
+ client_t *client;
+
+ sock = getTcpNewClient(server_sock);
+ setTcpSockNonBlock(sock);
+
+ client = newClient(sock);
+ addList(listClient, client);
+}
+
+static void eventRecvClient(client_t *client)
+{
+ char buffer[BUFFER_SIZE];
+ char line[PROTO_SIZE];
+ int ret;
+
+ memset(buffer, 0, BUFFER_SIZE);
+
+ ret = readTcpSocket(client->socket, buffer, BUFFER_SIZE-1);
+ //printf("readTcpSocket = %d\n", ret);
+
+ if( ret <= 0 )
+ {
+ client->status = NET_STATUS_ZOMBIE;
+ return;
+ }
+
+ if( addBuffer(client->recvBuffer, buffer, ret) < 0 )
+ {
+ client->status = NET_STATUS_ZOMBIE;
+ return;
+ }
+
+ while( getBufferLine(client->recvBuffer, line, PROTO_SIZE) >= 0 )
+ {
+ doProto(client, line);
+ }
+}
+
+static void eventSendClient(client_t *client)
+{
+ void *data;
+ int len;
+ int res;
+
+ len = getBufferSize(client->sendBuffer);
+
+ if( len == 0 )
+ {
+ return;
+ }
+
+ data = getBufferData(client->sendBuffer);
+
+ res = writeTcpSocket(client->socket, data, len);
+ //printf("send = %d\n", res);
+ //printf("writeTcpSocket = %d\n", res);
+
+ if( res < 0 )
+ {
+ client->status = NET_STATUS_ZOMBIE;
+ return;
+ }
+
+ cutBuffer(client->sendBuffer, res);
+}
+
+static void eventClient(client_t *client)
+{
+ if( client->file != NULL && getBufferSize(client->sendBuffer) == 0 )
+ {
+ char buffer[BUFFER_SEND_FILE_SIZE];
+ int count;
+ int ret;
+
+ count = client->fileSize - client->fileOffset;
+
+ if( count > BUFFER_SEND_FILE_SIZE )
+ {
+ count = BUFFER_SEND_FILE_SIZE;
+ }
+
+ ret = fread(buffer, count, 1, client->file);
+ //printf("read = %d\n", count);
+
+ if( ret == 1 )
+ {
+ if( addBuffer(client->sendBuffer, buffer, count) < 0 )
+ {
+ client->status = NET_STATUS_ZOMBIE;
+ return;
+ }
+
+ client->fileOffset += count;
+ }
+ else
+ {
+ client->status = NET_STATUS_ZOMBIE;
+ }
+ }
+}
+
+void startDownServer()
+{
+ struct timeval tv;
+ fd_set readfds;
+ fd_set writefds;
+ int max_fd;
+ int ret;
+ int i;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+
+ max_fd = sock_server_tcp->sock;
+
+ FD_SET(sock_server_tcp->sock, &readfds);
+
+ for( i = 0 ; i < listClient->count ; i++ )
+ {
+ client_t *client;
+ int sock;
+
+ client = (client_t *)listClient->list[i];
+
+ if( client->status != NET_STATUS_ZOMBIE )
+ {
+ sock = client->socket->sock;
+
+ if( sock > max_fd )
+ {
+ max_fd = sock;
+ }
+
+ FD_SET(sock, &readfds);
+
+ if( getBufferSize(client->sendBuffer) > 0 )
+ {
+ FD_SET(sock, &writefds);
+ }
+ }
+ }
+
+ ret = select(max_fd+1, &readfds, &writefds, (fd_set *)NULL, &tv);
+
+ if( ret > 0 )
+ {
+ if( FD_ISSET(sock_server_tcp->sock, &readfds) )
+ {
+ eventNewClient(sock_server_tcp);
+ }
+
+ for( i = 0 ; i < listClient->count ; i++ )
+ {
+ client_t *client;
+ int sock;
+
+ client = (client_t *)listClient->list[i];
+ sock = client->socket->sock;
+
+ if( FD_ISSET(sock, &readfds) )
+ {
+ eventRecvClient(client);
+ }
+
+ if( FD_ISSET(sock, &writefds) )
+ {
+ eventSendClient(client);
+ }
+ }
+ }
+
+ for( i = 0 ; i < listClient->count ; i++ )
+ {
+ client_t *client;
+
+ client = (client_t *)listClient->list[i];
+
+ if( client->status == NET_STATUS_ZOMBIE )
+ {
+ delListItem(listClient, i, destroyClient);
+ i--;
+ continue;
+ }
+
+ eventClient(client);
+ }
+}
+
+void quitDownServer()
+{
+ closeTcpSocket(sock_server_tcp);
+ destroyListItem(listClient, destroyClient);
+}
+
+int isFillPath(const char *path)
+{
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ signal(SIGPIPE, SIG_IGN);
+
+ initDownServer("127.0.0.1", 2200);
+
+ while(1)
+ {
+ startDownServer();
+ }
+}