/* * Copyright Colten Edwards (c) 1996 */ #include "irc.h" #include "struct.h" #include "server.h" #include "dcc.h" #include "commands.h" #include "crypt.h" #include "vars.h" #include "ircaux.h" #include "lastlog.h" #include "window.h" #include "screen.h" #include "who.h" #include "hook.h" #include "input.h" #include "ignore.h" #include "keys.h" #include "names.h" #include "alias.h" #include "history.h" #include "funny.h" #include "ctcp.h" #include "output.h" #include "exec.h" #include "notify.h" #include "numbers.h" #include "status.h" #include "list.h" #include "timer.h" #include "userlist.h" #include "misc.h" #include "gui.h" #include "flood.h" #include "parse.h" #include "whowas.h" #include "hash2.h" #include "cset.h" #include #include #include #include #include #include #include #ifndef __OPENNT #include #endif #include #if defined(sparc) && defined(sun4c) #include #endif #ifdef GUI extern int guiipc[2]; extern int newscrollerpos, lastscrollerpos, lastscrollerwindow; #endif extern int user_count; extern int shit_count; extern int bot_count; extern int in_server_ping; int serv_action = 0; int first_time = 0; LastMsg last_msg[MAX_LAST_MSG+1] = { { NULL } }; LastMsg last_dcc[MAX_LAST_MSG+1] = { { NULL } }; LastMsg last_notice[MAX_LAST_MSG+1] = { { NULL } }; LastMsg last_servermsg[MAX_LAST_MSG+1] = { { NULL } }; LastMsg last_sent_msg[MAX_LAST_MSG+1] = {{ NULL }}; LastMsg last_sent_notice[MAX_LAST_MSG+1] = {{ NULL }}; LastMsg last_sent_topic[2] = {{ NULL }}; LastMsg last_sent_wall[2] = {{ NULL }}; LastMsg last_topic[2] = {{ NULL }}; LastMsg last_wall[MAX_LAST_MSG+1] = {{ NULL }}; LastMsg last_invite_channel[2] = {{ NULL }}; LastMsg last_ctcp[2] = {{ NULL }}; LastMsg last_sent_ctcp[2] = {{ NULL }}; LastMsg last_sent_dcc[MAX_LAST_MSG+1] = {{ NULL }}; extern int in_cparse; #define SPLIT 1 ChannelList *idlechan_list = NULL; extern NickTab *tabkey_array, *autoreply_array; extern Ignore *ignored_nicks; #ifdef REVERSE_WHITE_BLACK char *color_str[] = { "","","","","","","","", "","","","","","","","", "", "", "", "","", "","","", "", "", "", "","", "","","", "", "", "", "", ""}; #else char *color_str[] = { "","","","","","","","", "","","","","","","","", "", "", "", "","", "","","", "", "", "", "","", "","","", "", "", "", "", ""}; #endif irc_server /**tmplink = NULL, *server_last = NULL, *split_link = NULL,*/ *map = NULL; #define getrandom(min, max) ((rand() % (int)(((max)+1) - (min))) + (min)) char *awaymsg = NULL; char *convert_time (time_t ltime) { time_t days = 0,hours = 0,minutes = 0,seconds = 0; static char buffer[40]; *buffer = '\0'; seconds = ltime % 60; ltime = (ltime - seconds) / 60; minutes = ltime%60; ltime = (ltime - minutes) / 60; hours = ltime % 24; days = (ltime - hours) / 24; sprintf(buffer, "%2ldd %2ldh %2ldm %2lds", days, hours, minutes, seconds); return(*buffer ? buffer : empty_string); } BUILT_IN_COMMAND(do_uptime) { #ifdef ONLY_STD_CHARS put_it("%s",convert_output_format("%G--[ %WBitchX%g-%wClient%g-%RStatistics %G]------------------------------------------",NULL)); put_it("%s",convert_output_format("%G| %CClient Version: %W$0 $1","%s %s", irc_version, internal_version)); put_it("%s",convert_output_format("%G| %CClient Running Since %W$0-","%s",my_ctime(start_time))); put_it("%s",convert_output_format("%G| %CClient Uptime: %W$0-","%s",convert_time(now-start_time))); put_it("%s",convert_output_format("%G| %CCurrent UserName: %W$0-","%s", username)); put_it("%s",convert_output_format("%G| %CCurrent RealName: %W$0-","%s", realname)); put_it("%s",convert_output_format("%G| %CLast Recv Message: %W$0-","%s",last_msg[0].last_msg?last_msg[0].last_msg:"None")); put_it("%s",convert_output_format("%G| %CLast Recv Notice: %W$0-","%s",last_notice[0].last_msg?last_notice[0].last_msg:"None")); put_it("%s",convert_output_format("%G| %CLast Sent Msg: %W$0-","%s",last_sent_msg[0].last_msg?last_sent_msg[0].last_msg:"None")); put_it("%s",convert_output_format("%G| %CLast Sent Notice: %W$0-","%s",last_sent_notice[0].last_msg?last_sent_notice[0].last_msg:"None")); put_it("%s",convert_output_format("%G| %CLast Channel invited to: %R$0-","%s",invite_channel?invite_channel:"None")); put_it("%s",convert_output_format("%G| %cTotal Users on Userlist: %K[%R$0%K]","%d",user_count)); put_it("%s",convert_output_format("%G| %cTotal Users on Shitlist: %K[%R$0%K]","%d",shit_count)); #else put_it("%s",convert_output_format("%GÚÄ[ %WBitchX%gÄ%wClient%gÄ%RStatistics %G]ÄÄÄÄ---%gÄ--ÄÄ%K-%gÄÄÄÄÄ--%GÄ--ÄÄ%K-%gÄÄÄÄÄÄÄ--- %K--%g -",NULL)); put_it("%s",convert_output_format("%G| %CClient Version: %W$0 $1","%s %s", irc_version, internal_version)); put_it("%s",convert_output_format("%G³ %CClient Running Since %W$0-","%s",my_ctime(start_time))); put_it("%s",convert_output_format("%G| %CClient Uptime: %W$0-","%s",convert_time(now-start_time))); put_it("%s",convert_output_format("%G³ %CCurrent UserName: %W$0-","%s", username)); put_it("%s",convert_output_format("%G: %CCurrent RealName: %W$0-","%s", realname)); put_it("%s",convert_output_format("%G. %CLast Recv Message: %W$0-","%s",last_msg[0].last_msg?last_msg[0].last_msg:"None")); put_it("%s",convert_output_format("%G: %CLast Recv Notice: %W$0-","%s",last_notice[0].last_msg?last_notice[0].last_msg:"None")); put_it("%s",convert_output_format("%G. %CLast Sent Msg: %W$0-","%s",last_sent_msg[0].last_msg?last_sent_msg[0].last_msg:"None")); put_it("%s",convert_output_format("%G: %CLast Sent Notice: %W$0-","%s",last_sent_notice[0].last_msg?last_sent_notice[0].last_msg:"None")); put_it("%s",convert_output_format("%G³ %CLast Channel invited to: %R$0-","%s",invite_channel?invite_channel:"None")); put_it("%s",convert_output_format("%G| %cTotal Users on Userlist: %K[%R$0%K]","%d",user_count)); put_it("%s",convert_output_format("%G³ %cTotal Users on Shitlist: %K[%R$0%K]","%d",shit_count)); #endif } /* extern_write -- controls whether others may write to our terminal or not. */ /* This is basically stolen from bsd -- so its under the bsd copyright */ BUILT_IN_COMMAND(extern_write) { char *tty; struct stat sbuf; const int OTHER_WRITE = 020; int on = 0; if (!(tty = ttyname(2))) { yell("Internal error: notify %s", "edwac@sasknet.sk.ca"); yell("Error in ttyname()"); return; } if (stat(tty, &sbuf) < 0) { yell("Internal error: noTify %s", "edwac@sasknet.sk.ca"); yell("Error in stat()"); return; } if (!args || !*args) { if (sbuf.st_mode & 020) bitchsay("Mesg is \002On\002"); else bitchsay("Mesg is \002Off\002"); return; } if (!my_stricmp(args, "ON") || !my_stricmp(args, "YES")) on = 1; else if (!my_stricmp(args, "OFF") || !my_stricmp(args, "NO")) on = 0; else { userage("Mesg", helparg); return; } switch (on) { case 1 : if (chmod(tty, sbuf.st_mode | OTHER_WRITE) < 0) { yell("Sorry, couldnt set your tty's mode"); return; } bitchsay("Mesg is \002On\002"); break; case 0 : if (chmod(tty, sbuf.st_mode &~ OTHER_WRITE) < 0) { yell("Sorry, couldnt set your tty's mode"); return; } bitchsay("Mesg is \002Off\002"); break; } } int check_serverlag (void) { int i; time_t new_t = now; for (i = 0; i < number_of_servers; i++) { if (is_server_connected(i) && (new_t != server_list[i].lag_time)) { server_list[i].lag_time = new_t; my_send_to_server(i, "PING %lu %s", server_list[i].lag_time, get_server_itsname(i) ? get_server_itsname(i): get_server_name(i)); in_server_ping++; server_list[i].lag = -1; } } return 0; } int timer_unban (void *args) { char *p = (char *)args; char *channel; ChannelList *chan; char *ban; char *serv; int server = from_server; serv = next_arg(p, &p); if (my_atol(serv) != server) server = my_atol(serv); if (server < 0 || server > number_of_servers || !server_list[server].connected) server = from_server; channel = next_arg(p, &p); ban = next_arg(p, &p); if ((chan = (ChannelList *)find_in_list((List **)&server_list[server].chan_list, channel, 0)) && ban_is_on_channel(ban, chan)) my_send_to_server(server, "MODE %s -b %s", channel, ban); new_free(&serv); return 0; } int timer_idlekick (void *args) { char *channel = (char *)args; ChannelList *tmp = NULL; int kick_count = 0; UserList *user = NULL; if (channel && (tmp = lookup_channel(channel, from_server, CHAN_NOUNLINK)) && tmp->chop && tmp->max_idle && tmp->check_idle) { NickList *nick; for (nick = next_nicklist(tmp, NULL); nick; nick = next_nicklist(tmp, nick)) { if (!my_stricmp(nick->nick, get_server_nickname(from_server))) continue; if ((nick->chanop || nick->voice) && !get_cset_int_var(tmp->csets, KICK_OPS_CSET)) continue; if ((user=nick->userlist) && check_channel_match(user->channels, channel)) continue; if (now - nick->idle_time >= tmp->max_idle) { if (kick_count <= get_int_var(MAX_IDLEKICKS_VAR)) { char *p = NULL; malloc_sprintf(&p, "%s %s*!*%s", channel, nick->nick, nick->host); send_to_server("MODE %s +b %s*!*%s", channel, nick->nick, nick->host); send_to_server("KICK %s %s :\002%s\002: (Idle Channel User)", channel, nick->nick, version); add_timer(0, "", 60, 1, timer_unban, m_sprintf("%d %s", from_server, p), NULL, current_window); new_free(&p); } else break; kick_count++; } } } if (tmp && tmp->max_idle && tmp->check_idle) add_timer(0, "", get_int_var(IDLE_CHECK_VAR), 1, timer_idlekick, channel, NULL, current_window); else new_free(&channel); return 0; } BUILT_IN_COMMAND(addidle) { time_t default_idle = 10 * 60; char *channel = NULL, *p; time_t seconds = 0; ChannelList *tmp, *new = NULL; if ((p = next_arg(args, &args))) { malloc_strcpy(&channel, make_channel(p)); if (args && *args) seconds = atol(args); if (seconds < default_idle) seconds = default_idle; if (!(new = (ChannelList *)find_in_list((List **)&idlechan_list, channel, 0))) { new = (ChannelList *)new_malloc(sizeof(ChannelList)); malloc_strcpy(&new->channel, channel); add_to_list((List **)&idlechan_list, (List *)new); } new->max_idle = seconds; new->check_idle = (my_strnicmp(command, "UN", 2) == 0) ? 0: 1; if (!new->check_idle) { bitchsay("Idle checking turned %s for %s",on_off(new->check_idle), channel); if ((tmp = lookup_channel(channel, from_server, CHAN_NOUNLINK))) tmp->check_idle = tmp->max_idle = 0; new_free(&channel); new->max_idle = 0; } else { if ((tmp = lookup_channel(channel, from_server, CHAN_NOUNLINK))) { if (new && new->check_idle) { tmp->max_idle = new->max_idle; tmp->check_idle = new->check_idle; add_timer(0, "", get_int_var(IDLE_CHECK_VAR), 1, timer_idlekick, channel, NULL, current_window); bitchsay("Idle checking turned %s for %s %d mins",on_off(tmp->check_idle), channel, (int)(tmp->max_idle/60)); } } else new_free(&channel); } } else userage(command, helparg); } BUILT_IN_COMMAND(showidle) { ChannelList *tmp; char *channel = NULL; int count = 0; NickList *nick, *ntmp; time_t ltime; int server; int sorted = 0; while (args && *args) { if (!args || !*args) break; if ((*args == '-') && !my_strnicmp(args, "-sort", 3)) { next_arg(args, &args); sorted = NICKSORT_NONE; } else if (!my_strnicmp(args, "nick", 3) && sorted) { next_arg(args, &args); sorted = NICKSORT_NICK; } else if (!my_strnicmp(args, "host", 3) && sorted) { next_arg(args, &args); sorted = NICKSORT_HOST; } else if (!my_strnicmp(args, "time", 3) && sorted) { next_arg(args, &args); sorted = NICKSORT_TIME; } else if (!my_strnicmp(args, "ip", 2) && sorted) { next_arg(args, &args); sorted = NICKSORT_IP; } else channel = next_arg(args, &args); } if (!(tmp = prepare_command(&server, channel, NO_OP))) { userage(command, helparg); return; } ntmp = sorted_nicklist(tmp, sorted); for (nick = ntmp; nick; nick = nick->next) { if (!count && do_hook(SHOWIDLE_HEADER_LIST, "%s %ld", tmp->channel, tmp->max_idle)) put_it("%s", convert_output_format("$G %W$a%n: Idle check for %W$0%n Max Idle Time %K[%W$1- %K]", "%s %s", tmp->channel, convert_time(tmp->max_idle))); ltime = now - nick->idle_time; if (do_hook(SHOWIDLE_LIST, "%s %s %d %ld", nick->nick, nick->host, find_user_level(nick->nick, nick->host, tmp->channel), ltime)) put_it("%s", convert_output_format("$[20]0 Idle%W: %K[%n$1- %K]", "%s %s", nick->nick, convert_time(ltime))); count++; } if (count) do_hook(SHOWIDLE_FOOTER_LIST, "%s", "End of idlelist"); clear_sorted_nicklist(&ntmp); } BUILT_IN_COMMAND(kickidle) { char *channel = NULL; ChannelList *tmp; int kick_count = 0; int server = from_server; if (args && *args) channel = next_arg(args, &args); if ((tmp = prepare_command(&server, channel, NEED_OP)) && tmp->max_idle) { NickList *nick; for (nick = next_nicklist(tmp, NULL); nick; nick = next_nicklist(tmp, nick)) { if (!my_stricmp(nick->nick, get_server_nickname(from_server))) continue; if (nick->userlist && check_channel_match(nick->userlist->channels, tmp->channel)) continue; if (now - nick->idle_time >= tmp->max_idle) { if (kick_count <= get_int_var(MAX_IDLEKICKS_VAR)) my_send_to_server(server, "KICK %s %s :\002%s\002: (Idle Channel User)", tmp->channel, nick->nick, version); else bitchsay(" found idle user %-12s channel %s", nick->nick, tmp->channel); kick_count++; } } } else userage(command, helparg); } void save_idle(FILE *output) { ChannelList *chan; int count = 0; if (!output) return; if (idlechan_list) { fprintf(output, "# %s Idle Channel list\n", version); for (chan = idlechan_list; chan; chan = chan->next) { if (chan->max_idle) { fprintf(output, "ADDIDLE %s %d\n", chan->channel, (int)chan->max_idle); count++; } } } if (count && do_hook(SAVEFILE_LIST, "Idle %d", count)) bitchsay("Saved %d Idle channels", count); } BUILT_IN_COMMAND(channel_stats) { ChannelList *new = NULL; char *channel = NULL; WhowasChanList *new1 = NULL; int numircops = 0; int usershere = 0; int usersaway = 0; int chanops = 0; int chanunop = 0; char *ircops = NULL; int server = -1; NickList *l; unsigned long nick_mem = 0, ban_mem = 0; BanList *b; if (args && *args) { channel = next_arg(args, &args); if (my_strnicmp(channel, "-ALL", strlen(channel))) { channel = make_channel(channel); if (!(new = prepare_command(&server, channel, 3))) if ((channel && !(new1 = check_whowas_chan_buffer(channel, 0)))) return; } else { int stats_ops= 0, stats_dops = 0, stats_bans = 0, stats_unbans = 0; int stats_topics = 0, stats_kicks = 0, stats_pubs = 0, stats_parts = 0; int stats_signoffs = 0, stats_joins = 0; int total_nicks = 0, max_nicks = 0, total_bans = 0, max_bans = 0; int stats_sops = 0, stats_sdops = 0, stats_sbans = 0, stats_sunbans = 0; NickList *l; BanList *b; unsigned long chan_mem = 0; channel = NULL; if (from_server != -1) { for (new = server_list[from_server].chan_list; new; new = new->next) { if (!channel) malloc_strcpy(&channel, new->channel); else { malloc_strcat(&channel, ","); malloc_strcat(&channel, new->channel); } for (l = next_nicklist(new, NULL); l; l = next_nicklist(new, l)) { switch(l->away) { case 'H': usershere++; break; case 'G': usersaway++; default: break; } if (l->ircop) { numircops++; malloc_strcat(&ircops, " ("); malloc_strcat(&ircops, l->nick); malloc_strcat(&ircops, ")"); } if (l->chanop) chanops++; else chanunop++; nick_mem += sizeof(NickList); } for (b = new->bans; b; b = b->next) ban_mem += sizeof(BanList); chan_mem += sizeof(ChannelList); stats_ops += new->stats_ops; stats_dops += new->stats_dops; stats_bans += new->stats_bans; stats_unbans += new->stats_unbans; stats_topics += new->stats_topics; stats_kicks += new->stats_kicks; stats_pubs += new->stats_pubs; stats_parts += new->stats_parts; stats_signoffs += new->stats_signoffs; stats_joins += new->stats_joins; total_nicks += new->totalnicks; max_nicks += new->maxnicks; total_bans += new->totalbans; max_bans += new->maxbans; stats_sops += new->stats_sops; stats_sdops += new->stats_sdops; stats_sbans += new->stats_sbans; stats_sunbans += new->stats_sunbans; } } if (!ircops) malloc_strcat(&ircops, empty_string); if (do_hook(CHANNEL_STATS_LIST, "%s %s %s %lu %lu %lu %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s", channel, empty_string, empty_string, nick_mem+chan_mem+ban_mem, nick_mem, (unsigned long)sizeof(ChannelList),ban_mem, stats_ops, stats_dops, stats_bans, stats_unbans, stats_topics, stats_kicks, stats_pubs, stats_parts, stats_signoffs, stats_joins, total_bans, max_bans, stats_sops, stats_sdops,stats_sbans, stats_sunbans, usershere, usersaway, chanops, chanunop,total_nicks,max_nicks, numircops, ircops)) { put_it("%s", convert_output_format("$G %CInformation for channels %K: %W$0", "%s", channel)); put_it("%s", convert_output_format(" MEM usage%K:%w Total%K:%w %c$0 bytes %K[%cNicks $1 b Chan $2 b Bans $3 b%K]", "%d %d %d %d", (int)(nick_mem+chan_mem+ban_mem), (int)nick_mem, (int)sizeof(ChannelList), (int)ban_mem)); put_it("%s", convert_output_format("Ops %K[%W$[-5]0%K]%w De-Ops %K[%W$[-5]1%K]%w Bans %K[%W$[-5]2%K]%w Unbans %K[%W$[-5]3%K]%w", "%d %d %d %d", stats_ops, stats_dops, stats_bans, stats_unbans)); put_it("%s", convert_output_format("Topics %K[%W$[-5]0%K]%w Kicks %K[%W$[-5]1%K]%w Publics %K[%W$[-5]2%K]%w Parts %K[%W$[-5]3%K]%w", "%d %d %d %d", stats_topics, stats_kicks, stats_pubs, stats_parts)); put_it("%s", convert_output_format("Signoffs %C[%W$[-5]0%K]%w Joins %K[%W$[-5]1%K]%w TotalBans %K[%W$[-5]2%K]%w MaxBans %K[%W$[-5]3%K]%w", "%d %d %d %d", stats_signoffs, stats_joins, total_bans, max_bans)); put_it("%s", convert_output_format("ServOps %K[%W$[-5]0%K]%w ServDeop %K[%W$[-5]1%K]%w ServBans %K[%W$[-5]2%K]%w ServUB %K[%W$[-5]3%K]%w", "%d %d %d %d", stats_sops, stats_sdops,stats_sbans, stats_sunbans)); put_it("%s", convert_output_format("Users Here %K[%W$[-5]0%K]%w Users Away %K[%W$[-5]1%K]%w Opped %K[%W$[-5]2%K]%w Unopped %K[%W$[-5]3%K]%w", "%d %d %d %d", usershere, usersaway, chanops, chanunop)); put_it("%s", convert_output_format("TotalNicks %K[%W$[-5]0%K]%w MaxNicks %K[%W$[-5]1%K]%w", "%d %d", total_nicks,max_nicks)); put_it("%s", convert_output_format("IRCops %K[%W$[3]0%K]%w$1-", "%d %s", numircops, ircops)); } new_free(&ircops); new_free(&channel); return; } } else { if (!(new = prepare_command(&server, channel, 3))) if ((channel && !(new1 = check_whowas_chan_buffer(channel, 0)))) return; } if (!new && new1) new = new1->channellist; if (!new) { bitchsay("Try joining a channel first"); return; } if (new) { for (l = next_nicklist(new, NULL); l; l = next_nicklist(new, l)) { nick_mem += sizeof(NickList); switch(l->away) { case 'H': usershere++; break; case 'G': usersaway++; default: break; } if (l->ircop) { numircops++; malloc_strcat(&ircops, " ("); malloc_strcat(&ircops, l->nick); malloc_strcat(&ircops, ")"); } if (l->chanop) chanops++; else chanunop++; } for (b = new->bans; b; b = b->next) ban_mem += sizeof(BanList); } if (!ircops) malloc_strcat(&ircops, empty_string); if (do_hook(CHANNEL_STATS_LIST, "%s %s %s %ld %ld %ld %ld %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s", new->channel, my_ctime(new->channel_create.tv_sec), convert_time(now-new->join_time.tv_sec), nick_mem+sizeof(ChannelList)+ban_mem, nick_mem, (unsigned long)sizeof(ChannelList),ban_mem, new->stats_ops, new->stats_dops, new->stats_bans, new->stats_unbans, new->stats_topics, new->stats_kicks, new->stats_pubs, new->stats_parts, new->stats_signoffs, new->stats_joins, new->totalbans, new->maxbans, new->stats_sops, new->stats_sdops,new->stats_sbans, new->stats_sunbans, usershere, usersaway, chanops, chanunop,new->totalnicks,new->maxnicks, numircops, ircops)) { put_it("%s", convert_output_format("$G %CInformation for channel %K: %W$0", "%s", new->channel)); put_it("%s", convert_output_format("$G %CChannel created %K: %W$0 $1 $2 $3%n in memory %W$4-", "%s %s", convert_time(now-new->channel_create.tv_sec), my_ctime(new->join_time.tv_sec))); put_it("%s", convert_output_format(" MEM usage%K:%w Total%K:%w %c$0 bytes %K[%cNicks $1 b Chan $2 b Bans $3 b%K]", "%d %d %d %d", (int)(nick_mem+sizeof(ChannelList)+ban_mem), (int)nick_mem, (int)sizeof(ChannelList), (int)ban_mem)); put_it("%s", convert_output_format("Ops %K[%W$[-5]0%K]%w De-Ops %K[%W$[-5]1%K]%w Bans %K[%W$[-5]2%K]%w Unbans %K[%W$[-5]3%K]%w", "%d %d %d %d", new->stats_ops, new->stats_dops, new->stats_bans, new->stats_unbans)); put_it("%s", convert_output_format("Topics %K[%W$[-5]0%K]%w Kicks %K[%W$[-5]1%K]%w Publics %K[%W$[-5]2%K]%w Parts %K[%W$[-5]3%K]%w", "%d %d %d %d", new->stats_topics, new->stats_kicks, new->stats_pubs, new->stats_parts)); put_it("%s", convert_output_format("Signoffs %K[%W$[-5]0%K]%w Joins %K[%W$[-5]1%K]%w TotalBans %K[%W$[-5]2%K]%w MaxBans %K[%W$[-5]3%K]%w", "%d %d %d %d", new->stats_signoffs, new->stats_joins, new->totalbans, new->maxbans)); put_it("%s", convert_output_format("ServOps %K[%W$[-5]0%K]%w ServDeop %K[%W$[-5]1%K]%w ServBans %K[%W$[-5]2%K]%w ServUB %K[%W$[-5]3%K]%w", "%d %d %d %d", new->stats_sops, new->stats_sdops,new->stats_sbans, new->stats_sunbans)); put_it("%s", convert_output_format("Users Here %K[%W$[-5]0%K]%w Users Away %K[%W$[-5]1%K]%w Opped %K[%W$[-5]2%K]%w Unopped %K[%W$[-5]3%K]%w", "%d %d %d %d", usershere, usersaway, chanops, chanunop)); put_it("%s", convert_output_format("TotalNicks %K[%W$[-5]0%K]%w MaxNicks %K[%W$[-5]1%K]%w", "%d %d", new->totalnicks,new->maxnicks)); put_it("%s", convert_output_format("IRCops %K[%W$[3]0%K]%w$1-", "%d %s", numircops, ircops)); put_it("%s", convert_output_format(" %CThere is %R$0%C limit and limit checking is %R$1-", "%s %s", new->limit ? ltoa(new->limit): "no", new->tog_limit?"Enabled":"Disabled")); put_it("%s", convert_output_format(" %CIdle user check is %K[%R$0-%K]", "%s", new->check_idle?"Enabled":"Disabled")); /*put_it("%s", convert_output_format("$G End of channel stats for $0", "%s", new->channel));*/ /* wtf is do_scan in the channel struct */ } new_free(&ircops); } void update_stats(int what, char *channel, NickList *nick, ChannelList *chan, int splitter) { time_t this_time = now; int t = 0; if (!chan || !chan->channel) return; switch (what) { case KICKLIST: { chan->stats_kicks++; chan->totalnicks--; if (nick) nick->stat_kicks++; break; } case LEAVELIST: { chan->stats_parts++; chan->totalnicks--; break; } case JOINLIST: { chan->stats_joins++; chan->totalnicks++; if (chan->totalnicks > chan->maxnicks) { chan->maxnicks = chan->totalnicks; chan->maxnickstime = this_time; } if (!splitter) { if (chan->chop && is_other_flood(chan, nick, JOIN_FLOOD, &t)) { if (get_cset_int_var(chan->csets, JOINFLOOD_CSET) && get_cset_int_var(chan->csets, KICK_ON_JOINFLOOD_CSET) && !nick->kickcount++) { send_to_server("MODE %s -o+b %s *!*%s", chan->channel, nick->nick, clear_server_flags(nick->host)); send_to_server("KICK %s %s :\002Join flood\002 (%d joins in %dsecs of %dsecs)", chan->channel, nick->nick, get_cset_int_var(chan->csets, KICK_ON_JOINFLOOD_CSET)/*chan->set_kick_on_joinflood*/, t, get_cset_int_var(chan->csets, JOINFLOOD_TIME_CSET)); if (get_int_var(AUTO_UNBAN_VAR)) add_timer(0, "", get_int_var(AUTO_UNBAN_VAR), 1, timer_unban, m_sprintf("%d %s *!*%s", from_server, chan->channel, clear_server_flags(nick->host)), NULL, current_window); } } } break; } case CHANNELSIGNOFFLIST: { chan->stats_signoffs++; chan->totalnicks--; break; } case PUBLICLIST: case PUBLICOTHERLIST: case PUBLICNOTICELIST: case NOTICELIST: { chan->stats_pubs++; if (nick) { nick->stat_pub++; nick->idle_time = this_time; } break; } case TOPICLIST: { chan->stats_topics++; break; } case MODEOPLIST: if (splitter) chan->stats_sops++; else { if (nick) nick->stat_ops++; chan->stats_ops++; } break; case MODEHOPLIST: if (splitter) chan->stats_shops++; else { if (nick) nick->stat_hops++; chan->stats_hops++; } break; case MODEDEHOPLIST: if (splitter) chan->stats_sdehops++; else { if (nick) nick->stat_dhops++; chan->stats_dhops++; } break; case MODEDEOPLIST: if (splitter) chan->stats_sdops++; else { chan->stats_dops++; if (nick) nick->stat_dops++; } if (chan->chop && is_other_flood(chan, nick, DEOP_FLOOD, &t)) { if (get_cset_int_var(chan->csets, DEOP_ON_DEOPFLOOD_CSET) < get_cset_int_var(chan->csets, KICK_ON_DEOPFLOOD_CSET)) send_to_server("MODE %s -o %s", chan->channel, nick->nick); else if (!nick->kickcount++) send_to_server("KICK %s %s :\002De-op flood\002 (%d de-ops in %dsecs of %dsecs)", chan->channel, nick->nick, get_cset_int_var(chan->csets, KICK_ON_DEOPFLOOD_CSET), t, get_cset_int_var(chan->csets, DEOPFLOOD_TIME_CSET)); } break; case MODEBANLIST: if (splitter) chan->stats_sbans++; else { if (nick) nick->stat_bans++; chan->stats_bans++; } chan->totalbans++; if (chan->stats_bans > chan->maxbans) { chan->maxbans = chan->stats_bans; chan->maxbanstime = this_time; } break; case MODEUNBANLIST: if (splitter) chan->stats_sunbans++; else { if (nick) nick->stat_unbans++; chan->stats_unbans++; } if (chan->totalbans) chan->totalbans--; break; default: break; } } BUILT_IN_COMMAND(usage) { #if defined(HAVE_GETRUSAGE) struct rusage r_usage; if ((0 == getrusage(RUSAGE_SELF, &r_usage))) { /* struct timeval ru_utime; user time used * struct timeval ru_stime; system time used */ int secs = r_usage.ru_utime.tv_sec + r_usage.ru_stime.tv_sec; if (secs == 0) secs =1; #ifdef ONLY_STD_CHARS put_it("%s", convert_output_format("%G--%WBitchX%G-%WUsage%G-%WStatistics%G------------------------------------", NULL)); put_it("%s",convert_output_format("%G| %CCPU %cUsage: Secs %W$[-2]0%n:%W$[-2]1%n %K[%CU%cser %W$[-2]2%n:%W$[-2]3 %CS%cystem %W$[-2]4%n:%W$[-2]5%K]","%d %d %d %d %d %d", secs/60,secs%60,r_usage.ru_utime.tv_sec/60, r_usage.ru_utime.tv_sec%60,r_usage.ru_stime.tv_sec/60, r_usage.ru_stime.tv_sec%60)); put_it("%s",convert_output_format("%G| %CMEM %cUsage: MaXRSS %W$0 %cShMem %W$1 %cData %W$2 %cStack %W$3","%l %l %l %l", r_usage.ru_maxrss, r_usage.ru_ixrss, r_usage.ru_idrss,r_usage.ru_isrss)); put_it("%s",convert_output_format("%G| %CSwaps %W$[-8]0 %CReclaims %W$[-8]1 %CFaults %W$[-8]2","%l %l %l", r_usage.ru_nswap, r_usage.ru_minflt, r_usage.ru_majflt)); put_it("%s",convert_output_format("%G| %CBlock %K[%cin %W$[-8]0 %cout %W$[-8]1%K]","%l %l", r_usage.ru_inblock, r_usage.ru_oublock)); put_it("%s",convert_output_format("%G| %CMsg %K[%cRcv %W$[-8]0 %cSend %W$[-8]1%K]","%l %l", r_usage.ru_msgrcv, r_usage.ru_msgsnd)); put_it("%s",convert_output_format("%G| %CSignals %W$[-8]0 %CContext %cVol. %W$[-8]1 %cInvol %W$[-8]2","%l %l %l", r_usage.ru_nsignals, r_usage.ru_nvcsw, r_usage.ru_nivcsw)); #else put_it("%s", convert_output_format("%GÚÄ%WBitchX%GÄ%WUsage%GÄ%WStatistics%GÄÄÄÄ%g---%GÄ%g--%GÄÄ%g-%GÄÄÄÄÄÄ%g---%KÄ%g--%KÄÄ%g-%KÄÄÄÄÄÄÄÄ", NULL)); put_it("%s",convert_output_format("%G| %CCPU %cUsage: Secs %W$[-2]0%n:%W$[-2]1%n %K[%CU%cser %W$[-2]2%n:%W$[-2]3 %CS%cystem %W$[-2]4%n:%W$[-2]5%K]","%d %d %d %d %d %d", secs/60,secs%60,r_usage.ru_utime.tv_sec/60, r_usage.ru_utime.tv_sec%60,r_usage.ru_stime.tv_sec/60, r_usage.ru_stime.tv_sec%60)); put_it("%s",convert_output_format("%g³ %CMEM %cUsage: MaXRSS %W$0 %cShMem %W$1 %cData %W$2 %cStack %W$3","%l %l %l %l", r_usage.ru_maxrss, r_usage.ru_ixrss, r_usage.ru_idrss,r_usage.ru_isrss)); put_it("%s",convert_output_format("%g| %CSwaps %W$[-8]0 %CReclaims %W$[-8]1 %CFaults %W$[-8]2","%l %l %l", r_usage.ru_nswap, r_usage.ru_minflt, r_usage.ru_majflt)); put_it("%s",convert_output_format("%K³ %CBlock %K[%cin %W$[-8]0 %cout %W$[-8]1%K]","%l %l", r_usage.ru_inblock, r_usage.ru_oublock)); put_it("%s",convert_output_format("%K: %CMsg %K[%cRcv %W$[-8]0 %cSend %W$[-8]1%K]","%l %l", r_usage.ru_msgrcv, r_usage.ru_msgsnd)); put_it("%s",convert_output_format("%K. %CSignals %W$[-8]0 %CContext %cVol. %W$[-8]1 %cInvol %W$[-8]2","%l %l %l", r_usage.ru_nsignals, r_usage.ru_nvcsw, r_usage.ru_nivcsw)); #endif } #else bitchsay("Lack of getrusage(). This function needed to be disabled on your client"); #endif } char *clear_server_flags (char *userhost) { register char *uh = userhost; while(uh && (*uh == '~' || *uh == '#' || *uh == '+' || *uh == '-' || *uh == '=' || *uh == '^')) uh++; return uh; } /* * (max server send) and max mirc color change is 256 * so 256 * 8 should give us a safety margin for hackers. * BIG_BUFFER is 1024 * 3 is 3072 whereas 256*8 is 2048 */ static unsigned char newline1[BIG_BUFFER_SIZE+1]; #ifndef BITCHX_LITE1 char *mircansi(unsigned char *line) { /* mconv v1.00 (c) copyright 1996 Ananda, all rights reserved. */ /* ----------------------------------------------------------- */ /* mIRC->ansi color code convertor: 12.26.96 */ /* map of mIRC color values to ansi color codes */ /* format: ansi fg color ansi bg color */ /* modified Colten Edwards */ struct { char *fg, *bg; } codes[16] = { { "", "" }, /* white */ { "", "" }, /* black (grey for us) */ { "", "" }, /* blue */ { "", "" }, /* green */ { "", "" }, /* red */ { "", "" }, /* brown */ { "", "" }, /* magenta */ { "", "" }, /* bright red */ { "", "" }, /* yellow */ { "", "" }, /* bright green */ { "", "" }, /* cyan */ { "", "" }, /* bright cyan */ { "", "" }, /* bright blue */ { "", "" }, /* bright magenta */ { "", "" }, /* dark grey */ { "", "" } /* grey */ }; register unsigned char *sptr = line, *dptr = newline1; short code; if (!*line) return empty_string; *newline1 = 0; while (*sptr) { if (*sptr == '' && isdigit(sptr[1])) { sptr++; code = *sptr - '0'; sptr++; if isdigit (*sptr) { code = code * 10 + *sptr - '0'; sptr++; } if (code > 15 || code <= 0) code = code % 16; strcpy(dptr, codes[code].fg); while (*dptr) dptr++; if (*sptr == ',') { sptr++; code = *sptr - '0'; sptr++; if isdigit (*sptr) { code = code * 10 + *sptr - '0'; sptr++; } if (code > 15 || code <= 0) code = code % 16; strcpy(dptr, codes[code].bg); while (*dptr) dptr++; } } else if (*sptr == '') { strcpy(dptr, ""); while(*dptr) dptr++; sptr++; } else *dptr++ = *sptr++; } *dptr = 0; return (char *)newline1; } #endif /* Borrowed with permission from FLiER */ char *stripansicodes(const unsigned char *line) { register unsigned char *tstr; register unsigned char *nstr; int gotansi=0; tstr=(char *)line; nstr=newline1; while (*tstr) { if (*tstr==0x1B || *tstr == 0x9b) gotansi=1; if (gotansi && isalpha(*tstr)) gotansi = 0; else if (!gotansi) { *nstr = *tstr; nstr++; } tstr++; } *nstr = 0; return (char *)newline1; } char *stripansi(unsigned char *line) { register unsigned char *cp; unsigned char *newline; newline = m_strdup(line); for (cp = newline; *cp; cp++) if ((*cp < 31 && *cp > 13)) if (*cp != 1 && *cp != 15 && *cp !=22 && *cp != 0x9b) *cp = (*cp & 127) | 64; return (char *)newline; } int check_split(char *nick, char *reason, char *chan) { char *bogus = get_string_var(FAKE_SPLIT_PATS_VAR); char *Reason = m_strdup(reason); char *tmp; tmp = Reason; if (word_count(Reason) > 3) goto fail_split; if (wild_match("%.% %.%", Reason) && !strstr(Reason, "))") ) { char *host1 = next_arg(Reason, &Reason); char *host2 = next_arg(Reason, &Reason); char *x = NULL; if (!my_stricmp(host1, host2)) goto fail_split; if (wild_match(host1, "*..*") || wild_match(host2, "*..*")) goto fail_split; if ((x = strrchr(host1, '.'))) x++; if (!x || strlen(x) < 2 || strlen(x) > 3) goto fail_split; if ((x = strrchr(host2, '.'))) x++; if (!x || strlen(x) < 2 || strlen(x) > 3) goto fail_split; if (bogus) { char *copy = NULL; char *b_check; char *temp; malloc_strcpy(©, bogus); temp = copy; while((b_check = next_arg(copy, ©))) { if (wild_match(b_check, host1) || wild_match(b_check, host2)) { new_free(&temp); goto fail_split; } } new_free(&temp); } new_free(&tmp); return 1; } fail_split: new_free(&tmp); return 0; } void clear_array(NickTab **tmp) { NickTab *t, *q; for (t = *tmp; t; ) { q = t->next; new_free(&t->nick); new_free(&t->type); new_free((char **)&t); t = q; } *tmp = NULL; } BUILT_IN_COMMAND(clear_tab) { NickTab **tmp = &tabkey_array; if (command && *command && !my_stricmp(command, "CLEARAUTO")) tmp = &autoreply_array; clear_array(tmp); } void userage(char *command, char *use) { if (command) { if (do_hook(USAGE_LIST, "%s %s", command, use ? use : "No Help Available for this command")) put_it("%s", convert_output_format(fget_string_var(FORMAT_USAGE_FSET), "%s %s", command, convert_output_format(use ? use : "%WNo Help available for this command", NULL, NULL))); } else put_it("Please return the command you just typed to #bitchx on efnet"); } char *random_str(int min, int max) { int i, ii; static char str[BIG_BUFFER_SIZE/4+1]; while ((i = getrandom(min, max)) > BIG_BUFFER_SIZE/4) ; for (ii = 0; ii < i; ii++) str[ii] = (char) getrandom(97, 122); str[ii] = '\0'; return str; } void auto_away(unsigned long value) { if (get_int_var(AUTO_AWAY_VAR) && !get_server_away(from_server)) { char *msg = NULL; if (awaymsg) malloc_sprintf(&msg, "%s: [%d mins]", convert_output_format(awaymsg, NULL), get_int_var(AUTO_AWAY_TIME_VAR)/60); else malloc_sprintf(&msg, "Auto-Away after %d mins", get_int_var(AUTO_AWAY_TIME_VAR)/60); away(NULL, msg, NULL, NULL); new_free(&msg); } } /*char *logfile[] = { "tcl.log", "msg.log", NULL };*/ /* putlog(level,channel_name,format,...); */ void putlog(int type, ...) { va_list va; time_t t; char *format, *chname, *logfilen = NULL, s[BIG_BUFFER_SIZE+1], s1[40], s2[BIG_BUFFER_SIZE+1]; FILE *f; if (!get_int_var(BOT_LOG_VAR)) return; if (!(logfilen = get_string_var(BOT_LOGFILE_VAR))) return; #ifdef PUBLIC_ACCESS return; #endif va_start(va, type); t = now; strftime(s1, 30, "%I:%M%p", localtime(&t)); chname=va_arg(va,char *); format=va_arg(va,char *); vsprintf(s,format,va); if (!*s) strcpy(s2,empty_string); else sprintf(s2,"[%s] %s",s1,s); if (chname && *chname =='*') { if ((f=fopen(logfilen, "a+")) != NULL) { fprintf(f,"%s\n",s2); fclose(f); } } } int rename_file (char *old_file, char **new_file) { char *tmp = NULL; char buffer[BIG_BUFFER_SIZE+4]; char *c = NULL; FILE *fp; malloc_sprintf(&c,"%03i.",getrandom(0, 999)); if (get_string_var(DCC_DLDIR_VAR)) malloc_sprintf(&tmp, "%s/%s", get_string_var(DCC_DLDIR_VAR), &c); else malloc_sprintf(&tmp, "%s", &c); malloc_strcat(&tmp, *new_file); strmcpy(buffer, *new_file, BIG_BUFFER_SIZE); while ((fp = fopen(tmp, "r")) != NULL) { fclose(fp); new_free(&c); malloc_sprintf(&c,"%03i.",getrandom(0, 999)); if (get_string_var(DCC_DLDIR_VAR)) malloc_sprintf(&tmp, "%s/%s", get_string_var(DCC_DLDIR_VAR), &c); else malloc_sprintf(&tmp, "%s", &c); malloc_strcat(&tmp, buffer); } if (fp != NULL) fclose(fp); malloc_sprintf(new_file, "%s", c); malloc_strcat(new_file, buffer); new_free(&c); new_free(&tmp); return 0; } int isme(char *nick) { return ((my_stricmp(nick, get_server_nickname(from_server)) == 0) ? 1 : 0); } void clear_link(irc_server **serv1) { irc_server *temp = *serv1, *hold; while (temp != NULL) { hold = temp->next; new_free(&temp->name); new_free(&temp->link); new_free(&temp->time); new_free((char **) &temp); temp = hold; } *serv1 = NULL; } irc_server *add_server(irc_server **serv1, char *channel, char *arg, int hops, char *time) { irc_server *serv2; serv2 = (irc_server *) new_malloc(sizeof (irc_server)); serv2->next = *serv1; malloc_strcpy(&serv2->name, channel); malloc_strcpy(&serv2->link, arg); serv2->hopcount = hops; malloc_strcpy(&serv2->time, time); *serv1 = serv2; return serv2; } int find_server(irc_server *serv1, char *channel) { register irc_server *temp; for (temp = serv1; temp; temp = temp->next) { if (!my_stricmp(temp->name, channel)) return 1; } return 0; } void add_split_server(char *name, char *link, int hops) { irc_server *temp; temp = add_server(&(server_list[from_server].split_link), name, link, hops, update_clock(GET_TIME)); temp->status = SPLIT; } irc_server *check_split_server(char *server) { register irc_server *temp; if (!server) return NULL; for (temp = server_list[from_server].split_link; temp; temp = temp->next) if (!my_stricmp(temp->name, server)) return temp; return NULL; } void remove_split_server(char *server) { irc_server *temp; if ((temp = (irc_server *) remove_from_list((List **)&server_list[from_server].split_link, server))) { new_free(&temp->name); new_free(&temp->link); new_free(&temp->time); new_free((char **) &temp); } } void parse_364(char *channel, char *args, char *subargs) { if (!*channel || !*args || from_server < 0) return; add_server(&server_list[from_server].tmplink, channel, args, atol(subargs), update_clock(GET_TIME)); } void parse_365(char *channel, char *args, char *subargs) { register irc_server *serv1; for (serv1 = server_list[from_server].server_last; serv1; serv1 = serv1->next) { if (!find_server(server_list[from_server].tmplink, serv1->name)) { if (!(serv1->status & SPLIT)) serv1->status = SPLIT; if (serv1->count) continue; malloc_strcpy(&serv1->time, update_clock(GET_TIME)); if (do_hook(LLOOK_SPLIT_LIST, "%s %s %d %s", serv1->name, serv1->link, serv1->hopcount, serv1->time)) put_it("%s", convert_output_format(fget_string_var(FORMAT_NETSPLIT_FSET), "%s %s %s %d", serv1->time, serv1->name, serv1->link, serv1->hopcount)); serv1->count++; } else { if (serv1->status & SPLIT) { serv1->status = ~SPLIT; if (do_hook(LLOOK_JOIN_LIST, "%s %s %d %s", serv1->name, serv1->link, serv1->hopcount, serv1->time)) put_it("%s", convert_output_format(fget_string_var(FORMAT_NETJOIN_FSET), "%s %s %s %d", serv1->time, serv1->name, serv1->link, serv1->hopcount)); serv1->count = 0; } } } for (serv1 = server_list[from_server].tmplink; serv1; serv1 = serv1->next) { if (!find_server(server_list[from_server].server_last, serv1->name)) { if (first_time == 1) { if (do_hook(LLOOK_ADDED_LIST, "%s %s %d", serv1->name, serv1->link, serv1->hopcount)) put_it("%s", convert_output_format(fget_string_var(FORMAT_NETADD_FSET), "%s %s %s %d", serv1->time, serv1->name, serv1->link, serv1->hopcount)); serv1->count = 0; } add_server(&server_list[from_server].server_last, serv1->name, serv1->link, serv1->hopcount, update_clock(GET_TIME)); } } first_time = 1; clear_link(&server_list[from_server].tmplink); } /* * find split servers we hope */ BUILT_IN_COMMAND(linklook) { struct server_split *serv; int count; if (from_server == -1 || !(serv = server_list[from_server].server_last)) { bitchsay("No active splits"); return; } count = 0; while (serv) { if (serv->status & SPLIT) { if (!count) put_it("%s", convert_output_format(fget_string_var(FORMAT_NETSPLIT_HEADER_FSET), "%s %s %s %s", "time","server","uplink","hops")); if (do_hook(LLOOK_SPLIT_LIST, "%s %s %d", serv->name, serv->link, serv->hopcount)) put_it("%s", convert_output_format(fget_string_var(FORMAT_NETSPLIT_FSET), "%s %s %s %d", serv->time, serv->name, serv->link, serv->hopcount)); count++; } serv = serv->next; } if (count) bitchsay("There %s %d split servers", (count == 1) ? "is": "are", count); else bitchsay("No split servers found"); } enum REDIR_TYPES { PRIVMSG = 0, KICK, TOPIC, WALL, WALLOP, NOTICE, KBOOT, KILL, DCC, LIST}; void userhost_ban(UserhostItem *stuff, char *nick1, char *args); int redirect_msg(char *to, enum REDIR_TYPES what, char *str, int showansi) { char *new_str; if (showansi) new_str = str; else new_str = stripansicodes(str); switch(what) { case PRIVMSG: if (is_channel(to)) put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_PUBLIC_FSET), "%s %s %s %s", update_clock(GET_TIME), "*", to, str)); else if ((*to == '=') && dcc_activechat(to+1)) ; else put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_MSG_FSET), "%s %s %s %s", update_clock(GET_TIME), to, "*", str)); if ((*to == '=') && dcc_activechat(to+1)) dcc_chat_transmit(to+1, new_str, str, "PRIVMSG", 1); else send_to_server("PRIVMSG %s :%s", to, new_str); break; case KILL: send_to_server("KILL %s :%s", to, new_str); break; case KBOOT: userhostbase(to, userhost_ban, 1, "%s %s %s", get_current_channel_by_refnum(0), to, ""); case KICK: send_to_server("KICK %s %s :%s", get_current_channel_by_refnum(0), to, new_str); break; case TOPIC: send_to_server("TOPIC %s :%s", to, new_str); break; case WALL: { ChanWallOp(NULL, new_str, NULL, NULL); break; } case WALLOP: put_it("!! %s", str); send_to_server("WALLOPS :%s", new_str); break; case NOTICE: put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME), to, "*", str)); send_to_server("NOTICE %s :%s", to, new_str); break; case LIST: default: break; } return 1; } BUILT_IN_COMMAND(do_dirlasttype) { char *channel = NULL; int count = -1; LastMsg *t = NULL; char *form = NULL; char *sform; int numargs = 5; int size = 1; int len = strlen(command); int showansi = 0; enum REDIR_TYPES what = PRIVMSG; if (!my_strnicmp(command, "RELCR", 5)) { t = &last_ctcp[0]; form = fget_string_var(FORMAT_CTCP_REPLY_FSET); sform = "%s %s %s %s %s"; if (len == 6 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELC", 4)) { t = &last_sent_ctcp[0]; form = fget_string_var(FORMAT_SEND_CTCP_FSET); sform = "%s %s %s %s %s"; if (len > 4 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELD", 4)) { t = &last_dcc[0]; form = fget_string_var(FORMAT_DCC_CHAT_FSET); sform = "%s %s %s %s"; if (len > 4 && command[len-1] == 'T') what = TOPIC; numargs = 4; } else if (!my_strnicmp(command, "RELSD", 5)) { t = &last_sent_dcc[0]; form = fget_string_var(FORMAT_DCC_CHAT_FSET); sform = "%s %s %s %s"; if (len > 5 && command[len-1] == 'T') what = TOPIC; numargs = 4; } else if (!my_strnicmp(command, "RELI", 4)) { t = &last_invite_channel[0]; form = fget_string_var(FORMAT_INVITE_FSET); numargs = 4; sform = "%s %s %s"; if (len > 4 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELM", 4)) { /* ??? */ t = &last_msg[0]; size = MAX_LAST_MSG; form = fget_string_var(FORMAT_RELM_FSET); sform = "%s %s %s %s %s"; if (len > 4 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELN", 4)) { /* ??? */ t = &last_notice[0]; size = MAX_LAST_MSG; form = fget_string_var(FORMAT_RELN_FSET); sform = "%s %s %s %s %s"; if (len > 4 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELSM", 5)) { /* ??? */ t = &last_sent_msg[0]; size = MAX_LAST_MSG; form = fget_string_var(FORMAT_RELSM_FSET); sform = "%s %s %s %s %s"; if (len > 5 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELSN", 5)) { /* ??? */ t = &last_sent_notice[0]; size = MAX_LAST_MSG; form = fget_string_var(FORMAT_SEND_NOTICE_FSET); sform = "%s %s %s %s"; numargs = 4; if (len > 5 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELST", 5)) { /* ??? */ t = &last_sent_topic[0]; form = fget_string_var(FORMAT_TOPIC_FSET); sform = "%s %s %s"; numargs = 2; if (len > 5 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELSW", 5)) { /* ??? */ t = &last_sent_wall[0]; form = fget_string_var(FORMAT_WALLOP_FSET); sform = "%s %s %s %s %s"; if (len > 5 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELS", 4)) { t = &last_servermsg[0]; size = MAX_LAST_MSG; form = fget_string_var(FORMAT_RELS_FSET); sform = "%s %s %s %s"; numargs = 4; if (len > 4 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELT", 4)) { /* ??? */ t = &last_topic[0]; form = fget_string_var(FORMAT_TOPIC_FSET); sform = "%s %s %s"; numargs = 2; if (len > 4 && command[len-1] == 'T') what = TOPIC; } else if (!my_strnicmp(command, "RELW", 4)) { /* ??? */ t = &last_wall[0]; size = MAX_LAST_MSG; form = fget_string_var(FORMAT_WALLOP_FSET); sform = "%s %s %s %s"; numargs = 4; if (len > 4 && command[len-1] == 'T') what = TOPIC; } else { what = LIST; size = MAX_LAST_MSG; t = &last_msg[0]; for (count = size - 1; count != -1; count--) { if (t[count].last_msg) #if 0 { bitchsay("No such msg #%d for /%s received", count, command); break; } else #endif put_it("%2d %s", count, convert_output_format(fget_string_var(FORMAT_RELM_FSET), "%s %s %s %s %s", t[count].time, t[count].from, t[count].uh, t[count].to, t[count].last_msg)); } return; } while (args && *args) { char *comm; if (!(comm = next_arg(args, &args))) break; if (!my_strnicmp(comm, "-list", strlen(comm))) { for (count = size - 1; count != -1; count--) { #if 0 if (!count && !t[count].last_msg) { bitchsay("No such msg #%d for /%s received", count, command); break; } else if (!t[count].last_msg) break; #endif if (!t[count].last_msg) continue; switch(numargs) { case 2: put_it("%2d %s", count, convert_output_format(form, sform, t[count].time, t[count].to, t[count].last_msg)); break; case 3: put_it("%2d %s", count, convert_output_format(form, sform, t[count].time, t[count].from, t[count].last_msg)); break; case 4: put_it("%2d %s", count, convert_output_format(form, sform, t[count].time, t[count].from, t[count].to, t[count].last_msg)); break; case 5: put_it("%2d %s", count, convert_output_format(form, sform, t[count].time, t[count].from, t[count].uh, t[count].to, t[count].last_msg)); } } return; } else if (!my_strnicmp(comm, "-kick", strlen(comm))) what = KICK; else if (!my_strnicmp(comm, "-wall", strlen(comm))) what = WALL; else if (!my_strnicmp(comm, "-wallop", strlen(comm))) what = WALLOP; else if (!my_strnicmp(comm, "-msg", strlen(comm))) what = PRIVMSG; else if (!my_strnicmp(comm, "-notice", strlen(comm))) what = NOTICE; else if (!my_strnicmp(comm, "-topic", strlen(comm))) what = TOPIC; else if (!my_strnicmp(comm, "-kboot", strlen(comm))) what = KBOOT; else if (!my_strnicmp(comm, "-kill", strlen(comm))) what = KILL; else if (!my_strnicmp(comm, "-ansi", strlen(comm))) showansi++; else if (!my_strnicmp(comm, "-help", strlen(comm))) { userage(command, helparg/*"<-list|-kick|-wall|-wallop|-msg|-notice|-topic|-kboot|-ansi|-kill|-help> <#|channel|nick> "*/); return; } else { if (is_number(comm)) { count = my_atol(comm); if (count < 0) count *= -1; } else channel = comm; } if (count > size) count = size; } if (count == -1) count = 0; if (!channel) channel = get_current_channel_by_refnum(0); if (channel || what == WALLOP) { char *p = NULL; if (!t[count].last_msg) { bitchsay("No such msg #%d for /%s received", count, command); return; } switch(numargs) { case 2: malloc_strcpy(&p, convert_output_format(form, sform, t[count].time, t[count].to, t[count].last_msg)); break; case 3: malloc_strcpy(&p, convert_output_format(form, sform, t[count].time, t[count].from, t[count].last_msg)); break; case 4: malloc_strcpy(&p, convert_output_format(form, sform, t[count].time, t[count].from, t[count].to, t[count].last_msg)); break; case 5: malloc_strcpy(&p, convert_output_format(form, sform, t[count].time, t[count].from, t[count].uh, t[count].to, t[count].last_msg)); } redirect_msg(channel, what, p, showansi); new_free(&p); } else bitchsay("Can not %s what you requested", command); } /* * Wallop Sends NOTICE to all ops of Current Channel! */ BUILT_IN_COMMAND(ChanWallOp) { char *channel = NULL; char *chops = NULL; char *include = NULL; char *exclude = NULL; ChannelList *chan; NickList *tmp; int ver = 0; int enable_all = 0; char buffer[BIG_BUFFER_SIZE + 1]; if (!args || (args && !*args)) { userage("WALLMSG", helparg); return; } if (get_current_channel_by_refnum(0)) { int count = 0; int i = 0; char *nick = NULL; malloc_strcpy(&channel, get_current_channel_by_refnum(0)); chan = lookup_channel(channel, current_window->server, 0); if (((ver = get_server_version(current_window->server)) == Server2_8hybrid6)) enable_all = 1; else if (((ver = get_server_version(current_window->server)) < Server_u2_8)) { while (args && (*args == '-' || *args == '+')) { nick = next_arg(args, &args); if (*nick == '-') { malloc_strcat(&exclude, nick+1); malloc_strcat(&exclude, " "); } else { malloc_strcat(&include, nick+1); malloc_strcat(&include, " "); } } } if (!args || !*args) { bitchsay("NO Wallmsg included"); new_free(&exclude); new_free(&include); new_free(&channel); } message_from(channel, LOG_WALL); sprintf(buffer, "[\002BX-Wall\002/\002%s\002] %s", channel, args); if (ver >= Server_u2_10 || enable_all) { send_to_server(enable_all?"NOTICE @%s :%s":"WALLCHOPS %s :%s", channel, buffer); put_it("%s", convert_output_format(fget_string_var(FORMAT_BWALL_FSET), "%s %s %s %s %s", update_clock(GET_TIME), channel, "*", "*", args)); add_last_type(&last_sent_wall[0], 1, NULL, NULL, channel, buffer); new_free(&channel); message_from(NULL, LOG_CRAP); return; } for (tmp = next_nicklist(chan, NULL); tmp; tmp = next_nicklist(chan, tmp)) { if (!my_stricmp(tmp->nick, get_server_nickname(from_server))) continue; if (exclude && stristr(exclude, tmp->nick)) continue; if (tmp->chanop == 1 || (include && stristr(include, tmp->nick))) { if (chops) malloc_strcat(&chops, ","); malloc_strcat(&chops, tmp->nick); count++; } if (count >= 8 && chops) { send_to_server("%s %s :%s", "NOTICE", chops, buffer); i+=count; count = 0; new_free(&chops); } } i+=count; if (chops) send_to_server("%s %s :%s", "NOTICE", chops, buffer); if (i) { put_it("%s", convert_output_format(fget_string_var(FORMAT_BWALL_FSET), "%s %s %s %s %s", update_clock(GET_TIME), channel, "*", "*", args)); add_last_type(&last_sent_wall[0], 1, NULL, NULL, channel, buffer); if (exclude) bitchsay("Excluded <%s> from wallmsg", exclude); if (include) bitchsay("Included <%s> in wallmsg", include); } else put_it("%s", convert_output_format("$G No ops on $0", "%s", channel)); message_from(NULL, LOG_CRAP); } else say("No Current Channel for this Window."); new_free(&include); new_free(&channel); new_free(&chops); new_free(&exclude); } void log_toggle(int flag, ChannelList *chan) { char *logfile; if (((logfile = get_string_var(MSGLOGFILE_VAR)) == NULL) || !get_string_var(CTOOLZ_DIR_VAR)) { bitchsay("You must set the MSGLOGFILE and CTOOLZ_DIR variables first!"); set_int_var(MSGLOG_VAR, 0); return; } logmsg(LOG_CURRENT, NULL, flag ? 1 : 2, NULL); } void not_on_a_channel(Window *win) { if (win) message_to(win->refnum); bitchsay("You're not on a channel!"); message_to(0); } int are_you_opped(char *channel) { return is_chanop(channel, get_server_nickname(from_server)); } void error_not_opped(char *channel) { say("You're not opped on %s", channel); } int freadln(FILE *stream, char *lin) { char *p; do p = fgets(lin, BIG_BUFFER_SIZE/4, stream); while (p && (*lin == '#')); if (!p) return 0; chop(lin, 1); if (!*lin) return 0; return 1; } char *randreason(char *filename) { int count, min, i; FILE *bleah; static char buffer[BIG_BUFFER_SIZE/4 + 1]; min = 1; count = 0; buffer[0] = '\0'; if (!filename || !(bleah = fopen(filename, "r"))) return NULL; while (!feof(bleah)) if (freadln(bleah, buffer)) count++; if (!count) { strcpy(buffer, "No Reason"); return buffer; } fseek(bleah, 0, 0); i = getrandom(1, count); count = 0; while (!feof(bleah) && (count < i)) if (freadln(bleah, buffer)) count++; fclose(bleah); if (*buffer) return buffer; return NULL; } char *get_reason(char *nick, char *file) { char *temp, *p; char *filename = NULL; if (file && *file) malloc_sprintf(&filename, "%s", file); else #if defined(WINNT) || defined(__EMX__) malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "kck"); #else malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "reasons"); #endif p = expand_twiddle(filename); temp = randreason(p); new_free(&filename); new_free(&p); if ((!temp || !*temp) && get_string_var(DEFAULT_REASON_VAR)) temp = get_string_var(DEFAULT_REASON_VAR); return (stripansicodes(convert_output_format(temp, "%s %s", nick? nick: "error", get_server_nickname(from_server) ))); } char *get_realname(char *nick) { char *temp, *p; char *filename = NULL; #if defined(WINNT) || defined(__EMX__) malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "nam"); #else malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "ircnames"); #endif p = expand_twiddle(filename); temp = randreason(p); new_free(&filename); new_free(&p); if ((!temp || !*temp)) temp = "Who cares?"; return (stripansicodes(convert_output_format(temp, "%s %s", nick? nick: "error", get_server_nickname(from_server) ))); } char *get_signoffreason(char *nick) { char *temp, *p; char *filename = NULL; #if defined(WINNT) || defined(__EMX__) malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "qt"); #else malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "quit"); #endif p = expand_twiddle(filename); temp = randreason(p); new_free(&filename); new_free(&p); if (!temp || !*temp) temp = "$0 has no reason"; return (stripansicodes(convert_output_format(temp, "%s %s", nick? nick: "error", get_server_nickname(from_server)))); } #ifndef WINNT /* * arlib.c (C)opyright 1993 Darren Reed. All rights reserved. * This file may not be distributed without the author's permission in any * shape or form. The author takes no responsibility for any damage or loss * of property which results from the use of this software. * heavily modified for use in a irc client. */ #include #include #include #include #include #include #include #include #include #include #define HOSTLEN 100 extern int h_errno; static char ar_hostbuf[HOSTLEN+1], ar_domainname[HOSTLEN+1]; static char ar_dot[] = "."; static int ar_resfd = -1, ar_vc = 0; static struct reslist *ar_last = NULL, *ar_first = NULL; static int do_query_name(struct resinfo *, char *, register struct reslist *, char *, char *, char *, char *, int , void (*func)()); static int do_query_number(struct resinfo *, char *, register struct reslist *, char *, char *, char *, char *, int , void (*func)()); static int ar_resend_query(struct reslist *); #define MAX_RETRIES 4 #ifndef HFIXEDSZ #define HFIXEDSZ 12 #endif #ifndef INT32SZ #define INT32SZ 4 #endif /* * Statistics structure. */ static struct resstats { int re_errors; int re_nu_look; int re_na_look; int re_replies; int re_requests; int re_resends; int re_sent; int re_timeouts; } ar_reinfo; /* * ar_init * * Initializes the various ARLIB internal varilables and related DNS * options for res_init(). * * Returns 0 or the socket opened for use with talking to name servers * if 0 is passed or ARES_INITSOCK is set. */ int ar_init(int op) { int ret = 0; if (op & ARES_INITLIST) { memset(&ar_reinfo, 0, sizeof(ar_reinfo)); ar_first = ar_last = NULL; } if (op & ARES_CALLINIT && !(_res.options & RES_INIT)) { ret = res_init(); (void)strcpy(ar_domainname, ar_dot); (void)strncat(ar_domainname, _res.defdname, HOSTLEN-2); if (!_res.nscount) { _res.nscount = 1; _res.nsaddr_list[0].sin_addr.s_addr = inet_addr("127.0.0.1"); } } if (op & ARES_INITSOCK) ret = ar_resfd = ar_open(); if (op & ARES_INITDEBG) _res.options |= RES_DEBUG; if (op == 0) ret = ar_resfd; return ret; } /* * ar_open * * Open a socket to talk to a name server with. * Check _res.options to see if we use a TCP or UDP socket. */ int ar_open(void) { if (ar_resfd == -1) { if (_res.options & RES_USEVC) { struct sockaddr_in *sip; int i = 0; sip = _res.nsaddr_list; ar_vc = 1; ar_resfd = socket(AF_INET, SOCK_STREAM, 0); /* * Try each name server listed in sequence until we * succeed or run out. */ while (connect(ar_resfd, (struct sockaddr *)sip++, sizeof(struct sockaddr))) { (void)close(ar_resfd); ar_resfd = -1; if (i >= _res.nscount) break; ar_resfd = socket(AF_INET, SOCK_STREAM, 0); } } else { int on = 0; ar_resfd = socket(AF_INET, SOCK_DGRAM, 0); (void) setsockopt(ar_resfd, SOL_SOCKET, SO_BROADCAST,(char *)&on, sizeof(on)); } } if (ar_resfd >= 0) { /* Need one of these two here - and it MUST work!! */ if (set_non_blocking(ar_resfd) < 0) { (void)close(ar_resfd); ar_resfd = -1; } } return ar_resfd; } /* * ar_close * * Closes and flags the ARLIB socket as closed. */ void ar_close(void) { (void)close(ar_resfd); ar_resfd = -1; return; } /* * ar_add_request * * Add a new DNS query to the end of the query list. */ static int ar_add_request(struct reslist *new) { if (!new) return -1; if (!ar_first) ar_first = ar_last = new; else { ar_last->re_next = new; ar_last = new; } new->re_next = NULL; ar_reinfo.re_requests++; return 0; } /* * ar_remrequest * * Remove a request from the list. This must also free any memory that has * been allocated for temporary storage of DNS results. * * Returns -1 if there are anyy problems removing the requested structure * or 0 if the remove is successful. */ static int ar_remrequest(struct reslist *old) { struct reslist *rptr, *r2ptr; register char **s; if (!old) return -1; for (rptr = ar_first, r2ptr = NULL; rptr; rptr = rptr->re_next) { if (rptr == old) break; r2ptr = rptr; } if (!rptr) return -1; if (rptr == ar_first) ar_first = ar_first->re_next; else if (rptr == ar_last) { if ((ar_last = r2ptr)) ar_last->re_next = NULL; } else r2ptr->re_next = rptr->re_next; if (!ar_first) ar_last = ar_first; if (rptr->re_he.h_name) new_free(&rptr->re_he.h_name); if ((s = rptr->re_he.h_aliases)) { for (; *s; s++) new_free(s); new_free(&rptr->re_he.h_aliases); } #if 0 if ((s = rptr->re_he.h_addr_list)) { /* CDE memleak detected here */ for (; *s; s++) new_free(s); new_free(&rptr->re_he.h_addr_list); } #endif if (rptr->re_rinfo.ri_ptr) new_free(&rptr->re_rinfo.ri_ptr); new_free(&rptr->nick); new_free(&rptr->user); new_free(&rptr->host); new_free(&rptr->channel); new_free(&rptr); return 0; } /* * ar_make_request * * Create a DNS query recorded for the request being made and place it on the * current list awaiting replies. Initialization of the record with set * values should also be done. */ static struct reslist *ar_make_request(register struct resinfo *resi, char *nick, char *user, char *h, char *chan, int server, void (*func)()) { register struct reslist *rptr; register struct resinfo *rp; rptr = (struct reslist *)new_malloc(sizeof(struct reslist)); rp = &rptr->re_rinfo; rptr->re_next = NULL; /* where NULL is non-zero ;) */ rptr->re_sentat = now; rptr->re_retries = MAX_RETRIES;/*_res.retry + 2;*/ rptr->re_sends = 1; rptr->re_resend = 1; rptr->re_timeout = rptr->re_sentat + _res.retrans; rptr->re_he.h_name = NULL; rptr->re_he.h_addrtype = AF_INET; rptr->re_he.h_aliases[0] = NULL; rp->ri_ptr = resi->ri_ptr; rp->ri_size = resi->ri_size; if (nick) malloc_strcpy(&rptr->nick, nick); if (user) malloc_strcpy(&rptr->user, user); if (h) malloc_strcpy(&rptr->host, h); if (chan) rptr->channel = m_strdup(chan); rptr->server = server; if (func) rptr->func = func; (void)ar_add_request(rptr); return rptr; } void ar_rename_nick(char *old_nick, char *new_nick, int server) { register struct reslist *rptr; for (rptr = ar_first; rptr; rptr = rptr->re_next) { if (!rptr->nick) continue; if (!strcmp(rptr->nick, old_nick) && rptr->server == server) malloc_strcpy(&rptr->nick, new_nick); } } /* * ar_timeout * * Remove queries from the list which have been there too long without * being resolved. */ long ar_timeout(time_t now, char *info, int size, void (*func)(struct reslist *) ) { register struct reslist *rptr, *r2ptr; register long next = 0; for (rptr = ar_first, r2ptr = NULL; rptr; rptr = r2ptr) { r2ptr = rptr->re_next; if (now >= rptr->re_timeout) { /* * If the timeout for the query has been exceeded, * then resend the query if we still have some * 'retry credit' and reset the timeout. If we have * used it all up, then remove the request. */ if (--rptr->re_retries <= 0) { ar_reinfo.re_timeouts++; if (info && rptr->re_rinfo.ri_ptr) bcopy(rptr->re_rinfo.ri_ptr, info, MIN(rptr->re_rinfo.ri_size, size)); if (rptr->func) (*rptr->func)(rptr); else if (func) (*func)(rptr); (void)ar_remrequest(rptr); return now; } else { rptr->re_sends++; rptr->re_sentat = now; rptr->re_timeout = now + _res.retrans; (void)ar_resend_query(rptr); } } if (!next || rptr->re_timeout < next) next = rptr->re_timeout; } return next; } /* * ar_send_res_msg * * When sending queries to nameservers listed in the resolv.conf file, * don't send a query to every one, but increase the number sent linearly * to match the number of resends. This increase only occurs if there are * multiple nameserver entries in the resolv.conf file. * The return value is the number of messages successfully sent to * nameservers or -1 if no successful sends. */ static int ar_send_res_msg(char *msg, int len, int rcount) { register int i; int sent = 0; if (!msg) return -1; rcount = (_res.nscount > rcount) ? rcount : _res.nscount; if (_res.options & RES_PRIMARY) rcount = 1; if (!rcount) rcount = 1; if (ar_vc) { ar_reinfo.re_sent++; sent++; if (write(ar_resfd, msg, len) == -1) { int errtmp = errno; (void)close(ar_resfd); errno = errtmp; ar_resfd = -1; } } else for (i = 0; i < rcount; i++) { _res.nsaddr_list[i].sin_family = AF_INET; if (sendto(ar_resfd, msg, len, 0, (struct sockaddr *)&(_res.nsaddr_list[i]), sizeof(struct sockaddr_in)) == len) { ar_reinfo.re_sent++; sent++; } } return (sent) ? sent : -1; } /* * ar_find_id * * find a dns query record by the id (id is determined by dn_mkquery) */ static struct reslist *ar_find_id(int id) { register struct reslist *rptr; for (rptr = ar_first; rptr; rptr = rptr->re_next) if (rptr->re_id == id) return rptr; return NULL; } /* * ar_delete * * Delete a request from the waiting list if it has a data pointer which * matches the one passed. */ int ar_delete(char *ptr, int size) { register struct reslist *rptr; register struct reslist *r2ptr; int removed = 0; for (rptr = ar_first; rptr; rptr = r2ptr) { r2ptr = rptr->re_next; if (rptr->re_rinfo.ri_ptr && ptr && size && memcmp(rptr->re_rinfo.ri_ptr, ptr, size) == 0) { (void)ar_remrequest(rptr); removed++; } } return removed; } /* * ar_query_name * * generate a query based on class, type and name. */ static int ar_query_name(char *name, int class, int type, struct reslist *rptr) { static char buf[MAXPACKET]; int r,s; HEADER *hptr; memset(buf, 0, sizeof(buf)); r = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, buf, sizeof(buf)); if (r <= 0) { h_errno = NO_RECOVERY; return r; } hptr = (HEADER *)buf; rptr->re_id = ntohs(hptr->id); s = ar_send_res_msg(buf, r, rptr->re_sends); if (s == -1) { h_errno = TRY_AGAIN; return -1; } else rptr->re_sent += s; return 0; } /* * ar_gethostbyname * * Replacement library function call to gethostbyname(). This one, however, * doesn't return the record being looked up but just places the query in the * queue to await answers. */ int ar_gethostbyname(char *name, char *info, int size, char *nick, char *user, char *h, char *chan, int server, void (*func)()) { char host[HOSTLEN+1]; struct resinfo resi; register struct resinfo *rp = &resi; if (size && info) { rp->ri_ptr = (char *)new_malloc(size+1); if (*info) bcopy(info, rp->ri_ptr, size); rp->ri_size = size; } else memset((char *)rp, 0, sizeof(resi)); ar_reinfo.re_na_look++; (void)strncpy(host, name, 64); host[64] = '\0'; return (do_query_name(rp, host, NULL, nick, user, h, chan, server, func)); } static int do_query_name(struct resinfo *resi, char *name, register struct reslist *rptr, char *nick, char *user, char *h, char *chan, int server, void (*func)()) { char hname[HOSTLEN]; int len; len = strlen((char *)strncpy(hname, name, sizeof(hname)-1)); if (rptr && (hname[len-1] != '.')) { (void)strncat(hname, ar_dot, sizeof(hname)-len-1); /* * NOTE: The logical relationship between DNSRCH and DEFNAMES * is implies. ie no DEFNAES, no DNSRCH. */ if ((_res.options & (RES_DEFNAMES|RES_DNSRCH)) == (RES_DEFNAMES|RES_DNSRCH)) { if (_res.dnsrch[(int)rptr->re_srch]) (void)strncat(hname, _res.dnsrch[(int)rptr->re_srch], sizeof(hname) - ++len -1); } else if (_res.options & RES_DEFNAMES) (void)strncat(hname, ar_domainname, sizeof(hname) - len -1); } /* * Store the name passed as the one to lookup and generate other host * names to pass onto the nameserver(s) for lookups. */ if (!rptr) { rptr = ar_make_request(resi, nick, user, h, chan, server, func); rptr->re_type = T_A; (void)strncpy(rptr->re_name, name, sizeof(rptr->re_name)-1); } return (ar_query_name(hname, C_IN, T_A, rptr)); } /* * ar_gethostbyaddr * * Generates a query for a given IP address. */ int ar_gethostbyaddr(char *addr, char *info, int size, char *nick, char *user, char *h, char *chan, int server, void (*func)()) { struct resinfo resi; register struct resinfo *rp = &resi; if (size && info) { rp->ri_ptr = (char *)new_malloc(size+1); if (*info) bcopy(info, rp->ri_ptr, size); rp->ri_size = size; } else memset((char *)rp, 0, sizeof(resi)); ar_reinfo.re_nu_look++; return (do_query_number(rp, addr, NULL, nick, user, h, chan, server, func)); } /* * do_query_number * * Use this to do reverse IP# lookups. */ static int do_query_number(struct resinfo *resi, char *numb, register struct reslist *rptr, char *nick, char *user, char *h, char *chan, int server, void (*func)()) { register unsigned char *cp; static char ipbuf[32]; /* * Generate name in the "in-addr.arpa" domain. No addings bits to this * name to get more names to query!. */ cp = (unsigned char *)numb; (void)sprintf(ipbuf,"%u.%u.%u.%u.in-addr.arpa.", (unsigned int)(cp[3]), (unsigned int)(cp[2]), (unsigned int)(cp[1]), (unsigned int)(cp[0])); if (!rptr) { rptr = ar_make_request(resi, nick, user, h, chan, server, func); rptr->re_type = T_PTR; rptr->re_he.h_length = sizeof(struct in_addr); memcpy((char *)&rptr->re_addr, numb, rptr->re_he.h_length); memcpy((char *)&rptr->re_he.h_addr_list[0].s_addr, numb, rptr->re_he.h_length); } return (ar_query_name(ipbuf, C_IN, T_PTR, rptr)); } /* * ar_resent_query * * resends a query. */ static int ar_resend_query(struct reslist *rptr) { if (!rptr->re_resend) return -1; switch(rptr->re_type) { case T_PTR: ar_reinfo.re_resends++; return do_query_number(NULL, (char *)&rptr->re_addr, rptr, NULL, NULL, NULL, NULL, -1, NULL); case T_A: ar_reinfo.re_resends++; return do_query_name(NULL, rptr->re_name, rptr, NULL, NULL, NULL, NULL, -1, NULL); default: break; } return -1; } /* * ar_procanswer * * process an answer received from a nameserver. */ static int ar_procanswer(struct reslist *rptr, HEADER *hptr, char *buf, char *eob) { char *cp, **alias; int class, type, dlen, len, ans = 0, n; unsigned int ttl, dr, *adr; struct hent *hp; cp = buf + HFIXEDSZ; adr = (unsigned int *)rptr->re_he.h_addr_list; while (*adr) adr++; alias = rptr->re_he.h_aliases; while (*alias) alias++; hp = &rptr->re_he; /* * Skip over the original question. */ while (hptr->qdcount-- > 0) cp += dn_skipname(cp, eob) + QFIXEDSZ; /* * proccess each answer sent to us. blech. */ while (hptr->ancount-- > 0 && cp < eob) { n = dn_expand(buf, eob, cp, ar_hostbuf, sizeof(ar_hostbuf)-1); cp += n; if (n <= 0) return ans; ans++; /* * 'skip' past the general dns crap (ttl, class, etc) to get * the pointer to the right spot. Some of thse are actually * useful so its not a good idea to skip past in one big jump. */ type = (int)_getshort(cp); cp += sizeof(short); class = (int)_getshort(cp); cp += sizeof(short); ttl = (unsigned int)_getlong(cp); cp += INT32SZ; dlen = (int)_getshort(cp); cp += sizeof(short); rptr->re_type = type; switch(type) { case T_A : rptr->re_he.h_length = dlen; if (ans == 1) rptr->re_he.h_addrtype=(class == C_IN) ? AF_INET : AF_UNSPEC; memcpy(&dr, cp, dlen); *adr++ = dr; *adr = 0; cp += dlen; len = strlen(ar_hostbuf); if (!rptr->re_he.h_name) malloc_strcpy(&rptr->re_he.h_name, ar_hostbuf); break; case T_PTR : if ((n = dn_expand(buf, eob, cp, ar_hostbuf, sizeof(ar_hostbuf)-1 )) < 0) { cp += n; continue; } ar_hostbuf[HOSTLEN] = 0; cp += n; len = strlen(ar_hostbuf)+1; /* * copy the returned hostname into the host name * or alias field if there is a known hostname * already. */ if (!rptr->re_he.h_name) malloc_strcpy(&rptr->re_he.h_name, ar_hostbuf); else { *alias = (char *)new_malloc(len); strcpy(*alias++, ar_hostbuf); *alias = NULL; } break; case T_CNAME : cp += dlen; if (alias >= &(rptr->re_he.h_aliases[MAXALIASES-1])) continue; n = strlen(ar_hostbuf)+1; *alias = (char *)new_malloc(n); (void)strcpy(*alias++, ar_hostbuf); *alias = NULL; break; default : break; } } return ans; } /* * ar_answer * * Get an answer from a DNS server and process it. If a query is found to * which no answer has been given to yet, copy its 'info' structure back * to where "reip" points and return a pointer to the hostent structure. */ struct hostent *ar_answer(char *reip, int size, void (*func)(struct reslist *) ) { static char ar_rcvbuf[HFIXEDSZ + MAXPACKET]; static struct hostent ar_host; register HEADER *hptr; register struct reslist *rptr = NULL; register struct hostent *hp; register char **s; unsigned long *adr; int rc, i, n, a; rc = recv(ar_resfd, ar_rcvbuf, sizeof(ar_rcvbuf), 0); if (rc <= 0) goto getres_err; ar_reinfo.re_replies++; hptr = (HEADER *)ar_rcvbuf; /* * convert things to be in the right order. */ hptr->id = ntohs(hptr->id); hptr->ancount = ntohs(hptr->ancount); hptr->arcount = ntohs(hptr->arcount); hptr->nscount = ntohs(hptr->nscount); hptr->qdcount = ntohs(hptr->qdcount); /* * response for an id which we have already received an answer for * just ignore this response. */ rptr = ar_find_id(hptr->id); if (!rptr) goto getres_err; if ((hptr->rcode != NOERROR) || (hptr->ancount == 0)) { switch (hptr->rcode) { case NXDOMAIN: h_errno = HOST_NOT_FOUND; break; case SERVFAIL: h_errno = TRY_AGAIN; break; case NOERROR: h_errno = NO_DATA; break; case FORMERR: case NOTIMP: case REFUSED: default: h_errno = NO_RECOVERY; break; } ar_reinfo.re_errors++; /* ** If a bad error was returned, we stop here and dont send ** send any more (no retries granted). */ if (h_errno != TRY_AGAIN) { rptr->re_resend = 0; rptr->re_retries = 0; } goto getres_err; } a = ar_procanswer(rptr, hptr, ar_rcvbuf, ar_rcvbuf+rc); if ((rptr->re_type == T_PTR) && (_res.options & RES_CHECKPTR)) { /* * For reverse lookups on IP#'s, lookup the name that is given * for the ip# and return with that as the official result. * -avalon */ rptr->re_type = T_A; /* * Clean out the list of addresses already set, even though * there should only be one :) */ adr = (unsigned long *)rptr->re_he.h_addr_list; while (*adr) *adr++ = 0L; /* * Lookup the name that we were given for the ip# */ ar_reinfo.re_na_look++; (void)strncpy(rptr->re_name, rptr->re_he.h_name, sizeof(rptr->re_name)-1); rptr->re_he.h_name = NULL; rptr->re_retries = MAX_RETRIES;/*_res.retry + 2;*/ rptr->re_sends = 1; rptr->re_resend = 1; if (rptr->re_he.h_name) new_free(&rptr->re_he.h_name); ar_reinfo.re_na_look++; (void)ar_query_name(rptr->re_name, C_IN, T_A, rptr); return NULL; } if (reip && rptr->re_rinfo.ri_ptr && size) memcpy(reip, rptr->re_rinfo.ri_ptr, MIN(rptr->re_rinfo.ri_size, size)); /* * Clean up structure from previous usage. */ hp = &ar_host; if (hp->h_name) new_free(&hp->h_name); if ((s = hp->h_aliases)) { while (*s) { new_free(s); s++; } new_free(&hp->h_aliases); } if ((s = hp->h_addr_list)) { while (*s) { new_free(s); s++; } new_free(&hp->h_addr_list); hp->h_addr_list = NULL; } memset ((char *)hp, 0, sizeof(*hp)); /* * Setup and copy details for the structure we return a pointer to. */ hp->h_addrtype = AF_INET; hp->h_length = sizeof(struct in_addr); malloc_strcpy(&hp->h_name, rptr->re_he.h_name); /* * Count IP#'s. */ for (i = 0, n = 0; i < MAXADDRS; i++, n++) if (!rptr->re_he.h_addr_list[i].s_addr) break; s = hp->h_addr_list = (char **)new_malloc((n + 1) * sizeof(char *)); if (n) { *s = (char *)new_malloc(sizeof(struct in_addr)); memcpy(*s, (char *)&rptr->re_he.h_addr_list[0].s_addr, sizeof(struct in_addr)); s++; for (i = 1; i < n; i++, s++) { *s = (char *)new_malloc(sizeof(struct in_addr)); memcpy(*s, (char *)&rptr->re_he.h_addr_list[i].s_addr, sizeof(struct in_addr)); } } *s = NULL; /* * Count CNAMEs */ for (i = 0, n = 0; i < MAXADDRS; i++, n++) if (!rptr->re_he.h_aliases[i]) break; s = hp->h_aliases = (char **)new_malloc((n + 1) * sizeof(char *)); for (i = 0; i < n; i++) { *s++ = rptr->re_he.h_aliases[i]; rptr->re_he.h_aliases[i] = NULL; } *s = NULL; if (rptr->func) (*rptr->func)(rptr); else if (func) (*func)(rptr); if (a > 0) (void)ar_remrequest(rptr); else if (!rptr->re_sent) (void)ar_remrequest(rptr); return hp; getres_err: if (rptr) { if (reip && rptr->re_rinfo.ri_ptr && size) memcpy(reip, rptr->re_rinfo.ri_ptr, MIN(rptr->re_rinfo.ri_size, size)); if ((h_errno != TRY_AGAIN) && ((_res.options & (RES_DNSRCH|RES_DEFNAMES)) == (RES_DNSRCH|RES_DEFNAMES) )) if (_res.dnsrch[(int)rptr->re_srch]) { rptr->re_retries = MAX_RETRIES; /*_res.retry + 2;*/ rptr->re_sends = 1; rptr->re_resend = 1; (void)ar_resend_query(rptr); rptr->re_srch++; } return NULL; } return NULL; } static int ar_seq = 0; static int ar_lookup = 0; void auto_nslookup(struct reslist *rptr) { NickList *nick; ChannelList *chan; struct in_addr ip; if ((chan = lookup_channel(rptr->channel, rptr->server, 0))) { if ((nick = find_nicklist_in_channellist(rptr->nick, chan, 0))) { if (rptr->re_he.h_addr_list[0].s_addr) { bcopy(&rptr->re_he.h_addr_list[0], (char *)&ip, sizeof(ip)); nick->ip = m_strdup(inet_ntoa(ip)); check_auto(chan->channel, nick, chan); } else if (++nick->ip_count < 2) do_nslookup(rptr->host, rptr->nick, rptr->user, rptr->channel, rptr->server, auto_nslookup); #ifdef PANA_DEBUG else put_it("got here. nslookup failure %s!%s", nick->nick, nick->host); #endif } } return; } void print_ns_succede(struct reslist *rptr) { char *u, *n, *h; u = rptr->user ? rptr->user : empty_string; h = rptr->host; n = rptr->nick ? rptr->nick : empty_string; if (do_hook(NSLOOKUP_LIST, "%s %s %s %s %s", h, rptr->re_he.h_name?rptr->re_he.h_name:"", (char *)inet_ntoa(rptr->re_he.h_addr_list[0]), n, u)) { int i; char buffer[BIG_BUFFER_SIZE]; struct in_addr ip; *buffer = 0; if (rptr->nick && rptr->user) bitchsay("[%s!%s@%s]: %s", n, u, h, rptr->re_he.h_name ? rptr->re_he.h_name: "invalid hostname"); else bitchsay("%s is %s (%s)", h, rptr->re_he.h_name ? rptr->re_he.h_name:"invalid hostname", (char *)inet_ntoa(rptr->re_he.h_addr_list[0])); for (i = 0; rptr->re_he.h_addr_list[i].s_addr; i++) { bcopy(&rptr->re_he.h_addr_list[i], (char *)&ip, sizeof(ip)); strpcat(buffer, "[%s] ", inet_ntoa(ip)); if (strlen(buffer) > 490) break; } bitchsay("IPs: %s", buffer); for (i = 0; rptr->re_he.h_aliases[i]; i++) bitchsay("\talias %d = %s", i+1, rptr->re_he.h_aliases[i]); } } void print_ns_fail(struct reslist *rptr) { if (do_hook(NSLOOKUP_LIST, "%s %s %s", rptr->host, rptr->nick?rptr->nick:empty_string, rptr->user?rptr->user:empty_string)) { if (rptr->nick && rptr->user) bitchsay("nslookup of %s!%s@%s failed.", rptr->nick, rptr->user, rptr->host); else bitchsay("nslookup of host %s failed.", rptr->host); } } void set_nslookupfd(fd_set *rd) { int s; if ((s = ar_init(0)) != -1) FD_SET(s, rd); } long print_nslookup(fd_set *rd) { struct hostent *hp = NULL; int ar_del = 0; int s; if ((s = ar_init(0)) == -1) return -1; if (!(FD_ISSET(s, rd))) { unsigned long when = 0; when = ar_timeout(now, (char *)&ar_del, sizeof(ar_del), print_ns_fail); if (ar_del) ar_lookup--; return when; } if ((hp = ar_answer((char *)&ar_del, sizeof(ar_del), print_ns_succede))) { char **s; ar_lookup--; new_free(&hp->h_name); if ((s = hp->h_aliases)) { while (*s) { new_free(s); s++; } new_free(&hp->h_aliases); } if ((s = hp->h_addr_list)) { while (*s) { new_free(s); s++; } new_free(&hp->h_addr_list); } } return -1; } #else long print_nslookup(fd_set *rd) { return -1; } void set_nslookupfd(fd_set *rd) { } void auto_nslookup(struct reslist *res) { } #endif void ns_init(void) { #ifndef WINNT ar_init(ARES_INITLIST|ARES_CALLINIT|ARES_INITSOCK); #endif } char *do_nslookup(char *host, char *nick, char *user, char *chan, int server, void (*func)()) { #ifndef WINNT struct in_addr temp1; int s; if (!host) return NULL; if ((s = ar_init(0)) == -1) ar_init(ARES_INITLIST|ARES_INITSOCK|ARES_CALLINIT); ar_lookup++; if (isdigit(*(host + strlen(host) - 1))) { ar_seq++; temp1.s_addr = inet_addr(host); ar_gethostbyaddr((char *)&temp1.s_addr, (char *)&ar_seq, sizeof(ar_seq), nick, user, host, chan, server, func); } else { ar_seq++; ar_gethostbyname(host, (char *)&ar_seq, sizeof(ar_seq), nick, user, host, chan, server, func); } #endif return NULL; } #ifndef WINNT void userhost_nsl(UserhostItem *stuff, char *nick, char *args) { char *nsl; if (!stuff || !stuff->nick || !nick || !strcmp(stuff->user, "") || my_stricmp(stuff->nick, nick)) { say("No information for %s", nick); return; } nsl = do_nslookup(stuff->host, stuff->nick, stuff->user, NULL, from_server, NULL); } #endif BUILT_IN_COMMAND(nslookup) { #ifndef WINNT char *host, *hostname; if ((host = next_arg(args, &args))) { bitchsay("Checking tables..."); if (!strchr(host, '.')) userhostbase(host, userhost_nsl, 1, "%s", host); else hostname = do_nslookup(host, NULL, NULL, NULL, from_server, NULL); } else userage(command, helparg); #endif } char *rights(string, num) char *string; int num; { if (strlen(string) < num) return string; return (string + strlen(string) - num); } int numchar(char *string, char c) { int num = 0; while (*string) { if (tolower(*string) == tolower(c)) num++; string++; } return num; } char *cluster (char *hostname) { static char result[BIG_BUFFER_SIZE/4 + 1]; char temphost[BIG_BUFFER_SIZE + 1]; char *host; if (!hostname) return NULL; host = temphost; *result = 0; memset(result, 0, sizeof(result)); memset(temphost, 0, sizeof(temphost)); if (strchr(hostname, '@')) { if (*hostname == '~') hostname++; strcpy(result, hostname); *strchr(result, '@') = '\0'; if (strlen(result) > 9) { result[8] = '*'; result[9] = '\0'; } strcat(result, "@"); if (!(hostname = strchr(hostname, '@'))) return NULL; hostname++; } strcpy(host, hostname); if (*host && isdigit(*(host + strlen(host) - 1))) { /* Thanks icebreak for this small patch which fixes this function */ int i; char *tmp; char count=0; tmp = host; while((tmp-host) num)) { if ((host = strchr(host, '.')) != NULL) host++; else return (char *) NULL; } strcat(result, "*"); if (my_stricmp(host, temphost)) strcat(result, "."); strcat(result, host); } return result; } struct _sock_manager { int init; int count; int max_fd; SocketList sockets[FD_SETSIZE]; } sock_manager = {0, 0, -1, {{ 0, 0, 0, NULL, 0, 0, NULL, NULL, NULL }}}; #define SOCKET_TIMEOUT 120 #ifdef GUI char *checkmenu(MenuList *check, int menuid) { MenuList *tmpml; MenuStruct *tmpms; char *tmpalias; tmpml=check; while(tmpml!=NULL) { if (tmpml->menutype==GUISUBMENU || tmpml->menutype==GUISHARED || tmpml->menutype==GUIBRKSUBMENU) { tmpms = (MenuStruct *)findmenu(tmpml->submenu); if ((tmpalias=checkmenu(tmpms->menuorigin, menuid))!=NULL) return tmpalias; } if (tmpml->menuid==menuid) return tmpml->alias; tmpml=tmpml->next; } return NULL; } void scan_gui(fd_set *rd) { char guicmd[3]; extern MenuStruct *morigin; extern unsigned long menucmd; MenuStruct *tmpms; int newpos, cursb; char *alias; Window *scrollwin, *newfocuswindow; float bleah; Screen *newfocusscreen; #ifdef __EMXPM__ extern int just_resized; extern Screen *just_resized_screen; #endif #ifdef __EMXPM__ if(just_resized == 1) WinSendMsg(just_resized_screen->hwndFrame, 0x041e, 0, 0); #endif /* Read the data from the pipe and decide what to do */ if(FD_ISSET(guiipc[0], rd)) { read(guiipc[0], guicmd, 2); switch(guicmd[0]) { case '2': tmpms = morigin; while(tmpms!=NULL) { if((alias=checkmenu(tmpms->menuorigin, menucmd))!=NULL) { make_window_current(get_window_by_refnum((int)guicmd[1])); parse_line(NULL, alias, empty_string, 0, 0, 0); break; } tmpms=tmpms->next; } break; case '3': gui_flush(); newfocuswindow=get_window_by_refnum((int)guicmd[1]); if(newfocuswindow) newfocusscreen=newfocuswindow->screen; else newfocusscreen=NULL; if (newfocusscreen && newfocusscreen->current_window) { make_window_current(newfocusscreen->current_window); output_screen=last_input_screen=newfocusscreen; set_input_prompt(current_window, get_string_var(INPUT_PROMPT_VAR), 1); } update_input(UPDATE_ALL); break; case '4': refresh_window_screen(get_window_by_refnum((int)guicmd[1])); break; case '5': if(newscrollerpos != lastscrollerpos || lastscrollerwindow != (int)guicmd[1]) { lastscrollerpos=newscrollerpos; lastscrollerwindow=(int)guicmd[1]; scrollwin=get_window_by_refnum((int)guicmd[1]); bleah = get_int_var(SCROLLBACK_VAR); newpos = (int)(((bleah-newscrollerpos) / bleah) * (scrollwin->display_buffer_size)); cursb = scrollwin->distance_from_display; printf("lsp = %d lsw = %d newpos = %d cursb = %d\n", lastscrollerpos, lastscrollerwindow, newpos, cursb); if (newpos > cursb) scrollback_backwards_lines(newpos-cursb); if (newpos < cursb) scrollback_forwards_lines(cursb-newpos); } break; case '6': scrollback_backwards_lines(1); break; case '7': scrollback_forwards_lines(1); break; case '8': scrollback_backwards((char)NULL, NULL); break; case '9': scrollback_forwards((char)NULL, NULL); break; case 'A': wm_process((int)guicmd[1]); break; } } } #endif void read_clonelist(int s) { char buffer[IRCD_BUFFER_SIZE + 1]; char *str = buffer; switch(dgets(str, s, 0, IRCD_BUFFER_SIZE)) { case -1: { do_hook(SOCKET_LIST, "%d %s %d", s, sock_manager.sockets[s].server, sock_manager.sockets[s].port); close_socketread(s); break; } case 0: break; default: { if ((buffer[strlen(buffer)-1] == '\r') || (buffer[strlen(buffer)-1] == '\n')) buffer[strlen(buffer)-1] = 0; if ((buffer[strlen(buffer)-1] == '\r') || (buffer[strlen(buffer)-1] == '\n')) buffer[strlen(buffer)-1] = 0; if (*buffer) do_hook(SOCKET_LIST, "%d %s %d %s", s, sock_manager.sockets[s].server, sock_manager.sockets[s].port, buffer); } } } void read_clonenotify(int s) { unsigned long flags = 0; flags = get_socketflags(s); do_hook(SOCKET_NOTIFY_LIST, "%d %s %d %d", s, sock_manager.sockets[s].server, sock_manager.sockets[s].port, (unsigned int)flags); } unsigned long set_socketflags(int s, unsigned long flags) { if (check_socket(s)) { sock_manager.sockets[s].flags = flags; return sock_manager.sockets[s].flags; } return 0; } unsigned long get_socketflags(int s) { if (check_socket(s)) return sock_manager.sockets[s].flags; return 0; } char *get_socketserver(int s) { if (check_socket(s)) return sock_manager.sockets[s].server; return NULL; } void *get_socketinfo(int s) { if (check_socket(s)) return sock_manager.sockets[s].info; return NULL; } void set_socketinfo(int s, void *info) { if (check_socket(s)) sock_manager.sockets[s].info = info; } int get_max_fd(void) { return sock_manager.max_fd + 1; } int add_socketread(int s, int port, unsigned long flags, char *server, void (*func_read)(int), void (*func_write)(int)) { if (!sock_manager.init) { fd_set rd; FD_ZERO(&rd); set_socket_read(&rd, &rd); } if (s > FD_SETSIZE) return -1; if (s > sock_manager.max_fd) sock_manager.max_fd = s; sock_manager.count++; sock_manager.sockets[s].is_read = s; sock_manager.sockets[s].port = port; sock_manager.sockets[s].flags = flags; if (server) sock_manager.sockets[s].server = m_strdup(server); sock_manager.sockets[s].func_read = func_read; sock_manager.sockets[s].func_write = func_write; new_open(s); return s; } int set_socketwrite(int s) { if (s > FD_SETSIZE) return -1; if (s > sock_manager.max_fd) sock_manager.max_fd = s; sock_manager.sockets[s].is_write = s; new_open_write(s); return s; } void add_sockettimeout(int s, time_t timeout) { if (timeout < 0) { timeout = get_int_var(CONNECT_TIMEOUT_VAR); if (timeout <= 0) timeout = SOCKET_TIMEOUT; } if (timeout) sock_manager.sockets[s].time = now + timeout; else sock_manager.sockets[s].time = 0; } void close_socketread(int s) { if (!sock_manager.count) return; if (sock_manager.sockets[s].is_read) { new_free(&sock_manager.sockets[s].server); if (sock_manager.sockets[s].is_write) new_close_write(s); new_close(s); memset(&sock_manager.sockets[s], 0, sizeof(SocketList)); sock_manager.count--; if (s == sock_manager.max_fd) { int i; sock_manager.max_fd = -1; for (i = 0; i < FD_SETSIZE; i++) if (sock_manager.sockets[i].is_read) sock_manager.max_fd = i; } } } int check_socket(int s) { if (s != -1 && sock_manager.count && sock_manager.sockets[s].is_read) return 1; return 0; } int check_dcc_socket(int s) { if (sock_manager.count && sock_manager.sockets[s].is_read && sock_manager.sockets[s].info) { if ( ((dcc_struct_type *)sock_manager.sockets[s].info)->struct_type == DCC_STRUCT_TYPE) return 1; } return 0; } int write_sockets(int s, unsigned char *str, int len, int nl) { if (s < 1) return -1; if (nl) { unsigned char *buf; buf = alloca(strlen(str)+4); strcpy(buf, str); strcat(buf, "\r\n"); len += 2; return write(s, buf, len); } return write(s, str, len); } int read_sockets(int s, unsigned char *str, int len) { if (s < 1) return -1; return read(s, str, len); } void set_socket_read (fd_set *rd, fd_set *wr) { register int i; static int socket_init = 0; if (!socket_init) { memset(&sock_manager, 0, sizeof(sock_manager)); socket_init++; sock_manager.init++; } if (!sock_manager.count) return; for (i = 0; i < sock_manager.max_fd + 1; i++) { if (sock_manager.sockets[i].is_read) FD_SET(sock_manager.sockets[i].is_read, rd); if (sock_manager.sockets[i].is_write) FD_SET(sock_manager.sockets[i].is_write, wr); } } void scan_sockets(fd_set *rd, fd_set *wr) { register int i; time_t t = now; if (!sock_manager.count) return; for (i = 0; i < sock_manager.max_fd+1; i++) { if (sock_manager.sockets[i].is_read && FD_ISSET(sock_manager.sockets[i].is_read, rd)) (sock_manager.sockets[i].func_read) (sock_manager.sockets[i].is_read); if (sock_manager.sockets[i].func_write && sock_manager.sockets[i].is_write && FD_ISSET(sock_manager.sockets[i].is_write, wr)) (sock_manager.sockets[i].func_write) (sock_manager.sockets[i].is_write); if (sock_manager.sockets[i].time && (t >= sock_manager.sockets[i].time)) close_socketread(i); } } SocketList *get_socket(int s) { if (check_socket(s)) return &sock_manager.sockets[s]; return NULL; } extern int dgets_errno; void read_netfinger(int s) { char tmpstr[BIG_BUFFER_SIZE+1]; register unsigned char *p = tmpstr; *tmpstr = 0; switch(dgets(tmpstr, s, 0, BIG_BUFFER_SIZE)) { case 0: break; case -1: if (do_hook(SOCKET_LIST, "%d %d %s Remote closed connection", s, sock_manager.sockets[s].port, sock_manager.sockets[s].server)) { if (dgets_errno == -1) bitchsay("Remote closed connection"); } close_socketread(s); break; default: { chop(tmpstr, 1); while (*p) { switch(*p) { case 0210: case 0211: case 0212: case 0214: *p -= 0200; break; case 0x9b: case '\t': break; case '\n': case '\r': *p = '\0'; break; default: if (!isprint(*p)) *p = (*p & 0x7f) | 0x40; break; } p++; } if (do_hook(SOCKET_LIST, "%d %d %s %s", s, sock_manager.sockets[s].port, sock_manager.sockets[s].server, tmpstr)) put_it("%s", tmpstr); } } } void netfinger (char *name) { char *host = NULL; unsigned short port = 79; int s; if (name) { if ((host = strrchr(name, '@'))) *host++ = 0; else host = name; } if (!host || !*host) { say("Invalid @host or user@host."); return; } if (name && *name) { if ((s = connect_by_number(host, &port, SERVICE_CLIENT, PROTOCOL_TCP, 1)) < 0) { bitchsay("Finger connect error on %s@%s", name?name:empty_string, host); return; } if ((add_socketread(s, port, 0, name, read_netfinger, NULL)) > -1) { write_sockets(s, name, strlen(name), 1); add_sockettimeout(s, 120); } else close_socketread(s); } return; } void start_finger (UserhostItem *stuff, char *nick, char *args) { char *finger_userhost = NULL; char *str; if (!stuff || !stuff->nick || !nick || !strcmp(stuff->user, "") || my_stricmp(stuff->nick, nick)) { say("No information for %s", nick); return; } malloc_sprintf(&finger_userhost, "%s@%s", stuff->user, stuff->host); str = finger_userhost; str = clear_server_flags(finger_userhost); say("Launching finger for %s (%s)", nick, finger_userhost); netfinger(str); new_free(&finger_userhost); } BUILT_IN_COMMAND(finger) { char *userhost; if ((userhost = next_arg(args, &args))) { if (!strchr(userhost, '@')) { userhostbase(userhost, start_finger, 1, "%s", userhost); return; } netfinger(userhost); } else userage(command, helparg); } static void handle_socket_connect(int rc) { struct servent *serv; struct sockaddr_in addr; struct hostent *host; int address_len; address_len = sizeof(struct sockaddr_in); if ((getpeername(rc, (struct sockaddr *) &addr, &address_len)) != -1) { serv = getservbyport(addr.sin_port,"tcp"); address_len = sizeof(addr.sin_addr); host = gethostbyaddr((char *)&addr.sin_addr, address_len, AF_INET); put_it("Hostname %s:%s port %d is running (%s)", host->h_name, inet_ntoa(addr.sin_addr), htons(addr.sin_port), serv == NULL? "UNKNOWN":serv->s_name); } close_socketread(rc); } static int scan(char *remote_host, int low_port, int high_port, struct hostent *host) { unsigned short int port; int rc; if (low_port == 0) low_port = 1; for (port = low_port;port <= high_port;port++) { if ((rc = connect_by_number(remote_host, &port, SERVICE_CLIENT, PROTOCOL_TCP, 1)) < 0) continue; if ((add_socketread(rc, port, 0, NULL, handle_socket_connect, NULL)) > -1) add_sockettimeout(rc, 120); else close_socketread(rc); } return 1; } void userhost_scanport(UserhostItem *stuff, char *nick, char *args) { char *t; int low_port = 0, high_port = 0; struct hostent *host; if (!stuff || !stuff->nick || !nick || !strcmp(stuff->user, "") || my_stricmp(stuff->nick, nick)) { bitchsay("No such nick [%s] found", nick); return; } next_arg(args, &args); t = next_arg(args, &args); low_port = atol(t); t = next_arg(args, &args); high_port = atol(t); if ((host = resolv(stuff->host))) { bitchsay("Scanning %s ports %d to %d", stuff->host, low_port, high_port); scan(stuff->host, low_port, high_port, host); return; } bitchsay("Cannot resolv host %s for %s", stuff->host, stuff->nick); } BUILT_IN_COMMAND(findports) { char *remote_host; int low_port = 6660; int high_port = 7000; struct hostent *host; if (args && *args) { char *tmp = NULL; remote_host = next_arg(args, &args); if (args && *args) { tmp = next_arg(args, &args); low_port = strtoul(tmp, NULL, 10); if (args && *args) { tmp = next_arg(args, &args); high_port = strtoul(tmp, NULL, 10); } else high_port = low_port; } if (strchr(remote_host, '.')) { if ((host = resolv(remote_host))) { bitchsay("Scanning %s's tcp ports %d through %d",remote_host, low_port,high_port); scan(remote_host, low_port, high_port, host); } else bitchsay("No such host %s", remote_host); } else userhostbase(remote_host, userhost_scanport, 1, "%s %d %d", remote_host, low_port, high_port); } else userage("FPORT", helparg); return; } void userhost_ignore (UserhostItem *stuff, char *nick1, char *args) { char *p, *arg; char *nick = NULL, *user = NULL, *host = NULL; int old_window_display; char ignorebuf[BIG_BUFFER_SIZE+1]; Ignore *igptr, *igtmp; WhowasList *whowas; arg = next_arg(args, &args); if (!stuff || !stuff->nick || !nick1 || !strcmp(stuff->user, "") || my_stricmp(stuff->nick, nick1)) { if ((whowas = check_whowas_nick_buffer(nick1, arg, 0))) { bitchsay("Using WhoWas info for %s of %s ", arg, nick1); user = host; host = strchr(host, '@'); *host++ = 0; nick = whowas->nicklist->nick; } else { say("No match for user %s", nick1); return; } } else { user = clear_server_flags(stuff->user); host = stuff->host; nick = stuff->nick; } if (!arg || !*arg || !my_stricmp(arg, "+HOST")) sprintf(ignorebuf, "*!*@%s ALL -CRAP -PUBLIC", cluster(host)); else if (!my_stricmp(arg, "+USER")) sprintf(ignorebuf, "*%s@%s ALL -CRAP -PUBLIC", user, cluster(host)); else if (!my_stricmp(arg, "-USER") || !my_stricmp(arg, "-HOST")) { int found = 0; if (!my_stricmp(arg, "-HOST")) sprintf(ignorebuf, "*!*@%s", cluster(host)); else sprintf(ignorebuf, "%s!%s@%s", nick, user, host); igptr = ignored_nicks; while (igptr != NULL) { igtmp = igptr->next; if (wild_match(igptr->nick, ignorebuf) || wild_match(nick, igptr->nick)) { sprintf(ignorebuf, "%s NONE", igptr->nick); old_window_display = window_display; window_display = 0; ignore(NULL, ignorebuf, ignorebuf, NULL); window_display = old_window_display; bitchsay("Unignored %s!%s@%s", nick, user, host); found++; } igptr = igtmp; } if (!found) bitchsay("No Match for ignorance of %s", nick); return; } old_window_display = window_display; window_display = 0; ignore(NULL, ignorebuf, ignorebuf, NULL); if ((arg = next_arg(args, &args))) { char tmp[BIG_BUFFER_SIZE+1]; sprintf(tmp, "%s ^IGNORE %s NONE", arg, ignorebuf); timercmd("TIMER", tmp, NULL, NULL); } window_display = old_window_display; if ((p = strchr(ignorebuf, ' '))) *p = 0; say("Now ignoring ALL except CRAP and PUBLIC from %s", ignorebuf); return; } BUILT_IN_COMMAND(reset) { refresh_screen(0, NULL); } extern char *channel_key (char *); BUILT_IN_COMMAND(cycle) { char *to = NULL; int server = from_server; ChannelList *chan; if (args && args) to = next_arg(args, &args); if (!(chan = prepare_command(&server, to, NO_OP))) return; my_send_to_server(server, "PART %s\nJOIN %s%s%s", chan->channel, chan->channel, chan->key?" ":"", chan->key?chan->key:""); /* my_send_to_server(server, "JOIN %s%s%s", chan->channel, chan->key?" ":"", chan->key?chan->key:"");*/ } int do_newuser(char *command, char *args, char *subargs) { char *newusername = NULL; if ((newusername = next_arg(args, &args))) { #ifdef IDENT_FAKE FILE *outfile; char *p = NULL, *q = NULL; malloc_sprintf(&p, "~/%s", get_string_var(IDENT_HACK_VAR)); q = expand_twiddle(p); outfile = fopen(q,"w"); #ifdef CIDENTD fprintf(outfile,"hideme\nmynameis %s\n", newusername); #else fprintf(outfile,"%s", newusername); #endif fclose(outfile); #endif strmcpy(username, newusername, NAME_LEN); if (subargs && *subargs) strmcpy(realname, subargs, REALNAME_LEN); #ifdef IDENT_FAKE new_free(&p); new_free(&q); #endif reconnect_cmd(NULL, newusername, NULL, NULL); } else return 0; return 1; } BUILT_IN_COMMAND(newnick) { char *newnick, *newusername; if ((newnick = next_arg(args, &args)) && (newusername = next_arg(args, &args))) do_newuser(newnick, newusername, args); else say("You must specify a nick and username"); } BUILT_IN_COMMAND(newuser) { char *newusername; if ((newusername = next_arg(args, &args))) { if ((do_newuser(NULL, newusername, args))) say("You must specify a username."); } else userage(command, helparg); } BUILT_IN_COMMAND(do_ig) { char *nick; char ignore_type[6]; int got_ignore_type = 0; int need_time = 0; if (!args || !*args) goto bad_ignore; while ((nick = next_arg(args, &args))) { if (!nick || !*nick) goto bad_ignore; if (*nick == '-' || *nick == '+') { if (!my_stricmp(nick, "-USER") || !my_stricmp(nick, "+HOST") || !my_stricmp(nick, "+USER") || !my_stricmp(nick, "-HOST")) strcpy(ignore_type, nick); if (!args || !*args) goto bad_ignore; got_ignore_type++; continue; } else if (!got_ignore_type) { if (command && !my_strnicmp(command, "IGH",3)) strcpy(ignore_type, "+HOST"); else if (command && !my_strnicmp(command, "IG",2)) strcpy(ignore_type, "+USER"); if (command && !my_strnicmp(command, "UNIGH", 5)) strcpy(ignore_type, "-HOST"); else if (command && !my_strnicmp(command, "UNIG", 4)) strcpy(ignore_type, "-USER"); if (command && toupper(command[strlen(command)-1]) == 'T') need_time ++; } if (need_time) userhostbase(nick, userhost_ignore, 1, "%s %d", ignore_type, get_int_var(IGNORE_TIME_VAR)); else userhostbase(nick, userhost_ignore, 1, "%s", ignore_type); } return; bad_ignore: userage(command, helparg); } BUILT_IN_COMMAND(users) { ChannelList *chan; NickList *nicks; NickList *sortl = NULL; char *to = NULL, *spec = "*!*@*", *temp1 = NULL; char modebuf[BIG_BUFFER_SIZE + 1]; char msgbuf[BIG_BUFFER_SIZE +1]; int count = 0, ops = 0, msg = 0, num_kicks = 0, hook = 0, not = 0, server = from_server, sorted = NICKSORT_NORMAL; *msgbuf = 0; *modebuf = 0; while (args && *args) { if (!args || !*args) break; temp1 = next_arg(args, &args); if (*temp1 == '-') { if (!my_strnicmp(temp1, "-ops", strlen(temp1))) ops = 1; else if (!my_strnicmp(temp1, "-nonops", strlen(temp1))) ops = 2; else if (!my_strnicmp(temp1, "-msg", strlen(temp1))) msg = 1; else if (!my_strnicmp(temp1, "-notice", strlen(temp1))) msg = 2; else if (!my_strnicmp(temp1, "-nkill", strlen(temp1))) msg = 3; else if (!my_strnicmp(temp1, "-kill", strlen(temp1))) msg = 4; else if (!my_strnicmp(temp1, "-kick", strlen(temp1))) msg = 5; else if (!my_strnicmp(temp1, "-stats", strlen(temp1))) msg = 6; else if (!my_strnicmp(temp1, "-ips", strlen(temp1))) msg = 7; else if (!my_strnicmp(temp1, "-sort", strlen(temp1)) && args && *args) { if (!my_strnicmp(args, "none", 4)) sorted = NICKSORT_NONE; else if (!my_strnicmp(args, "host", 4)) sorted = NICKSORT_HOST; else if (!my_strnicmp(args, "nick", 4)) sorted = NICKSORT_NICK; else if (!my_strnicmp(args, "ip", 3)) sorted = NICKSORT_IP; else if (!my_strnicmp(args, "time", 3)) sorted = NICKSORT_TIME; if (sorted != NICKSORT_NORMAL) next_arg(args, &args); } else if (strpbrk(temp1, "*!@.")) { spec = temp1+1; not = 1; } } else if (temp1 && is_channel(temp1)) to = temp1; else if (strpbrk(temp1, "*!@.")) spec = temp1; else { if (args && *args) temp1[strlen(temp1)] = ' '; args = temp1; break; } } if (!spec || !*spec) spec = "*!*@*"; if (!(chan = prepare_command(&server, to, NO_OP))) { bitchsay(to?"Not on that channel %s":"No such channel %s", to?to:empty_string); return; } message_from(chan->channel, LOG_CRAP); if (command && !my_stricmp(command, "CHOPS")) ops = 1; if (command && !my_stricmp(command, "NOPS")) ops = 2; if ((msg == 1 || msg == 2) && (!args || !*args)) { say("No message given"); message_from(NULL, LOG_CRAP); return; } switch (msg) { case 6: if (do_hook(STAT_HEADER_LIST, "%s %s %s %s %s", "Nick", "dops", "kicks","nicks","publics")) put_it("Nick dops kicks nicks publics"); break; case 0: { char *f; if ((f = fget_string_var(FORMAT_USERS_TITLE_FSET))) put_it("%s", convert_output_format(f, "%s %s", update_clock(GET_TIME), chan->channel)); } default: break; } sortl = sorted_nicklist(chan, sorted); for (nicks = sortl; nicks; nicks = nicks->next) { sprintf(modebuf, "%s!%s", nicks->nick, nicks->host ? nicks->host : ""); if (msg == 7 && nicks->ip) { strcat(modebuf, " "); strcat(modebuf, nicks->ip); } if (((!not && wild_match(spec, modebuf)) || (not && !wild_match(spec, modebuf))) && (!ops || ((ops == 1) && nicks->chanop) || ((ops == 2) && !nicks->chanop) )) { switch(msg) { case 3: /* nokill */ count--; break; case 4: /* kill */ { if (!isme(nicks->nick)) my_send_to_server(server, "KILL %s :%s (%i", nicks->nick, args && *args ? args : get_reason(nicks->nick, NULL), count + 1); else count--; break; } case 5: /* mass kick */ { if (!isme(nicks->nick)) { if (*msgbuf) strcat(msgbuf, ","); strcat(msgbuf, nicks->nick); num_kicks++; } else count--; if ((get_int_var(NUM_KICKS_VAR) && (num_kicks == get_int_var(NUM_KICKS_VAR))) || strlen(msgbuf) >= 450) { my_send_to_server(server, "KICK %s %s :%s", chan->channel, msgbuf, (args && *args) ? args : "-=punt=-"); *msgbuf = 0; num_kicks = 0; } break; } case 6: { if (!isme(nicks->nick)) { if (do_hook(STAT_LIST, "%s %d %d %d %d", nicks->nick, nicks->dopcount, nicks->kickcount, nicks->nickcount, nicks->floodcount)) put_it("%-10s %4d %4d %4d %4d", nicks->nick, nicks->dopcount, nicks->kickcount, nicks->nickcount, nicks->floodcount); } break; } case 7: if (do_hook(USERS_IP_LIST, "%s %s %s", nicks->nick, nicks->host, nicks->ip?nicks->ip:"Unknown")) put_it("%s!%s = %s", nicks->nick, nicks->host, nicks->ip?nicks->ip:"Unknown"); break; case 1: case 2: { if (*msgbuf) strcat(msgbuf, ","); strcat(msgbuf, nicks->nick); if (strlen(msgbuf)+strlen(args) >= 490) { put_it("%s", convert_output_format(fget_string_var((msg == 1)?FORMAT_SEND_MSG_FSET:FORMAT_SEND_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME),msgbuf, get_server_nickname(from_server), args)); my_send_to_server(server, "%s %s :%s", (msg == 1) ? "PRIVMSG" : "NOTICE", msgbuf, args); *msgbuf = 0; } break; } default: { if (!count && do_hook(USERS_HEADER_LIST, "%s %s %s %s %s %s %s", "Level", "aop", "prot", "Channel", "Nick", "+o", "UserHost") && fget_string_var(FORMAT_USERS_HEADER_FSET)) put_it("%s", convert_output_format(fget_string_var(FORMAT_USERS_HEADER_FSET), "%s", chan->channel)); if ((hook = do_hook(USERS_LIST, "%lu %s %s %s %c", nicks->userlist ? nicks->userlist->flags:nicks->shitlist?nicks->shitlist->level:0, chan->channel, nicks->nick, nicks->host, nicks->chanop ? '@' : ' '))) { put_it("%s", convert_output_format(fget_string_var(nicks->userlist?FORMAT_USERS_USER_FSET:nicks->shitlist?FORMAT_USERS_SHIT_FSET:FORMAT_USERS_FSET), "%s %s %s %s %s", nicks->userlist ? convert_flags(nicks->userlist->flags) : nicks->shitlist?ltoa(nicks->shitlist->level):"n/a ", chan->channel, nicks->nick, nicks->host, nicks->chanop ? "@" : (nicks->voice? "v" : "ÿ"))); } } } count++; } else if (msg == 3) { count++; if (!isme(nicks->nick)) { my_send_to_server(server, "KILL %s :%s (%i", nicks->nick, args && *args ? args : get_reason(nicks->nick, NULL), count); } else count--; } } clear_sorted_nicklist(&sortl); if (!msg && do_hook(USERS_FOOTER_LIST, "%s", "End of Users")) ; else if (msg == 6 && do_hook(STAT_FOOTER_LIST, "%s", "End of stats")) ; else if (!count) { if (chan) { if (!command) say("No match of %s on %s", spec, chan->channel); else say("There are no [\002%s\002] on %s", command, chan->channel); } } else if (!msg && !hook) bitchsay("End of UserList on %s %d counted", chan->channel, count); if (count && *msgbuf) { switch(msg) { case 1: case 2: { put_it("%s", convert_output_format(fget_string_var((msg == 1)?FORMAT_SEND_MSG_FSET:FORMAT_SEND_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME),msgbuf, get_server_nickname(from_server), args)); my_send_to_server(server, "%s %s :%s", (msg == 1) ? "PRIVMSG" : "NOTICE", msgbuf, args); break; } case 5: { if (chan) my_send_to_server(server, "KICK %s %s :%s", chan->channel, msgbuf, (args && *args) ? args : "-=punt=-"); } default: break; } } message_from(NULL, LOG_CRAP); } int caps_fucknut (register unsigned char *crap) { int total = 0, allcaps = 0; /* removed from ComStud client */ while (*crap) { if (isalpha(*crap)) { total++; if (isupper(*crap)) allcaps++; } crap++; } if (total > 12) { if ( ((unsigned int)(((float) allcaps / (float) total) * 100) >= 75)) return (1); } return (0); } int char_fucknut (register unsigned char *crap, char looking, int max) { int total = strlen(crap), allchar = 0; while (*crap) { if ((*crap == looking)) { crap++; while(*crap && *crap != looking) { allchar++; crap++; } } if (*crap) crap++; } if (total > 12) { if ( ((unsigned int)(((float) allchar / (float) total) * 100)) >= 75) return (1); } return (0); } static int cparse_recurse = -1; #define MAX_RECURSE 5 #define RECURSE_CPARSE char *convert_output_format_raw(const char *format, const char *str, va_list args) { static unsigned char buffer[MAX_RECURSE*BIG_BUFFER_SIZE+1]; char buffer2[3*BIG_BUFFER_SIZE+1]; enum color_attributes this_color = BLACK; register unsigned char *s; char *copy = NULL; char *tmpc = NULL; register char *p; int old_who_level = who_level; int bold = 0; extern int in_chelp; /*va_list args;*/ int arg_flags; char color_mod[] = "kbgcrmywKBGCRMYWn"; if (!format) return empty_string; copy = alloca(strlen(format)+2); strcpy(copy, format); memset(buffer2, 0, BIG_BUFFER_SIZE); if (cparse_recurse < MAX_RECURSE) cparse_recurse++; if (str) { p = (char *)str; /* va_start(args, str);*/ while(p && *p) { if (*p == '%') { switch(*++p) { case 's': { char *q, *s = (char *)va_arg(args, char *); #ifdef RECURSE_CPARSE char buff[BIG_BUFFER_SIZE]; q = buff; while (s && *s) { if (*s == '%') *q++ = '%'; else if (*s == '$') *q++ = '$'; *q++ = *s++; } *q = 0; if (*buff) strcat(buffer2, buff); #else if (s) strcat(buffer2, s); #endif break; } case 'd': { int d = (int) va_arg(args, int); strcat(buffer2, ltoa((long)d)); break; } case 'c': { char c = (char )va_arg(args, int); buffer2[strlen(buffer2)] = c; break; } case 'u': { unsigned int d = (unsigned int) va_arg(args, unsigned int); strcat(buffer2, ltoa(d)); break; } case 'l': { unsigned long d = (unsigned long) va_arg(args, unsigned long); strcat(buffer2, ltoa(d)); break; } case '%': { buffer2[strlen(buffer2)] = '%'; p++; break; } default: strcat(buffer2, "%"); buffer2[strlen(buffer2)] = *p; } p++; } else { buffer2[strlen(buffer2)] = *p; p++; } } /* va_end(args);*/ } else if (str) strcpy(buffer2, str); s = buffer + (BIG_BUFFER_SIZE * cparse_recurse); memset(s, 0, BIG_BUFFER_SIZE); tmpc = copy; if (!tmpc) goto done; while (*tmpc) { if (*tmpc == '%') { char *cs; tmpc++; this_color = BLACK; if (*tmpc == '%') { *s++ = *tmpc++; continue; } else if (isdigit(*tmpc)) { char background_mod[] = "01234567"; if ((cs = strchr(background_mod, *tmpc))) { this_color = ((int)cs - (int)&background_mod) + (bold ? BACK_BBLACK : BACK_BLACK); bold = 0; } else if (*tmpc == '8') { this_color = REVERSE_COLOR; bold = 0; } else { this_color = BOLD_COLOR; bold ^= 1; } } else if ((cs = strchr(color_mod, *tmpc))) this_color = ((int)cs - (int)&color_mod); else if (*tmpc == 'F') this_color = BLINK_COLOR; else if (*tmpc == 'U') this_color = UNDERLINE_COLOR; else if (*tmpc == 'A') this_color = (int) (((float)UNDERLINE_COLOR * rand())/RAND_MAX); else if (*tmpc == 'P') this_color = MAGENTAB; else if (*tmpc == 'p') this_color = MAGENTA; else { *s++ = *tmpc; continue; } strcpy(s, color_str[this_color]); while(*s) s++; tmpc++; continue; } else if (*tmpc == '$' && !in_chelp) { char *new_str = NULL; tmpc++; if (*tmpc == '$') { *s++ = *tmpc++; continue; } in_cparse++; tmpc = alias_special_char(&new_str, tmpc, buffer2, NULL, &arg_flags); in_cparse--; if (new_str) #ifdef RECURSE_CPARSE strcat(s, convert_output_format_raw(new_str, NULL, NULL)); #else strcat(s, new_str); #endif new_free(&new_str); while (*s) { if (*s == 255) *s = ' '; s++; } if (!tmpc) break; continue; } else *s = *tmpc; tmpc++; s++; } *s = 0; done: s = buffer + (BIG_BUFFER_SIZE * cparse_recurse); /* if (*s) strcat(s, color_str[NO_COLOR]);*/ who_level = old_who_level; cparse_recurse--; return s; } char *convert_output_format(const char *format, const char *str, ...) { char *ret; va_list args; va_start(args, str); ret = convert_output_format_raw(format, str, args); va_end(args); if (*ret) strcat(ret, color_str[NO_COLOR]); return ret; } char *convert_output_format2(const char *str) { unsigned char buffer[3*BIG_BUFFER_SIZE+1]; unsigned char buffer2[3*BIG_BUFFER_SIZE+1]; register unsigned char *s; char *copy = NULL; char *tmpc = NULL; int arg_flags; if (!str) return m_strdup(empty_string); memset(buffer, 0, BIG_BUFFER_SIZE); strcpy(buffer2, str); copy = tmpc = buffer2; s = buffer; while (*tmpc) { if (*tmpc == '$') { char *new_str = NULL; tmpc++; in_cparse++; tmpc = alias_special_char(&new_str, tmpc, copy, NULL, &arg_flags); in_cparse--; if (new_str) #ifdef RECURSE_CPARSE strcat(s, convert_output_format(new_str, NULL, NULL)); #else strcat(s, new_str); #endif s=s+(strlen(new_str)); new_free(&new_str); if (!tmpc) break; continue; } else *s = *tmpc; tmpc++; s++; } *s = 0; return m_strdup(buffer); } void add_last_type (LastMsg *array, int size, char *from, char *uh, char *to, char *str) { int i; for (i = size - 1; i > 0; i--) { malloc_strcpy(&(array[i].last_msg), array[i - 1].last_msg); malloc_strcpy(&(array[i].from), array[i - 1].from); malloc_strcpy(&(array[i].uh), array[i - 1].uh); malloc_strcpy(&(array[i].to), array[i - 1].to); malloc_strcpy(&(array[i].time), array[i - 1].time); } malloc_strcpy(&array->last_msg, str); malloc_strcpy(&array->from, from); malloc_strcpy(&array->to, to); malloc_strcpy(&array->uh, uh); malloc_strcpy(&array->time, update_clock(GET_TIME)); } int check_last_type(LastMsg *array, int size, char *from, char *uh) { int i; for (i = 0; i < size-1; i++) { if (array[i].from && array[i].uh && !my_stricmp(from, array[i].from) && !my_stricmp(uh, array[i].uh)) return 1; } return 0; } int matchmcommand(char *origline,int count) { int startnum=0; int endnum=0; char *tmpstr; char tmpbuf[BIG_BUFFER_SIZE]; strncpy(tmpbuf,origline, BIG_BUFFER_SIZE-1); tmpstr=tmpbuf; if (*tmpstr=='*') return(1); while (tmpstr && *tmpstr) { startnum=0; endnum=0; if (tmpstr && *tmpstr && *tmpstr=='-') { while (tmpstr && *tmpstr && !isdigit(*tmpstr)) tmpstr++; endnum=atoi(tmpstr); startnum=1; while (tmpstr && *tmpstr && isdigit(*tmpstr)) tmpstr++; } else { while (tmpstr && *tmpstr && !isdigit(*tmpstr)) tmpstr++; startnum=atoi(tmpstr); while (tmpstr && *tmpstr && isdigit(*tmpstr)) tmpstr++; if (tmpstr && *tmpstr && *tmpstr=='-') { while (tmpstr && *tmpstr && !isdigit(*tmpstr)) tmpstr++; endnum=atoi(tmpstr); if (!endnum) endnum=1000; while (tmpstr && *tmpstr && isdigit(*tmpstr)) tmpstr++; } } if (count==startnum || (count>=startnum && count<=endnum)) return(1); } if (count==startnum || (count>=startnum && count<=endnum)) return(1); return(0); } ChannelList *prepare_command(int *active_server, char *channel, int need_op) { int server = 0; ChannelList *chan = NULL; if (!channel && !get_current_channel_by_refnum(0)) { if (need_op != 3) not_on_a_channel(current_window); return NULL; } server = current_window->server; *active_server = server; if (!(chan = lookup_channel(channel? channel : get_current_channel_by_refnum(0), server, 0))) { if (need_op != 3) not_on_a_channel(current_window); return NULL; } if (need_op == NEED_OP && chan && !chan->chop) { error_not_opped(chan->channel); return NULL; } return chan; } char *make_channel (char *chan) { static char buffer[IRCD_BUFFER_SIZE+1]; *buffer = 0; if (*chan != '#' && *chan != '&' && *chan != '+' && *chan != '!') snprintf(buffer, IRCD_BUFFER_SIZE-2, "#%s", chan); else strmcpy(buffer, chan, IRCD_BUFFER_SIZE-1); return buffer; } BUILT_IN_COMMAND(do_map) { if (server_list[from_server].link_look == 0) { bitchsay("Generating irc server map"); send_to_server("LINKS"); server_list[from_server].link_look = 2; } else bitchsay("Wait until previous %s is done", server_list[from_server].link_look == 2? "MAP":"LLOOK"); } void add_to_irc_map(char *server1, char *distance) { irc_server *tmp, *insert, *prev; int dist = 0; if (distance) dist = atoi(distance); tmp = (irc_server *) new_malloc(sizeof(irc_server)); malloc_strcpy(&tmp->name, server1); tmp->hopcount = dist; if (!map) { map = tmp; return; } for (insert = map, prev = map; insert && insert->hopcount < dist; ) { prev = insert; insert = insert->next; } if (insert && insert->hopcount >= dist) { tmp->next = insert; if (insert == map) map = tmp; else prev->next = tmp; } else prev->next = tmp; } void show_server_map (void) { int prevdist = 0; irc_server *tmp; char tmp1[80]; char tmp2[BIG_BUFFER_SIZE+1]; #ifdef ONLY_STD_CHARS char *ascii="-> "; #else char *ascii = "ÀÄ> "; #endif if (map) prevdist = map->hopcount; for (tmp = map; tmp; tmp = map) { map = tmp->next; if (!tmp->hopcount || tmp->hopcount != prevdist) strmcpy(tmp1, convert_output_format("%K[%G$0%K]", "%d", tmp->hopcount), 79); else *tmp1 = 0; snprintf(tmp2, BIG_BUFFER_SIZE, "$G %%W$[-%d]1%%c $0 %s", tmp->hopcount*3, tmp1); put_it("%s", convert_output_format(tmp2, "%s %s", tmp->name, prevdist!=tmp->hopcount?ascii:empty_string)); prevdist = tmp->hopcount; new_free(&tmp->name); new_free((char **)&tmp); } } extern int timed_server (void *); extern int in_timed_server; void check_server_connect(int server) { if (!get_int_var(AUTO_RECONNECT_VAR)) return; if ((from_server == -1) || (!in_timed_server && server_list[from_server].last_msg + 50 < now)) { add_timer(0, "", 10, 1, timed_server, m_strdup(zero), NULL, current_window); in_timed_server++; } } char *country(char *hostname) { typedef struct _domain { char *code; char *country; } Domain; Domain domain[] = { {"AD", "Andorra" }, {"AE", "United Arab Emirates" }, {"AF", "Afghanistan" }, {"AG", "Antigua and Barbuda" }, {"AI", "Anguilla" }, {"AL", "Albania" }, {"AM", "Armenia" }, {"AN", "Netherlands Antilles" }, {"AO", "Angola" }, {"AQ", "Antarctica (pHEAR)" }, {"AR", "Argentina" }, {"AS", "American Samoa" }, {"AT", "Austria" }, {"AU", "Australia" }, {"AW", "Aruba" }, {"AZ", "Azerbaijan" }, {"BA", "Bosnia and Herzegovina" }, {"BB", "Barbados" }, {"BD", "Bangladesh" }, {"BE", "Belgium" }, {"BF", "Burkina Faso" }, {"BG", "Bulgaria" }, {"BH", "Bahrain" }, {"BI", "Burundi" }, {"BJ", "Benin" }, {"BM", "Bermuda" }, {"BN", "Brunei Darussalam" }, {"BO", "Bolivia" }, {"BR", "Brazil" }, {"BS", "Bahamas" }, {"BT", "Bhutan" }, {"BV", "Bouvet Island" }, {"BW", "Botswana" }, {"BY", "Belarus" }, {"BZ", "Belize" }, {"CA", "Canada (pHEAR)" }, {"CC", "Cocos Islands" }, {"CF", "Central African Republic" }, {"CG", "Congo" }, {"CH", "Switzerland" }, {"CI", "Cote D'ivoire" }, {"CK", "Cook Islands" }, {"CL", "Chile" }, {"CM", "Cameroon" }, {"CN", "China" }, {"CO", "Colombia" }, {"CR", "Costa Rica" }, {"CS", "Former Czechoslovakia" }, {"CU", "Cuba" }, {"CV", "Cape Verde" }, {"CX", "Christmas Island" }, {"CY", "Cyprus" }, {"CZ", "Czech Republic" }, {"DE", "Germany" }, {"DJ", "Djibouti" }, {"DK", "Denmark" }, {"DM", "Dominica" }, {"DO", "Dominican Republic" }, {"DZ", "Algeria" }, {"EC", "Ecuador" }, {"EE", "Estonia" }, {"EG", "Egypt" }, {"EH", "Western Sahara" }, {"ER", "Eritrea" }, {"ES", "Spain" }, {"ET", "Ethiopia" }, {"FI", "Finland" }, {"FJ", "Fiji" }, {"FK", "Falkland Islands" }, {"FM", "Micronesia" }, {"FO", "Faroe Islands" }, {"FR", "France" }, {"FX", "France, Metropolitan" }, {"GA", "Gabon" }, {"GB", "Great Britain" }, {"GD", "Grenada" }, {"GE", "Georgia" }, {"GF", "French Guiana" }, {"GH", "Ghana" }, {"GI", "Gibraltar" }, {"GL", "Greenland" }, {"GM", "Gambia" }, {"GN", "Guinea" }, {"GP", "Guadeloupe" }, {"GQ", "Equatorial Guinea" }, {"GR", "Greece" }, {"GS", "S. Georgia and S. Sandwich Isles." }, {"GT", "Guatemala" }, {"GU", "Guam" }, {"GW", "Guinea-Bissau" }, {"GY", "Guyana" }, {"HK", "Hong Kong" }, {"HM", "Heard and McDonald Islands" }, {"HN", "Honduras" }, {"HR", "Croatia" }, {"HT", "Haiti" }, {"HU", "Hungary" }, {"ID", "Indonesia" }, {"IE", "Ireland" }, {"IL", "Israel" }, {"IN", "India" }, {"IO", "British Indian Ocean Territory" }, {"IQ", "Iraq" }, {"IR", "Iran" }, {"IS", "Iceland" }, {"IT", "Italy" }, {"JM", "Jamaica" }, {"JO", "Jordan" }, {"JP", "Japan" }, {"KE", "Kenya" }, {"KG", "Kyrgyzstan" }, {"KH", "Cambodia" }, {"KI", "Kiribati" }, {"KM", "Comoros" }, {"KN", "St. Kitts and Nevis" }, {"KP", "North Korea" }, {"KR", "South Korea" }, {"KW", "Kuwait" }, {"KY", "Cayman Islands" }, {"KZ", "Kazakhstan" }, {"LA", "Laos" }, {"LB", "Lebanon" }, {"LC", "Saint Lucia" }, {"LI", "Liechtenstein" }, {"LK", "Sri Lanka" }, {"LR", "Liberia" }, {"LS", "Lesotho" }, {"LT", "Lithuania" }, {"LU", "Luxembourg" }, {"LV", "Latvia" }, {"LY", "Libya" }, {"MA", "Morocco" }, {"MC", "Monaco" }, {"MD", "Moldova" }, {"MG", "Madagascar" }, {"MH", "Marshall Islands" }, {"MK", "Macedonia" }, {"ML", "Mali" }, {"MM", "Myanmar" }, {"MN", "Mongolia" }, {"MO", "Macau" }, {"MP", "Northern Mariana Islands" }, {"MQ", "Martinique" }, {"MR", "Mauritania" }, {"MS", "Montserrat" }, {"MT", "Malta" }, {"MU", "Mauritius" }, {"MV", "Maldives" }, {"MW", "Malawi" }, {"MX", "Mexico" }, {"MY", "Malaysia" }, {"MZ", "Mozambique" }, {"NA", "Namibia" }, {"NC", "New Caledonia" }, {"NE", "Niger" }, {"NF", "Norfolk Island" }, {"NG", "Nigeria" }, {"NI", "Nicaragua" }, {"NL", "Netherlands" }, {"NO", "Norway" }, {"NP", "Nepal" }, {"NR", "Nauru" }, {"NT", "Neutral Zone (pHEAR)" }, {"NU", "Niue" }, {"NZ", "New Zealand" }, {"OM", "Oman" }, {"PA", "Panama" }, {"PE", "Peru" }, {"PF", "French Polynesia" }, {"PG", "Papua New Guinea" }, {"PH", "Philippines" }, {"PK", "Pakistan" }, {"PL", "Poland" }, {"PM", "St. Pierre and Miquelon" }, {"PN", "Pitcairn" }, {"PR", "Puerto Rico" }, {"PT", "Portugal" }, {"PW", "Palau" }, {"PY", "Paraguay" }, {"QA", "Qatar" }, {"RE", "Reunion" }, {"RO", "Romania" }, {"RU", "Russian Federation (pHEAR)" }, {"RW", "Rwanda" }, {"SA", "Saudi Arabia" }, {"Sb", "Solomon Islands" }, {"SC", "Seychelles" }, {"SD", "Sudan" }, {"SE", "Sweden" }, {"SG", "Singapore" }, {"SH", "St. Helena" }, {"SI", "Slovenia" }, {"SJ", "Svalbard and Jan Mayen Islands" }, {"SK", "Slovak Republic" }, {"SL", "Sierra Leone" }, {"SM", "San Marino" }, {"SN", "Senegal" }, {"SO", "Somalia" }, {"SR", "Suriname" }, {"ST", "Sao Tome and Principe" }, {"SU", "Former USSR (pHEAR)" }, {"SV", "El Salvador" }, {"SY", "Syria" }, {"SZ", "Swaziland" }, {"TC", "Turks and Caicos Islands" }, {"TD", "Chad" }, {"TF", "French Southern Territories" }, {"TG", "Togo" }, {"TH", "Thailand" }, {"TJ", "Tajikistan" }, {"TK", "Tokelau" }, {"TM", "Turkmenistan" }, {"TN", "Tunisia" }, {"TO", "Tonga" }, {"TP", "East Timor" }, {"TR", "Turkey" }, {"TT", "Trinidad and Tobago" }, {"TV", "Tuvalu" }, {"TW", "Taiwan" }, {"TZ", "Tanzania" }, {"UA", "Ukraine" }, {"UG", "Uganda" }, {"UK", "United Kingdom" }, {"UM", "US Minor Outlying Islands" }, {"US", "United States of America" }, {"UY", "Uruguay" }, {"UZ", "Uzbekistan" }, {"VA", "Vatican City State" }, {"VC", "St. Vincent and the grenadines" }, {"VE", "Venezuela" }, {"VG", "British Virgin Islands" }, {"VI", "US Virgin Islands" }, {"VN", "Vietnam" }, {"VU", "Vanuatu" }, {"WF", "Wallis and Futuna Islands" }, {"WS", "Samoa" }, {"YE", "Yemen" }, {"YT", "Mayotte" }, {"YU", "Yugoslavia" }, {"ZA", "South Africa" }, {"ZM", "Zambia" }, {"ZR", "Zaire" }, {"ZW", "Zimbabwe" }, {"COM", "Internic Commercial" }, {"EDU", "Educational Institution" }, {"GOV", "Government" }, {"INT", "International" }, {"MIL", "Military" }, {"NET", "Internic Network" }, {"ORG", "Internic Non-Profit Organization" }, {"RPA", "Old School ARPAnet" }, {"ATO", "Nato Fiel" }, {"MED", "United States Medical" }, {"ARPA", "Reverse DNS" }, {NULL, NULL} }; char *p; int i = 0; if (!hostname || !*hostname || isdigit(hostname[strlen(hostname)-1])) return "unknown"; if ((p = strrchr(hostname, '.'))) p++; else p = hostname; for (i = 0; domain[i].code; i++) if (!my_stricmp(p, domain[i].code)) return domain[i].country; return "unknown"; }