/* Copyright (C) 2000-2003 Markus Lausser (sgop@users.sf.net) This is free software distributed under the terms of the GNU Public License. See the file COPYING for details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include "support.h" #include "handler.h" #include "napster_handler.h" #include "lopster.h" #include "utils.h" #include "chat.h" #include "server.h" #include "log.h" #include "files.h" #include "search.h" #include "transfer.h" #include "global.h" #include "connection.h" #include "resume.h" #include "whois.h" #include "browse.h" #include "hotlist.h" #include "string_list.h" #include "napster.h" #include "file_tree.h" #include "subscription.h" #include "userinfo.h" #include "statistic.h" static HANDLER_ENTRY Protocol_Napster[] = { {NAP_ERROR, nap_server_error}, // 0 {NAP_EMAIL, nap_login_ack}, // 3 {NAP_REGISTER_OK, NULL}, // 8 {NAP_REGISTER_FAIL, nap_register_fail}, // 9 {NAP_BAD_NICK, nap_bad_nick}, // 10 {NAP_UNSHARE_ALL_ACK, NULL}, // 110 {NAP_SEARCH_RESULT, nap_search_response}, // 201 {NAP_SEARCH_END, nap_end_of_search}, // 202 {NAP_FILE_READY, nap_download_ack}, // 204 {NAP_PRIVMSG, nap_private_message}, // 205 {NAP_SEND_ERROR, nap_get_error}, // 206 {NAP_USER_SIGNON, nap_user_sign_on}, // 209 {NAP_USER_SIGNOFF, nap_user_sign_off}, // 210 {NAP_BROWSE_RESPONSE, nap_browse_response}, // 212 {NAP_BROWSE_END, nap_browse_end}, // 213 {NAP_STATS, nap_server_stats}, // 214 {NAP_RESUME_MATCH, nap_resume_match}, // 216 {NAP_RESUME_MATCH_END, NULL}, // 217 {NAP_HOTLIST_ACK, nap_hotlist_ack}, // 301 {NAP_HOTLIST_ERROR, nap_hotlist_error}, // 302 {NAP_DISCONNECTING, nap_disconnecting}, // 316 {NAP_IGNORE_LIST, NULL}, // 320 {NAP_IGNORE_ENTRY, nap_ignore_user}, // 321 {NAP_IGNORE_USER, nap_ignore_user}, // 322 {NAP_UNIGNORE_USER, nap_unignore_user}, // 323 {NAP_NOT_IGNORED, NULL}, // 324 {NAP_ALREADY_IGNORED, NULL}, // 325 {NAP_PART, nap_part_channel}, // 401 {NAP_PUBLIC, nap_public_message}, // 403 {NAP_NOSUCH, nap_error_message}, // 404 {NAP_JOIN_ACK, nap_create_channel}, // 405 {NAP_JOIN, nap_join_message}, // 406 {NAP_USER_PART, nap_part_message}, // 407 {NAP_CHANNEL_USER_LIST, nap_user_online}, // 408 {NAP_CHANNEL_USER_LIST_END, NULL}, // 409 {NAP_TOPIC, nap_channel_topic}, // 410 {NAP_CHANNEL_BAN_LIST_END, NULL}, // 420 {NAP_CHANNEL_BAN_LIST, nap_banlist_entry}, // 421 {NAP_CHANNEL_ALT_TOPIC, nap_channel_alt_topic}, // 425 {NAP_UPLOAD_FIREWALL, nap_alternate_ack}, // 501 {NAP_USER_SPEED, nap_linkspeed_response},// 601 {NAP_WHOIS_RESPONSE, nap_eval_whois}, // 604 {NAP_WHOWAS, nap_eval_whowas}, // 605 {NAP_UPLOAD_REQUEST, nap_upload_request}, // 607 {NAP_GET_ERROR, nap_get_error}, // 609 {NAP_ALTER_PORT, nap_set_port}, // 613 {NAP_BANLIST, NULL}, // 615 {NAP_IP_BANLIST, nap_banlist_entry}, // 616 {NAP_CHANNEL_LIST_END, nap_channel_list_end}, // 617 {NAP_CHANNEL_LIST, nap_channel_list}, // 618 {NAP_LIMIT, nap_remote_queued}, // 620 {NAP_MOTD, nap_motd}, // 621 {NAP_DATA_PORT_ERROR, nap_data_port_error}, // 626 {NAP_WALLOP, nap_operator_message}, // 627 {NAP_ANNOUNCE, nap_global_message}, // 628 {NAP_NICK_BANLIST, nap_nick_banlist}, // 629 {NAP_BROWSE_DIRECT, nap_browse_direct}, // 640 {NAP_BROWSE_DIRECT_OK, nap_browse_direct_ok}, // 641 {NAP_BROWSE_DIRECT_ERR, nap_browse_direct_err}, // 642 {NAP_GHOST, nap_ghost}, // 748 {NAP_PING_SERVER, nap_sping}, // 750 {NAP_PING, nap_ping}, // 751 {NAP_PONG, nap_pong}, // 752 {NAP_REDIRECT, nap_redirect}, // 821 {NAP_CYCLE, nap_cycle}, // 822 {NAP_EMOTE, nap_emote}, // 824 {NAP_NAMES_LIST, nap_user_online}, // 825 {NAP_FULL_CHANNEL_LIST, nap_channel_list_end}, // 827 {NAP_FULL_CHANNEL_INFO, nap_channel_list_entry},// 828 {NAP_NAMES_LIST_END, NULL}, // 830 {NAP_GUSER_LIST_END, nap_global_user_end}, // 831 {NAP_GUSER_LIST, nap_global_user}, // 832 {NAP_BLOCKMD5, NULL}, // 931 {NAP_LINKS, nap_server_links}, // 10112 {NAP_USAGE_STATS, nap_usage_stats}, // 10115 {NAP_WHO_WAS, nap_whowas}, // 10121 {NAP_HISTOGRAM, nap_histogram}, // 10123 {NAP_HISTOGRAM_END, nap_histogram_end}, // 10124 {NAP_SHISTOGRAM, nap_shistogram}, // 10125 {NAP_SHISTOGRAM_END, nap_shistogram_end}, // 10126 {NAP_VERSION_STATS, nap_version_stats}, // 10118 {NAP_USER_MODE, nap_user_mode}, // 10203 {NAP_CLASS_LIST, nap_acl_list}, // 10252 {NAP_DLINE_LIST, nap_acl_list}, // 10255 {NAP_ILINE_LIST, nap_acl_list}, // 10258 {NAP_ELINE_LIST, nap_acl_list}, // 10261 {NAP_BROWSE_NEW, nap_browse_end}, // 10301 {NAP_BROWSE_RESULT_NEW, nap_browse_new}, // 10302 }; HANDLER_ENTRY* search_handler_nap(int command) { int i1; int Protocol_Size; Protocol_Size = sizeof(Protocol_Napster) / sizeof(HANDLER_ENTRY); for (i1 = 0; i1 < Protocol_Size; i1++) { if (Protocol_Napster[i1].code == command) return &(Protocol_Napster[i1]); } return NULL; } HANDLER(nap_server_error) { nap_error_message(net, data); } HANDLER(nap_login_ack) { #ifdef HAVE_ZLIB char *email; char *compress; if (*data == ' ') { //bypass bug in opennap-ng email = NULL; compress = arg(data, 0); } else { email = arg(data, 0); compress = arg(NULL, 0); } if (compress) { net->compress = atoi(compress); /* printf("[ZLIB] [%s] compression level: %s\n", net->name, compress); */ } else { net->compress = 0; } #endif if (!net->active_server) return; if (!network_success(net)) { server_disconnect(net->active_server, "Server error", 0); return; } #ifdef PROTOCOL_DEBUG l_log(net, "protocol", LOG_PROTOCOL, "Connected to %s:%d\n", net->active_server->address, net->active_server->port); #endif } HANDLER(nap_register_fail) { (void)data; if (!net->active_server) return; server_disconnect(net->active_server, "Nick already registered", 0); } HANDLER(nap_bad_nick) { (void)data; if (!net->active_server) return; server_disconnect(net->active_server, "Invalid Nick", 0); } HANDLER(nap_search_response) { file_t *file; file = file_create_from_search_response(net, data); if (!file) return; // resume = resume_list_search_file(file); file_insert_search(file, DEST_NAPSTER); file_destroy(file); } HANDLER(nap_end_of_search) { (void)data; if (net->skip_search_end) { net->skip_search_end--; } else { search_finish_oldest(net); } } HANDLER(nap_download_ack) { socket_t *socket; download_t *download; char *username; int port; unsigned long ip_long; char *winname; char *md5; int linespeed; net_user_t* nu; transfer_t* trans; username = arg(data, 0); ip_long = strtoul(arg(NULL, 0), NULL, 10); port = atoi(arg(NULL, 0)); winname = arg(NULL, 0); md5 = arg(NULL, 0); // is ignored linespeed = atoi(arg(NULL, 0)); if (!winname) return; if (global.status.exiting == E_SAFE) return; socket = download_search_mapable(net, username, winname); if (!socket) { // printf("download not found [%s][%s]\n", winname, username); return; } if (!download_real_allowed()) { socket_end(socket, S_QUEUED); return; } if (socket->timer >= 0) { gtk_timeout_remove(socket->timer); socket->timer = -1; } download = socket->data; trans = TRANS(download); nu = download->nets->data; // dont allow peer to start DCCs if (trans->is_dcc) return; if (!download_grab_resume(socket, download->resume)) { socket_end(socket, S_QUEUED); return; } // set/update IP/port socket->port = htons(port); // host ->net socket->ip_long = BSWAP32(ip_long); // little->net // update linespeed trans->user_info->linespeed = linespeed; if (socket->port == 0) { if (!global.upload_socket) { socket_end(socket, S_FIREWALL); } else { command_send(net, CMD_DOWNLOAD_FIREWALL, username, download->file->winname); } } else { #ifdef TRANSFER_DEBUG printf("download ack [%s][%s]\n", username, winname); #endif transfer_connect_and_start(socket); } } HANDLER(nap_private_message) { char *username; char *message; username = arg(data, 0); message = arg(NULL, 1); if (dcc_check_message(username, message, net)) return; private_message(net, username, message); } HANDLER(nap_get_error) { socket_t *socket; char *username; char *winname; download_t* download; username = arg(data, 0); winname = arg(NULL, 0); if (!username || !winname) return; socket = download_search_mapable(net, username, winname); if (!socket) return; download = socket->data; if (!download) return; socket_end(socket, S_UNAVAILABLE); } HANDLER(nap_user_sign_on) { char *nick; char* speed; hot_t *hot; nick = arg(data, 0); speed = arg(NULL, 0); if (!nick) return; hot = hotlist_search_user(nick); if (!hot) return; if (speed) hot->speed = atoi(speed); else hot->speed = 0; hotlist_user_online(net, hot); } HANDLER(nap_user_sign_off) { char *nick; hot_t *hot; nick = arg(data, 0); if (!nick) return; hot = hotlist_search_user(nick); if (!hot) return; hotlist_user_offline(net, hot); } HANDLER(nap_browse_response) { file_t *file; browse_t* browse; file = file_create_from_browse_response(net, data); if (!file) return; browse = browse_search_user_net(file->user, file->net); if (!browse) { file_destroy(file); return; } browse_insert_file(browse, file); } HANDLER(nap_browse_end) { browse_t *browse; char *nick; char *ip; unsigned long ip_long; nick = arg(data, 0); ip = arg(NULL, 0); /* printf("browse end %s %s %s\n", nick, ip?ip:"NULL", net?net->name:"NULL"); */ browse = browse_search_user_net(nick, net); if (!browse) return; if (ip) { ip_long = BSWAP32(strtoul(ip, NULL, 10)); /* if (!g_strncasecmp(nick, net->user.username)) global.my_ip = ip_long; */ } else { ip_long = 0; } browse_finish(browse, ip_long); } HANDLER(nap_server_stats) { int files, gigs, users; server_t* server; server = net->active_server; sscanf(data, "%d %d %d", &users, &files, &gigs); server->users = users; server->files = files; server->gigs = gigs; server_update_stats(); server_update(net->active_server); network_update(net, 1); net_group_update(net->group); } HANDLER(nap_resume_match) { (void)net; (void)data; printf("(nap_resume_match) not definied\n"); /* (void)data; sscanf(data, "%s %*s %*s %s %*s %s %s", tstr[1], tstr[0], tstr[2], tstr[3]); strcpy(tstr[3], LineSpeed(atoi(tstr[3]))); temp = lookup_widget(global.resume_win, "clist2"); gtk_clist_append(GTK_CLIST(temp), list); */ } HANDLER(nap_hotlist_ack) { (void)data; (void)net; // doing nothing } HANDLER(nap_hotlist_error) { (void)net; (void)data; /* chat_page_t* page; char* prefix; page = chat_page_get_printable(); chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 0); chat_print_text(page, M_PUBLIC, "user", "["); chat_print_network(page, M_PUBLIC, net, 0, 1); chat_print_text(page, M_PUBLIC, "user", "] "); chat_print_text(page, M_PUBLIC, "user", "<"); chat_print_nick(page, M_PUBLIC, data, net); chat_print_text(page, M_PUBLIC, "user", "> "); chat_print_text(page, M_PUBLIC, "message", "Could not be added to your hotlist!\n"); */ } HANDLER(nap_disconnecting) { (void)data; server_message(net, "You will be disconnected\n"); } HANDLER(nap_ignore_user) { (void)net; ignore_add(data); } HANDLER(nap_unignore_user) { (void)net; ignore_remove(data); } HANDLER(nap_part_channel) { chat_page_t *page; page = chat_page_search(net, data, P_PUBLIC, 3); if (!page) return; destroy_channel(page); } HANDLER(nap_public_message) { char *channel; char *user; char *message; if (!data) return; channel = arg(data, 0); user = arg(NULL, 0); if (!user) return; message = arg(NULL, 1); public_message(net, channel, user, message); } int check_not_known1(net_t* net, char *data) { char *text; char *user; char *data2; if (!strncmp("User is not currently online", data, 28)) return 1; data2 = g_strdup(data); text = arg(data2, 0); if (!text) { g_free(data2); return 0; } if (g_strcasecmp("user", text)) { g_free(data2); return 0; } user = arg(NULL, 0); if (!user) { g_free(data2); return 0; } text = arg(NULL, 1); if (!text) { g_free(data2); return 0; } if (strncmp("is not a known user", text, 19)) { g_free(data2); return 0; } whois_eval_not_online(net, user); g_free(data2); return 1; } int check_not_known2(net_t* net, char *data) { char *text; char *user; char *data2; data2 = g_strdup(data); text = arg(data2, 0); if (!text) { g_free(data2); return 0; } if (g_strcasecmp("information", text)) { g_free(data2); return 0; } text = arg(NULL, 0); if (!text) { g_free(data2); return 0; } if (g_strcasecmp("on", text)) { g_free(data2); return 0; } user = arg(NULL, 0); if (!user) { g_free(data2); return 0; } text = arg(NULL, 1); if (!text) { g_free(data2); return 0; } if (strncmp("is not available", text, 16)) { g_free(data2); return 0; } whois_eval_not_online(net, user); g_free(data2); return 1; } int check_whois(net_t* net, char *data) { char *text; text = strchr(data, ' '); if (!text) return 0; if (strcmp(text+1, "has requested your info")) return 0; *text = 0; ext_handle(EVENT_WHOIS_REQUEST, data, net->name); *text = ' '; return 1; } void check_ping(net_t* net ATTR_UNUSED, char *data) { char *text; char *user; char *data2; user_timestamp_t *stamp; data2 = g_strdup(data); text = arg(data2, 0); if (!text) { g_free(data2); return; } if (g_strcasecmp("ping", text)) { g_free(data2); return; } text = arg(NULL, 0); if (!text) { g_free(data2); return; } if (g_strcasecmp("failed,", text)) { g_free(data2); return; } user = arg(NULL, 0); if (!user) { g_free(data2); return; } stamp = timestamp_search(global.userstamp, user); if (!stamp) return; global.userstamp = g_list_remove(global.userstamp, stamp); g_free(stamp->user); g_free(stamp); return; } void check_chat_page(net_t* net, char *data) { GList* dlist; chat_page_t *page; for (dlist = global.chat_pages; dlist; dlist = dlist->next) { page = dlist->data; if ((page->type != P_PUBLIC) && (page->type != P_PRIVATE)) continue; if (page->net != net) continue; if (!strcasestr(data, page->name)) continue; chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 0); chat_print_colored(page, M_PUBLIC, "error", data); chat_print_colored(page, M_PUBLIC, "error", "\n"); if (page == global.current_page) return; } page = global.current_page; if (page && strstr(data, net->user.username)) { chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 0); chat_print_text(page, M_PUBLIC, "user", "["); chat_print_network(page, M_PUBLIC, net, 0, 1); chat_print_text(page, M_PUBLIC, "user", "] "); chat_print_colored(page, M_PUBLIC, "error", data); chat_print_colored(page, M_PUBLIC, "error", "\n"); } } static int check_channel_kick(net_t* net, char* data) { char* temp; char* channel; char* who; char* reason; char* user; chat_page_t* page; if (!data) return 0; if (!strncmp("You were kicked from channel ", data, 29)) { temp = g_strdup(data+29); channel = arg(temp, 0); who = arg(NULL, 0); // by who = arg(NULL, 0); if (!who) { g_free(temp); return 0; } if (!g_strcasecmp(who, "server")) { who = arg(NULL, 0); who = NULL; } reason = arg(NULL, 1); if (who) who[strlen(who)-1] = 0; // we need to search also inactive pages, cause we get the part // message first page = chat_page_search(net, channel, P_PUBLIC, 3); if (page) user_parted(net, page, net->user.username, reason, -1, -1, 2, who); g_free(temp); return 1; } if (strstr(data, "kicked") && strstr(data, " out of channel ")) { temp = g_strdup(data); who = arg(temp, 0); if (who && !g_strcasecmp(who, "server")) { who = arg(temp, 0); who = NULL; } user = arg(NULL, 0); // kicked user = arg(NULL, 0); reason = arg(NULL, 1); if (!reason || strncmp("out of channel ", reason, 15)) { g_free(temp); return 0; } channel = arg(reason+15, 0); reason = arg(NULL, 1); if (!channel) { g_free(temp); return 0; } channel[strlen(channel)-1] = 0; if (!strcmp(user, net->user.username)) { g_free(temp); return 1; } page = chat_page_search(net, channel, P_PUBLIC, 1); if (page) user_parted(net, page, user, reason, -1, -1, 2, who); g_free(temp); return 1; } if (strstr(data, " cleared channel ")) { temp = g_strdup(data); who = arg(temp, 0); channel = arg(NULL, 0); // cleared channel = arg(NULL, 0); // channel channel = arg(NULL, 0); reason = arg(NULL, 1); if (!channel) { g_free(temp); return 0; } channel[strlen(channel)-1] = 0; page = chat_page_search(net, channel, P_PUBLIC, 1); if (page) { chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 0); chat_print_text(page, M_PUBLIC, "text", "("); chat_print_channel(page, M_PUBLIC, page->name, page->net); chat_print_text(page, M_PUBLIC, "text", ") "); chat_print_nick(page, M_PUBLIC, who, net); chat_print_text(page, M_PUBLIC, "error", " cleared the channel"); if (reason) { chat_print_text(page, M_PUBLIC, "error", ": "); chat_print_text(page, M_PUBLIC, "text", reason); } chat_print_text(page, M_PUBLIC, "text", "\n"); } g_free(temp); return 1; } return 0; } static int check_level_set(net_t* net, char* data) { char* pos; char* who; int level; chat_page_t* page; pos = strstr(data, " changed your user level to "); if (pos) { who = arg(data, 0); level = level2int(pos+28); if (level < 0) { pos = strchr(pos+28, '('); if (!pos) return 1; level = atoi(pos+1); // need to add one level on slavanap (and maybe other non-opennaps) // because there is no chatter if (net->subtype != N_OPENNAP && level >= L_CHAT) level++; } if (net->user.level != (unsigned)level) set_user_level(net, level); page = chat_page_get_printable(); chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 0); chat_print_text(page, M_PUBLIC, "user", "["); chat_print_network(page, M_PUBLIC, net, 0, 1); chat_print_text(page, M_PUBLIC, "user", "] "); chat_print_nick(page, M_PUBLIC, who, net); chat_print_text(page, M_PUBLIC, "error", " has set your user level to "); chat_print_text(page, M_PUBLIC, "text", Level(level)); chat_print_text(page, M_PUBLIC, "error", "\n"); return 1; } pos = strstr(data, " set your user level to "); if (pos) { level = level2int(pos+24); if (level < 0) { pos = strchr(pos+24, '('); if (!pos) return 1; level = atoi(pos+1); // need to add one level on slavanap (and maybe other non-opennaps) // because there is no chatter if (net->subtype != N_OPENNAP && level >= L_CHAT) level++; } if (net->user.level != (unsigned)level) set_user_level(net, level); page = chat_page_get_printable(); chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 0); chat_print_text(page, M_PUBLIC, "user", "["); chat_print_network(page, M_PUBLIC, net, 0, 1); chat_print_text(page, M_PUBLIC, "user", "]"); chat_print_text(page, M_PUBLIC, "error", " has set your user level to "); chat_print_text(page, M_PUBLIC, "text", Level(level)); chat_print_text(page, M_PUBLIC, "error", "\n"); return 1; } return 0; } static int chmode2int_nap(char* mode) { if (*mode == '+') mode++; else if (*mode == '-') mode++; if (!g_strcasecmp(mode, "REGISTERED")) return CMODE_REGISTERED; else if (!g_strcasecmp(mode, "TOPIC")) return CMODE_TOPIC; else if (!g_strcasecmp(mode, "PRIVATE")) return CMODE_PRIVATE; else if (!g_strcasecmp(mode, "INVITE")) return CMODE_INVITE; else if (!g_strcasecmp(mode, "MODERATED")) return CMODE_MODERATED; else return 0; } static int check_channel_mode(net_t* net, char* data) { char* channel; char* mode; char* temp; int chmode = 0; chat_page_t* page; if (strncmp("mode for channel ", data, 17)) return 0; temp = g_strdup(data+17); channel = arg(temp, 0); data = arg(NULL, 1); if (!channel) { g_free(temp); return 0; } page = chat_page_search(net, channel, P_PUBLIC, 1); if (!page) { g_free(temp); return 0; } while ((mode = arg(data, 0)) != NULL) { chmode |= chmode2int_nap(mode); data = NULL; } chmode ^= CMODE_TOPIC; // switch topic flag on napster channel_set_mode(page, NULL, chmode & CMODE_MASK_NAP, (~chmode) & CMODE_MASK_NAP, 0); g_free(temp); return 1; } static int check_channel_topic(net_t* net, char* data) { char* who; char* pos; char* temp; char* channel; char* topic; chat_page_t* page; pos = strstr(data, " set topic on "); if (!pos) return 0; temp = g_strdup(data); pos = strstr(temp, " set topic on "); *pos = 0; who = temp; pos += 14; channel = arg(pos, 0); if (!channel) { g_free(temp); return 0; } channel[strlen(channel)-1] = 0; topic = arg(NULL, 1); page = chat_page_search(net, channel, P_PUBLIC, 1); if (!page) return 0; channel_set_topic(page, who, topic, 0); g_free(temp); return 1; } static int check_channel_mode2(net_t* net, char* data) { char* who; char* pos; char* temp; char* channel; char* mode; int chmode1 = 0; int chmode2 = 0; chat_page_t* page; pos = strstr(data, " changed mode on channel "); if (!pos) return 0; temp = g_strdup(data); pos = strstr(temp, " changed mode on channel "); *pos = 0; who = temp; pos += 25; channel = arg(pos, 0); if (!channel) { g_free(temp); return 0; } channel[strlen(channel)-1] = 0; data = arg(NULL, 1); if (!data) return 0; page = chat_page_search(net, channel, P_PUBLIC, 1); if (!page) return 0; while ((mode = arg(data, 0)) != NULL) { if (*mode == '+') chmode1 |= chmode2int_nap(mode); else if (*mode == '-') chmode2 |= chmode2int_nap(mode); data = NULL; } if (chmode1 & CMODE_TOPIC) { chmode1 &= ~CMODE_TOPIC; chmode2 |= CMODE_TOPIC; } else if (chmode2 & CMODE_TOPIC) { chmode2 &= ~CMODE_TOPIC; chmode1 |= CMODE_TOPIC; } channel_set_mode(page, who, chmode1, chmode2, 0); g_free(temp); return 1; } static int check_channel_wallop(net_t* net, char *data) { char *pos; char *nick; char *message; char *channel; pos = strchr(data, ' '); if (!pos) return 0; if (strncmp(pos, " [ops/", 5)) return 0; nick = arg(data, 0); if (!nick) return 1; pos = arg(NULL, 0); message = arg(NULL, 1); channel = strchr(pos, '/') + 1; if (!channel) return 1; pos = strchr(channel, ']'); if (pos) *pos = 0; public_wallop(net, channel, nick, message); return 1; } static int check_channel_limit_level(net_t* net, char* data) { char* channel; char* temp; char* rest; chat_page_t* page; if (net->subtype == N_OPENNAP || net->subtype == N_OPENNAP_NG) { if (strncmp("Channel ", data, 8)) return 0; temp = g_strdup(data+8); channel = arg(temp, 0); if (!channel) { g_free(temp); return 0; } rest = arg(NULL, 1); if (!rest) { g_free(temp); return 0; } if (!strncmp("has limit ", rest, 10)) { page = chat_page_search(net, channel, P_PUBLIC, 1); if (page) channel_set_limit(page, NULL, atoi(rest+10), 0); g_free(temp); return 1; } if (!strncmp("is level ", rest, 9)) { page = chat_page_search(net, channel, P_PUBLIC, 1); if (page) channel_set_level(page, NULL, level2int(rest+9), 0); g_free(temp); return 1; } g_free(temp); return 1; } /* if (server->network == N_SLAVANAP) { } */ return 0; } int check_channel_limit(net_t* net, char* data) { char* who; char* pos1; char* channel; char* limit; char* temp; chat_page_t* page; pos1 = strstr(data, " set limit on channel "); if (!pos1) return 0; temp = g_strdup(data); pos1 = strstr(temp, " set limit on channel "); *pos1 = 0; who = temp; pos1 += 22; channel = arg(pos1, 0); pos1 = arg(NULL, 0); limit = arg(NULL, 0); if (!limit) { g_free(temp); return 0; } page = chat_page_search(net, channel, P_PUBLIC, 1); if (!page) return 0; channel_set_limit(page, who, atoi(limit), 0); g_free(temp); return 1; } int check_channel_level(net_t* net, char* data) { char* who; char* pos1; char* pos2; char* channel; char* level; char* temp; chat_page_t* page; pos1 = strstr(data, " set channel "); pos2 = strstr(data, " to level "); if (!pos1 || !pos2) return 0; temp = g_strdup(data); pos1 = strstr(temp, " set channel "); pos2 = strstr(temp, " to level "); *pos1 = 0; *pos2 = 0; who = arg(data, 0); pos1 += 13; pos2 += 10; channel = arg(pos1, 0); level = arg(pos2, 0); if (!channel || !level) { g_free(temp); return 0; } page = chat_page_search(net, channel, P_PUBLIC, 1); if (!page) return 0; channel_set_level(page, who, level2int(level), 0); g_free(temp); return 1; } int check_search_valid_words(net_t* net, char* data) { search_t* search; GList* dlist; if (strcmp(data, "search failed: request contained no valid words")) return 0; server_message(net, "%s", data); if (!net->active_searches) { server_message(net, "[Search]: No active search found!"); return 1; } server_message(net, "[Search]: Potential searches are:"); for (dlist = net->active_searches; dlist; dlist = dlist->next) { search = dlist->data; server_message(net, "[Search]: Search String: (%s)", search->pattern->include); } return 1; } void check_pending_searches(net_t* net, char *data) { search_t* search; if (!strcmp(data, "search failed: too many pending searches")) { if (net->subtype == N_SLAVANAP) { // we do too many searches per minute. if (net->max_searches_pm > 1) net->max_searches_pm--; net->skip_search_end++; } else if (net->subtype == N_OPENNAP || net->subtype == N_OPENNAP_NG) { // we do too many concurrent searches if (net->max_searches > 1) net->max_searches--; } else if (net->max_searches > 1) { /* UNKNOWN server type below*/ // we have assumed opennap style (default on unknown servers) net->max_searches--; } else if (net->max_searches_pm > 1) { // we had switched to slavanap style, now adjust the values net->max_searches_pm--; net->skip_search_end++; } else if (net->max_searches_pm == 0) { // we have opennap style, but it seems the wrong one, // switch to slavanap style now. net->max_searches_pm = 3; } #ifdef SEARCH_DEBUG printf("[SEARCH] too many pending on %s [%d][%d][%d]\n", net->name, net->cur_searches, net->max_searches, net->max_searches_pm); #endif search = search_finish_latest(net); if (search) { #ifdef SEARCH_DEBUG printf("[SEARCH] (%s) was finished, requeuing\n", search->pattern->include?search->pattern->include:"null"); #endif search_queue(search, net, 1); } } } static void check_share_limit(net_t* net, char *data) { if (!strncmp(data, "You may only share ", 19)) { net->max_share = atoi(data+19); #ifdef SHARE_DEBUG printf("[SHARE] max share limited to %d\n", net->max_share); #endif } } int check_locate(net_t* net, char *data) { char* data2 = g_strdup(data); char* user; char* rest; chat_page_t* page; user = arg(data2, 0); rest = arg(NULL, 1); if (!user || !rest) { g_free(data2); return 0; } if (strncmp(rest, "is on ", 6)) { g_free(data2); return 0; } page = chat_page_get_printable(); chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 0); chat_print_text(page, M_PUBLIC, "user", "<"); chat_print_nick(page, M_PUBLIC, user, net); chat_print_text(page, M_PUBLIC, "user", "> "); chat_print_text(page, M_PUBLIC, "error", "is on "); chat_print_text(page, M_PUBLIC, "text", rest+6); chat_print_text(page, M_PUBLIC, "user", " ["); chat_print_network(page, M_PUBLIC, net, 0, 1); chat_print_text(page, M_PUBLIC, "user", "]\n"); g_free(data2); return 1; } static int check_server_pong(net_t* net, char *data) { char *serv; char *temp; char *ping; link_t *link; if (strncmp("Pong from server", data, 16)) return 0; temp = g_strdup(data + 17); serv = arg(temp, 0); ping = arg(NULL, 0); if (ping) ping++; else { g_free(temp); return 1; } if ((link = link_search_rec(net->links, serv)) == NULL) { g_free(temp); return 1; } if (link->ping) g_free(link->ping); link->ping = g_strdup(ping); g_free(temp); return 1; } static int check_op_voice_ban(net_t* net, char *data) { char* data2; char* who; char* pos1; char* nick = NULL; chat_page_t* page; int flag = -1; int set = 0; if (!data) return 0; data2 = g_strdup(data); who = arg(data2, 0); if (!who) { g_free(data2); return 0; } if (!strcmp("Server", who)) who = arg(NULL, 0); pos1 = arg(NULL, 1); if (!pos1) { g_free(data2); return 0; } if (!strncmp(pos1, "opped ", 6)) { nick = arg(pos1+6, 0); flag = CU_OP; set = 1; } if (!strncmp(pos1, "deopped ", 8)) { nick = arg(pos1+8, 0); flag = CU_OP; set = 0; } if (!strncmp(pos1, "voiced ", 7)) { nick = arg(pos1+7, 0); flag = CU_VOICE; set = 1; } if (!strncmp(pos1, "devoiced ", 9)) { nick = arg(pos1+9, 0); flag = CU_VOICE; set = 0; } if (!strncmp(pos1, "muzzled ", 8)) { nick = arg(pos1+7, 0); flag = CU_MUZZLED; set = 1; } if (!strncmp(pos1, "unmuzzled ", 10)) { nick = arg(pos1+9, 0); flag = CU_MUZZLED; set = 0; } if (flag != -1) { pos1 = arg(NULL, 1); if (!pos1) { g_free(data2); return 0; } // nick cant be NULL here, unless pos1 is NULL if (!strncmp(pos1, "on channel ", 11)) { char* channel; char* reason; channel = arg(pos1+11, 0); if (!channel) { g_free(data2); return 0; } if (channel[strlen(channel)-1] == ':') { channel[strlen(channel)-1] = 0; reason = arg(NULL, 1); } else { reason = NULL; } page = chat_page_search(net, channel, P_PUBLIC, 3); if (page) user_flagged(page, who, nick, set, flag, reason); g_free(data2); return 1; } g_free(data2); return 0; } flag = -1; if (!strncmp(pos1, "banned ", 7)) { nick = arg(pos1+7, 0); flag = CU_BANNED; set = 1; } if (!strncmp(pos1, "unbanned ", 9)) { nick = arg(pos1+9, 0); flag = CU_BANNED; set = 0; } if (flag != -1) { pos1 = arg(NULL, 1); if (!pos1) { g_free(data2); return 0; } // nick cant be NULL here, unless pos1 is NULL if (!strncmp(pos1, "from ", 5)) { char* channel; char* reason; channel = arg(pos1+5, 0); if (!channel) { g_free(data2); return 0; } channel[strlen(channel)-1] = 0; reason = arg(NULL, 1); page = chat_page_search(net, channel, P_PUBLIC, 3); if (page) user_flagged(page, who, nick, set, flag, reason); g_free(data2); return 1; } g_free(data2); return 0; } if ((who = strstr(pos1, " as operator on channel ")) != NULL) { nick = arg(pos1, 0); nick = arg(NULL, 0); nick = arg(NULL, 0); page = chat_page_search(net, who+24, P_PUBLIC, 3); if (page) user_flagged(page, ".", net->user.username, 1, CU_OP, NULL); g_free(data2); return 1; } g_free(data2); return 0; } HANDLER(nap_error_message) { if (!data) return; if (check_channel_wallop(net, data)) return; if (check_locate(net, data)) return; if (check_not_known1(net, data)) return; if (check_not_known2(net, data)) return; if (check_search_valid_words(net, data)) return; check_share_limit(net, data); check_whois(net, data); check_server_join_quit(net, data); check_server_pong(net, data); if (check_op_voice_ban(net, data)) return; check_pending_searches(net, data); check_ping(net, data); if (check_channel_kick(net, data)) return; if (check_level_set(net, data)) return; if (check_channel_topic(net, data)) return; if (check_channel_mode(net, data)) return; if (check_channel_mode2(net, data)) return; if (check_channel_limit_level(net, data)) return; if (check_channel_level(net, data)) return; if (check_channel_limit(net, data)) return; check_chat_page(net, data); server_message(net, "%s", data); l_log(net, "Messages", LOG_MESSAGE, "%s\n", data); if (net->active_server->status == SERVER_CONNECTING) server_disconnect(net->active_server, data, 1); } HANDLER(nap_create_channel) { char* channel; chat_page_t* page; channel = arg(data, 0); if (!channel) return; page = chat_page_search(net, channel, P_PUBLIC, 3); if (!page) { // we havent requested the join! command_send(net, CMD_PART, channel, "I haven't requested to listen to that channel!"); return; } channel_join_ack(page); } HANDLER(nap_join_message) { char *channel; char *user; char *link; char *share; chat_page_t *page; channel = arg(data, 0); user = arg(NULL, 0); share = arg(NULL, 0); link = arg(NULL, 0); if (!link) return; page = chat_page_search(net, channel, P_PUBLIC, 1); if (!page) return; user_joined(page, user, atoi(share), atoi(link)); } HANDLER(nap_part_message) { char *channel; char *user; char *link; char *share; chat_page_t *page; channel = arg(data, 0); user = arg(NULL, 0); share = arg(NULL, 0); link = arg(NULL, 0); if (!link) return; page = chat_page_search(net, channel, P_PUBLIC, 3); if (!page) return; user_parted(net, page, user, NULL, atoi(share), atoi(link), 0, NULL); } HANDLER(nap_user_online) { char *channel; char *user; char *share; char *speed; chat_page_t *page; channel = arg(data, 0); user = arg(NULL, 0); share = arg(NULL, 0); speed = arg(NULL, 0); if (!speed) return; page = chat_page_search(net, channel, P_PUBLIC, 3); if (!page) return; user_online(page, user, atoi(share), atoi(speed), -1); } HANDLER(nap_channel_topic) { char *room; char *topic; chat_page_t *page; room = arg(data, 0); topic = arg(NULL, 1); if (!room) return; page = chat_page_search(net, room, P_PUBLIC, 1); if (!page) return; channel_set_topic(page, NULL, topic, 2); } HANDLER(nap_banlist_entry) { char* nick; char* sender; char* reason; char* when; char* timeout; time_t l1; time_t l2; GtkWidget *temp; (void)net; if (!global.ban_win) return; temp = lookup_widget(global.ban_win, "clist3"); nick = arg(data, 0); sender = arg(NULL, 0); reason = arg(NULL, 0); when = arg(NULL, 0); timeout = arg(NULL, 0); if (!timeout) return; strcpy(tstr[0], nick); strcpy(tstr[1], sender); strcpy(tstr[3], reason); l1 = strtoul(when, NULL, 10); if (timeout) { l2 = strtoul(timeout, NULL, 10); strcpy(tstr[2], ctime(&l1)); tstr[2][strlen(tstr[2])-1] = 0; if (l2 > 0) { l2 += l1; strcat(tstr[2], " (expires "); strcat(tstr[2], ctime(&l2)); tstr[2][strlen(tstr[2])-1] = 0; strcat(tstr[2], ")"); } } else { sprintf(tstr[2], "%s", ctime(&l1)); } gtk_clist_append(GTK_CLIST(temp), list); } HANDLER(nap_channel_alt_topic) { (void)net; client_message("Additional Topic", "%s", data); } HANDLER(nap_alternate_ack) { transfer_t *trans; socket_t *socket; char *username; char *ip; char *port; char *winname; char *md5; char *linespeed; username = arg(data, 0); ip = arg(NULL, 0); port = arg(NULL, 0); winname = arg(NULL, 0); md5 = arg(NULL, 0); linespeed = arg(NULL, 0); if (!winname) return; socket = upload_search_mapable(net, username, winname); if (!socket || !socket->data) return; trans = TRANS(socket->data); if (trans->status != S_WAITING) return; trans->user_info->linespeed = atoi(linespeed); socket->port = htons(atoi(port)); socket->ip_long = BSWAP32(strtoul(ip, NULL, 10)); // upload->segment->stop = upload->file->size; if (socket->port == 0) { socket_end(socket, S_FIREWALL); } else { transfer_connect_and_start(socket); } } HANDLER(nap_linkspeed_response) { char *nick; char *linespeed; speed_t *speed; // printf("**** linkspeed response [%s]\n", data); nick = arg(data, 0); linespeed = arg(NULL, 0); if (!nick || !linespeed) return; speed = speed_search(net, nick); if (!speed) return; speed->speed = atoi(linespeed); speed_action(speed); } HANDLER(nap_eval_whois) { whois_eval_whois(net, data); } HANDLER(nap_eval_whowas) { whois_eval_whowas(net, data); } void upload_queue(upload_t* upload); HANDLER(nap_upload_request) { socket_t *socket; char *username; char *winname; char *speed; subscription_t* sub; char* found; file_t* file; file_node_t* node; upload_t* upload; transfer_t* trans = NULL; username = arg(data, 0); winname = arg(NULL, 0); speed = arg(NULL, 0); if (!username || !winname) return; // do not allow uploads from enemies if (string_list_search(LIST_ENEMY, username)) return; socket = upload_search_mapable(net, username, winname); if (!socket) { node = file_tree_search_winname(FILE_TREE(global.lib), NULL, winname); if (!node || ((node->flags & LIB_SHARED) == 0)) return; upload = upload_new(net, node->file->longname, username, node->flags&LIB_VIRTUAL); trans = TRANS(upload); file = upload->file; socket = socket_new(S_UPLOAD); socket->data = upload; if (speed) trans->user_info->linespeed = atoi(speed); // upload->size = file->size; upload_show(socket); sub = subscription_lookup_file(username, file->longname, &found); if (sub && !found) { chat_page_t* page = chat_page_get_printable(); chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 1); chat_print_text(page, M_PUBLIC, "user", "<"); chat_print_nick(page, M_PUBLIC, username, net); chat_print_text(page, M_PUBLIC, "user", "> "); chat_print_text(page, M_PUBLIC, "message", "has requested a not subscribed file ["); chat_print_file(page, file->longname, file->filename); chat_print_text(page, M_PUBLIC, "user", "\n"); found = g_strdup_printf("Automatic Notification: File [%s] was not subscribed by you, this request will be queued", file->shortname); send_notice(net, username, found, 0); g_free(found); send_notice(net, username, "To view your subscriptions, send me a private message: '!Subscription'", 0); } ext_handle(EVENT_UPLOAD_REQUEST, username, winname); } else { upload = socket->data; trans = TRANS(upload); // updating network upload->nu.net = net; user_info_get(trans->user_info, net); } /* only count now if access_transferring is not enabled */ if (!global.options.access_transferring) access_new_request(upload); if (!transfer_in_progress(trans)) { if (trans->status == S_QUEUED) { // immediately send queue upload_queue(upload); } else { upload_status_set(socket, S_REQUESTED); check_uploads_again(); } } } HANDLER(nap_set_port) { int port; chat_page_t* page = chat_page_get_printable(); char* text; port = atoi(data); chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 1); chat_print_text(page, M_PUBLIC, "message", "Server"); chat_print_text(page, M_PUBLIC, "user", " ["); chat_print_network(page, M_PUBLIC, net, 0, 1); chat_print_text(page, M_PUBLIC, "user", "] "); text = g_strdup_printf("has set your data port to %d\n", port); chat_print_text(page, M_PUBLIC, "message", text); g_free(text); create_upload_port(port, FALSE); } HANDLER(nap_channel_list) { char* name; char* online; char* topic; name = arg(data, 0); online = arg(NULL, 0); topic = arg(NULL, 1); if (!online) return; channel_entry_new(net, name, online, topic, NULL, NULL); } HANDLER(nap_remote_queued) { // GList *dlist; // GList *result; socket_t *socket; download_t *download; char *username; char *winname; char* queue; username = arg(data, 0); winname = arg(NULL, 0); queue = arg(NULL, 0); queue = arg(NULL, 0); if (!username || !winname) return; // printf("remote [%s][%s]\n", user, winname); socket = download_search_mapable(net, username, winname); if (!socket) return; download = socket->data; if (queue) download->queue = atoi(queue); if (TRANS(download)->status == S_WAITING) socket_end(socket, S_REMOTE); return; ////////////////////////////////////////////// // find all queued transfer from this user /* result = NULL; for (dlist = global.sockets; dlist; dlist = dlist->next) { socket = (socket_t *) (dlist->data); if (socket->type != S_TRANSFER) continue; transfer = (transfer_t *) (socket->data); if (!transfer) continue; if (transfer->type != T_DOWNLOAD) continue; if (transfer->status != S_QUEUED) continue; if (strcmp(transfer->user_info->user, user)) continue; result = g_list_append(result, socket); } // now remote queue the transfers for (dlist = result; dlist; dlist = dlist->next) { result = g_list_find(global.sockets, dlist->data); if (!result) continue; // socket not in downloads any more socket = (socket_t *) (result->data); transfer = (transfer_t *) (socket->data); if (transfer->status != S_QUEUED) continue; //transfer not queued anymore socket_end(socket, S_REMOTE); } */ } HANDLER(nap_motd) { server_t *server; server = net->active_server; if (net->subtype == -1) { get_version(net, data); if (net->subtype == N_OPENNAP || net->subtype == N_OPENNAP_NG) { // fast search (opennap's the better one) net->max_searches_pm = 0; net->max_searches = 3; } else if (net->subtype == N_SLAVANAP) { // slow search net->max_searches_pm = 3; net->max_searches = 1; } else { // first try the fast version net->max_searches_pm = 0; net->max_searches = 1; } network_go(net); } if (!net->links) get_server(net, data); motd_message(net, data); } HANDLER(nap_data_port_error) { chat_page_t* page = chat_page_get_printable(); char* nick; char* port; nick = arg(data, 0); port = arg(NULL, 0); if (!nick) return; chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 1); chat_print_text(page, M_PUBLIC, "user", "<"); chat_print_nick(page, M_PUBLIC, nick, net); chat_print_text(page, M_PUBLIC, "user", "> "); chat_print_text(page, M_PUBLIC, "message", "reports that your dataport is not reachable!\n"); } HANDLER(nap_operator_message) { char *user; char *message; user = arg(data, 0); message = arg(NULL, 1); if (!user) return; operator_message(net, user, message); } HANDLER(nap_global_message) { char *user; char *message; user = arg(data, 0); message = arg(NULL, 1); if (!user) return; global_message(net, user, message); } HANDLER(nap_nick_banlist) { GtkWidget *temp; (void)net; if (!global.ban_win) return; temp = lookup_widget(global.ban_win, "clist3"); strcpy(tstr[0], data); tstr[1][0] = 0; tstr[2][0] = 0; tstr[3][0] = 0; gtk_clist_append(GTK_CLIST(temp), list); } HANDLER(nap_browse_direct) { socket_t *socket; char *nick; char *ip; char *port; if (!data) return; nick = arg(data, 0); if (!nick) return; ip = arg(NULL, 0); port = arg(NULL, 0); if (string_list_search(LIST_ENEMY, nick)) return; ext_handle(EVENT_DIRECT_BROWSE, nick, net->name); socket = socket_new(S_SHARE); socket->data = share_new(net, nick); share_show(socket); if (ip && port) { socket->port = htons(atoi(port)); socket->ip_long = BSWAP32(strtoul(ip, NULL, 10)); share_status_set(socket, S_CONNECTING); if (!connect_socket(socket, "TCP", SOCK_STREAM)) { socket_destroy(socket, 0); return; } socket->input = gdk_input_add(socket->fd, GDK_INPUT_READ, GTK_SIGNAL_FUNC(await_conn_ack3), socket); } else { share_status_set(socket, S_WAITING); command_send(net, CMD_BROWSE_DIRECT_OK, nick); } } HANDLER(nap_browse_direct_ok) { char *nick; char *ip; char *port; socket_t *socket; (void)net; nick = arg(data, 0); ip = arg(NULL, 0); port = arg(NULL, 0); if (!nick || !ip || !port) return; if (atoi(port) > 0) { socket = browse_search_socket(nick); if (!socket) return; socket->port = htons(atoi(port)); socket->ip_long = BSWAP32(strtoul(ip, NULL, 10)); browse_connect_and_start(socket); } } HANDLER(nap_browse_direct_err) { char *nick; char *message; socket_t *socket; (void)net; nick = arg(data, 0); message = arg(NULL, 0); socket = browse_search_socket(nick); if (!socket) return; client_message("Browse", "%s", message); socket_destroy(socket, 0); } HANDLER(nap_ghost) { (void)data; server_message(net, "Someone else is trying to login with your Nick"); } HANDLER(nap_sping) { char *serv; user_timestamp_t *stamp; (void)net; serv = arg(data, 0); if (!serv) return; stamp = timestamp_search(global.userstamp, serv); if (!stamp) { // client_message("Message", "Unrequested pong from %s", nick); } else { client_message("Message", "Pong from server <%s> [%d ms]", serv, timestamp_difference(stamp)); global.userstamp = g_list_remove(global.userstamp, stamp); g_free(stamp->user); g_free(stamp); } } HANDLER(nap_ping) { char* nick; char* add; chat_page_t* page; int ignored = 0; nick = arg(data, 0); add = arg(NULL, 1); if (!nick) return; // just reply slavanap server pings if (!strcmp(nick, "server")) { command_send(net, CMD_PONG, "server"); return; } if (string_list_search(LIST_IGNORE, nick)) { if (global.options.no_piping & NOPIPE_IGNORE) return; page = chat_page_search(NULL, "Ignored", P_OTHER, 3); if (!page) page = create_other_page(NULL, "Ignored", "Ignored users"); ignored = 1; } else { page = chat_page_get_printable(); } chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 1); chat_print_text(page, M_PUBLIC, "user", "<"); chat_print_nick(page, M_PUBLIC, nick, net); chat_print_text(page, M_PUBLIC, "user", "> "); if (add) { chat_print_text(page, M_PUBLIC, "message", "("); chat_print_colored(page, M_PUBLIC, "message", add); chat_print_text(page, M_PUBLIC, "message", ") "); } chat_print_text(page, M_PUBLIC, "message", "has pinged you!\n"); if (nick && !ignored) command_send(net, CMD_PONG, nick); } HANDLER(nap_pong) { char *nick; user_timestamp_t *stamp; char* add; chat_page_t* page; char t[1024]; nick = arg(data, 0); if (!nick) return; add = arg(NULL, 1); stamp = timestamp_search(global.userstamp, nick); if (!stamp) return; page = chat_page_get_printable(); chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 1); chat_print_text(page, M_PUBLIC, "message", "Pong from "); chat_print_text(page, M_PUBLIC, "user", "<"); chat_print_nick(page, M_PUBLIC, nick, net); chat_print_text(page, M_PUBLIC, "user", "> "); if (add) { chat_print_text(page, M_PUBLIC, "message", "("); chat_print_colored(page, M_PUBLIC, "message", add); chat_print_text(page, M_PUBLIC, "message", ")"); } sprintf(t, "[%d ms]\n", timestamp_difference(stamp)); chat_print_text(page, M_PUBLIC, "message", t); global.userstamp = g_list_remove(global.userstamp, stamp); g_free(stamp->user); g_free(stamp); } HANDLER(nap_emote) { char *channel; char *user; char *message; channel = arg(data, 0); user = arg(NULL, 0); if (!user) return; message = arg(NULL, 0); // quoted public_emote(net, channel, user, message); } HANDLER(nap_channel_list_entry) { char* name; char* online; char* limit; char* level; char* topic; name = arg(data, 0); online = arg(NULL, 0); level = arg(NULL, 0); level = arg(NULL, 0); limit = arg(NULL, 0); topic = arg(NULL, 0); if (!online) return; channel_entry_new(net, name, online, topic, limit, level); } HANDLER(nap_channel_list_end) { chat_page_t* page; (void)data; page = chat_page_search(net, "Channels", P_CHANNEL, 3); if (page) channel_list_end(page); } HANDLER(nap_global_user_end) { GtkWidget *temp; (void)data; (void)net; if (!global.user_win) return; temp = lookup_widget(global.user_win, "button164"); gtk_widget_set_sensitive(temp, TRUE); } HANDLER(nap_global_user) { char *nick; char *ip; GtkCList *clist; nick = arg(data, 0); ip = arg(NULL, 0); (void)net; if (!global.user_win) return; clist = GTK_CLIST(lookup_widget(global.user_win, "clist12")); strcpy(tstr[0], nick); strcpy(tstr[1], ip); gtk_clist_append(clist, list); } HANDLER(nap_server_links) { network_new_link(net, data); } HANDLER(nap_whowas) { char *pos1; GtkEntry *entry; GtkWidget *temp; time_t last_seen; char str[200]; if (global.whois_win == NULL) { global.whois_win = create_whois_win(); } gtk_widget_show(global.whois_win); gtk_object_set_data(GTK_OBJECT(global.whois_win), "network", net); gtk_window_set_title(GTK_WINDOW(global.whois_win), "Whowas User"); temp = lookup_widget(global.whois_win, "label116"); gtk_label_set_text(GTK_LABEL(temp), "Last Seen"); pos1 = arg(data, 0); temp = lookup_widget(global.whois_win, "label527"); gtk_label_set_text(GTK_LABEL(temp), pos1); pos1 = arg(NULL, 0); entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry61")); gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); gtk_entry_set_text(entry, ntoa(BSWAP32(strtoul(pos1, NULL, 10)))); pos1 = arg(NULL, 0); entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry62")); gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); gtk_entry_set_text(entry, pos1); pos1 = arg(NULL, 0); entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry26")); gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); last_seen = strtoul(pos1, NULL, 10); sprintf(str, "%s", ctime(&last_seen)); gtk_entry_set_text(entry, str); // -- temp = lookup_widget(global.whois_win, "entry25"); gtk_entry_set_text(GTK_ENTRY(temp), ""); gtk_widget_set_sensitive(temp, FALSE); temp = lookup_widget(global.whois_win, "entry28"); gtk_entry_set_text(GTK_ENTRY(temp), ""); gtk_widget_set_sensitive(temp, FALSE); temp = lookup_widget(global.whois_win, "entry60"); gtk_entry_set_text(GTK_ENTRY(temp), ""); gtk_widget_set_sensitive(temp, FALSE); temp = lookup_widget(global.whois_win, "entry27"); gtk_entry_set_text(GTK_ENTRY(temp), ""); gtk_widget_set_sensitive(temp, FALSE); temp = lookup_widget(global.whois_win, "entry30"); gtk_entry_set_text(GTK_ENTRY(temp), ""); gtk_widget_set_sensitive(temp, FALSE); temp = lookup_widget(global.whois_win, "entry59"); gtk_entry_set_text(GTK_ENTRY(temp), ""); gtk_widget_set_sensitive(temp, FALSE); temp = lookup_widget(global.whois_win, "table18"); gtk_widget_hide(temp); } void print_stat_message(chat_page_t* page, char* tag, char* message) { chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 0); chat_print_text(page, M_PUBLIC, "error", tag); chat_print_text(page, M_PUBLIC, "user", " : "); chat_print_text(page, M_PUBLIC, "text", message); chat_print_text(page, M_PUBLIC, "text", "\n"); } char* get_tag(int id) { switch (id) { case 0: return "Local Clients "; case 1: return "Local Servers "; case 2: return "Users "; case 3: return "Files "; case 4: return "Channels "; case 5: return "Boot Time "; case 6: return "Uptime "; case 7: return "Memory "; case 8: return "Registered Users"; case 9: return "KBytes In/sec "; case 10: return "KBytes Out/sec "; case 11: return "Searches/sec "; case 12: return "Traffic In "; case 13: return "Traffic Out "; case 14: return "Pending Searches"; default: return "Unknown "; } } HANDLER(nap_usage_stats) { char *pos; char *pos2; time_t stime; int t1; char str[1024]; char str2[1024]; double gigs; chat_page_t* page; (void)net; page = chat_page_get_printable(); pos = arg(data, 0); print_stat_message(page, get_tag(0), pos); pos = arg(NULL, 0); print_stat_message(page, get_tag(1), pos); pos = arg(NULL, 0); print_stat_message(page, get_tag(2), pos); pos = arg(NULL, 0); pos2 = arg(NULL, 0); gigs = strtod(pos2, NULL); print_size(str, gigs); sprintf(str2, "%s (%s)", pos, str); print_stat_message(page, get_tag(3), str2); pos = arg(NULL, 0); print_stat_message(page, get_tag(4), pos); pos = arg(NULL, 0); sscanf(pos, "%ld", &stime); strcpy(str, ctime(&stime)); str[strlen(str) - 1] = 0; print_stat_message(page, get_tag(5), str); pos = arg(NULL, 0); t1 = strtoul(pos, NULL, 10); sprintf(str, "%d days %d hours %d minutes %d seconds", t1 / (60 * 60 * 24), (t1 % (60 * 60 * 24)) / (60 * 60), (t1 % (60 * 60)) / 60, t1 % 60); print_stat_message(page, get_tag(6), str); pos = arg(NULL, 0); if (!pos) return; print_stat_message(page, get_tag(7), pos); pos = arg(NULL, 0); if (!pos) return; print_stat_message(page, get_tag(8), pos); pos = arg(NULL, 0); if (!pos) return; print_stat_message(page, get_tag(9), pos); pos = arg(NULL, 0); if (!pos) return; print_stat_message(page, get_tag(10), pos); pos = arg(NULL, 0); if (!pos) return; print_stat_message(page, get_tag(11), pos); pos = arg(NULL, 0); if (!pos) return; gigs = strtod(pos, NULL); print_size(str, gigs); print_stat_message(page, get_tag(12), str); pos = arg(NULL, 0); if (!pos) return; gigs = strtod(pos, NULL); print_size(str, gigs); print_stat_message(page, get_tag(13), str); pos = arg(NULL, 0); if (!pos) return; print_stat_message(page, get_tag(14), pos); } HANDLER(nap_version_stats) { GtkCList *clist; GdkColor color = { 0, 0x9900, 0x0f00, 0x0f00 }; GtkWidget *temp; GList *dlist; char *info; char *number; client_t *client; client_t *client2; char *short_info; int flag; int threshold; int row; (void)net; if (!global.client_win) return; clist = GTK_CLIST(lookup_widget(global.client_win, "clist8")); if (*data) { info = arg(data, 0); number = arg(NULL, 0); client = (client_t *) g_malloc(sizeof(client_t)); client->cnt = 0; client->info = g_strdup(info); if (number) client->logins = atoi(number); else client->logins = 0; global.client_list = g_list_append(global.client_list, client); short_info = strtok(info, " -"); if (!short_info) short_info = info; client2 = is_client_in_list(global.client_list, short_info); if (!client2) { client2 = (client_t *) g_malloc(sizeof(client_t)); client2->cnt = 1; client2->info = g_strdup(short_info); client2->logins = client->logins; global.client_list = g_list_append(global.client_list, client2); } else { client2->cnt++; client2->logins += client->logins; } return; } temp = lookup_widget(global.client_win, "checkbutton30"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(temp))) { temp = lookup_widget(global.client_win, "spinbutton19"); threshold = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(temp)); } else { threshold = 0; } flag = 0; temp = lookup_widget(global.client_win, "checkbutton32"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(temp))) flag |= 1; // single temp = lookup_widget(global.client_win, "checkbutton31"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(temp))) flag |= 2; // sum gtk_clist_freeze(clist); dlist = g_list_first(global.client_list); while (dlist) { client = (client_t *) (dlist->data); if (client->logins >= threshold) { if ((client->cnt == 0) && (flag & 1)) { strcpy(tstr[1], client->info); sprintf(tstr[0], "%d", client->logins); row = gtk_clist_append(clist, list); } if ((client->cnt > 0) && (flag & 2)) { sprintf(tstr[1], "%s%s", client->info, (flag & 1) ? " (SUM)" : ""); sprintf(tstr[0], "%d", client->logins); row = gtk_clist_append(clist, list); if (flag & 1) { gdk_color_alloc(gtk_widget_get_colormap(GTK_WIDGET(clist)), &color); gtk_clist_set_foreground(clist, row, &color); } } } dlist = dlist->next; } gtk_clist_thaw(clist); } HANDLER(nap_user_mode) { (void)net; client_message("Usermode", "%s", data); } // deprecated HANDLER(nap_browse_new) { (void)net; (void)data; printf("*** browse_new deprecated\n"); } HANDLER(nap_redirect) { char* address; char* port; server_t* server; if (net->active_server->status != SERVER_CONNECTING) { server_message(net, "[REDIRECT] %s (ignoring)", data); return; } else { server_message(net, "[REDIRECT] %s", data); } address = arg(data, 0); port = arg(NULL, 0); if (!port) return; server = network_search_server(net, address); if (!server) { server = server_create(address, NULL, atoi(port), "0", "0", "0", "0", 0); network_add_server(net, server); } else { server->port = atoi(port); } if (!net->active_server) { printf("redirect ops"); return; } server_disconnect(net->active_server, "Redirect", 1); if (!(server->flags & SERVER_IGNORE)) server_connect(server); } HANDLER(nap_cycle) { server_message(net, "Cycle [%s] (ignoring)", data); } HANDLER(nap_histogram) { int id; unsigned long count; double bytes; char *arg1; char str[1024]; (void)net; arg1 = arg(data, 0); if (!arg1) return; id = atoi(arg1); arg1 = arg(NULL, 0); if (!arg1) return; count = strtoul(arg1, NULL, 10); arg1 = arg(NULL, 0); if (!arg1) return; bytes = strtod(arg1, NULL); if (count > 0) { arg1 = g_strdup_printf("%5d", id); print_size(str, bytes); client_message(arg1, "%10lu %10s", count, str); g_free(arg1); } } HANDLER(nap_histogram_end) { int id; unsigned long count; double bytes; char *arg1; char str[1024]; (void)net; arg1 = arg(data, 0); if (!arg1) return; id = atoi(arg1); arg1 = arg(NULL, 0); if (!arg1) return; count = strtoul(arg1, NULL, 10); arg1 = arg(NULL, 0); if (!arg1) return; bytes = strtod(arg1, NULL); print_size(str, bytes); arg1 = g_strdup_printf("%5d", id); client_message(arg1, "%10lu %10s", count, str); g_free(arg1); client_message("-ID--", "----calls- ----bytes-"); arg1 = arg(NULL, 0); if (!arg1) return; count = strtoul(arg1, NULL, 10); arg1 = arg(NULL, 0); if (!arg1) return; bytes = strtod(arg1, NULL); print_size(str, bytes); client_message("-SUM-", "%10lu %10s", count, str); } HANDLER(nap_shistogram) { int id; unsigned long count; double bytes; char *arg1, *name; char str[1024]; (void)net; arg1 = arg(data, 0); if (!arg1) return; id = atoi(arg1); arg1 = arg(NULL, 0); if (!arg1) return; count = strtoul(arg1, NULL, 10); arg1 = arg(NULL, 0); if (!arg1) return; bytes = strtod(arg1, NULL); name = arg(NULL, 1); if (!name) return; if (count > 0) { arg1 = g_strdup_printf("%5d", id); print_size(str, bytes); client_message(arg1, "%10lu %10s %s", count, str, name); g_free(arg1); } } HANDLER(nap_shistogram_end) { unsigned long count; double bytes; char *arg1; char str[1024]; (void)net; client_message("-ID--", "----calls- ----bytes-"); arg1 = arg(data, 0); if (!arg1) return; count = strtoul(arg1, NULL, 10); arg1 = arg(NULL, 0); if (!arg1) return; bytes = strtod(arg1, NULL); print_size(str, bytes); client_message("-SUM-", "%10lu %10s", count, str); } HANDLER(nap_acl_list) { char *ip; char *count; char *pos; char str[1024]; (void)net; ip = arg(data, 0); count = arg(NULL, 0); if (!ip) { client_message("End of List", ""); return; } if (!count) return; pos = strchr(ip, '/'); sprintf(str, "%2s", count); if (pos) { *pos = 0; pos++; client_message(str, "%15s %s", ip, pos); } else { client_message(str, "%15s", ip); } }