diff --git a/src/client/main.c b/src/client/main.c
index ed7d1a22bbcf5fda3975fabf7548bb57174ea909..361d62dbe27fce61d5c89670197eccbc42276add 100644
--- a/src/client/main.c
+++ b/src/client/main.c
@@ -39,7 +39,7 @@ void	PrintAlign(int Row, int Col, int Width, const char *Left, char Pad1, const
 
  int	sendf(int Socket, const char *Format, ...);
  int	OpenConnection(const char *Host, int Port);
-void	Authenticate(int Socket);
+ int	Authenticate(int Socket);
 char	*trim(char *string);
  int	RunRegex(regex_t *regex, const char *string, int nMatches, regmatch_t *matches, const char *errorMessage);
 void	CompileRegex(regex_t *regex, const char *pattern, int flags);
@@ -193,9 +193,8 @@ int main(int argc, char *argv[])
 	}
 	#endif
 	
-	Authenticate(sock);
-	
-	if( i >= 0 )
+	// Check for a valid item ID and if so, authenticate
+	if( i >= 0 && Authenticate(sock) )
 	{	
 		// Dispense!
 		sendf(sock, "DISPENSE %s\n", gaItems[i].Ident);
@@ -222,6 +221,9 @@ int main(int argc, char *argv[])
 		case 500:
 			printf("Item failed to dispense, is the slot empty?\n");
 			break;
+		case 501:
+			printf("Dispense not possible (slot empty/permissions)\n");
+			break;
 		default:
 			printf("Unknown response code %i ('%s')\n", responseCode, buffer);
 			break;
@@ -233,6 +235,10 @@ int main(int argc, char *argv[])
 	return 0;
 }
 
+/**
+ * \brief Show item \a Index at (\a Col, \a Row)
+ * \note Part of the NCurses UI
+ */
 void ShowItemAt(int Row, int Col, int Width, int Index)
 {
 	 int	_x, _y, times;
@@ -253,6 +259,7 @@ void ShowItemAt(int Row, int Col, int Width, int Index)
 }
 
 /**
+ * \brief Render the NCurses UI
  */
 int ShowNCursesUI(void)
 {
@@ -369,7 +376,19 @@ int ShowNCursesUI(void)
 	return -1;
 }
 
-void PrintAlign(int Row, int Col, int Width, const char *Left, char Pad1, const char *Mid, char Pad2, const char *Right, ...)
+/**
+ * \brief Print a three-part string at the specified position (formatted)
+ * \note NCurses UI Helper
+ * 
+ * Prints \a Left on the left of the area, \a Right on the righthand side
+ * and \a Mid in the middle of the area. These are padded with \a Pad1
+ * between \a Left and \a Mid, and \a Pad2 between \a Mid and \a Right.
+ * 
+ * ::printf style format codes are allowed in \a Left, \a Mid and \a Right,
+ * and the arguments to these are read in that order.
+ */
+void PrintAlign(int Row, int Col, int Width, const char *Left, char Pad1,
+	const char *Mid, char Pad2, const char *Right, ...)
 {
 	 int	lLen, mLen, rLen;
 	 int	times;
@@ -482,12 +501,17 @@ int OpenConnection(const char *Host, int Port)
 	return sock;
 }
 
-void Authenticate(int Socket)
+/**
+ * \brief Authenticate with the server
+ * \return Boolean Failure
+ */
+int Authenticate(int Socket)
 {
 	struct passwd	*pwd;
 	char	buf[512];
 	 int	responseCode;
 	char	salt[32];
+	 int	i;
 	regmatch_t	matches[4];
 	
 	// Get user name
@@ -504,7 +528,7 @@ void Authenticate(int Socket)
 	switch( responseCode )
 	{
 	case 200:	// Authenticated, return :)
-		return ;
+		return 0;
 	case 401:	// Untrusted, attempt password authentication
 		sendf(Socket, "USER %s\n", pwd->pw_name);
 		printf("Using username %s\n", pwd->pw_name);
@@ -515,23 +539,31 @@ void Authenticate(int Socket)
 		// Expected format: 100 SALT <something> ...
 		// OR             : 100 User Set
 		RunRegex(&gSaltRegex, buf, 4, matches, "Malformed server response");
-		if( atoi(buf) != 100 ) {
-			exit(-1);	// ERROR
+		responseCode = atoi(buf);
+		if( responseCode != 100 ) {
+			fprintf(stderr, "Unknown repsonse code %i from server\n", responseCode);
+			return -1;	// ERROR
 		}
+		
+		// Check for salt
 		if( memcmp( buf+matches[2].rm_so, "SALT", matches[2].rm_eo - matches[2].rm_so) == 0) {
-			// Set salt
 			memcpy( salt, buf + matches[3].rm_so, matches[3].rm_eo - matches[3].rm_so );
 			salt[ matches[3].rm_eo - matches[3].rm_so ] = 0;
-//			printf("Salt: '%s'\n", salt);
 		}
 		
+		// Get password
 		fflush(stdout);
+		
+		// Give three attempts
+		for( i = 0; i < 3; i ++ )
 		{
 			 int	ofs = strlen(pwd->pw_name)+strlen(salt);
 			char	tmp[ofs+20];
 			char	*pass = getpass("Password: ");
 			uint8_t	h[20];
 			
+			// Create hash string
+			// <username><salt><hash>
 			strcpy(tmp, pwd->pw_name);
 			strcat(tmp, salt);
 			SHA1( (unsigned char*)pass, strlen(pass), h );
@@ -543,23 +575,35 @@ void Authenticate(int Socket)
 				h[ 0], h[ 1], h[ 2], h[ 3], h[ 4], h[ 5], h[ 6], h[ 7], h[ 8], h[ 9],
 				h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19]
 				);
-//			printf("Final hash: '%s'\n", buf);
 			fflush(stdout);	// Debug
-		}
 		
-		sendf(Socket, "PASS %s\n", buf);
-		recv(Socket, buf, 511, 0);
-		break;
+			// Send password
+			sendf(Socket, "PASS %s\n", buf);
+			recv(Socket, buf, 511, 0);
+		
+			responseCode = atoi(buf);
+			// Auth OK?
+			if( responseCode == 200 )	break;
+			// Bad username/password
+			if( responseCode == 401 )	continue;
+			
+			fprintf(stderr, "Unknown repsonse code %i from server\n", responseCode);
+			return -1;
+		}
+		return 2;	// 2 = Bad Password
+	
 	case 404:	// Bad Username
 		fprintf(stderr, "Bad Username '%s'\n", pwd->pw_name);
-		exit(-1);
+		return 1;
+	
 	default:
 		fprintf(stderr, "Unkown response code %i from server\n", responseCode);
 		printf("%s\n", buf);
-		exit(-1);
+		return -1;
 	}
 	
 	printf("%s\n", buf);
+	return 0;	// Seems OK
 }
 
 char *trim(char *string)
diff --git a/src/server/common.h b/src/server/common.h
index 0d97ad5f968e465f579757a773b3a5db140d1eb2..932c00662904f6af97744a36860e8cc3b8013873 100644
--- a/src/server/common.h
+++ b/src/server/common.h
@@ -52,6 +52,10 @@ struct sHandler
 {
 	char	*Name;
 	 int	(*Init)(int NConfig, tConfigItem *Config);
+	/**
+	 * \brief Check if an item can be dispensed
+	 * \return Boolean Failure
+	 */
 	 int	(*CanDispense)(int User, int ID);
 	 int	(*DoDispense)(int User, int ID);
 };
diff --git a/src/server/dispense.c b/src/server/dispense.c
index 884c541cf2ec342a2a747dc496aea0d9459fb138..09b2c4fdb60409d67e2055b0c691a377ee3577ad 100644
--- a/src/server/dispense.c
+++ b/src/server/dispense.c
@@ -20,14 +20,14 @@ int DispenseItem(int User, tItem *Item)
 	// Check if the dispense is possible
 	if( handler->CanDispense ) {
 		ret = handler->CanDispense( User, Item->ID );
-		if(!ret)	return 1;	// 1: Unknown Error
+		if(ret)	return 1;	// 1: Unable to dispense
 	}
 	
 	// Subtract the balance
 	ret = Transfer( User, GetUserID(">sales"), Item->Price, "" );
 	// What value should I use for this error?
 	// AlterBalance should return the final user balance
-	if(ret != 0)	return 2;	// 2: No balance
+	if(ret)	return 2;	// 2: No balance
 	
 	// Get username for debugging
 	username = GetUserName(User);
diff --git a/src/server/handler_coke.c b/src/server/handler_coke.c
index 3ab46c59d189f7c9279b33748cd8b39afa514097..ce6ff1f1a922af176aba411e6ec2e77e97ca04a2 100644
--- a/src/server/handler_coke.c
+++ b/src/server/handler_coke.c
@@ -77,9 +77,9 @@ int Coke_CanDispense(int User, int Item)
 	printf("Machine responded slot status '%s'\n", status);
 
 	if( strcmp(status, "full") == 0 )
-		return 1;
+		return 0;
 
-	return 0;
+	return 1;
 }
 
 /**
diff --git a/src/server/handler_snack.c b/src/server/handler_snack.c
index 2e7c4a6ef43f87649200171890664b3c47cc5a76..50a0d5352ebe1b2702a2ea44ebd8509afda81126 100644
--- a/src/server/handler_snack.c
+++ b/src/server/handler_snack.c
@@ -49,7 +49,7 @@ int Snack_CanDispense(int User, int Item)
 	
 	// Hmm... could we implement slot statuses?
 	
-	return 1;
+	return 0;
 }
 
 /**
diff --git a/src/server/server.c b/src/server/server.c
index e0fcafa64b2511173f37de18229901842690af14..bd451ee0dba762c5502f2a01543c7f1044f55305 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -466,6 +466,7 @@ char *Server_Cmd_ITEMINFO(tClient *Client, char *Args)
 char *Server_Cmd_DISPENSE(tClient *Client, char *Args)
 {
 	tItem	*item;
+	 int	ret;
 	if( !Client->bIsAuthed )	return strdup("401 Not Authenticated\n");
 
 	item = _GetItemFromString(Args);
@@ -473,7 +474,7 @@ char *Server_Cmd_DISPENSE(tClient *Client, char *Args)
 		return strdup("406 Bad Item ID\n");
 	}
 
-	switch( DispenseItem( Client->UID, item ) )
+	switch( ret = DispenseItem( Client->UID, item ) )
 	{
 	case 0:	return strdup("200 Dispense OK\n");
 	case 1:	return strdup("501 Unable to dispense\n");