/* 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 #include #include "support.h" #include "lopster.h" #include "global.h" #include "handler.h" #include "connection.h" #include "chat.h" #include "userinfo.h" #include "transfer.h" #include "whois.h" #include "utils.h" /* static void request_online_servers(whois_t* whois) { if (!whois || !NET_CONNECTED(whois->net)) return; send_notice(whois->net, whois->user, "!GetOnline", 0); } */ void whois_request(net_t* net, char *user, int flag) { whois_t *whois; whois = whois_search(net, user); if (whois) { // whois already in progress, adding flag; whois->flag |= flag; if (global.current_time - whois->sent > 60) { command_send(net, CMD_WHOIS, whois->user); whois->sent = global.current_time; } } else { whois = whois_new(user, flag); whois->net = net; command_send(net, CMD_WHOIS, whois->user); whois->sent = global.current_time; } } whois_t *whois_new(char *user, int flag) { whois_t *result; if (!user) return NULL; result = (whois_t *) g_malloc(sizeof(whois_t)); result->flag = flag; result->received = 0; result->online = 0; result->advanced = 0; result->yourself = 0; result->user = g_strdup(user); result->level = L_USER; result->online_time = 0; result->channels = NULL; result->status = NULL; result->shared = 0; result->downloads = 0; result->uploads = 0; result->link = 0; result->client = NULL; result->total_down = 0; result->total_up = 0; result->ip = NULL; result->server_port = 0; result->data_port = 0; result->email = NULL; result->where = NULL; result->net = NULL; global.whois_requests = g_list_append(global.whois_requests, result); return result; } void whois_destroy(whois_t * whois) { if (whois->user) g_free(whois->user); if (whois->channels) g_free(whois->channels); if (whois->status) g_free(whois->status); if (whois->client) g_free(whois->client); if (whois->ip) g_free(whois->ip); if (whois->email) g_free(whois->email); if (whois->where) g_free(whois->where); g_free(whois); } static char* get_whois_tag(int id) { switch (id) { case 0: return "User "; case 1: return "Online "; case 2: return "Last Seen"; case 3: return "Status "; case 4: return "Level "; case 5: return "Channels "; case 6: return "Sharing "; case 7: return "Transfers"; case 8: return "Link "; case 9: return "Client "; case 10: return "Server "; case 11: return "E-mail "; default: return "Unknown "; } } static void print_whois_tag(chat_page_t* page, int tag) { chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 0); chat_print_text(page, M_PUBLIC, "error", get_whois_tag(tag)); chat_print_text(page, M_PUBLIC, "user", " : "); } void whois_remove(whois_t * whois) { global.whois_requests = g_list_remove(global.whois_requests, whois); whois_destroy(whois); } static void whois_action_text(whois_t * whois) { char *text; char str[1024]; chat_page_t* page; char* channel; char* channels; if (!whois) return; if (!whois->received) return; page = chat_page_get_printable(); chat_print_time_stamp(page, M_PUBLIC); chat_print_prefix(page, 0); chat_print_text(page, M_PUBLIC, "error", "Whois received from "); chat_print_text(page, M_PUBLIC, "user", "["); chat_print_network(page, M_PUBLIC, whois->net, 0, 1); chat_print_text(page, M_PUBLIC, "user", "]\n"); print_whois_tag(page, 0); chat_print_text(page, M_PUBLIC, "user", "<"); chat_print_nick(page, M_PUBLIC, whois->user, whois->net); chat_print_text(page, M_PUBLIC, "user", ">"); if (whois->online && whois->advanced) { chat_print_text(page, M_PUBLIC, "text", " ("); chat_print_text(page, M_PUBLIC, "text", whois->ip); chat_print_text(page, M_PUBLIC, "text", ")"); } chat_print_text(page, M_PUBLIC, "text", "\n"); if (whois->online) { print_whois_tag(page, 1); if (whois->online_time >= 60 * 60 * 24) text = g_strdup_printf("%ld days %ld hours %ld minutes %ld seconds", whois->online_time / (24 * 60 * 60), (whois->online_time % (24 * 60 * 60)) / (60 * 60), (whois->online_time % (60 * 60)) / 60, whois->online_time % 60); else if (whois->online_time >= 60 * 60) text = g_strdup_printf("%ld hours %ld minutes %ld seconds", whois->online_time / (60 * 60), (whois->online_time % (60 * 60)) / 60, whois->online_time % 60); else text = g_strdup_printf("%ld minutes %ld seconds", whois->online_time / 60, whois->online_time % 60); chat_print_text(page, M_PUBLIC, "text", text); chat_print_text(page, M_PUBLIC, "text", "\n"); g_free(text); } else if (whois->online_time > 0) { print_whois_tag(page, 2); text = g_strdup_printf("%s", ctime(&whois->online_time)); chat_print_text(page, M_PUBLIC, "text", text); g_free(text); } else { print_whois_tag(page, 3); text = g_strdup("Unregistered\n"); chat_print_text(page, M_PUBLIC, "text", text); g_free(text); return; } print_whois_tag(page, 4); chat_print_text(page, M_PUBLIC, "text", LevelShort(whois->level)); if (whois->online) { chat_print_text(page, M_PUBLIC, "text", " ("); chat_print_text(page, M_PUBLIC, "text", whois->status); chat_print_text(page, M_PUBLIC, "text", ")"); } chat_print_text(page, M_PUBLIC, "text", "\n"); if (!whois->online) return; print_whois_tag(page, 5); channels = g_strdup(whois->channels); channel = arg(channels, 0); while (channel) { chat_print_text(page, M_PUBLIC, "user", "["); chat_print_channel(page, M_PUBLIC, channel, whois->net); chat_print_text(page, M_PUBLIC, "user", "]"); channel = arg(NULL, 0); } g_free(channels); chat_print_text(page, M_PUBLIC, "text", "\n"); print_whois_tag(page, 6); if (whois->shared == 1) sprintf(str, "1 file"); else sprintf(str, "%d files", whois->shared); chat_print_text(page, M_PUBLIC, "text", str); if (whois->advanced) { sprintf(str, " on port %d", whois->data_port); chat_print_text(page, M_PUBLIC, "text", str); } chat_print_text(page, M_PUBLIC, "text", "\n"); print_whois_tag(page, 7); if (whois->advanced) sprintf(str, "%d (%d) down %d (%d) up", whois->downloads, whois->total_down, whois->uploads, whois->total_up); else sprintf(str, "%d down %d up", whois->downloads, whois->uploads); chat_print_text(page, M_PUBLIC, "text", str); chat_print_text(page, M_PUBLIC, "text", "\n"); print_whois_tag(page, 8); chat_print_text(page, M_PUBLIC, "text", LineSpeed(whois->link)); chat_print_text(page, M_PUBLIC, "text", "\n"); print_whois_tag(page, 9); chat_print_colored(page, M_PUBLIC, "text", whois->client); chat_print_text(page, M_PUBLIC, "text", "\n"); if (whois->advanced) { print_whois_tag(page, 10); if (whois->where) { sprintf(str, "%s:%d", whois->where, whois->server_port); } else { sprintf(str, "%d", whois->server_port); } chat_print_text(page, M_PUBLIC, "text", str); chat_print_text(page, M_PUBLIC, "text", "\n"); print_whois_tag(page, 11); chat_print_text(page, M_PUBLIC, "text", whois->email); chat_print_text(page, M_PUBLIC, "text", "\n"); } /* if (whois->advanced && whois->ip) { exec_command_safe(0, 0, "nslookup", whois->ip, 0); } */ } static void whois_action_show(whois_t * whois) { char *text; char str[1024]; GtkEntry *entry; GtkWidget *temp; if (!whois) return; if (!whois->received) return; if (!global.whois_win) { global.whois_win = create_whois_win(); } else { gdk_window_raise(global.whois_win->window); } gtk_widget_show(global.whois_win); gtk_object_set_data(GTK_OBJECT(global.whois_win), "network", whois->net); text = g_strdup_printf("%s [%s]", "Whois User", whois->net->name); gtk_window_set_title(GTK_WINDOW(global.whois_win), text); g_free(text); temp = lookup_widget(global.whois_win, "label116"); if (whois->online) gtk_label_set_text(GTK_LABEL(temp), "Online"); else gtk_label_set_text(GTK_LABEL(temp), "Last Seen"); temp = lookup_widget(global.whois_win, "label527"); gtk_label_set_text(GTK_LABEL(temp), whois->user); entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry25")); gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); gtk_entry_set_text(entry, "Level: "); gtk_entry_append_text(entry, LevelShort(whois->level)); entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry26")); if (whois->online) { if (whois->online_time >= 60 * 60 * 24) text = g_strdup_printf("%ld days %ld hours %ld minutes %ld seconds", whois->online_time / (24 * 60 * 60), (whois->online_time % (24 * 60 * 60)) / (60 * 60), (whois->online_time % (60 * 60)) / 60, whois->online_time % 60); else if (whois->online_time >= 60 * 60) text = g_strdup_printf("%ld hours %ld minutes %ld seconds", whois->online_time / (60 * 60), (whois->online_time % (60 * 60)) / 60, whois->online_time % 60); else text = g_strdup_printf("%ld minutes %ld seconds", whois->online_time / 60, whois->online_time % 60); } else if (whois->online_time > 0) { text = g_strdup_printf("%s", ctime(&whois->online_time)); } else { text = g_strdup("Unregistered"); } gtk_entry_set_text(entry, text); g_free(text); entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry27")); if (whois->online) { gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); gtk_entry_set_text(entry, whois->channels); } else { gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE); gtk_entry_set_text(entry, ""); } entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry28")); if (whois->online) { gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); gtk_entry_set_text(entry, "Status: "); gtk_entry_append_text(entry, whois->status); } else { gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE); gtk_entry_set_text(entry, ""); } entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry62")); if (whois->online) { gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); gtk_entry_set_text(entry, "Shared: "); sprintf(str, "%d", whois->shared); gtk_entry_append_text(entry, str); } else { gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE); gtk_entry_set_text(entry, ""); } entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry30")); if (whois->online) { gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); if (whois->advanced) sprintf(str, "%d (%d) ", whois->downloads, whois->total_down); else sprintf(str, "%d ", whois->downloads); gtk_entry_set_text(entry, str); gtk_entry_append_text(entry, "downloads"); } else { gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE); gtk_entry_set_text(entry, ""); } entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry59")); if (whois->online) { gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); if (whois->advanced) sprintf(str, "%d (%d) ", whois->uploads, whois->total_up); else sprintf(str, "%d ", whois->uploads); gtk_entry_set_text(entry, str); gtk_entry_append_text(entry, "uploads"); } else { gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE); gtk_entry_set_text(entry, ""); } entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry61")); if (whois->online) { gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); gtk_entry_set_text(entry, "Link: "); gtk_entry_append_text(entry, LineSpeed(whois->link)); } else { gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE); gtk_entry_set_text(entry, ""); } entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry60")); if (whois->online) { gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); gtk_entry_set_text(entry, whois->client); } else { gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE); gtk_entry_set_text(entry, ""); } temp = lookup_widget(global.whois_win, "table18"); if (!whois->advanced) { gtk_widget_hide(temp); return; } else { gtk_widget_show(temp); } entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry65")); sprintf(str, "%s:%d %s:%d", whois->ip, whois->data_port, whois->where?whois->where:"Server", whois->server_port); gtk_entry_set_text(entry, str); entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry68")); gtk_entry_set_text(entry, whois->email); } static void whois_action_yourself(whois_t * whois) { if (!whois) return; whois->net->user.status = status2int(whois->status); if (whois->advanced && whois->ip) { global.my_ip = inet_addr(whois->ip); } // dont get user level here, cause SlavaNap has sometimes // user defined user levels, so the result could be // _unknown_level_ /* if (whois->net->user.level != whois->level) set_user_level(whois->net, whois->level); */ } static void whois_action_userinfo(whois_t * whois) { user_info_t *userinfo; userinfo = user_info_search(whois->user); if (!userinfo) userinfo = user_info_new(whois->user); if (!whois->online) { // make lopster request info if user appears again userinfo->timestamp = 1; return; } if (userinfo->linespeed != whois->link) { userinfo->linespeed = whois->link; upload_update_speed(userinfo); } userinfo->shares = whois->shared; userinfo->timestamp = global.current_time; userinfo->last_seen = global.current_time; if (userinfo->last_server) g_free(userinfo->last_server); userinfo->last_server = g_strdup(whois->net->name); if (!strncasecmp(whois->client, "WinMX v2.6", 10)) userinfo->client = C_WINMX_26; else if (!strncasecmp(whois->client, "WinMX", 5)) userinfo->client = C_WINMX; else if (!strncasecmp(whois->client, "TrippyMX", 8)) userinfo->client = C_WINMX_26; else if (!strncasecmp(whois->client, "Lopster", 7)) { int v1 = 0; int v2 = 0; int v3 = 0; int v4 = 0; if (sscanf(whois->client+7, " %d.%d.%d-dev%d", &v1, &v2, &v3, &v4) < 2) { userinfo->client = C_OTHER; /* } else if ((v1 > 1) || (v1 == 1 && v2 > 2) || (v1 == 1 && v2 == 2 && v3 > 0) || (v1 == 1 && v2 == 2 && v3 == 0 && v4 >= 2)) { userinfo->client = C_LOPSTER_ADV; request_online_servers(whois); */ } else if ((v1 > 1) || (v1 == 1 && v2 > 0) || (v1 == 1 && v2 == 0 && v3 > 1) || (v1 == 1 && v2 == 0 && v3 == 1 && v4 >= 6)) { userinfo->client = C_LOPSTER_ADV; } else { userinfo->client = C_OTHER; } } else userinfo->client = C_OTHER; } void whois_action(whois_t * whois) { if (!whois) return; if (!whois->received) return; if (whois->yourself) whois_action_yourself(whois); if (whois->flag & WHOIS_SHOW) whois_action_show(whois); if (whois->flag & WHOIS_TEXT) whois_action_text(whois); whois_action_userinfo(whois); whois_remove(whois); } whois_t *whois_search(net_t* net, char *user) { GList *dlist; whois_t *whois; if (!user || !*user) return NULL; for (dlist = global.whois_requests; dlist; dlist = dlist->next) { whois = dlist->data; if (whois->net != net) continue; if (!g_strcasecmp(whois->user, user)) return whois; } return NULL; } void whois_remove_network(net_t* net) { GList* dlist; GList* remove = NULL; whois_t* whois; for (dlist = global.whois_requests; dlist; dlist = dlist->next) { whois = dlist->data; if (whois->net == net) remove = g_list_append(remove, whois); } for (dlist = remove; dlist; dlist = dlist->next) { whois = dlist->data; whois_remove(whois); } g_list_free(remove); } whois_t *whois_search_unreceived(net_t* net, char *user) { GList *dlist; whois_t *whois; if (!user || !*user) return NULL; for (dlist = global.whois_requests; dlist; dlist = dlist->next) { whois = dlist->data; if (whois->net != net) continue; if (!g_strcasecmp(whois->user, user) && !whois->received) return whois; } return NULL; } void whois_eval_whois(net_t* net, char *data) { whois_t *whois; char *pos1; pos1 = arg(data, 0); whois = whois_search_unreceived(net, pos1); if (!whois) return; g_free(whois->user); whois->user = g_strdup(pos1); if (!g_strcasecmp(whois->user, net->user.username)) whois->yourself = 1; whois->online = 1; whois->received = global.current_time; pos1 = arg(NULL, 0); if (!pos1) return; whois->level = level2int(pos1); pos1 = arg(NULL, 0); if (!pos1) return; whois->online_time = strtoul(pos1, NULL, 10); pos1 = arg(NULL, 0); if (!pos1) return; if (whois->channels) g_free(whois->channels); if (net->subtype == N_CLEANNAP) whois->channels = g_strdup(strcmp(pos1, "none")?pos1:""); else whois->channels = g_strdup(pos1); pos1 = arg(NULL, 0); if (!pos1) return; if (whois->status) g_free(whois->status); whois->status = g_strdup(pos1); pos1 = arg(NULL, 0); if (!pos1) return; whois->shared = atoi(pos1); pos1 = arg(NULL, 0); if (!pos1) return; whois->downloads = atoi(pos1); pos1 = arg(NULL, 0); if (!pos1) return; whois->uploads = atoi(pos1); pos1 = arg(NULL, 0); if (!pos1) return; whois->link = atoi(pos1); pos1 = arg(NULL, 0); if (!pos1) return; if (whois->client) g_free(whois->client); whois->client = g_strdup(pos1); pos1 = arg(NULL, 0); if (!pos1) { whois->advanced = 0; } else { whois->advanced = 1; whois->total_down = atoi(pos1); pos1 = arg(NULL, 0); if (!pos1) { whois_action(whois); return; } whois->total_up = atoi(pos1); pos1 = arg(NULL, 0); if (!pos1) { whois_action(whois); return; } if (whois->ip) g_free(whois->ip); whois->ip = g_strdup(pos1); pos1 = arg(NULL, 0); if (!pos1) { whois_action(whois); return; } whois->server_port = atoi(pos1); pos1 = arg(NULL, 0); if (!pos1) { whois_action(whois); return; } whois->data_port = atoi(pos1); pos1 = arg(NULL, 0); if (pos1) { if (whois->email) g_free(whois->email); whois->email = g_strdup(pos1); } pos1 = arg(NULL, 0); if (pos1) { if (whois->where) g_free(whois->where); whois->where = g_strdup(pos1); } } whois_action(whois); } void whois_eval_whowas(net_t* net, char *data) { whois_t *whois; char *pos1; pos1 = arg(data, 0); whois = whois_search_unreceived(net, pos1); if (!whois) return; g_free(whois->user); whois->user = g_strdup(pos1); whois->online = 0; whois->advanced = 0; whois->received = global.current_time; pos1 = arg(NULL, 0); whois->level = level2int(pos1); pos1 = arg(NULL, 0); whois->online_time = strtoul(pos1, NULL, 10); whois_action(whois); } void whois_eval_not_online(net_t* net, char *data) { whois_t *whois; whois = whois_search_unreceived(net, data); if (!whois) return; g_free(whois->user); whois->user = g_strdup(data); whois->online = 0; whois->advanced = 0; whois->received = global.current_time; whois->level = L_USER; whois->online_time = 0; whois_action(whois); } static speed_t *speed_new(char *user) { speed_t *speed; if (!user || !(*user)) return NULL; speed = (speed_t *) g_malloc(sizeof(speed_t)); speed->speed = -1; speed->sent = 0; speed->user = g_strdup(user); speed->net = NULL; global.speed_requests = g_list_prepend(global.speed_requests, speed); return speed; } void speed_request(net_t* net, char *user) { speed_t *speed; GList* dlist; if (net) { speed = speed_search(net, user); if (speed) { if (speed->speed >= 0) speed_action(speed); return; } speed = speed_new(user); if (!speed) return; speed->net = net; command_send(net, CMD_GET_USERSPEED, speed->user); speed->sent = global.current_time; } else { for (dlist = global.net_active; dlist; dlist = dlist->next) { net = dlist->data; speed_request(net, user); } } } void speed_destroy(speed_t * speed) { if (speed->user) g_free(speed->user); g_free(speed); } void speed_remove(speed_t * speed) { global.speed_requests = g_list_remove(global.speed_requests, speed); if (speed->speed < 0) speed_action(speed); speed_destroy(speed); } void speed_remove_network(net_t* net) { GList* dlist; GList* remove = NULL; speed_t* speed; for (dlist = global.speed_requests; dlist; dlist = dlist->next) { speed = dlist->data; if (speed->net == net) remove = g_list_append(remove, speed); } for (dlist = remove; dlist; dlist = dlist->next) { speed = dlist->data; speed_remove(speed); } g_list_free(remove); } static void speed_action_show(speed_t * speed) { char* str; chat_page_t* page; 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, speed->net, 0, 1); chat_print_text(page, M_PUBLIC, "user", "] "); chat_print_text(page, M_PUBLIC, "user", "<"); chat_print_nick(page, M_PUBLIC, speed->user, speed->net); chat_print_text(page, M_PUBLIC, "user", "> "); if (speed->speed >= 0) str = g_strdup_printf("has linespeed [%s]\n", LineSpeed(speed->speed)); else str = g_strdup_printf("seems to be offline\n"); chat_print_text(page, M_PUBLIC, "message", str); g_free(str); } void speed_action(speed_t * speed) { if (!speed) return; speed_action_show(speed); } speed_t *speed_search(net_t* net, char *user) { GList *dlist; speed_t *speed; if (!user || !*user) return NULL; for (dlist = global.speed_requests; dlist; dlist = dlist->next) { speed = dlist->data; if (!g_strcasecmp(speed->user, user) && (speed->net == net)) return speed; } return NULL; } void on_whois_join(GtkMenuItem * menuitem, gpointer user_data) { net_t* net = user_data; GtkLabel *label; label = GTK_LABEL(GTK_BIN(menuitem)->child); join_channel(net, label->label); } GtkWidget* create_join_popup(net_t* net) { GtkWidget* popup; GtkWidget* item; GtkEntry* entry; char* channels; char* channel; int cnt; popup = gtk_menu_new(); if (!NET_CONNECTED(net)) { item = gtk_menu_item_new_with_label("Not connected to Network"); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(popup), item); gtk_widget_set_sensitive(item, FALSE); return popup; } else { entry = GTK_ENTRY(lookup_widget(global.whois_win, "entry27")); channels = g_strdup(gtk_entry_get_text(entry)); cnt = 0; channel = arg(channels, 0); while (channel) { cnt++; item = gtk_menu_item_new_with_label(channel); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(popup), item); gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(on_whois_join), net); channel = arg(NULL, 0); } g_free(channels); if (cnt == 0) { item = gtk_menu_item_new_with_label("No channels"); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(popup), item); gtk_widget_set_sensitive(item, FALSE); } } return popup; }