From 05918a67e8509a2b2df6509039a801affd3444eb Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 21 Nov 2010 02:11:07 +0800 Subject: [PATCH] Cleanups of bugs and segfaults --- RunServerTest | 6 +++- proto.txt | 14 ++++---- src/cokebank_basic/main.c | 2 ++ src/server/common.h | 2 ++ src/server/dispense.c | 43 ++++++++++++------------- src/server/main.c | 8 +++++ src/server/server.c | 68 ++++++++++++++++++++++++++++++--------- 7 files changed, 97 insertions(+), 46 deletions(-) diff --git a/RunServerTest b/RunServerTest index d0c2fa3..d4f7d6e 100755 --- a/RunServerTest +++ b/RunServerTest @@ -1,3 +1,7 @@ #!/bin/sh -LD_LIBRARY_PATH=. ./dispsrv --itemsfile items.cfg -p 11020 +if [ "x$1" != "x" ]; then + LD_LIBRARY_PATH=. gdb --args ./dispsrv --itemsfile items.cfg -p 11020 +else + LD_LIBRARY_PATH=. ./dispsrv --itemsfile items.cfg -p 11020 +fi diff --git a/proto.txt b/proto.txt index e8d235c..8c5e1f6 100644 --- a/proto.txt +++ b/proto.txt @@ -16,6 +16,7 @@ All server responses are on one line and are prefixed by a three digit response 404 Bad other username 406 Bad Item ID 500 Unknown Dispense Failure +501 Action Rejected == Item IDs == represents the item ID @@ -35,12 +36,6 @@ c AUTOAUTH \n s 200 Auth OK\n or 401 Auth Failure\n or 401 Untrusted\n === Commands === ---- Get Item list --- -c ENUM_ITEMS\n -s 201 Items ...\n ---- Get Item Information --- -c ITEM_INFO \n -s 202 Item \n --- Dispense an item --- c DISPENSE \n s 200 Dispense OK\n or 402 Poor You\n or 500 Dispense Error\n or 406 Bad Item\n @@ -50,6 +45,13 @@ s 200 Give OK\n or 402 Poor You\n or 404 Bad User\n --- Update balance --- c ADD \n s 200 Add OK\n or 403 Not Coke\n or 404 Bad User\n + +--- Get Item list --- +c ENUM_ITEMS\n +s 201 Items ...\n +--- Get Item Information --- +c ITEM_INFO \n +s 202 Item \n --- Set Balance --- c SET \n s 200 Set OK\n or 403 Not allowed\n or 404 Bad User\n diff --git a/src/cokebank_basic/main.c b/src/cokebank_basic/main.c index 11b822c..fbc8f6e 100644 --- a/src/cokebank_basic/main.c +++ b/src/cokebank_basic/main.c @@ -13,6 +13,8 @@ #include #include "common.h" +#define HACK_TPG_NOAUTH 1 + // === IMPORTS === extern int Bank_GetMinAllowedBalance(int ID); extern int Bank_GetUserBalance(int ID); diff --git a/src/server/common.h b/src/server/common.h index 9105db1..d790c82 100644 --- a/src/server/common.h +++ b/src/server/common.h @@ -62,6 +62,8 @@ extern int giNumHandlers; extern int giDebugLevel; // === FUNCTIONS === +extern int DispenseItem(int User, tItem *Item); + // --- Logging --- extern void Log_Error(const char *Format, ...); extern void Log_Info(const char *Format, ...); diff --git a/src/server/dispense.c b/src/server/dispense.c index f851731..884c541 100644 --- a/src/server/dispense.c +++ b/src/server/dispense.c @@ -9,50 +9,47 @@ * * The core of the dispense system, I kinda like it :) */ -int DispenseItem(int User, int Item) +int DispenseItem(int User, tItem *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 = item->Handler; + handler = Item->Handler; // Check if the dispense is possible - ret = handler->CanDispense( User, item->ID ); - if(!ret) return ret; + if( handler->CanDispense ) { + ret = handler->CanDispense( User, Item->ID ); + if(!ret) return 1; // 1: Unknown Error + } // Subtract the balance - ret = Transfer( User, GetUserID(">sales"), item->Price, "" ); + 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 1; + if(ret != 0) return 2; // 2: No balance // 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); - Transfer( GetUserID(">sales"), User, item->Price, "rollback" ); - free( username ); - return 1; + if( handler->DoDispense ) { + ret = handler->DoDispense( User, Item->ID ); + if(ret) { + Log_Error("Dispense failed after deducting cost (%s dispensing %s - %ic)", + username, Item->Name, Item->Price); + Transfer( GetUserID(">sales"), User, Item->Price, "rollback" ); + free( username ); + return -1; // 1: Unkown Error again + } } // And log that it happened Log_Info("Dispensed %s (%i:%i) for %s [cost %i, balance %i cents]", - item->Name, handler->Name, item->ID, - username, item->Price, GetBalance(User) + Item->Name, handler->Name, Item->ID, + username, Item->Price, GetBalance(User) ); free( username ); - return 0; + return 0; // 0: EOK } diff --git a/src/server/main.c b/src/server/main.c index d327db3..76e720b 100644 --- a/src/server/main.c +++ b/src/server/main.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "common.h" // === IMPORTS === @@ -25,6 +26,11 @@ extern char* gsCoke_SerialPort; char *gsCokebankPath = "cokebank.db"; // === CODE === +void sigint_handler() +{ + exit(0); +} + int main(int argc, char *argv[]) { int i; @@ -70,6 +76,8 @@ int main(int argc, char *argv[]) Server_Start(); + signal(SIGINT, sigint_handler); + return 0; } diff --git a/src/server/server.c b/src/server/server.c index c9ab63e..9f59489 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -48,6 +48,7 @@ char *Server_Cmd_PASS(tClient *Client, char *Args); char *Server_Cmd_AUTOAUTH(tClient *Client, char *Args); char *Server_Cmd_ENUMITEMS(tClient *Client, char *Args); char *Server_Cmd_ITEMINFO(tClient *Client, char *Args); +char *Server_Cmd_DISPENSE(tClient *Client, char *Args); // --- Helpers --- void HexBin(uint8_t *Dest, char *Src, int BufSize); @@ -63,7 +64,8 @@ struct sClientCommand { {"PASS", Server_Cmd_PASS}, {"AUTOAUTH", Server_Cmd_AUTOAUTH}, {"ENUM_ITEMS", Server_Cmd_ENUMITEMS}, - {"ITEM_INFO", Server_Cmd_ITEMINFO} + {"ITEM_INFO", Server_Cmd_ITEMINFO}, + {"DISPENSE", Server_Cmd_DISPENSE} }; #define NUM_COMMANDS (sizeof(gaServer_Commands)/sizeof(gaServer_Commands[0])) @@ -302,6 +304,15 @@ char *Server_Cmd_PASS(tClient *Client, char *Args) // Read user's hash HexBin(clienthash, Args, HASH_LENGTH); + // TODO: Decrypt password passed + + Client->UID = GetUserAuth(Client->Username, ""); + + if( Client->UID != -1 ) { + Client->bIsAuthed = 1; + return strdup("200 Auth OK\n"); + } + if( giDebugLevel ) { int i; printf("Client %i: Password hash ", Client->ID); @@ -374,21 +385,15 @@ char *Server_Cmd_ENUMITEMS(tClient *Client, char *Args) return ret; } -/** - * \brief Fetch information on a specific item - */ -char *Server_Cmd_ITEMINFO(tClient *Client, char *Args) +tItem *_GetItemFromString(char *String) { - int retLen = 0; - char *ret; - tItem *item; tHandler *handler; - char *type = Args; - char *colon = strchr(Args, ':'); + char *type = String; + char *colon = strchr(String, ':'); int num, i; if( !colon ) { - return strdup("406 Bad Item ID\n"); + return NULL; } num = atoi(colon+1); @@ -404,7 +409,7 @@ char *Server_Cmd_ITEMINFO(tClient *Client, char *Args) } } if( !handler ) { - return strdup("406 Bad Item ID\n"); + return NULL; } // Find item @@ -412,23 +417,54 @@ char *Server_Cmd_ITEMINFO(tClient *Client, char *Args) { if( gaItems[i].Handler != handler ) continue; if( gaItems[i].ID != num ) continue; - item = &gaItems[i]; - break; + return &gaItems[i]; } + return NULL; +} + +/** + * \brief Fetch information on a specific item + */ +char *Server_Cmd_ITEMINFO(tClient *Client, char *Args) +{ + int retLen = 0; + char *ret; + tItem *item = _GetItemFromString(Args); + if( !item ) { return strdup("406 Bad Item ID\n"); } // Create return retLen = snprintf(NULL, 0, "202 Item %s:%i %i %s\n", - handler->Name, item->ID, item->Price, item->Name); + item->Handler->Name, item->ID, item->Price, item->Name); ret = malloc(retLen+1); sprintf(ret, "202 Item %s:%i %i %s\n", - handler->Name, item->ID, item->Price, item->Name); + item->Handler->Name, item->ID, item->Price, item->Name); return ret; } +char *Server_Cmd_DISPENSE(tClient *Client, char *Args) +{ + tItem *item; + if( !Client->bIsAuthed ) return strdup("401 Not Authenticated\n"); + + item = _GetItemFromString(Args); + if( !item ) { + return strdup("406 Bad Item ID\n"); + } + + switch( DispenseItem( Client->UID, item ) ) + { + case 0: return strdup("200 Dispense OK\n"); + case 1: return strdup("501 Unable to dispense\n"); + case 2: return strdup("402 Poor You\n"); + default: + return strdup("500 Dispense Error\n"); + } +} + // --- INTERNAL HELPERS --- // TODO: Move to another file void HexBin(uint8_t *Dest, char *Src, int BufSize) -- 2.20.1