From bb42916dda07ba08b2cf3cba590fa0f74ec27333 Mon Sep 17 00:00:00 2001
From: John Hodge <tpg@mutabah.net>
Date: Sun, 11 Jul 2010 18:24:22 +0800
Subject: [PATCH] Skeleton server code (compiles, just doesn't do anything)

---
 server/src/Makefile   | 20 ++++++++++++
 server/src/cokebank.c | 40 ++++++++++++++++++++++++
 server/src/common.h   | 58 ++++++++++++++++++++++++++++++++++
 server/src/dispense.c | 46 +++++++++++++++++++++++++++
 server/src/itemdb.c   | 19 ++++++++++++
 server/src/logging.c  | 19 ++++++++++++
 server/src/main.c     | 30 ++++++++++++++++++
 server/src/server.c   | 72 +++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 304 insertions(+)
 create mode 100644 server/src/Makefile
 create mode 100644 server/src/cokebank.c
 create mode 100644 server/src/common.h
 create mode 100644 server/src/dispense.c
 create mode 100644 server/src/itemdb.c
 create mode 100644 server/src/logging.c
 create mode 100644 server/src/main.c
 create mode 100644 server/src/server.c

diff --git a/server/src/Makefile b/server/src/Makefile
new file mode 100644
index 0000000..9df8c06
--- /dev/null
+++ b/server/src/Makefile
@@ -0,0 +1,20 @@
+# OpenDispense 2
+#
+
+OBJ := main.o logging.o dispense.o cokebank.o itemdb.o
+BIN := ../dispsrv
+
+LINKFLAGS := 
+CPPFLAGS := 
+CFLAGS := -Wall
+
+.PHONY: all clean
+
+all: $(BIN)
+
+clean:
+	$(RM) $(BIN) $(OBJ)
+
+$(BIN): $(OBJ)
+	$(CC) -o $(BIN) $(LINKFLAGS) $(OBJ)
+
diff --git a/server/src/cokebank.c b/server/src/cokebank.c
new file mode 100644
index 0000000..cb29eaf
--- /dev/null
+++ b/server/src/cokebank.c
@@ -0,0 +1,40 @@
+/*
+ * OpenDispense 2 
+ * UCC (University [of WA] Computer Club) Electronic Accounting System
+ *
+ * cokebank.c - Coke-Bank management
+ *
+ * This file is licenced under the 3-clause BSD Licence. See the file COPYING
+ * for full details.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include "common.h"
+
+// === CODE ===
+int AlterBalance(int User, int Delta)
+{
+	return 0;
+}
+
+/**
+ * \brief Get the balance of the passed user
+ */
+int GetBalance(int User)
+{
+	return 0;
+}
+
+/**
+ * \brief Return the name the passed user
+ */
+char *GetUserName(int User)
+{
+	return NULL;
+}
+
+int GetUserID(const char *Username)
+{
+	return 0;
+}
+
diff --git a/server/src/common.h b/server/src/common.h
new file mode 100644
index 0000000..3e47fb7
--- /dev/null
+++ b/server/src/common.h
@@ -0,0 +1,58 @@
+/*
+ * OpenDispense2
+ *
+ * This code is published under the terms of the Acess licence.
+ * See the file COPYING for details.
+ *
+ * common.h - Core Header
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+// === CONSTANTS ===
+#define	DEFAULT_CONFIG_FILE	"/etc/opendispense/main.cfg"
+
+// === STRUCTURES ===
+typedef struct sItem	tItem;
+struct sItem
+{
+	char	*Name;	//!< Display Name
+	 int	Price;	//!< Price
+	
+	short	Type;	//!< References an action
+	short	ID;	//!< Item ID
+};
+
+typedef struct sUser	tUser;
+struct sUser
+{
+	 int	ID;		//!< User ID (LDAP ID)
+	 int	Balance;	//!< Balance in cents
+	 int	Bytes;	//!< Traffic Usage
+	char	Name[];	//!< Username
+};
+
+typedef struct sHandler	tHandler;
+struct sHandler
+{
+	char	*Name;
+	 int	(*CanDispense)(int User, int ID);
+	 int	(*DoDispense)(int User, int ID);
+};
+
+// === GLOBALS ===
+extern tItem	*gaItems;
+extern int	giNumItems;
+extern tHandler	*gaHandlers;
+
+// === FUNCTIONS ===
+// --- Logging ---
+extern void	Log_Error(const char *Format, ...);
+extern void	Log_Info(const char *Format, ...);
+
+// --- Cokebank Functions ---
+extern int	AlterBalance(int User, int Ammount);
+extern int	GetBalance(int User);
+extern char	*GetUserName(int User);
+
+#endif
diff --git a/server/src/dispense.c b/server/src/dispense.c
new file mode 100644
index 0000000..ee07bb9
--- /dev/null
+++ b/server/src/dispense.c
@@ -0,0 +1,46 @@
+/**
+ */
+#include "common.h"
+#include <stdlib.h>
+
+// === CODE ===
+int DispenseItem(int User, int Item)
+{
+	 int	ret;
+	tItem	*item;
+	tHandler	*handler;
+	char	*username;
+	
+	if(Item < 0 || Item >= giNumItems)
+		return -1;
+	
+	item = &gaItems[Item];
+	handler = &gaHandlers[ item->Type ];
+	
+	username = GetUserName(User);
+	
+	ret = handler->CanDispense( User, item->ID );
+	if(!ret)	return ret;
+	
+	ret = AlterBalance( User, -item->Price );
+	// What value should I use for this error?
+	// AlterBalance should return the final user balance
+	if(ret == 0)	return 1;
+	
+	ret = handler->DoDispense( User, item->ID );
+	if(ret) {
+		Log_Error("Dispense failed after deducting cost (%s dispensing %s - %ic)",
+			username, item->Name, item->Price);
+		AlterBalance( User, item->Price );
+		free( username );
+		return 1;
+	}
+	
+	Log_Info("Dispensed %s (%i:%i) for %s [cost %i, balance %i cents]",
+		item->Name, item->Type, item->ID,
+		username, item->Price, GetBalance(User)
+		);
+	
+	free( username );
+	return 0;
+}
diff --git a/server/src/itemdb.c b/server/src/itemdb.c
new file mode 100644
index 0000000..116b047
--- /dev/null
+++ b/server/src/itemdb.c
@@ -0,0 +1,19 @@
+/*
+ * OpenDispense 2 
+ * UCC (University [of WA] Computer Club) Electronic Accounting System
+ *
+ * itemdb.c - Dispense Item Databse
+ *
+ * This file is licenced under the 3-clause BSD Licence. See the file COPYING
+ * for full details.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include "common.h"
+
+// === GLOBALS ===
+ int	giNumItems = 0;
+tItem	*gaItems = NULL;
+tHandler	*gaHandlers = NULL;
+
+// === CODE ===
diff --git a/server/src/logging.c b/server/src/logging.c
new file mode 100644
index 0000000..51cc8d2
--- /dev/null
+++ b/server/src/logging.c
@@ -0,0 +1,19 @@
+/*
+ * OpenDispense2
+ *
+ * logging.c - Debug/Logging Routines
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include "common.h"
+
+// === CODE ==
+void Log_Error(const char *Format, ...)
+{
+	
+}
+
+void Log_Info(const char *Format, ...)
+{
+}
+
diff --git a/server/src/main.c b/server/src/main.c
new file mode 100644
index 0000000..5b8e8b5
--- /dev/null
+++ b/server/src/main.c
@@ -0,0 +1,30 @@
+/*
+ * OpenDispense 2 
+ * UCC (University [of WA] Computer Club) Electronic Accounting System
+ *
+ * main.c - Initialisation Code
+ *
+ * This file is licenced under the 3-clause BSD Licence. See the file
+ * COPYING for full details.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include "common.h"
+
+// === IMPORTS ===
+extern void	Init_Cokebank(void);
+extern void	Load_Itemlist(void);
+extern void	Server_Start(void);
+
+// === CODE ===
+int main(int argc, char *argv[])
+{
+	Cokebank_Init();
+	
+	Load_Itemlist();
+	
+	Server_Start();
+	
+	return 0;
+}
+
diff --git a/server/src/server.c b/server/src/server.c
new file mode 100644
index 0000000..6d1ed5d
--- /dev/null
+++ b/server/src/server.c
@@ -0,0 +1,72 @@
+/*
+ * OpenDispense 2 
+ * UCC (University [of WA] Computer Club) Electronic Accounting System
+ *
+ * server.c - Client Server Code
+ *
+ * This file is licenced under the 3-clause BSD Licence. See the file
+ * COPYING for full details.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "common.h"
+#include <sys/socket.h>
+
+#define MAX_CONNECTION_QUEUE	5
+#define INPUT_BUFFER_SIZE	100
+
+#define MSG_STR_TOO_LONG	"499 Malformed Command String"
+
+// === GLOBALS ===
+ int	giServer_Port = 1020;
+
+// === CODE ===
+void Server_Start(void)
+{
+	// Create Server
+}
+
+void Server_HandleClient(int Socket)
+{
+	char	inbuf[INPUT_BUFFER_SIZE];
+	char	*buf = inbuf;
+	 int	remspace = INPUT_BUFFER_SIZE-1;
+	 int	bytes = -1;
+		
+	// Read from client
+	while( (bytes = recv(Socket, buf, remspace, 0)) > 0 )
+	{
+		char	*eol, *start;
+		buf[bytes] = '\0';	// Allow us to use stdlib string functions on it
+		
+		// Split by lines
+		start = inbuf;
+		while( (eol = strchr(start, '\n')) )
+		{
+			*eol = '\0';
+			Server_ParseClientCommand(Socket, start);
+			start = eol + 1;
+		}
+		
+		// Check if there was an incomplete line
+		if( *start != '\0' ) {
+			 int	tailBytes = bytes - (start-buf);
+			// Roll back in buffer
+			memcpy(inbuf, start, tailBytes);
+			remspace -= tailBytes;
+			if(remspace == 0) {
+				send(Socket, MSG_STR_TOO_LONG, sizeof(MSG_STR_TOO_LONG));
+			}
+		}
+		else {
+			buf = inbuf;
+			remspace = INPUT_BUFFER_SIZE - 1;
+		}
+	}
+	
+	// Check for errors
+	if( bytes < 0 ) {
+		fprintf(stderr, "ERROR: Unable to recieve from client on socket %i\n", Socket);
+		return ;
+	}
+}
-- 
GitLab