Moar server work
authorJohn Hodge <[email protected]>
Sun, 11 Jul 2010 11:22:59 +0000 (19:22 +0800)
committerJohn Hodge <[email protected]>
Sun, 11 Jul 2010 11:22:59 +0000 (19:22 +0800)
server/src/Makefile
server/src/common.h
server/src/main.c
server/src/server.c

index 9df8c06..3fee2f0 100644 (file)
@@ -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 := 
index 3e47fb7..f310e9a 100644 (file)
 // === 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
index 5b8e8b5..2d9f70e 100644 (file)
@@ -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();
        
index 6d1ed5d..8c87c65 100644 (file)
 #include <stdlib.h>
 #include "common.h"
 #include <sys/socket.h>
+#include <string.h>
 
 #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;
+}

UCC git Repository :: git.ucc.asn.au