1b356e75cdfb1599e6042c9dc2f5fe80f4c13ee0
[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_GetUserFlags(int ID)
60 {
61         if( ID < 0 || ID >= giBank_NumUsers )
62                 return INT_MIN;
63
64         return gaBank_Users[ID].Flags;
65 }
66
67 int Bank_AlterUserBalance(int ID, int Delta)
68 {
69         // Sanity
70         if( ID < 0 || ID >= giBank_NumUsers )
71                 return -1;
72
73         // Update
74         gaBank_Users[ID].Balance += Delta;
75
76         // Commit
77         fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
78         fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
79         
80         return 0;
81 }
82
83 int Bank_SetUserBalance(int ID, int Value)
84 {
85         // Sanity
86         if( ID < 0 || ID >= giBank_NumUsers )
87                 return -1;
88
89         // Update
90         gaBank_Users[ID].Balance = Value;
91         
92         // Commit
93         fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
94         fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
95         
96         return 0;
97 }
98
99 int Bank_GetMinAllowedBalance(int ID)
100 {
101         if( ID < 0 || ID >= giBank_NumUsers )
102                 return 0;
103
104 //      printf("gaBank_Users[%i].Flags = 0x%x\n", ID, gaBank_Users[ID].Flags);
105
106         switch( gaBank_Users[ID].Flags & FLAG_TYPEMASK )
107         {
108         case USER_TYPE_NORMAL:  return     0;
109         case USER_TYPE_COKE:    return  -2000;
110         case USER_TYPE_WHEEL:   return -10000;
111         case USER_TYPE_GOD:     return INT_MIN;
112         default:        return 0;
113         }
114 }
115
116 /**
117  * \brief Create a new user in our database
118  */
119 int Bank_AddUser(const char *Username)
120 {
121         void    *tmp;
122          int    uid = GetUnixID(Username);
123
124         // Can has moar space plz?
125         tmp = realloc(gaBank_Users, (giBank_NumUsers+1)*sizeof(gaBank_Users[0]));
126         if( !tmp )      return -1;
127         gaBank_Users = tmp;
128
129         // Crete new user
130         gaBank_Users[giBank_NumUsers].UnixID = uid;
131         gaBank_Users[giBank_NumUsers].Balance = 0;
132         gaBank_Users[giBank_NumUsers].Flags = 0;
133         
134         if( strcmp(Username, ">liability") == 0 ) {
135                 gaBank_Users[giBank_NumUsers].Flags = USER_TYPE_GOD;    // No minium
136         }
137         else if( strcmp(Username, "root") == 0 ) {
138                 gaBank_Users[giBank_NumUsers].Flags = USER_TYPE_GOD;    // No minium
139         }
140         
141         // Commit to file
142         fseek(gBank_File, giBank_NumUsers*sizeof(gaBank_Users[0]), SEEK_SET);
143         fwrite(&gaBank_Users[giBank_NumUsers], sizeof(gaBank_Users[0]), 1, gBank_File);
144
145         // Increment count
146         giBank_NumUsers ++;
147
148         return 0;
149 }
150
151 // ---
152 // Unix user dependent code
153 // TODO: Modify to keep its own list of usernames
154 // ---
155 char *Bank_GetUserName(int ID)
156 {
157         struct passwd   *pwd;
158         
159         if( ID < 0 || ID >= giBank_NumUsers )
160                 return NULL;
161         
162         if( gaBank_Users[ID].UnixID == -1 )
163                 return strdup(">sales");
164
165         if( gaBank_Users[ID].UnixID == -2 )
166                 return strdup(">liability");
167
168         pwd = getpwuid(gaBank_Users[ID].UnixID);
169         if( !pwd )      return NULL;
170
171         return strdup(pwd->pw_name);
172 }
173
174 static int GetUnixID(const char *Username)
175 {
176          int    uid;
177
178         if( strcmp(Username, ">sales") == 0 ) { // Pseudo account that sales are made into
179                 uid = -1;
180         }
181         else if( strcmp(Username, ">liability") == 0 ) {        // Pseudo acount that money is added from
182                 uid = -2;
183         }
184         else {
185                 struct passwd   *pwd;
186                 // Get user ID
187                 pwd = getpwnam(Username);
188                 if( !pwd )      return -1;
189                 uid = pwd->pw_uid;
190         }
191         return uid;
192 }

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