From 7d2c06b12b6e45d31d9359c54fa37f451b6eb4bd Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 7 Jan 2011 11:20:52 +0800 Subject: [PATCH] Implemented altering user flags - `dispense user type` added to set flags --- proto.txt | 2 ++ src/client/main.c | 3 ++ src/cokebank.h | 1 + src/cokebank_basic/bank.c | 15 +++++++++ src/cokebank_basic/common.h | 1 + src/cokebank_basic/main.c | 5 +++ src/server/server.c | 66 ++++++++++++++++++++++++++++++++++++- 7 files changed, 92 insertions(+), 1 deletion(-) diff --git a/proto.txt b/proto.txt index 3adcaf2..436c713 100644 --- a/proto.txt +++ b/proto.txt @@ -75,5 +75,7 @@ s 202 User \n c USER_ADD \n s 200 User Added\n or 403 Not Wheel\n or 404 User Exists\n --- Set user flags --- + is a comma-separated list of flag values (optionally preceded by + - to remove the flag) Valid values are: user,coke,wheel,meta,disabled,door c USER_FLAGS \n s 200 User Updated\n or 403 Not Wheel\n or 404 Bad User\n or 407 Unknown Flags\n diff --git a/src/client/main.c b/src/client/main.c index d3adeee..94da826 100644 --- a/src/client/main.c +++ b/src/client/main.c @@ -929,6 +929,9 @@ int Dispense_SetBalance(int Socket, const char *Username, int Ammount, const cha return -1; } +/** + * \brief Enumerate users + */ int Dispense_EnumUsers(int Socket) { char *buf; diff --git a/src/cokebank.h b/src/cokebank.h index 85a4b8a..09e6d18 100644 --- a/src/cokebank.h +++ b/src/cokebank.h @@ -27,6 +27,7 @@ enum eCokebank_Flags { // --- Cokebank Functions --- extern int Transfer(int SourceUser, int DestUser, int Ammount, const char *Reason); extern int GetFlags(int User); +extern int SetFlags(int User, int Mask, int Value); extern int GetBalance(int User); extern char *GetUserName(int User); extern int GetUserID(const char *Username); diff --git a/src/cokebank_basic/bank.c b/src/cokebank_basic/bank.c index 9b9e2d5..abf5763 100644 --- a/src/cokebank_basic/bank.c +++ b/src/cokebank_basic/bank.c @@ -106,6 +106,21 @@ int Bank_GetUserFlags(int ID) return gaBank_Users[ID].Flags; } +int Bank_SetUserFlags(int ID, int Mask, int Value) +{ + // Sanity + if( ID < 0 || ID >= giBank_NumUsers ) + return -1; + + // Silently ignore changes to root and meta accounts + if( gaBank_Users[ID].UnixID <= 0 ) return 0; + + gaBank_Users[ID].Flags &= Mask; + gaBank_Users[ID].Flags |= Value; + + return 0; +} + int Bank_AlterUserBalance(int ID, int Delta) { // Sanity diff --git a/src/cokebank_basic/common.h b/src/cokebank_basic/common.h index f7744dd..83480b7 100644 --- a/src/cokebank_basic/common.h +++ b/src/cokebank_basic/common.h @@ -24,6 +24,7 @@ extern int Bank_GetUserBalance(int ID); extern int Bank_AlterUserBalance(int ID, int Delta); extern char *Bank_GetUserName(int ID); extern int Bank_GetUserFlags(int ID); +extern int Bank_SetUserFlags(int ID, int Mask, int Value); extern int Bank_GetUserByName(const char *Username); extern int Bank_AddUser(const char *Username); extern FILE *gBank_File; diff --git a/src/cokebank_basic/main.c b/src/cokebank_basic/main.c index fe16f6f..9ddb85e 100644 --- a/src/cokebank_basic/main.c +++ b/src/cokebank_basic/main.c @@ -78,6 +78,11 @@ int GetFlags(int User) return Bank_GetUserFlags(User); } +int SetFlags(int User, int Mask, int Flags) +{ + return Bank_SetUserFlags(User, Mask, Flags); +} + /** * \brief Get the balance of the passed user */ diff --git a/src/server/server.c b/src/server/server.c index 9ca0be9..930298a 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -765,6 +765,8 @@ void Server_Cmd_USERFLAGS(tClient *Client, char *Args) { char *username, *flags; char *space; + int mask=0, value=0; + int uid; // Check permissions if( (GetFlags(Client->UID) & USER_FLAG_TYPEMASK) < USER_TYPE_WHEEL ) { @@ -781,14 +783,76 @@ void Server_Cmd_USERFLAGS(tClient *Client, char *Args) sendf(Client->Socket, "407 USER_FLAGS requires 2 arguments, 1 given\n"); return ; } + *space = '\0'; // - Flags flags = space + 1; while( *flags == ' ' ) flags ++; space = strchr(flags, ' '); if(space) *space = '\0'; - printf("Username = '%s', flags = '%s'\n", username, flags); + // Get UID + uid = GetUserID(username); + if( uid == -1 ) { + sendf(Client->Socket, "404 User '%s' not found\n", username); + return ; + } + + // Parse flags + do { + int bRemove = 0; + int i; + struct { + const char *Name; + int Mask; + int Value; + } cFLAGS[] = { + {"disabled", USER_FLAG_DISABLED, USER_FLAG_DISABLED}, + {"door", USER_FLAG_DOORGROUP, USER_FLAG_DOORGROUP}, + {"user", USER_FLAG_TYPEMASK, USER_TYPE_NORMAL}, + {"coke", USER_FLAG_TYPEMASK, USER_TYPE_COKE}, + {"wheel", USER_FLAG_TYPEMASK, USER_TYPE_WHEEL}, + {"meta", USER_FLAG_TYPEMASK, USER_TYPE_GOD} + }; + const int ciNumFlags = sizeof(cFLAGS)/sizeof(cFLAGS[0]); + + while( *flags == ' ' ) flags ++; // Eat whitespace + space = strchr(flags, ','); // Find the end of the flag + if(space) *space = '\0'; + + // Check for inversion/removal + if( *flags == '!' || *flags == '-' ) { + bRemove = 1; + flags ++; + } + else if( *flags == '+' ) { + flags ++; + } + + // Check flag values + for( i = 0; i < ciNumFlags; i ++ ) + { + if( strcmp(flags, cFLAGS[i].Name) == 0 ) { + mask |= cFLAGS[i].Mask; + value &= ~cFLAGS[i].Mask; + if( !bRemove ) + value |= cFLAGS[i].Value; + break; + } + } + + // Error check + if( i == ciNumFlags ) { + sendf(Client->Socket, "407 Unknown flag value '%s'\n", flags); + return ; + } + + flags = space + 1; + } while(space); + + // Apply flags + SetFlags(uid, mask, value); + // Return OK sendf(Client->Socket, "200 User Updated\n"); } -- 2.20.1