--- /dev/null
+#!/bin/sh
+
+LD_LIBRARY_PATH=. ./dispsrv --itemsfile items.cfg -p 11020
--- /dev/null
+cokebank_basic
\ No newline at end of file
BIN := ../../cokebank.so
-OBJ := main.o
+OBJ := main.o bank.o
CPPFLAGS :=
CFLAGS := -Wall -Werror -g -fPIC
* for full details.
*/
#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "common.h"
enum {
FLAG_TYPEMASK = 0x03,
- USER_FLAG_NORMAL = 0x00,
- USER_FLAG_COKE = 0x01,
- USER_FLAG_WHEEL = 0x02,
- USER_FLAG_GOD = 0x03
+ USER_TYPE_NORMAL = 0x00,
+ USER_TYPE_COKE = 0x01,
+ USER_TYPE_WHEEL = 0x02,
+ USER_TYPE_GOD = 0x03
};
+// === GLOBALS ===
+tUser *gaBank_Users;
+ int giBank_NumUsers;
+FILE *gBank_File;
+
// === CODE ===
-int Bank_GetUserByUnixID(int UnixUID)
+int Bank_GetUserByUnixID(int UnixID)
{
+ int i;
// Expensive search :(
for( i = 0; i < giBank_NumUsers; i ++ )
{
}
}
+int Bank_GetUserUnixID(int ID)
+{
+ if( ID < 0 || ID >= giBank_NumUsers )
+ return -1;
+
+ return gaBank_Users[ID].UnixID;
+}
+
/**
* \brief Create a new user in our database
*/
// Commit to file
fseek(gBank_File, giBank_NumUsers*sizeof(gaBank_Users[0]), SEEK_SET);
- fwrite(gaBank_Users[giBank_NumUsers], sizeof(gaBank_Users[0]), 1, gBank_File);
+ fwrite(&gaBank_Users[giBank_NumUsers], sizeof(gaBank_Users[0]), 1, gBank_File);
// Increment count
giBank_NumUsers ++;
--- /dev/null
+/*
+ * 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.
+ */
+#ifndef _COKEBANK_COMMON_H_
+#define _COKEBANK_COMMON_H_
+
+typedef struct sUser {
+ int UnixID;
+ int Balance;
+ int Flags;
+} tUser;
+
+#endif
#include <stdio.h>
#include <pwd.h>
#include <string.h>
+#include "common.h"
// === IMPORTS ===
- int Bank_GetMinAllowedBalance(int ID);
- int Bank_GetUserBalance(int ID);
- int Bank_AlterUserBalance(int ID, int Delta);
- int Bank_GetUserByUnixID(int UnixID);
- int Bank_GetUserByName(const char *Name);
- int Bank_AddUser(int UnixID);
+extern int Bank_GetMinAllowedBalance(int ID);
+extern int Bank_GetUserBalance(int ID);
+extern int Bank_AlterUserBalance(int ID, int Delta);
+extern int Bank_GetUserByUnixID(int UnixID);
+extern int Bank_GetUserUnixID(int ID);
+extern int Bank_AddUser(int UnixID);
+extern FILE *gBank_File;
+extern tUser *gaBank_Users;
+extern int giBank_NumUsers;
// === PROTOTYPES ===
-void Init_Cokebank(void);
+void Init_Cokebank(const char *Argument);
int Transfer(int SourceUser, int DestUser, int Ammount, const char *Reason);
int GetBalance(int User);
char *GetUserName(int User);
/**
* \brief Load the cokebank database
*/
-void Init_Cokebank(void)
+void Init_Cokebank(const char *Argument)
{
-
+ gBank_File = fopen(Argument, "rb+");
+ if( !gBank_File ) {
+ gBank_File = fopen(Argument, "wb+");
+ }
+ if( !gBank_File ) {
+ perror("Opening coke bank");
+ }
+
+ fseek(gBank_File, 0, SEEK_END);
+ giBank_NumUsers = ftell(gBank_File) / sizeof(gaBank_Users[0]);
+ fseek(gBank_File, 0, SEEK_SET);
+ gaBank_Users = malloc( giBank_NumUsers * sizeof(gaBank_Users[0]) );
+ fread(gaBank_Users, sizeof(gaBank_Users[0]), giBank_NumUsers, gBank_File);
}
/**
*/
char *GetUserName(int User)
{
- return NULL;
+ struct passwd *pwd;
+ int unixid = Bank_GetUserUnixID(User);
+
+ if( unixid == -1 )
+ return strdup(">sales");
+
+ if( unixid == -2 )
+ return strdup(">liability");
+
+ pwd = getpwuid(unixid);
+ if( !pwd ) return NULL;
+
+ return strdup(pwd->pw_name);
}
/**
*/
int GetUserID(const char *Username)
{
- struct passwd *pwd;
- int ret;
+ int ret, uid;
- // Get user ID
- pwd = getpwnam(Username);
- if( !pwd ) {
- return -1;
+ if( strcmp(Username, ">sales") == 0 ) { // Pseudo account that sales are made into
+ uid = -1;
+ }
+ else if( strcmp(Username, ">liability") == 0 ) { // Pseudo acount that money is added from
+ uid = -2;
+ }
+ else {
+ struct passwd *pwd;
+ // Get user ID
+ pwd = getpwnam(Username);
+ if( !pwd ) return -1;
+ uid = pwd->pw_uid;
}
// Get internal ID (or create new user)
- ret = Bank_GetUserByUnixID(pwd->pw_uid);
+ ret = Bank_GetUserByUnixID(uid);
if( ret == -1 ) {
- ret = Bank_AddUser(pwd->pw_uid);
+ ret = Bank_AddUser(uid);
}
return ret;
*/
int GetUserAuth(const char *Username, const char *Password)
{
- if( strcmp(Username, "test") == 0 )
- return Bank_GetUserByName("test");
+ #if HACK_TPG_NOAUTH
+ if( strcmp(Username, "tpg") == 0 )
+ return GetUserID("tpg");
+ #endif
return -1;
}
if(!ret) return ret;
// Subtract the balance
- ret = AlterBalance( User, -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) {
Log_Error("Dispense failed after deducting cost (%s dispensing %s - %ic)",
username, item->Name, item->Price);
- AlterBalance( User, item->Price );
+ Transfer( GetUserID(">sales"), User, item->Price, "rollback" );
free( username );
return 1;
}
int Coke_InitHandler()
{
giCoke_SerialFD = open(gsCoke_SerialPort, O_RDWR);
- regexc(&gCoke_StatusRegex, "^$", REG_EXTENDED);
+ regcomp(&gCoke_StatusRegex, "^$", REG_EXTENDED);
return 0;
}
// Read the response
read(giCoke_SerialFD, tmp, sizeof(tmp)-1);
- regexec(&gCoke_StatusRegex, tmp, sizeof(matches)/sizeof(matches[0]), matches);
+ regexec(&gCoke_StatusRegex, tmp, sizeof(matches)/sizeof(matches[0]), matches, 0);
printf("s%i response '%s'\n", Item, tmp);
int Coke_DoDispense(int User, int Item)
{
char tmp[32];
+ regmatch_t matches[4];
// Sanity please
if( Item < 0 || Item > 6 ) return -1;
// Get status
read(giCoke_SerialFD, tmp, sizeof(tmp)-1);
- regexec(&gCoke_StatusRegex, tmp, sizeof(matches)/sizeof(matches[0]), matches);
+ regexec(&gCoke_StatusRegex, tmp, sizeof(matches)/sizeof(matches[0]), matches, 0);
printf("d%i response '%s'\n", Item, tmp);
#include "common.h"
// === IMPORTS ===
-extern void Init_Cokebank(void); // cokebank.c
+extern void Init_Cokebank(const char *Argument); // cokebank.c
extern void Load_Itemlist(void);
extern void Server_Start(void);
extern int giServer_Port;
// === GLOBALS ===
int giDebugLevel = 0;
+char *gsCokebankPath = "cokebank.db";
// === CODE ===
int main(int argc, char *argv[])
}
}
- Init_Cokebank();
+ Init_Cokebank(gsCokebankPath);
Load_Itemlist();