}
}
+static void raw_005_network(struct ClientSocket *client, char *value) {
+ if(!value) return;
+ //check all other networknames
+ //if they are NOT simular to value throw a warning
+ SYNCHRONIZE(cache_sync); //all bots connect to the same time so there is a higher chance that this code is running on multiple threads at the same time
+ if(client->network_name)
+ free(client->network_name);
+ client->network_name = strdup(value);
+ struct ClientSocket *bot;
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if(bot == client) continue;
+ if(!bot->network_name) continue;
+ if(stricmp(bot->network_name, value)) {
+ putlog(LOGLEVEL_ERROR, "WARNING: Network name '%s' (%s) differs from '%s' (%s)! Connecting to multiple IRC-Networks with one instance is NOT supported!\n", client->network_name, client->nick, bot->network_name, bot->nick);
+ break;
+ }
+ }
+ DESYNCHRONIZE(cache_sync);
+}
+
+static IRC_CMD(raw_005) {
+ char *ptr1 = merge_argv(argv, 1, argc);
+ char *ptr2, *name, *value;
+ do {
+ ptr2 = strchr(ptr1, ' ');
+ if(ptr2)
+ *ptr2 = '\0';
+ name = ptr1;
+ if((value = strchr(ptr1, '='))) {
+ *value = '\0';
+ value++;
+ }
+ if(!stricmp(name, "NETWORK")) raw_005_network(client, value);
+ if(ptr2)
+ ptr1 = ptr2 + 1;
+ } while(ptr2);
+ return 1;
+}
+
void init_parser() {
//all the raws we receive...
register_irc_function("437", raw_437);
register_irc_function("002", raw_002);
+ register_irc_function("005", raw_005);
register_irc_function("251", raw_251);
register_irc_function("254", raw_254);
register_irc_function("324", raw_324);
--- /dev/null
+/* module.c - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "../../timeq.h"
+#include "../../ConfigParser.h"
+#include "../../mysqlConn.h"
+#include "../../ClientSocket.h"
+#include "../../UserNode.h"
+
+#define STATS_UPDATE_SECONDS 1800
+#define STATS_UPDATE_HOST "neonserv.krypton-bouncer.de"
+#define STATS_UPDATE_PORT 1675
+#define STATS_IDENTIFIER_LEN 10
+#define STATS_IDENTIFIER_POOL "abcdefghijklmnopqrstuvwxyz0123456789#*+-_.:;,!§$%&/()=?[]{}<>|@"
+#define STATS_IDENTIFIER_POOL_SIZE 63
+
+static TIMEQ_CALLBACK(stats_timer_callback);
+
+static int module_initialize() {
+ return 0;
+}
+
+static void module_start(int type) {
+ if(!timeq_name_exists("stats"))
+ timeq_add_name("stats", 60, module_id, stats_timer_callback, NULL);
+}
+
+static void module_loop() {
+
+}
+
+static void module_stop(int type) {
+ timeq_del_name("stats");
+}
+
+static char *get_identifier() {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `value` FROM `settings` WHERE `name` = 'identifier'");
+ res = mysql_use();
+ if(!(row = mysql_fetch_row(res))) {
+ srand(time(NULL));
+ char identifier[STATS_IDENTIFIER_LEN+1];
+ int i;
+ char *pool = STATS_IDENTIFIER_POOL;
+ for(i = 0; i < STATS_IDENTIFIER_LEN; i++) {
+ identifier[i] = pool[(rand() % STATS_IDENTIFIER_POOL_SIZE)];
+ }
+ identifier[i] = 0;
+ printf_mysql_query("INSERT INTO `settings` (`name`, `value`) VALUES ('identifier', '%s')", escape_string(identifier));
+ printf_mysql_query("SELECT `value` FROM `settings` WHERE `name` = 'identifier'");
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(!row) return NULL;
+ }
+ if(strlen(row[0]) < 10) return NULL;
+ return row[0];
+}
+
+static TIMEQ_CALLBACK(stats_timer_callback) {
+ timeq_add_name("stats", STATS_UPDATE_SECONDS, module_id, stats_timer_callback, NULL);
+ char tmp[200];
+ char pkgbuf[1024];
+ int pkgpos = 0;
+ char *modname = get_module_name(module_id);
+ char *bot_identifier = get_identifier();
+ if(!bot_identifier) return;
+ //build update package
+ pkgpos += sprintf(pkgbuf + pkgpos, "nsupdate\n%s\n%s.%d %s\n", bot_identifier, NEONSERV_VERSION, get_patchlevel(), (strcmp(get_revision(), "") ? get_revision() : "-"));
+ sprintf(tmp, "modules/%s/hide_networkname", modname);
+ if(get_int_field(tmp))
+ pkgpos += sprintf(pkgbuf + pkgpos, "*\n");
+ else {
+ struct ClientSocket *bot;
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if(bot->network_name) break;
+ }
+ if(bot)
+ pkgpos += sprintf(pkgbuf + pkgpos, "%s\n", bot->network_name);
+ else
+ pkgpos += sprintf(pkgbuf + pkgpos, "?\n");
+ }
+ sprintf(tmp, "modules/%s/hide_botnick", modname);
+ if(get_int_field(tmp))
+ pkgpos += sprintf(pkgbuf + pkgpos, "*\n");
+ else {
+ struct ClientSocket *bot, *bot1, *bot2, *bot3;
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if(bot->botid == 1 && (bot->flags & SOCKET_FLAG_PREFERRED))
+ bot1 = bot;
+ else if((bot->flags & SOCKET_FLAG_PREFERRED))
+ bot2 = bot;
+ else
+ bot3 = bot;
+ }
+ if(bot1)
+ bot = bot1;
+ else if(bot2)
+ bot = bot2;
+ else
+ bot = bot3;
+ if(bot) {
+ pkgpos += sprintf(pkgbuf + pkgpos, "%s!%s@%s %d\n", bot->user->nick, bot->user->ident, bot->host, bot->port);
+ } else
+ pkgpos += sprintf(pkgbuf + pkgpos, "?\n");
+ }
+ sprintf(tmp, "modules/%s/hide_chancount", modname);
+ if(get_int_field(tmp))
+ pkgpos += sprintf(pkgbuf + pkgpos, "*\n");
+ else {
+ int channel_count = getChannelCount();
+ pkgpos += sprintf(pkgbuf + pkgpos, "%d\n", channel_count);
+ }
+ sprintf(tmp, "modules/%s/hide_usercount", modname);
+ if(get_int_field(tmp))
+ pkgpos += sprintf(pkgbuf + pkgpos, "*\n");
+ else {
+ int user_count = getUserCount();
+ int chanuser_count = getChanUserCount();
+ pkgpos += sprintf(pkgbuf + pkgpos, "%d %d\n", user_count, chanuser_count);
+ }
+ pkgbuf[pkgpos] = 0;
+ //send package
+ #ifndef WIN32
+ struct sockaddr_in si_other;
+ int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock == -1) return;
+ memset((char *) &si_other, 0, sizeof(si_other));
+ si_other.sin_family = AF_INET;
+ si_other.sin_port = htons(STATS_UPDATE_PORT);
+ if (!inet_aton(STATS_UPDATE_HOST, &si_other.sin_addr)) {
+ struct hostent *host = gethostbyname(STATS_UPDATE_HOST);
+ if (!host) return;
+ si_other.sin_addr = *(struct in_addr*)host->h_addr;
+ }
+ #else
+ struct sockaddr_in si_other;
+ int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock == -1) return;
+ si_other.sin_family = AF_INET;
+ si_other.sin_port = htons(STATS_UPDATE_PORT);
+ si_other.sin_addr.s_addr = inet_addr(client->host);
+ if (si_other.sin_addr.s_addr == INADDR_NONE) {
+ struct hostent *host = gethostbyname(client->host);
+ if(!host) return;
+ memcpy(&(si_other.sin_addr), host->h_addr_list[0], 4);
+ }
+ #endif
+ sendto(sock, pkgbuf, pkgpos, 0, &si_other, sizeof(si_other));
+ close(sock);
+}
+
+MODULE_HEADER(module_initialize, module_start, module_loop, module_stop);