+
+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
+ */
+int DispenseDonate(int ActualUser, int User, int Ammount, const char *ReasonGiven)
+{
+ int ret;
+ char *srcName, *byName;
+
+ if( Ammount < 0 ) return 2;
+
+ ret = _Transfer( User, Bank_GetAcctByName(COKEBANK_DEBT_ACCT), Ammount, ReasonGiven );
+ if(ret) return 2;
+
+ byName = Bank_GetAcctName(ActualUser);
+ srcName = Bank_GetAcctName(User);
+
+ Log_Info("donate %i from %s by %s [balance %i] - %s",
+ Ammount, srcName, byName, Bank_GetBalance(User), ReasonGiven
+ );
+
+ free(byName);
+ free(srcName);
+
+ return 0;
+}
+
+// --- Internal Functions ---
+int _GetMinBalance(int Account)
+{
+ int flags = Bank_GetFlags(Account);
+
+ // Evil little piece of HACK:
+ // root's balance cannot be changed by any of the above functions
+ // - Stops dispenses as root by returning insufficent balance.
+ {
+ char *username = Bank_GetAcctName(Account);
+ if( strcmp(username, "root") == 0 )
+ {
+ free(username);
+ return INT_MAX;
+ }
+ free(username);
+ }
+
+ // - Internal accounts have no lower bound
+ if( flags & USER_FLAG_INTERNAL ) return INT_MIN;
+
+ // Admin to -$10
+ if( flags & USER_FLAG_ADMIN ) return -1000;
+
+ // Coke to -$5
+ if( flags & USER_FLAG_COKE ) return -500;
+
+ // Anyone else, non-negative
+ return 0;
+}
+
+/**
+ * \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 0;
+ }
+ else
+ {
+ if( Bank_GetBalance(Destination) - Ammount < _GetMinBalance(Destination) )
+ 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);
+}