Abstraced updates to the cokebank file to a function
[tpg/opendispense2.git] / src / cokebank_basic / bank.c
index 55a1957..56db422 100644 (file)
 #include <string.h>
 #include <limits.h>
 #include <pwd.h>
+#include <grp.h>
 #include "common.h"
 
+#define USE_UNIX_GROUPS        1
+
 // === PROTOTYPES ===
 static int     GetUnixID(const char *Username);
 
@@ -24,6 +27,19 @@ tUser        *gaBank_Users;
 FILE   *gBank_File;
 
 // === CODE ===
+static int Bank_int_WriteEntry(int ID)
+{
+       if( ID < 0 || ID >= giBank_NumUsers ) {
+               return -1;
+       }
+       
+       // Commit to file
+       fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
+       fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
+       
+       return 0;
+}
+
 int Bank_GetUserByName(const char *Username)
 {
         int    i, uid;
@@ -51,58 +67,107 @@ int Bank_GetUserBalance(int ID)
 int Bank_GetUserFlags(int ID)
 {
        if( ID < 0 || ID >= giBank_NumUsers )
-               return INT_MIN;
+               return -1;
+
+       // root
+       if( gaBank_Users[ID].UnixID == 0 ) {
+               gaBank_Users[ID].Flags |= USER_FLAG_WHEEL|USER_FLAG_COKE;
+       }
+
+       #if USE_UNIX_GROUPS
+       // TODO: Implement checking the PAM groups and status instead, then
+       // fall back on the database. (and update if there is a difference)
+       if( gaBank_Users[ID].UnixID > 0 )
+       {
+               struct passwd   *pwd;
+               struct group    *grp;
+                int    i;
+               
+               // Get username
+               pwd = getpwuid( gaBank_Users[ID].UnixID );
+               
+               // Check for additions to the "coke" group
+               grp = getgrnam("coke");
+               if( grp ) {
+                       for( i = 0; grp->gr_mem[i]; i ++ )
+                       {
+                               if( strcmp(grp->gr_mem[i], pwd->pw_name) == 0 ) {
+                                       gaBank_Users[ID].Flags |= USER_FLAG_COKE;
+                                       break ;
+                               }
+                       }
+               }
+               
+               // Check for additions to the "wheel" group
+               grp = getgrnam("wheel");
+               if( grp ) {
+                       for( i = 0; grp->gr_mem[i]; i ++ )
+                       {
+                               if( strcmp(grp->gr_mem[i], pwd->pw_name) == 0 ) {
+                                       gaBank_Users[ID].Flags |= USER_FLAG_WHEEL;
+                                       break ;
+                               }
+                       }
+               }
+       }
+       #endif
 
        return gaBank_Users[ID].Flags;
 }
 
-int Bank_AlterUserBalance(int ID, int Delta)
+int Bank_SetUserFlags(int ID, int Mask, int Value)
 {
        // Sanity
        if( ID < 0 || ID >= giBank_NumUsers )
                return -1;
+       
+       // Silently ignore changes to root and meta accounts
+       if( gaBank_Users[ID].UnixID <= 0 )      return 0;
+       
+       gaBank_Users[ID].Flags &= ~Mask;
+       gaBank_Users[ID].Flags |= Value;
 
-       // Update
-       gaBank_Users[ID].Balance += Delta;
-
-       // Commit
-       fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
-       fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
+       Bank_int_WriteEntry(ID);
        
        return 0;
 }
 
-int Bank_SetUserBalance(int ID, int Value)
+int Bank_AlterUserBalance(int ID, int Delta)
 {
        // Sanity
        if( ID < 0 || ID >= giBank_NumUsers )
                return -1;
 
        // Update
-       gaBank_Users[ID].Balance = Value;
-       
-       // Commit
-       fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
-       fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
+       gaBank_Users[ID].Balance += Delta;
+
+       Bank_int_WriteEntry(ID);
        
        return 0;
 }
 
 int Bank_GetMinAllowedBalance(int ID)
 {
+        int    flags;
        if( ID < 0 || ID >= giBank_NumUsers )
                return 0;
 
-//     printf("gaBank_Users[%i].Flags = 0x%x\n", ID, gaBank_Users[ID].Flags);
+       flags = Bank_GetUserFlags(ID);
 
-       switch( gaBank_Users[ID].Flags & USER_FLAG_TYPEMASK )
-       {
-       case USER_TYPE_NORMAL:  return     0;
-       case USER_TYPE_COKE:    return  -2000;
-       case USER_TYPE_WHEEL:   return -10000;
-       case USER_TYPE_GOD:     return INT_MIN;
-       default:        return 0;
-       }
+       // Internal accounts have no limit
+       if( (flags & USER_FLAG_INTERNAL) )
+               return INT_MIN;
+
+       // Wheel is allowed to go to -$100
+       if( (flags & USER_FLAG_WHEEL) )
+               return -10000;
+       
+       // Coke is allowed to go to -$20
+       if( (flags & USER_FLAG_COKE) )
+               return -2000;
+
+       // For everyone else, no negative
+       return 0;
 }
 
 /**
@@ -124,18 +189,19 @@ int Bank_AddUser(const char *Username)
        gaBank_Users[giBank_NumUsers].Flags = 0;
        
        if( strcmp(Username, COKEBANK_DEBT_ACCT) == 0 ) {
-               gaBank_Users[giBank_NumUsers].Flags = USER_TYPE_GOD;    // No minium
+               gaBank_Users[giBank_NumUsers].Flags = USER_FLAG_INTERNAL;
+       }
+       else if( strcmp(Username, COKEBANK_SALES_ACCT) == 0 ) {
+               gaBank_Users[giBank_NumUsers].Flags = USER_FLAG_INTERNAL;
        }
        else if( strcmp(Username, "root") == 0 ) {
-               gaBank_Users[giBank_NumUsers].Flags = USER_TYPE_GOD;    // No minium
+               gaBank_Users[giBank_NumUsers].Flags = USER_FLAG_WHEEL|USER_FLAG_COKE;
        }
-       
-       // 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);
 
        // Increment count
        giBank_NumUsers ++;
+       
+       Bank_int_WriteEntry(giBank_NumUsers - 1);
 
        return 0;
 }

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