3 * UCC (University [of WA] Computer Club) Electronic Accounting System
4 * - Cokebank (Basic Version)
6 * bank.c - Actual bank database
8 * This file is licenced under the 3-clause BSD Licence. See the file COPYING
19 #define USE_UNIX_GROUPS 1
22 static int GetUnixID(const char *Username);
30 static int Bank_int_WriteEntry(int ID)
32 if( ID < 0 || ID >= giBank_NumUsers ) {
37 fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
38 fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
43 int Bank_GetUserByName(const char *Username)
47 uid = GetUnixID(Username);
49 // Expensive search :(
50 for( i = 0; i < giBank_NumUsers; i ++ )
52 if( gaBank_Users[i].UnixID == uid )
59 int Bank_GetUserBalance(int ID)
61 if( ID < 0 || ID >= giBank_NumUsers )
64 return gaBank_Users[ID].Balance;
67 int Bank_GetUserFlags(int ID)
69 if( ID < 0 || ID >= giBank_NumUsers )
73 if( gaBank_Users[ID].UnixID == 0 ) {
74 gaBank_Users[ID].Flags |= USER_FLAG_WHEEL|USER_FLAG_COKE;
78 // TODO: Implement checking the PAM groups and status instead, then
79 // fall back on the database. (and update if there is a difference)
80 if( gaBank_Users[ID].UnixID > 0 )
87 pwd = getpwuid( gaBank_Users[ID].UnixID );
89 // Check for additions to the "coke" group
90 grp = getgrnam("coke");
92 for( i = 0; grp->gr_mem[i]; i ++ )
94 if( strcmp(grp->gr_mem[i], pwd->pw_name) == 0 ) {
95 gaBank_Users[ID].Flags |= USER_FLAG_COKE;
101 // Check for additions to the "wheel" group
102 grp = getgrnam("wheel");
104 for( i = 0; grp->gr_mem[i]; i ++ )
106 if( strcmp(grp->gr_mem[i], pwd->pw_name) == 0 ) {
107 gaBank_Users[ID].Flags |= USER_FLAG_WHEEL;
115 return gaBank_Users[ID].Flags;
118 int Bank_SetUserFlags(int ID, int Mask, int Value)
121 if( ID < 0 || ID >= giBank_NumUsers )
124 // Silently ignore changes to root and meta accounts
125 if( gaBank_Users[ID].UnixID <= 0 ) return 0;
127 gaBank_Users[ID].Flags &= ~Mask;
128 gaBank_Users[ID].Flags |= Value;
130 Bank_int_WriteEntry(ID);
135 int Bank_AlterUserBalance(int ID, int Delta)
138 if( ID < 0 || ID >= giBank_NumUsers )
142 gaBank_Users[ID].Balance += Delta;
144 Bank_int_WriteEntry(ID);
149 int Bank_GetMinAllowedBalance(int ID)
152 if( ID < 0 || ID >= giBank_NumUsers )
155 flags = Bank_GetUserFlags(ID);
157 // Internal accounts have no limit
158 if( (flags & USER_FLAG_INTERNAL) )
161 // Wheel is allowed to go to -$100
162 if( (flags & USER_FLAG_WHEEL) )
165 // Coke is allowed to go to -$20
166 if( (flags & USER_FLAG_COKE) )
169 // For everyone else, no negative
174 * \brief Create a new user in our database
176 int Bank_AddUser(const char *Username)
179 int uid = GetUnixID(Username);
181 // Can has moar space plz?
182 tmp = realloc(gaBank_Users, (giBank_NumUsers+1)*sizeof(gaBank_Users[0]));
183 if( !tmp ) return -1;
187 gaBank_Users[giBank_NumUsers].UnixID = uid;
188 gaBank_Users[giBank_NumUsers].Balance = 0;
189 gaBank_Users[giBank_NumUsers].Flags = 0;
191 if( strcmp(Username, COKEBANK_DEBT_ACCT) == 0 ) {
192 gaBank_Users[giBank_NumUsers].Flags = USER_FLAG_INTERNAL;
194 else if( strcmp(Username, COKEBANK_SALES_ACCT) == 0 ) {
195 gaBank_Users[giBank_NumUsers].Flags = USER_FLAG_INTERNAL;
197 else if( strcmp(Username, "root") == 0 ) {
198 gaBank_Users[giBank_NumUsers].Flags = USER_FLAG_WHEEL|USER_FLAG_COKE;
204 Bank_int_WriteEntry(giBank_NumUsers - 1);
210 // Unix user dependent code
211 // TODO: Modify to keep its own list of usernames
213 char *Bank_GetUserName(int ID)
217 if( ID < 0 || ID >= giBank_NumUsers )
220 if( gaBank_Users[ID].UnixID == -1 )
221 return strdup(COKEBANK_SALES_ACCT);
223 if( gaBank_Users[ID].UnixID == -2 )
224 return strdup(COKEBANK_DEBT_ACCT);
226 pwd = getpwuid(gaBank_Users[ID].UnixID);
227 if( !pwd ) return NULL;
229 return strdup(pwd->pw_name);
232 static int GetUnixID(const char *Username)
236 if( strcmp(Username, COKEBANK_SALES_ACCT) == 0 ) { // Pseudo account that sales are made into
239 else if( strcmp(Username, COKEBANK_DEBT_ACCT) == 0 ) { // Pseudo acount that money is added from
245 pwd = getpwnam(Username);
246 if( !pwd ) return -1;