#include "ChanUser.h"
#include "UserNode.h"
#include "modcmd.h"
-#include "mysqlConn.h"
static struct ChanNode **chanList;
static int modes_with_strarg, modes_with_intarg;
#undef MODE_VALUE
#undef MODE_VALUE_INDEX
}
-
-
-void load_channel_settings(struct ChanNode *chan) {
- if(!(chan->flags & CHANFLAG_REQUESTED_CHANINFO)) {
- check_mysql();
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `channel_id` FROM `channels` WHERE `channel_name` = '%s'", escape_string(chan->name));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- chan->flags |= CHANFLAG_CHAN_REGISTERED;
- chan->channel_id = atoi(row[0]);
- }
- chan->flags |= CHANFLAG_REQUESTED_CHANINFO;
- }
-}
void parseModes(struct ChanNode* chan, char *modeStr, char **argv, int argc);
void getModeString(struct ChanNode* chan, char *modesStr);
-void load_channel_settings(struct ChanNode *chan);
-
#endif
\ No newline at end of file
#define CHANUSERFLAG_VOICED 0x02
+#define DB_CHANUSER_SUSPENDED = 0x01
+#define DB_CHANUSER_AUTOINVITE = 0x02
+#define DB_CHANUSER_NOAUTOOP = 0x04
+
#define CHANUSERFLAG_OPPED_OR_VOICED (CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED)
struct ChanNode;
--- /dev/null
+
+#include "DBHelper.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "mysqlConn.h"
+#include "lang.h"
+
+
+void _loadUserSettings(struct UserNode *user) {
+ check_mysql();
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `user_lang`, `user_reply_privmsg`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ user->language = get_language_by_tag(row[0]);
+ if(user->language == NULL) user->language = get_default_language();
+ if(strcmp(row[1], "0"))
+ user->flags |= USERFLAG_REPLY_PRIVMSG;
+ if(strcmp(row[2], "0"))
+ user->flags |= USERFLAG_GOD_MODE;
+ } else
+ user->language = get_default_language();
+ user->flags |= USERFLAG_LOADED_SETTINGS;
+}
+
+int isGodMode(struct UserNode *user) {
+ loadUserSettings(user);
+ return (user->flags & USERFLAG_GOD_MODE);
+}
+
+int getChannelAccess(struct UserNode *user, struct ChanNode *chan, int override) {
+ if(!(user->flags & USERFLAG_ISAUTHED)) return 0;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return 0;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ check_mysql();
+ int caccess = 0;
+ printf_mysql_query("SELECT `user_id`, `user_access`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(strcmp(row[2], "0") && override)
+ caccess = atoi(row[1]);
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` WHERE `chanuser_uid` = '%s' AND `chanuser_cid` = '%d'", row[0], chan->channel_id);
+ //
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(!(atoi(row[1]) & DB_CHANUSER_SUSPENDED) && atoi(row[0]) > caccess)
+ caccess = atoi(row[0]);
+ }
+ return caccess;
+ }
+ return 0;
+}
+
+int checkChannelAccess(struct UserNode *user, struct ChanNode *chan, char *channel_setting, int allow_override, int allow_501) {
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return 0;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", channel_setting, chan->channel_id);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) return 0;
+ int require_access = atoi(row[0]);
+ if(require_access == 0) return 1;
+ if(!(user->flags & USERFLAG_ISAUTHED)) return 0;
+ int caccess = 0;
+ printf_mysql_query("SELECT `user_id`, `user_access`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` WHERE `chanuser_uid` = '%s' AND `chanuser_cid` = '%d'", row[0], chan->channel_id);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(!(atoi(row[1]) & DB_CHANUSER_SUSPENDED))
+ caccess = atoi(row[0]);
+ }
+ }
+ if(caccess >= require_access) return 1;
+ if(caccess == 500 && require_access == 501 && allow_501) return 1;
+ return 0;
+}
+
+void _loadChannelSettings(struct ChanNode *chan) {
+ check_mysql();
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `channel_id` FROM `channels` WHERE `channel_name` = '%s'", escape_string(chan->name));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ chan->flags |= CHANFLAG_CHAN_REGISTERED;
+ chan->channel_id = atoi(row[0]);
+ }
+ chan->flags |= CHANFLAG_REQUESTED_CHANINFO;
+}
+
+
--- /dev/null
+#ifndef _DBHelper_h
+#define _DBHelper_h
+
+#include "main.h"
+
+void _loadUserSettings(struct UserNode* user);
+#define loadUserSettings(USER) if((USER->flags & USERFLAG_ISAUTHED) && !(USER->flags & USERFLAG_LOADED_SETTINGS)) _loadUserSettings(USER)
+int isGodMode(struct UserNode *user);
+int getChannelAccess(struct UserNode *user, struct ChanNode *chan, int override);
+int checkChannelAccess(struct UserNode *user, struct ChanNode *chan, char *channel_setting, int allow_override, int allow_501);
+void _loadChannelSettings(struct ChanNode *chan);
+#define loadChannelSettings(CHAN) if(!(CHAN->flags & CHANFLAG_REQUESTED_CHANINFO)) _loadChannelSettings(CHAN)
+
+#endif
\ No newline at end of file
gcc -g -O2 ${LIBS} -c lang.c -o lang.o ${CFLAGS}
gcc -g -O2 ${LIBS} -c HandleInfoHandler.c -o HandleInfoHandler.o ${CFLAGS}
gcc -g -O2 ${LIBS} -c tools.c -o tools.o ${CFLAGS}
+ gcc -g -O2 ${LIBS} -c DBHelper.c -o DBHelper.o ${CFLAGS}
gcc -g -O2 ${LIBS} -c bots.c -o bots.o ${CFLAGS}
gcc -g -O2 ${LIBS} -c bot_NeonServ.c -o bot_NeonServ.o ${CFLAGS}
#include "UserNode.h"
#include "ChanUser.h"
-#include "mysqlConn.h"
-#include "lang.h"
static struct UserNode **userList;
last_user = cuser;
}
}
-
-
-void load_user_settings(struct UserNode *user) {
- if(!(user->flags & USERFLAG_ISAUTHED) || (user->flags & USERFLAG_LOADED_SETTINGS))
- return;
- check_mysql();
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `user_lang`, `user_reply_privmsg`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- user->language = get_language_by_tag(row[0]);
- if(user->language == NULL) user->language = get_default_language();
- if(strcmp(row[1], "0"))
- user->flags |= USERFLAG_REPLY_PRIVMSG;
- if(strcmp(row[2], "0"))
- user->flags |= USERFLAG_GOD_MODE;
- } else
- user->language = get_default_language();
- user->flags |= USERFLAG_LOADED_SETTINGS;
-}
-
-int isGodMode(struct UserNode *user) {
- load_user_settings(user);
- return (user->flags & USERFLAG_GOD_MODE);
-}
void delUser(struct UserNode* user, int freeUser);
void clearTempUsers();
-void load_user_settings(struct UserNode* user);
-int isGodMode(struct UserNode *user);
-
#endif
{"NS_ADDUSER_DONE", "Added %s to the %s user list with access %d."},
{"NS_NOT_ON_USERLIST", "%s lacks access to \002%s\002."},
{"NS_DELUSER_DONE", "Deleted %s (with access %d) from the %s user list."},
+ {"NS_ACCESS_OUTRANKED", "You cannot give users access greater than or equal to your own."},
+ {"NS_USER_OUTRANKED", "\002%s\002 outranks you (command has no effect)."},
+ {"NS_ACCESS_DENIED", "Access denied."},
+ {"NS_CLVL_DONE", "%s now has access \002%d\002 in %s."},
{NULL, NULL}
};
MYSQL_RES *res;
MYSQL_ROW row;
check_mysql();
- //check acccess
+ checkChannelAccess(user, chan, "channel_canadd", 1, 0);
caccess = atoi(argv[1]);
if(caccess <= 0 || caccess > 500) {
reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
return;
}
+ if(caccess >= getChannelAccess(user, chan, 1)) {
+ reply(getTextBot(), user, "NS_ACCESS_OUTRANKED");
+ return;
+ }
//check own access
if(argv[0][0] == '*') {
//we've got an auth
--- /dev/null
+
+/*
+* argv[0] - nick / *auth
+* argv[1] - access
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_clvl_nick_lookup);
+static void neonserv_cmd_clvl_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, int caccess);
+
+struct neonserv_cmd_clvl_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ char *nick;
+ int access;
+};
+
+static CMD_BIND(neonserv_cmd_clvl) {
+ int caccess;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ check_mysql();
+ checkChannelAccess(user, chan, "channel_canclvl", 1, 0);
+ caccess = atoi(argv[1]);
+ if(caccess <= 0 || caccess > 500) {
+ reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
+ return;
+ }
+ if(caccess >= getChannelAccess(user, chan, 1)) {
+ reply(getTextBot(), user, "NS_ACCESS_OUTRANKED");
+ return;
+ }
+ if(argv[0][0] == '*') {
+ //we've got an auth
+ argv[0]++;
+ neonserv_cmd_clvl_async1(client, getTextBot(), user, chan, argv[0], argv[0], caccess);
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_clvl_async1(client, getTextBot(), user, chan, argv[0], cuser->auth, caccess);
+ } else {
+ struct neonserv_cmd_clvl_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->nick = strdup(argv[0]);
+ cache->access = caccess;
+ get_userauth(cuser, neonserv_cmd_clvl_nick_lookup, cache);
+ }
+ }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_clvl_nick_lookup) {
+ struct neonserv_cmd_clvl_cache *cache = data;
+ if(!user) {
+ //USER_DOES_NOT_EXIST
+ reply(cache->textclient, cache->user, "NS_USER_UNKNOWN", cache->nick);
+ }
+ else if(!(user->flags & USERFLAG_ISAUTHED)) {
+ //USER_NOT_AUTHED
+ reply(cache->textclient, cache->user, "NS_USER_NEED_AUTH", cache->nick);
+ }
+ else
+ neonserv_cmd_clvl_async1(cache->client, cache->textclient, cache->user, cache->chan, user->nick, user->auth, cache->access);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_clvl_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, int caccess) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int userid;
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ userid = atoi(row[0]);
+ //check if the user is already added
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ //clvl
+ if(atoi(row[0]) >= getChannelAccess(user, chan, 1)) {
+ reply(cache->textclient, cache->user, "NS_USER_OUTRANKED", nick);
+ return;
+ }
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '%d' WHERE `chanuser_id` = '%s'", caccess, row[1]);
+ reply(textclient, user, "NS_CLVL_DONE", nick, caccess, chan->name);
+ return;
+ }
+ }
+ reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
+}
/*
* argv[0] - nick / *auth
*/
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_deluser_auth_lookup);
static USERAUTH_CALLBACK(neonserv_cmd_deluser_nick_lookup);
static void neonserv_cmd_deluser_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth);
MYSQL_RES *res;
MYSQL_ROW row;
check_mysql();
+ checkChannelAccess(user, chan, "channel_candel", 1, 0);
if(argv[0][0] == '*') {
//we've got an auth
argv[0]++;
- printf_mysql_query("SELECT `user_user` FROM `users` WHERE `user_user` = '%s'", escape_string(argv[0]));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- neonserv_cmd_deluser_async1(client, getTextBot(), user, chan, argv[0], row[0]);
- } else {
- //we need to create a new user...
- //but first lookup the auth to check if it really exists
- struct neonserv_cmd_deluser_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->nick = strdup(argv[0]);
- lookup_authname(argv[0], neonserv_cmd_deluser_auth_lookup, cache);
- }
+ neonserv_cmd_deluser_async1(client, getTextBot(), user, chan, argv[0], argv[0]);
} else {
struct UserNode *cuser = getUserByNick(argv[0]);
if(!cuser) {
}
}
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_deluser_auth_lookup) {
- struct neonserv_cmd_deluser_cache *cache = data;
- if(!exists) {
- //AUTH_DOES_NOT_EXIST
- reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
- } else
- neonserv_cmd_deluser_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->nick, auth);
- free(cache->nick);
- free(cache);
-}
-
static USERAUTH_CALLBACK(neonserv_cmd_deluser_nick_lookup) {
struct neonserv_cmd_deluser_cache *cache = data;
if(!user) {
printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
res = mysql_use();
if ((row = mysql_fetch_row(res)) != NULL) {
+ if(atoi(row[0]) >= getChannelAccess(user, chan, 1)) {
+ reply(textclient, cache->user, "NS_USER_OUTRANKED", nick);
+ return;
+ }
//delete
printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[1]);
reply(textclient, user, "NS_DELUSER_DONE", nick, atoi(row[0]), chan->name);
#include "WHOHandler.h"
#include "lang.h"
#include "mysqlConn.h"
+#include "DBHelper.h"
struct trigger_callback {
int botid;
break;
}
if((cbind->func->flags & CMDFLAG_REGISTERED_CHAN)) {
- load_channel_settings(chan);
+ loadChannelSettings(chan);
if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
reply(tmp_text_client, user, "MODCMD_CHAN_REQUIRED");
break;