More cleanup, implementing `dispense give`
[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 -1;
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         // Commit to file
125         fseek(gBank_File, giBank_NumUsers*sizeof(gaBank_Users[0]), SEEK_SET);
126         fwrite(&gaBank_Users[giBank_NumUsers], sizeof(gaBank_Users[0]), 1, gBank_File);
127
128         // Increment count
129         giBank_NumUsers ++;
130
131         return 0;
132 }
133
134 // ---
135 // Unix user dependent code
136 // TODO: Modify to keep its own list of usernames
137 // ---
138 char *Bank_GetUserName(int ID)
139 {
140         struct passwd   *pwd;
141         
142         if( ID < 0 || ID >= giBank_NumUsers )
143                 return NULL;
144         
145         if( gaBank_Users[ID].UnixID == -1 )
146                 return strdup(">sales");
147
148         if( gaBank_Users[ID].UnixID == -2 )
149                 return strdup(">liability");
150
151         pwd = getpwuid(gaBank_Users[ID].UnixID);
152         if( !pwd )      return NULL;
153
154         return strdup(pwd->pw_name);
155 }
156
157 static int GetUnixID(const char *Username)
158 {
159          int    uid;
160
161         if( strcmp(Username, ">sales") == 0 ) { // Pseudo account that sales are made into
162                 uid = -1;
163         }
164         else if( strcmp(Username, ">liability") == 0 ) {        // Pseudo acount that money is added from
165                 uid = -2;
166         }
167         else {
168                 struct passwd   *pwd;
169                 // Get user ID
170                 pwd = getpwnam(Username);
171                 if( !pwd )      return -1;
172                 uid = pwd->pw_uid;
173         }
174         return uid;
175 }

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