Fixes to bugs pointed by [BOB]
authorJohn Hodge <[email protected]>
Wed, 2 Feb 2011 13:24:15 +0000 (21:24 +0800)
committerJohn Hodge <[email protected]>
Wed, 2 Feb 2011 13:24:15 +0000 (21:24 +0800)
- Error in SQL code (assumed time_t was 64-bits)
- Lack of `dispense acct =` (still needs client support)
- Bumped the coke read timeout down
- Made balance alter happen after the dispense

cokebank.db [new symlink]
cokebank.so [new symlink]
src/cokebank_sqlite/main.c
src/server/common.h
src/server/dispense.c
src/server/handler_coke.c
src/server/server.c

diff --git a/cokebank.db b/cokebank.db
new file mode 120000 (symlink)
index 0000000..0508c2f
--- /dev/null
@@ -0,0 +1 @@
+cokebank_sqlite.db
\ No newline at end of file
diff --git a/cokebank.so b/cokebank.so
new file mode 120000 (symlink)
index 0000000..4548509
--- /dev/null
@@ -0,0 +1 @@
+cokebank_sqlite.so
\ No newline at end of file
index c112260..0d5e139 100644 (file)
@@ -7,6 +7,7 @@
  * This file is licenced under the 3-clause BSD Licence. See the file
  * COPYING for full details.
  */
+#include <inttypes.h>
 #include <stdlib.h>
 #include <limits.h>
 #include <stdio.h>
@@ -386,7 +387,7 @@ tAcctIterator *Bank_Iterator(int FlagMask, int FlagValues, int Flags, int MinMax
        query = mkstr("SELECT acct_id FROM accounts WHERE 1=1"
                "%s%s%s%s%s"    // Flags
                "%s%i"  // Balance
-               "%sdatetime(%lli,'unixepoch')"  // Last seen
+               "%sdatetime(%"PRIu64",'unixepoch')"     // Last seen
                "%s%s"  // Sort and direction
                ,
                MAP_FLAG("acct_is_coke", USER_FLAG_COKE),
@@ -395,7 +396,7 @@ tAcctIterator *Bank_Iterator(int FlagMask, int FlagValues, int Flags, int MinMax
                MAP_FLAG("acct_is_internal", USER_FLAG_INTERNAL),
                MAP_FLAG("acct_is_disabled", USER_FLAG_DISABLED),
                balanceClause, MinMaxBalance,
-               lastSeenClause, LastSeen,
+               lastSeenClause, (uint64_t)LastSeen,
                orderClause, revSort
                );
        //printf("query = \"%s\"\n", query);
index 8aaf4c0..06a9100 100644 (file)
@@ -81,6 +81,7 @@ extern char   *mkstr(const char *Format, ...);
 extern int     DispenseItem(int ActualUser, int User, tItem *Item);
 extern int     DispenseGive(int ActualUser, int SrcUser, int DestUser, int Ammount, const char *ReasonGiven);
 extern int     DispenseAdd(int ActualUser, int User, int Ammount, const char *ReasonGiven);
+extern int     DispenseSet(int ActualUser, int User, int Balance, const char *ReasonGiven);
 extern int     DispenseDonate(int ActualUser, int User, int Ammount, const char *ReasonGiven);
 
 // --- Logging ---
index 09fe567..52d978c 100644 (file)
@@ -5,6 +5,7 @@
 #include <limits.h>
 
  int   _GetMinBalance(int Account);
+ int   _CanTransfer(int Source, int Destination, int Ammount);
  int   _Transfer(int Source, int Destination, int Ammount, const char *Reason);
 
 // === CODE ===
  */
 int DispenseItem(int ActualUser, int User, tItem *Item)
 {
-        int    ret;
+        int    ret, salesAcct;
        tHandler        *handler;
        char    *username, *actualUsername;
-       char    *reason;
+       
+       salesAcct = Bank_GetAcctByName(COKEBANK_SALES_ACCT);
+
+       // Check if the user can afford it
+       if( Item->Price && !_CanTransfer(User, salesAcct, Item->Price) )
+       {
+               return 2;       // 2: No balance
+       }
        
        handler = Item->Handler;
        
@@ -27,16 +35,6 @@ int DispenseItem(int ActualUser, int User, tItem *Item)
                ret = handler->CanDispense( User, Item->ID );
                if(ret) return 1;       // 1: Unable to dispense
        }
-
-       // Subtract the balance
-       if( Item->Price )
-       {
-               reason = mkstr("Dispense - %s:%i %s", handler->Name, Item->ID, Item->Name);
-               if( !reason )   reason = Item->Name;    // TODO: Should I instead return an error?
-               ret = _Transfer( User, Bank_GetAcctByName(COKEBANK_SALES_ACCT), Item->Price, reason);
-               free(reason);
-               if(ret) return 2;       // 2: No balance
-       }
        
        // Get username for debugging
        username = Bank_GetAcctName(User);
@@ -45,15 +43,22 @@ int DispenseItem(int ActualUser, int User, tItem *Item)
        if( handler->DoDispense ) {
                ret = handler->DoDispense( User, Item->ID );
                if(ret) {
-                       Log_Error("Dispense failed after deducting cost (%s dispensing %s - %ic)",
+                       Log_Error("Dispense failed (%s dispensing '%s' - %ic)",
                                username, Item->Name, Item->Price);
-                       if( Item->Price )
-                               _Transfer( Bank_GetAcctByName(COKEBANK_SALES_ACCT), User, Item->Price, "rollback" );
                        free( username );
-                       return -1;      // 1: Unkown Error again
+                       return -1;      // 1: Unknown Error again
                }
        }
        
+       // Take away money
+       if( Item->Price )
+       {
+               char    *reason;
+               reason = mkstr("Dispense - %s:%i %s", handler->Name, Item->ID, Item->Name);
+               _Transfer( User, salesAcct, Item->Price, reason );
+               free(reason);
+       }
+       
        actualUsername = Bank_GetAcctName(ActualUser);
        
        // And log that it happened
@@ -123,6 +128,26 @@ int DispenseAdd(int ActualUser, int User, int Ammount, const char *ReasonGiven)
        return 0;
 }
 
+int DispenseSet(int ActualUser, int User, int Balance, const char *ReasonGiven)
+{
+        int    curBal = Bank_GetBalance(User);
+       char    *byName, *dstName;
+       
+       _Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Balance-curBal, ReasonGiven );
+       
+       byName = Bank_GetAcctName(ActualUser);
+       dstName = Bank_GetAcctName(User);
+       
+       Log_Info("set balance of %s to %i by %s [balance %i] - %s",
+               dstName, Balance, byName, Bank_GetBalance(User), ReasonGiven
+               );
+       
+       free(byName);
+       free(dstName);
+       
+       return 0;
+}
+
 /**
  * \brief Donate money to the club
  */
@@ -167,18 +192,27 @@ int _GetMinBalance(int Account)
        return 0;
 }
 
-int _Transfer(int Source, int Destination, int Ammount, const char *Reason)
+/**
+ * \brief Check if a transfer is possible
+ */
+int _CanTransfer(int Source, int Destination, int Ammount)
 {
        if( Ammount > 0 )
        {
                if( Bank_GetBalance(Source) + Ammount < _GetMinBalance(Source) )
-                       return 1;
+                       return 0;
        }
        else
        {
                if( Bank_GetBalance(Destination) - Ammount < _GetMinBalance(Destination) )
-                       return 1;
+                       return 0;
        }
-       
+       return 1;
+}
+
+int _Transfer(int Source, int Destination, int Ammount, const char *Reason)
+{
+       if( !_CanTransfer(Source, Destination, Ammount) )
+               return 1;
        return Bank_Transfer(Source, Destination, Ammount, Reason);
 }
index a6b3cb9..4043cfc 100644 (file)
@@ -18,6 +18,8 @@
 #include <fcntl.h>
 #include <regex.h>
 
+#define READ_TIMEOUT   2       // 2 seconds for ReadChar
+
 // === IMPORTS ===
 
 // === PROTOTYPES ===
@@ -191,7 +193,7 @@ char ReadChar()
         int    ret;
        struct timeval  timeout;
        
-       timeout.tv_sec = 5;     // 5 second timeout
+       timeout.tv_sec = READ_TIMEOUT;
        timeout.tv_usec = 0;
        
        FD_ZERO(&readfs);
index 9c36f3d..ca4aceb 100644 (file)
@@ -771,6 +771,75 @@ void Server_Cmd_ADD(tClient *Client, char *Args)
        }
 }
 
+void Server_Cmd_SET(tClient *Client, char *Args)
+{
+       char    *user, *ammount, *reason;
+        int    uid, iAmmount;
+       
+       if( !Client->bIsAuthed ) {
+               sendf(Client->Socket, "401 Not Authenticated\n");
+               return ;
+       }
+
+       user = Args;
+
+       ammount = strchr(Args, ' ');
+       if( !ammount ) {
+               sendf(Client->Socket, "407 Invalid Argument, expected 3 parameters, 1 encountered\n");
+               return ;
+       }
+       *ammount = '\0';
+       ammount ++;
+
+       reason = strchr(ammount, ' ');
+       if( !reason ) {
+               sendf(Client->Socket, "407 Invalid Argument, expected 3 parameters, 2 encountered\n");
+               return ;
+       }
+       *reason = '\0';
+       reason ++;
+
+       // Check user permissions
+       if( !(Bank_GetFlags(Client->UID) & USER_FLAG_ADMIN)  ) {
+               sendf(Client->Socket, "403 Not an admin\n");
+               return ;
+       }
+
+       // Get recipient
+       uid = Bank_GetAcctByName(user);
+       if( uid == -1 ) {
+               sendf(Client->Socket, "404 Invalid user\n");
+               return ;
+       }
+       
+       // You can't alter an internal account
+       if( Bank_GetFlags(uid) & USER_FLAG_INTERNAL ) {
+               sendf(Client->Socket, "404 Invalid user\n");
+               return ;
+       }
+
+       // Parse ammount
+       iAmmount = atoi(ammount);
+       if( iAmmount == 0 && ammount[0] != '0' ) {
+               sendf(Client->Socket, "407 Invalid Argument\n");
+               return ;
+       }
+
+       // Do give
+       switch( DispenseSet(Client->UID, uid, iAmmount, reason) )
+       {
+       case 0:
+               sendf(Client->Socket, "200 Add OK\n");
+               return ;
+       case 2:
+               sendf(Client->Socket, "402 Poor Guy\n");
+               return ;
+       default:
+               sendf(Client->Socket, "500 Unknown error\n");
+               return ;
+       }
+}
+
 void Server_Cmd_ENUMUSERS(tClient *Client, char *Args)
 {
         int    i, numRet = 0;

UCC git Repository :: git.ucc.asn.au