+
+/**
+ * \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_DONATE_ACCT,1), 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;
+}
+
+int DispenseUpdateItem(int User, tItem *Item, const char *NewName, int NewPrice)
+{
+ char *username;
+
+ // Sanity checks
+ if( NewPrice < 0 ) return 2;
+ if( !Item ) return 2;
+ if( strlen(NewName) < 1 ) return 2;
+
+ // Update the item
+ free(Item->Name);
+ Item->Name = strdup(NewName);
+ Item->Price = NewPrice;
+
+ username = Bank_GetAcctName(User);
+
+ Log_Info("item %s:%i updated to '%s' %i by %s",
+ Item->Handler->Name, Item->ID,
+ NewName, NewPrice, username
+ );
+
+ free(username);
+
+ // Update item file
+ Items_UpdateFile();
+
+ 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 -$50
+// if( flags & USER_FLAG_ADMIN ) return -5000;
+
+ // Coke to -$20
+// if( flags & USER_FLAG_COKE ) return -2000;
+
+ // 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);
+}
+
+int _GetSalesAcct(tItem *Item)
+{
+ char string[sizeof(COKEBANK_SALES_PREFIX)+strlen(Item->Handler->Name)];
+ strcpy(string, COKEBANK_SALES_PREFIX);
+ strcat(string, Item->Handler->Name);
+ return Bank_GetAcctByName(string, 1);
+}