Cleanup and Implementations
[tpg/opendispense2.git] / src / cokebank_basic / bank.c
1 /*
2  * OpenDispense 2
3  * UCC (University [of WA] Computer Club) Electronic Accounting System
4  * - Cokebank (Basic Version)
5  *
6  * bank.c - Actual bank database
7  *
8  * This file is licenced under the 3-clause BSD Licence. See the file COPYING
9  * for full details.
10  */
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <limits.h>
15 #include <pwd.h>
16 #include "common.h"
17
18 enum {
19         FLAG_TYPEMASK    = 0x03,
20         USER_TYPE_NORMAL = 0x00,
21         USER_TYPE_COKE   = 0x01,
22         USER_TYPE_WHEEL  = 0x02,
23         USER_TYPE_GOD    = 0x03
24 };
25
26 // === PROTOTYPES ===
27 static int      GetUnixID(const char *Username);
28
29 // === GLOBALS ===
30 tUser   *gaBank_Users;
31  int    giBank_NumUsers;
32 FILE    *gBank_File;
33
34 // === CODE ===
35 int Bank_GetUserByName(const char *Username)
36 {
37          int    i, uid;
38         
39         uid = GetUnixID(Username);
40         
41         // Expensive search :(
42         for( i = 0; i < giBank_NumUsers; i ++ )
43         {
44                 if( gaBank_Users[i].UnixID == uid )
45                         return i;
46         }
47
48         return -1;
49 }
50
51 int Bank_GetUserBalance(int ID)
52 {
53         if( ID < 0 || ID >= giBank_NumUsers )
54                 return INT_MIN;
55
56         return gaBank_Users[ID].Balance;
57 }
58
59 int Bank_AlterUserBalance(int ID, int Delta)
60 {
61         // Sanity
62         if( ID < 0 || ID >= giBank_NumUsers )
63                 return -1;
64
65         // Update
66         gaBank_Users[ID].Balance += Delta;
67
68         // Commit
69         fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
70         fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
71         
72         return 0;
73 }
74
75 int Bank_SetUserBalance(int ID, int Value)
76 {
77         // Sanity
78         if( ID < 0 || ID >= giBank_NumUsers )
79                 return -1;
80
81         // Update
82         gaBank_Users[ID].Balance = Value;
83         
84         // Commit
85         fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
86         fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
87         
88         return 0;
89 }
90
91 int Bank_GetMinAllowedBalance(int ID)
92 {
93         if( ID < 0 || ID >= giBank_NumUsers )
94                 return 0;
95
96         switch( gaBank_Users[ID].Flags & FLAG_TYPEMASK )
97         {
98         case USER_TYPE_NORMAL:  return     0;
99         case USER_TYPE_COKE:    return  -2000;
100         case USER_TYPE_WHEEL:   return -10000;
101         case USER_TYPE_GOD:     return INT_MIN;
102         default:        return 0;
103         }
104 }
105
106 /**
107  * \brief Create a new user in our database
108  */
109 int Bank_AddUser(const char *Username)
110 {
111         void    *tmp;
112          int    uid = GetUnixID(Username);
113
114         // Can has moar space plz?
115         tmp = realloc(gaBank_Users, (giBank_NumUsers+1)*sizeof(gaBank_Users[0]));
116         if( !tmp )      return -1;
117         gaBank_Users = tmp;
118
119         // Crete new user
120         gaBank_Users[giBank_NumUsers].UnixID = uid;
121         gaBank_Users[giBank_NumUsers].Balance = 0;
122         gaBank_Users[giBank_NumUsers].Flags = 0;
123         
124         if( strcmp(Username, ">liability") == 0 ) {
125                 gaBank_Users[giBank_NumUsers].Flags = USER_TYPE_GOD;    // No minium
126         }
127         
128         // Commit to file
129         fseek(gBank_File, giBank_NumUsers*sizeof(gaBank_Users[0]), SEEK_SET);
130         fwrite(&gaBank_Users[giBank_NumUsers], sizeof(gaBank_Users[0]), 1, gBank_File);
131
132         // Increment count
133         giBank_NumUsers ++;
134
135         return 0;
136 }
137
138 // ---
139 // Unix user dependent code
140 // TODO: Modify to keep its own list of usernames
141 // ---
142 char *Bank_GetUserName(int ID)
143 {
144         struct passwd   *pwd;
145         
146         if( ID < 0 || ID >= giBank_NumUsers )
147                 return NULL;
148         
149         if( gaBank_Users[ID].UnixID == -1 )
150                 return strdup(">sales");
151
152         if( gaBank_Users[ID].UnixID == -2 )
153                 return strdup(">liability");
154
155         pwd = getpwuid(gaBank_Users[ID].UnixID);
156         if( !pwd )      return NULL;
157
158         return strdup(pwd->pw_name);
159 }
160
161 static int GetUnixID(const char *Username)
162 {
163          int    uid;
164
165         if( strcmp(Username, ">sales") == 0 ) { // Pseudo account that sales are made into
166                 uid = -1;
167         }
168         else if( strcmp(Username, ">liability") == 0 ) {        // Pseudo acount that money is added from
169                 uid = -2;
170         }
171         else {
172                 struct passwd   *pwd;
173                 // Get user ID
174                 pwd = getpwnam(Username);
175                 if( !pwd )      return -1;
176                 uid = pwd->pw_uid;
177         }
178         return uid;
179 }

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