qboolean Irc_If_Connect(void) { const char * const server = Cvar_GetStringValue(irc_server); const unsigned short port = Cvar_GetIntegerValue(irc_port); qboolean *c; Irc_Logic_Connect(server, port); // try to connect IRC_IMPORT.Dynvar_GetValue(irc_connected, (void**) &c); // get connection status return !*c; }
static void Irc_Rcon_CmdQuit_f(irc_command_t cmd, const char *prefix, const char *params, const char *trailing) { assert(irc_rcon); if (Cvar_GetIntegerValue(irc_rcon)) { irc_rcon_user_t *rcon_user; if (IRC_IMPORT.Trie_Remove(irc_rcon_users, prefix, (void**) &rcon_user) == TRIE_OK) Irc_MemFree(rcon_user); } }
static void Irc_Rcon_CmdPrivmsg_f(irc_command_t cmd, const char *prefix, const char *params, const char *trailing) { assert(irc_rcon); if (Cvar_GetIntegerValue(irc_rcon)) { // irc_rcon is set, check for rcon command if (*params != '#' && *params != '&') { // not a channel message, but a client-to-client message Irc_Rcon_ProcessMsg(prefix, trailing); } } }
static void Irc_Rcon_ProcessMsg(const char *user, const char *msg) { static char nick[IRC_SEND_BUF_SIZE]; irc_nick_prefix_t prefix; char *buf = (char*) Irc_MemAlloc((int) strlen(msg) + 1); const char *word; Irc_ParseName(user, nick, &prefix); strcpy(buf, msg); word = strtok(buf, " "); if (word && !strcasecmp(word, IRC_RCON_PREFIX)) { // it really is an RCON message, not a normal PRIVMSG unsigned int millis = IRC_IMPORT.Milliseconds(); irc_rcon_user_t *rcon_user; if (IRC_IMPORT.Trie_Find(irc_rcon_users, user, TRIE_EXACT_MATCH, (void**) &rcon_user) == TRIE_OK) { // user is already authorized const unsigned int timeout = Cvar_GetIntegerValue(irc_rconTimeout); if (!timeout || ((millis - rcon_user->millis) / 1000) < timeout) { // no timeout, reset user timestamp irc_rcon_user_t *rcon_user_old; rcon_user->millis = millis; IRC_IMPORT.Trie_Replace(irc_rcon_users, user, (void*) rcon_user, (void**) &rcon_user_old); assert(rcon_user == rcon_user_old); word = strtok(NULL, " "); if (word) { if (!strcasecmp(word, IRC_RCON_LOGOUT)) { // user wants to log off Irc_Proto_Msg(nick, "Logged out. You may login again via " IRC_RCON_PREFIX " " IRC_RCON_LOGIN " <rcon_password>."); IRC_IMPORT.Trie_Remove(irc_rcon_users, user, (void**) &rcon_user); Irc_MemFree(rcon_user); } else { // redirect console and execute char cmd_buf[IRC_SEND_BUF_SIZE + 2]; char rcon_buf[16384]; // make it big, we don't trust console redirect char *c = cmd_buf; size_t word_len = strlen(word); memset(rcon_buf, 0, sizeof(rcon_buf)); memcpy(c, word, word_len); c += word_len; for (word = strtok(NULL, " "); word; word = strtok(NULL, " ")) { *c++ = ' '; word_len = strlen(word); memcpy(c, word, word_len); c += word_len; } *c = '\0'; rcon_flush_to = nick; IRC_IMPORT.Com_BeginRedirect(1, rcon_buf, sizeof(rcon_buf) - 1, Irc_Rcon_Flush_f, NULL); IRC_IMPORT.Cmd_ExecuteString(cmd_buf); IRC_IMPORT.Com_EndRedirect(); } } } else { // timeout, inform user Irc_Proto_Msg(nick, "Timed out. Please login via " IRC_RCON_PREFIX " " IRC_RCON_LOGIN " <rcon_password>."); IRC_IMPORT.Trie_Remove(irc_rcon_users, user, (void**) &rcon_user); Irc_MemFree(rcon_user); } } else { // user not authorized, check for IRC_RCON_LOGIN command word = strtok(NULL, " "); if (word && !strcasecmp(word, IRC_RCON_LOGIN)) { const cvar_t * const rcon_password = IRC_IMPORT.Cvar_Get("rcon_password", "", CVAR_ARCHIVE); word = strtok(NULL, " "); if (word && !strcmp(word, Cvar_GetStringValue(rcon_password))) { // password correct, authorize Irc_Proto_Msg(nick, "Logged in. You may now issue commands via " IRC_RCON_PREFIX " <command> {<arg>}. Log out via " IRC_RCON_PREFIX " " IRC_RCON_LOGOUT "."); rcon_user = (irc_rcon_user_t*) Irc_MemAlloc(sizeof(irc_rcon_user_t)); rcon_user->millis = millis; IRC_IMPORT.Trie_Insert(irc_rcon_users, user, (void*) rcon_user); } } } } Irc_MemFree(buf); }