diff --git a/items.cfg b/items.cfg
index aa381cd6e9622cddace1970a86e267337f18643b..b101b7e463806541fa61f00693a34ffc6c04420c 100644
--- a/items.cfg
+++ b/items.cfg
@@ -1,13 +1,15 @@
 
+# Type	ID	Price	Description
+
 # Drinks
-drink	0	70	Lemonade
-drink	1	71	solo++
-drink	2	70	Solo
-drink	3	70	Orange Foo
-drink	4	255	V Black
-drink	5	101	Coke Zero
-drink	6	96	Coke
+coke	0	70	Lemonade
+coke	1	71	solo++
+coke	2	70	Solo
+coke	3	70	Orange Foo
+coke	4	255	V Black
+coke	5	101	Coke Zero
+coke	6	96	Coke
 
 # Pseudo items
 pseudo	0	128	clue	# clue.flac
-pseudo	0	10	laserprint	# print 10 pages
+pseudo	1	10	laserprint	# print 10 pages
diff --git a/proto.txt b/proto.txt
index 0e2575b72c6d16995d49de1ffbd5856128213ffa..e8d235c27f8903c7b6581630fcd55a65d17f944d 100644
--- a/proto.txt
+++ b/proto.txt
@@ -40,7 +40,7 @@ c	ENUM_ITEMS\n
 s	201 Items <count> <item_id> <item_id> ...\n
 --- Get Item Information ---
 c	ITEM_INFO <item_id>\n
-s	202 Item <item_id> <price> "<description>"\n
+s	202 Item <item_id> <price> <description>\n
 --- Dispense an item ---
 c	DISPENSE <item_id>\n
 s	200 Dispense OK\n or 402 Poor You\n or 500 Dispense Error\n or 406 Bad Item\n
@@ -48,10 +48,10 @@ s	200 Dispense OK\n or 402 Poor You\n or 500 Dispense Error\n or 406 Bad Item\n
 c	GIVE <user> <ammount> <reason>\n
 s	200 Give OK\n or 402 Poor You\n or 404 Bad User\n
 --- Update balance ---
-c	ADD <user> <ammount> "<reason>"\n
+c	ADD <user> <ammount> <reason>\n
 s	200 Add OK\n or 403 Not Coke\n or 404 Bad User\n
 --- Set Balance ---
-c	SET <user> <balance> "<reason>"\n
+c	SET <user> <balance> <reason>\n
 s	200 Set OK\n or 403 Not allowed\n or 404 Bad User\n
 --- Get Users Balances ---
 c	ENUM_USERS[ <max balance>]\n
diff --git a/server/.gitignore b/server/.gitignore
deleted file mode 100644
index fec2672cba52504447d14c102487f0d881eb5f80..0000000000000000000000000000000000000000
--- a/server/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.[od]
-*~
-dispsrv
diff --git a/server/src/Makefile b/server/src/Makefile
deleted file mode 100644
index 256ba4241698558d7ec2d0c8869f65dd23cdefb7..0000000000000000000000000000000000000000
--- a/server/src/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# OpenDispense 2
-#
-
-OBJ := main.o server.o logging.o
-OBJ += dispense.o cokebank.o itemdb.o
-BIN := ../dispsrv
-
-LINKFLAGS := -g
-CPPFLAGS := 
-CFLAGS := -Wall -g
-
-.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
deleted file mode 100644
index 00d7d4f1d20def7c1e101fa97873f8548ac12139..0000000000000000000000000000000000000000
--- a/server/src/cokebank.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.
- * 
- * TODO: Make this a Dynamic Library and load it at runtime
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include "common.h"
-
-// === PROTOTYPES ===
-void	Init_Cokebank(void);
- int	AlterBalance(int User, int Delta);
- int	GetBalance(int User);
-char	*GetUserName(int User);
- int	GetUserID(const char *Username); 
-
-// === CODE ===
-/**
- * \brief Load the cokebank database
- */
-void Init_Cokebank(void)
-{
-	
-}
-
-/**
- * \brief Alters a user's balance by \a Delta
- */
-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;
-}
-
-/**
- * \brief Get the User ID of the named user
- */
-int GetUserID(const char *Username)
-{
-	return -1;
-}
-
diff --git a/server/src/common.h b/server/src/common.h
deleted file mode 100644
index a7e319df763118674551959f789cf892d91c195c..0000000000000000000000000000000000000000
--- a/server/src/common.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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"
-#define	DEFAULT_ITEM_FILE	"/etc/opendispense/items.cfg"
-
-// === HELPER MACROS ===
-#define _EXPSTR(x)	#x
-#define EXPSTR(x)	_EXPSTR(x)
-
-// === 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;
-extern int	giDebugLevel;
-
-// === 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);
-extern int	GetUserID(const char *Username);
-
-#endif
diff --git a/server/src/dispense.c b/server/src/dispense.c
deleted file mode 100644
index 5552277b7c93d8fa239ff9cbacbdbb13c131e228..0000000000000000000000000000000000000000
--- a/server/src/dispense.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- */
-#include "common.h"
-#include <stdlib.h>
-
-// === CODE ===
-/**
- * \brief Dispense an item for a user
- * 
- * The core of the dispense system, I kinda like it :)
- */
-int DispenseItem(int User, int Item)
-{
-	 int	ret;
-	tItem	*item;
-	tHandler	*handler;
-	char	*username;
-	
-	// Sanity check please?
-	if(Item < 0 || Item >= giNumItems)
-		return -1;
-	
-	// Get item pointers
-	item = &gaItems[Item];
-	handler = &gaHandlers[ item->Type ];
-	
-	// Check if the dispense is possible
-	ret = handler->CanDispense( User, item->ID );
-	if(!ret)	return ret;
-	
-	// Subtract the balance
-	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;
-	
-	// Get username for debugging
-	username = GetUserName(User);
-	
-	// Actually do the dispense
-	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;
-	}
-	
-	// And log that it happened
-	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
deleted file mode 100644
index 0ddcbf78fc758ae6f4255101210630e1005df84e..0000000000000000000000000000000000000000
--- a/server/src/itemdb.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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 <string.h>
-#include <ctype.h>
-#include "common.h"
-#include <regex.h>
-
-// === GLOBALS ===
- int	giNumItems = 0;
-tItem	*gaItems = NULL;
-tHandler	*gaHandlers = NULL;
-char	*gsItemListFile = DEFAULT_ITEM_FILE;
-
-// === PROTOTYPES ===
-void	Load_Itemlist(void);
-char	*trim(char *__str);
-
-// === CODE ===
-/**
- * \brief Read the item list from disk
- */
-void Load_Itemlist(void)
-{
-	FILE	*fp = fopen(gsItemListFile, "r");
-	char	buffer[BUFSIZ];
-	char	*line;
-	 int	lineNum = 0;
-	 int	i;
-	regex_t	regex;
-	regmatch_t	matches[5];
-	
-	i = regcomp(&regex, "^([a-zA-Z][a-zA-Z0-9]*)\\s+([0-9]+)\\s+([0-9]+)\\s+(.*)", REG_EXTENDED);
-	//i = regcomp(&regex, "\\(\\d+\\)", 0);//\\s+([0-9]+)\\s+([0-9]+)\\s+(.*)", 0);
-	if( i )
-	{
-		size_t	len = regerror(i, &regex, NULL, 0);
-		char	*errorStr = malloc(len);
-		regerror(i, &regex, errorStr, len);
-		fprintf(stderr, "Rexex compilation failed - %s\n", errorStr);
-		free(errorStr);
-		exit(-1);
-	}
-
-	// Error check
-	if(!fp) {
-		fprintf(stderr, "Unable to open item file '%s'\n", gsItemListFile);
-		perror("Unable to open item file");
-	}
-	
-	while( fgets(buffer, BUFSIZ, fp) )
-	{
-		char	*tmp;
-		char	*type, *desc;
-		 int	num, price;
-
-		lineNum ++;
-
-		// Remove comments
-		tmp = strchr(buffer, '#');
-		if(tmp)	*tmp = '\0';
-		tmp = strchr(buffer, ';');
-		if(tmp)	*tmp = '\0';
-		
-		// Trim whitespace
-		line = trim(buffer);
-		
-		if(strlen(line) == 0)	continue;
-		
-		// Pass regex over line
-		if( (i = regexec(&regex, line, 5, matches, 0)) ) {
-			size_t  len = regerror(i, &regex, NULL, 0);
-			char    *errorStr = malloc(len);
-			regerror(i, &regex, errorStr, len);
-			fprintf(stderr, "Syntax error on line %i of item file '%s'\n%s", lineNum, gsItemListFile, errorStr);
-			free(errorStr);
-			exit(-1);
-		}
-
-		// Read line data
-		type  = line + matches[1].rm_so;	line[ matches[1].rm_eo ] = '\0';
-		num   = atoi( line + matches[2].rm_so );
-		price = atoi( line + matches[3].rm_so );
-		desc  = line + matches[4].rm_so;
-		
-
-		printf("Item '%s' - %i cents, %s:%i\n", desc, price, type, num);
-	}	
-}
-
-char *trim(char *__str)
-{
-	char	*ret;
-	 int	i;
-	
-	while( isspace(*__str) )
-		__str++;
-	ret = __str;
-
-	i = strlen(ret);
-	while( i-- && isspace(__str[i]) ) {
-		__str[i] = '\0';
-	}
-
-	return ret;
-}
diff --git a/server/src/logging.c b/server/src/logging.c
deleted file mode 100644
index 51cc8d22c1b2d0a6d041a4292351e65ab9c90749..0000000000000000000000000000000000000000
--- a/server/src/logging.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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
deleted file mode 100644
index daf209f3efa52af33e9bb8059e95ab8c845ba9e7..0000000000000000000000000000000000000000
--- a/server/src/main.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 <string.h>
-#include "common.h"
-
-// === IMPORTS ===
-extern void	Init_Cokebank(void);	// cokebank.c
-extern void	Load_Itemlist(void);
-extern void	Server_Start(void);
-extern int	giServer_Port;
-extern char    *gsItemListFile;
-
-// === GLOBALS ===
- int	giDebugLevel = 0;
-
-// === CODE ===
-int main(int argc, char *argv[])
-{
-	 int	i;
-	
-	// Parse Arguments
-	for( i = 1; i < argc; i++ )
-	{
-		char	*arg = argv[i];
-		if( arg[0] == '-' && arg[1] != '-')
-		{
-			switch(arg[1])
-			{
-			case 'p':
-				giServer_Port = atoi(argv[++i]);
-				break;
-			case 'd':
-				giDebugLevel = atoi(argv[++i]);
-				break;
-			default:
-				// Usage Error?
-				break;
-			}
-		}
-		else if( arg[0] == '-' && arg[1] == '-' ) {
-			if( strcmp(arg, "--itemsfile") == 0 ) {
-				gsItemListFile = argv[++i];
-			}
-			else {
-				// Usage error?
-			}
-		}
-		else {
-			// Usage Error?
-		}
-	}
-	
-	Init_Cokebank();
-	
-	Load_Itemlist();
-	
-	Server_Start();
-	
-	return 0;
-}
-
diff --git a/server/src/server.c b/server/src/server.c
deleted file mode 100644
index 6bf0434dd83fedd0c2a8ef2b4d472c3ad2407566..0000000000000000000000000000000000000000
--- a/server/src/server.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * 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>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <string.h>
-
-#define MAX_CONNECTION_QUEUE	5
-#define INPUT_BUFFER_SIZE	256
-
-#define HASH_TYPE	SHA512
-#define HASH_LENGTH	64
-
-#define MSG_STR_TOO_LONG	"499 Command too long (limit "EXPSTR(INPUT_BUFFER_SIZE)")\n"
-
-// === TYPES ===
-typedef struct sClient
-{
-	 int	ID;	// Client ID
-	 
-	 int	bIsTrusted;	// Is the connection from a trusted host/port
-	
-	char	*Username;
-	char	Salt[9];
-	
-	 int	UID;
-	 int	bIsAuthed;
-}	tClient;
-
-// === PROTOTYPES ===
-void	Server_Start(void);
-void	Server_HandleClient(int Socket, int bTrusted);
-char	*Server_ParseClientCommand(tClient *Client, char *CommandString);
-// --- Commands ---
-char	*Server_Cmd_USER(tClient *Client, char *Args);
-char	*Server_Cmd_PASS(tClient *Client, char *Args);
-char	*Server_Cmd_AUTOAUTH(tClient *Client, char *Args);
-// --- Helpers ---
-void	HexBin(uint8_t *Dest, char *Src, int BufSize);
-
-// === 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},
-	{"PASS", Server_Cmd_PASS},
-	{"AUTOAUTH", Server_Cmd_AUTOAUTH}
-};
-#define NUM_COMMANDS	(sizeof(gaServer_Commands)/sizeof(gaServer_Commands[0]))
-
-// === CODE ===
-/**
- * \brief Open listenting socket and serve connections
- */
-void Server_Start(void)
-{
-	 int	server_socket, client_socket;
-	struct sockaddr_in	server_addr, client_addr;
-
-	// Create Server
-	server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-	if( server_socket < 0 ) {
-		fprintf(stderr, "ERROR: Unable to create server socket\n");
-		return ;
-	}
-	
-	// Make listen address
-	memset(&server_addr, 0, sizeof(server_addr));
-	server_addr.sin_family = AF_INET;	// Internet Socket
-	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);	// Listen on all interfaces
-	server_addr.sin_port = htons(giServer_Port);	// Port
-
-	// Bind
-	if( bind(server_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0 ) {
-		fprintf(stderr, "ERROR: Unable to bind to 0.0.0.0:%i\n", giServer_Port);
-		return ;
-	}
-	
-	// Listen
-	if( listen(server_socket, MAX_CONNECTION_QUEUE) < 0 ) {
-		fprintf(stderr, "ERROR: Unable to listen to socket\n");
-		return ;
-	}
-	
-	printf("Listening on 0.0.0.0:%i\n", giServer_Port);
-	
-	for(;;)
-	{
-		uint	len = sizeof(client_addr);
-		 int	bTrusted = 0;
-		
-		client_socket = accept(server_socket, (struct sockaddr *) &client_addr, &len);
-		if(client_socket < 0) {
-			fprintf(stderr, "ERROR: Unable to accept client connection\n");
-			return ;
-		}
-		
-		if(giDebugLevel >= 2) {
-			char	ipstr[INET_ADDRSTRLEN];
-			inet_ntop(AF_INET, &client_addr.sin_addr, ipstr, INET_ADDRSTRLEN);
-			printf("Client connection from %s:%i\n",
-				ipstr, ntohs(client_addr.sin_port));
-		}
-		
-		// Trusted Connections
-		if( ntohs(client_addr.sin_port) < 1024 )
-		{
-			// TODO: Make this runtime configurable
-			switch( ntohl( client_addr.sin_addr.s_addr ) )
-			{
-			case 0x7F000001:	// 127.0.0.1	localhost
-			//case 0x825E0D00:	// 130.95.13.0
-			case 0x825E0D12:	// 130.95.13.18	mussel
-			case 0x825E0D17:	// 130.95.13.23	martello
-				bTrusted = 1;
-				break;
-			default:
-				break;
-			}
-		}
-		
-		// TODO: Multithread this?
-		Server_HandleClient(client_socket, bTrusted);
-		
-		close(client_socket);
-	}
-}
-
-/**
- * \brief Reads from a client socket and parses the command strings
- * \param Socket	Client socket number/handle
- * \param bTrusted	Is the client trusted?
- */
-void Server_HandleClient(int Socket, int bTrusted)
-{
-	char	inbuf[INPUT_BUFFER_SIZE];
-	char	*buf = inbuf;
-	 int	remspace = INPUT_BUFFER_SIZE-1;
-	 int	bytes = -1;
-	tClient	clientInfo = {0};
-	
-	// Initialise Client info
-	clientInfo.ID = giServer_NextClientID ++;
-	clientInfo.bIsTrusted = bTrusted;
-	
-	// Read from client
-	/*
-	 * Notes:
-	 * - The `buf` and `remspace` variables allow a line to span several
-	 *   calls to recv(), if a line is not completed in one recv() call
-	 *   it is saved to the beginning of `inbuf` and `buf` is updated to
-	 *   the end of it.
-	 */
-	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')) )
-		{
-			char	*ret;
-			*eol = '\0';
-			ret = Server_ParseClientCommand(&clientInfo, start);
-			// `ret` is a string on the heap
-			send(Socket, ret, strlen(ret), 0);
-			free(ret);
-			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), 0);
-				buf = inbuf;
-				remspace = INPUT_BUFFER_SIZE - 1;
-			}
-		}
-		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 ;
-	}
-	
-	if(giDebugLevel >= 2) {
-		printf("Client %i: Disconnected\n", clientInfo.ID);
-	}
-}
-
-/**
- * \brief Parses a client command and calls the required helper function
- * \param Client	Pointer to client state structure
- * \param CommandString	Command from client (single line of the command)
- * \return Heap String to return to the client
- */
-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
- * 
- * Usage: USER <username>
- */
-char *Server_Cmd_USER(tClient *Client, char *Args)
-{
-	char	*ret;
-	
-	// Debug!
-	if( giDebugLevel )
-		printf("Client %i authenticating as '%s'\n", Client->ID, Args);
-	
-	// Save username
-	if(Client->Username)
-		free(Client->Username);
-	Client->Username = strdup(Args);
-	
-	#if USE_SALT
-	// Create a salt (that changes if the username is changed)
-	// Yes, I know, I'm a little paranoid, but who isn't?
-	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);
-	#else
-	ret = strdup("100 User Set\n");
-	#endif
-	return ret;
-}
-
-/**
- * \brief Authenticate as a user
- * 
- * Usage: PASS <hash>
- */
-char *Server_Cmd_PASS(tClient *Client, char *Args)
-{
-	uint8_t	clienthash[HASH_LENGTH] = {0};
-	
-	// Read user's hash
-	HexBin(clienthash, Args, HASH_LENGTH);
-	
-	if( giDebugLevel ) {
-		 int	i;
-		printf("Client %i: Password hash ", Client->ID);
-		for(i=0;i<HASH_LENGTH;i++)
-			printf("%02x", clienthash[i]&0xFF);
-		printf("\n");
-	}
-	
-	return strdup("401 Auth Failure\n");
-}
-
-/**
- * \brief Authenticate as a user without a password
- * 
- * Usage: AUTOAUTH <user>
- */
-char *Server_Cmd_AUTOAUTH(tClient *Client, char *Args)
-{
-	char	*spos = strchr(Args, ' ');
-	if(spos)	*spos = '\0';	// Remove characters after the ' '
-	
-	// Check if trusted
-	if( !Client->bIsTrusted ) {
-		if(giDebugLevel)
-			printf("Client %i: Untrusted client attempting to AUTOAUTH\n", Client->ID);
-		return strdup("401 Untrusted\n");
-	}
-	
-	// Get UID
-	Client->UID = GetUserID( Args );
-	if( Client->UID < 0 ) {
-		if(giDebugLevel)
-			printf("Client %i: Unknown user '%s'\n", Client->ID, Args);
-		return strdup("401 Auth Failure\n");
-	}
-	
-	if(giDebugLevel)
-		printf("Client %i: Authenticated as '%s' (%i)\n", Client->ID, Args, Client->UID);
-	
-	return strdup("200 Auth OK\n");
-}
-
-// --- INTERNAL HELPERS ---
-// TODO: Move to another file
-void HexBin(uint8_t *Dest, char *Src, int BufSize)
-{
-	 int	i;
-	for( i = 0; i < BufSize; i ++ )
-	{
-		uint8_t	val = 0;
-		
-		if('0' <= *Src && *Src <= '9')
-			val |= (*Src-'0') << 4;
-		else if('A' <= *Src && *Src <= 'F')
-			val |= (*Src-'A'+10) << 4;
-		else if('a' <= *Src && *Src <= 'f')
-			val |= (*Src-'a'+10) << 4;
-		else
-			break;
-		Src ++;
-		
-		if('0' <= *Src && *Src <= '9')
-			val |= (*Src-'0');
-		else if('A' <= *Src && *Src <= 'F')
-			val |= (*Src-'A'+10);
-		else if('a' <= *Src && *Src <= 'f')
-			val |= (*Src-'a'+10);
-		else
-			break;
-		Src ++;
-		
-		Dest[i] = val;
-	}
-	for( ; i < BufSize; i++ )
-		Dest[i] = 0;
-}
-
-/**
- * \brief Decode a Base64 value
- */
-int UnBase64(uint8_t *Dest, char *Src, int BufSize)
-{
-	uint32_t	val;
-	 int	i, j;
-	char	*start_src = Src;
-	
-	for( i = 0; i+2 < BufSize; i += 3 )
-	{
-		val = 0;
-		for( j = 0; j < 4; j++, Src ++ ) {
-			if('A' <= *Src && *Src <= 'Z')
-				val |= (*Src - 'A') << ((3-j)*6);
-			else if('a' <= *Src && *Src <= 'z')
-				val |= (*Src - 'a' + 26) << ((3-j)*6);
-			else if('0' <= *Src && *Src <= '9')
-				val |= (*Src - '0' + 52) << ((3-j)*6);
-			else if(*Src == '+')
-				val |= 62 << ((3-j)*6);
-			else if(*Src == '/')
-				val |= 63 << ((3-j)*6);
-			else if(!*Src)
-				break;
-			else if(*Src != '=')
-				j --;	// Ignore invalid characters
-		}
-		Dest[i  ] = (val >> 16) & 0xFF;
-		Dest[i+1] = (val >> 8) & 0xFF;
-		Dest[i+2] = val & 0xFF;
-		if(j != 4)	break;
-	}
-	
-	// Finish things off
-	if(i   < BufSize)
-		Dest[i] = (val >> 16) & 0xFF;
-	if(i+1 < BufSize)
-		Dest[i+1] = (val >> 8) & 0xFF;
-	
-	return Src - start_src;
-}