#!/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
404 Bad other username
406 Bad Item ID
500 Unknown Dispense Failure
+501 Action Rejected
== Item IDs ==
<item_id> represents the item ID
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 <count> <item_id> <item_id> ...\n
---- Get Item Information ---
-c ITEM_INFO <item_id>\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
--- Update balance ---
c ADD <user> <ammount> <reason>\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 <count> <item_id> <item_id> ...\n
+--- Get Item Information ---
+c ITEM_INFO <item_id>\n
+s 202 Item <item_id> <price> <description>\n
--- Set Balance ---
c SET <user> <balance> <reason>\n
s 200 Set OK\n or 403 Not allowed\n or 404 Bad User\n
#include <string.h>
#include "common.h"
+#define HACK_TPG_NOAUTH 1
+
// === IMPORTS ===
extern int Bank_GetMinAllowedBalance(int ID);
extern int Bank_GetUserBalance(int ID);
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, ...);
*
* 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
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <signal.h>
#include "common.h"
// === IMPORTS ===
char *gsCokebankPath = "cokebank.db";
// === CODE ===
+void sigint_handler()
+{
+ exit(0);
+}
+
int main(int argc, char *argv[])
{
int i;
Server_Start();
+ signal(SIGINT, sigint_handler);
+
return 0;
}
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);
{"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]))
// 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);
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);
}
}
if( !handler ) {
- return strdup("406 Bad Item ID\n");
+ return NULL;
}
// Find item
{
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)