From 7c5c2dd3c8cf3f88daf1a12beacd607ce176a8dc Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 11 Jul 2010 19:22:59 +0800 Subject: [PATCH] Moar server work --- server/src/Makefile | 3 +- server/src/common.h | 5 ++ server/src/main.c | 4 +- server/src/server.c | 111 ++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 116 insertions(+), 7 deletions(-) diff --git a/server/src/Makefile b/server/src/Makefile index 9df8c06..3fee2f0 100644 --- a/server/src/Makefile +++ b/server/src/Makefile @@ -1,7 +1,8 @@ # OpenDispense 2 # -OBJ := main.o logging.o dispense.o cokebank.o itemdb.o +OBJ := main.o server.o logging.o +OBJ += dispense.o cokebank.o itemdb.o BIN := ../dispsrv LINKFLAGS := diff --git a/server/src/common.h b/server/src/common.h index 3e47fb7..f310e9a 100644 --- a/server/src/common.h +++ b/server/src/common.h @@ -12,6 +12,10 @@ // === CONSTANTS === #define DEFAULT_CONFIG_FILE "/etc/opendispense/main.cfg" +// === HELPER MACROS === +#define _EXPSTR(x) #x +#define EXPSTR(x) _EXPSTR(x) + // === STRUCTURES === typedef struct sItem tItem; struct sItem @@ -54,5 +58,6 @@ extern void Log_Info(const char *Format, ...); extern int AlterBalance(int User, int Ammount); extern int GetBalance(int User); extern char *GetUserName(int User); +extern int GetUserID(const char *Username); #endif diff --git a/server/src/main.c b/server/src/main.c index 5b8e8b5..2d9f70e 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -19,9 +19,9 @@ extern void Server_Start(void); // === CODE === int main(int argc, char *argv[]) { - Cokebank_Init(); + //Init_Cokebank(); - Load_Itemlist(); + //Load_Itemlist(); Server_Start(); diff --git a/server/src/server.c b/server/src/server.c index 6d1ed5d..8c87c65 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -11,27 +11,57 @@ #include #include "common.h" #include +#include #define MAX_CONNECTION_QUEUE 5 -#define INPUT_BUFFER_SIZE 100 +#define INPUT_BUFFER_SIZE 128 -#define MSG_STR_TOO_LONG "499 Malformed Command String" +#define MSG_STR_TOO_LONG "499 Command too long (limit "EXPSTR(INPUT_BUFFER_SIZE)")\n" + +// === TYPES === +typedef struct sClient +{ + int UID; + int bIsAuthed; +} tClient; + +// === PROTOTYPES === +void Server_Start(void); +void Server_HandleClient(int Socket); +char *Server_ParseClientCommand(tClient *Client, char *CommandString); +char *Server_Cmd_USER(tClient *Client, char *Args); // === GLOBALS === int giServer_Port = 1020; + int giServer_NextClientID = 1; +// - Commands +struct sClientCommand { + char *Name; + char *(*Function)(tClient *Client, char *Arguments); +} gaServer_Commands[] = { + {"USER", Server_Cmd_USER} +}; +#define NUM_COMMANDS (sizeof(gaServer_Commands)/sizeof(gaServer_Commands[0])) // === CODE === +/** + * \brief Open listenting socket and serve connections + */ void Server_Start(void) { // Create Server } +/** + * \brief Reads from a client socket and parses the command strings + */ void Server_HandleClient(int Socket) { char inbuf[INPUT_BUFFER_SIZE]; char *buf = inbuf; int remspace = INPUT_BUFFER_SIZE-1; int bytes = -1; + tClient clientInfo = {0}; // Read from client while( (bytes = recv(Socket, buf, remspace, 0)) > 0 ) @@ -43,8 +73,12 @@ void Server_HandleClient(int Socket) start = inbuf; while( (eol = strchr(start, '\n')) ) { + char *ret; *eol = '\0'; - Server_ParseClientCommand(Socket, start); + ret = Server_ParseClientCommand(&clientInfo, start); + // `ret` is a string on the heap + send(Socket, ret, strlen(ret), 0); + free(ret); start = eol + 1; } @@ -55,7 +89,9 @@ void Server_HandleClient(int Socket) memcpy(inbuf, start, tailBytes); remspace -= tailBytes; if(remspace == 0) { - send(Socket, MSG_STR_TOO_LONG, sizeof(MSG_STR_TOO_LONG)); + send(Socket, MSG_STR_TOO_LONG, sizeof(MSG_STR_TOO_LONG), 0); + buf = inbuf; + remspace = INPUT_BUFFER_SIZE - 1; } } else { @@ -70,3 +106,70 @@ void Server_HandleClient(int Socket) return ; } } + +/** + * \brief Parses a client command and calls the required helper function + * \param Client Pointer to client state structure + */ +char *Server_ParseClientCommand(tClient *Client, char *CommandString) +{ + char *space, *args; + int i; + + // Split at first space + space = strchr(CommandString, ' '); + if(space == NULL) { + args = NULL; + } + else { + *space = '\0'; + args = space + 1; + } + + // Find command + for( i = 0; i < NUM_COMMANDS; i++ ) + { + if(strcmp(CommandString, gaServer_Commands[i].Name) == 0) + return gaServer_Commands[i].Function(Client, args); + } + + return strdup("400 Unknown Command\n"); +} + +// --- +// Commands +// --- +/** + * \brief Set client username + */ +char *Server_Cmd_USER(tClient *Client, char *Args) +{ + char *ret; + + // Debug! + if( gbDebugLevel ) + printf("Client %i authenticating as '%s'\n", Args); + + // Save username + if(Client->Username) + free(Client->Username); + Client->Username = strdup(Args); + + // Create a salt (that changes if the username is changed) + if(!Client->Salt) + Client->Salt = malloc(9); + Client->Salt[0] = 0x21 + (rand()&0x3F); + Client->Salt[1] = 0x21 + (rand()&0x3F); + Client->Salt[2] = 0x21 + (rand()&0x3F); + Client->Salt[3] = 0x21 + (rand()&0x3F); + Client->Salt[4] = 0x21 + (rand()&0x3F); + Client->Salt[5] = 0x21 + (rand()&0x3F); + Client->Salt[6] = 0x21 + (rand()&0x3F); + Client->Salt[7] = 0x21 + (rand()&0x3F); + + // "100 Salt xxxxXXXX\n" + ret = strdup("100 SALT xxxxXXXX\n"); + sprintf(ret, "100 SALT %s\n", Client->Salt); + + return ret; +} -- 2.20.1