Removed heap abuse from server (now uses sendf)
[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 // === PROTOTYPES ===
19 static int      GetUnixID(const char *Username);
20
21 // === GLOBALS ===
22 tUser   *gaBank_Users;
23  int    giBank_NumUsers;
24 FILE    *gBank_File;
25
26 // === CODE ===
27 int Bank_GetUserByName(const char *Username)
28 {
29          int    i, uid;
30         
31         uid = GetUnixID(Username);
32         
33         // Expensive search :(
34         for( i = 0; i < giBank_NumUsers; i ++ )
35         {
36                 if( gaBank_Users[i].UnixID == uid )
37                         return i;
38         }
39
40         return -1;
41 }
42
43 int Bank_GetUserBalance(int ID)
44 {
45         if( ID < 0 || ID >= giBank_NumUsers )
46                 return INT_MIN;
47
48         return gaBank_Users[ID].Balance;
49 }
50
51 int Bank_GetUserFlags(int ID)
52 {
53         if( ID < 0 || ID >= giBank_NumUsers )
54                 return INT_MIN;
55
56         return gaBank_Users[ID].Flags;
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 //      printf("gaBank_Users[%i].Flags = 0x%x\n", ID, gaBank_Users[ID].Flags);
97
98         switch( gaBank_Users[ID].Flags & USER_FLAG_TYPEMASK )
99         {
100         case USER_TYPE_NORMAL:  return     0;
101         case USER_TYPE_COKE:    return  -2000;
102         case USER_TYPE_WHEEL:   return -10000;
103         case USER_TYPE_GOD:     return INT_MIN;
104         default:        return 0;
105         }
106 }
107
108 /**
109  * \brief Create a new user in our database
110  */
111 int Bank_AddUser(const char *Username)
112 {
113         void    *tmp;
114          int    uid = GetUnixID(Username);
115
116         // Can has moar space plz?
117         tmp = realloc(gaBank_Users, (giBank_NumUsers+1)*sizeof(gaBank_Users[0]));
118         if( !tmp )      return -1;
119         gaBank_Users = tmp;
120
121         // Crete new user
122         gaBank_Users[giBank_NumUsers].UnixID = uid;
123         gaBank_Users[giBank_NumUsers].Balance = 0;
124         gaBank_Users[giBank_NumUsers].Flags = 0;
125         
126         if( strcmp(Username, COKEBANK_DEBT_ACCT) == 0 ) {
127                 gaBank_Users[giBank_NumUsers].Flags = USER_TYPE_GOD;    // No minium
128         }
129         else if( strcmp(Username, "root") == 0 ) {
130                 gaBank_Users[giBank_NumUsers].Flags = USER_TYPE_GOD;    // No minium
131         }
132         
133         // Commit to file
134         fseek(gBank_File, giBank_NumUsers*sizeof(gaBank_Users[0]), SEEK_SET);
135         fwrite(&gaBank_Users[giBank_NumUsers], sizeof(gaBank_Users[0]), 1, gBank_File);
136
137         // Increment count
138         giBank_NumUsers ++;
139
140         return 0;
141 }
142
143 // ---
144 // Unix user dependent code
145 // TODO: Modify to keep its own list of usernames
146 // ---
147 char *Bank_GetUserName(int ID)
148 {
149         struct passwd   *pwd;
150         
151         if( ID < 0 || ID >= giBank_NumUsers )
152                 return NULL;
153         
154         if( gaBank_Users[ID].UnixID == -1 )
155                 return strdup(COKEBANK_SALES_ACCT);
156
157         if( gaBank_Users[ID].UnixID == -2 )
158                 return strdup(COKEBANK_DEBT_ACCT);
159
160         pwd = getpwuid(gaBank_Users[ID].UnixID);
161         if( !pwd )      return NULL;
162
163         return strdup(pwd->pw_name);
164 }
165
166 static int GetUnixID(const char *Username)
167 {
168          int    uid;
169
170         if( strcmp(Username, COKEBANK_SALES_ACCT) == 0 ) {      // Pseudo account that sales are made into
171                 uid = -1;
172         }
173         else if( strcmp(Username, COKEBANK_DEBT_ACCT) == 0 ) {  // Pseudo acount that money is added from
174                 uid = -2;
175         }
176         else {
177                 struct passwd   *pwd;
178                 // Get user ID
179                 pwd = getpwnam(Username);
180                 if( !pwd )      return -1;
181                 uid = pwd->pw_uid;
182         }
183         return uid;
184 }

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