/* * Copyright Colten Edwards (c) 1996 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #if defined(sparc) && defined(sun4c) #include #endif #ifdef HAVE_ASSERT_H # include #endif #include "irc.h" #include "server.h" #include "commands.h" #include "vars.h" #include "ircaux.h" #include "lastlog.h" #include "window.h" #include "screen.h" #include "whois.h" #include "hook.h" #include "input.h" #include "ignore.h" #include "keys.h" #include "names.h" #include "history.h" #include "funny.h" #include "ctcp.h" #include "dcc.h" #include "output.h" #include "exec.h" #include "notify.h" #include "numbers.h" #include "status.h" #include "list.h" #include "timer.h" #include "misc.h" #include "flood.h" #include "parse.h" #include "whowas.h" #include "hash.h" #include "fset.h" char *alias_special_char(char **, char *, char *, char *, int *); extern time_t start_time; extern int in_server_ping; int split_watch = 0; int serv_action = 0; int first_time = 0; char *convertstring = NULL; extern int in_cparse; extern char *mircansi(char *); extern NickTab *tabkey_array; extern Ignore *ignored_nicks; #ifdef REVERSE_WHITE_BLACK char *color_str[] = { "\e[0m", "\e[0;34m", "\e[0;32m", "\e[0;36m", "\e[0;31m", "\e[0;35m", "\e[0;33m", "\e[0;30m", "\e[1;37m", "\e[1;34m", "\e[1;32m", "\e[1;36m", "\e[1;31m", "\e[1;35m", "\e[1;33m", "\e[1;30m", "\e[0m", "\e[0;47m", "\e[0;41m", "\e[0;42m", "\e[0;43m", "\e[0;44m", "\e[0;45m", "\e[0;46m", "\e[0;40m", "\e[1;47m", "\e[1;41m", "\e[1;42m", "\e[1;43m", "\e[1;44m", "\e[1;45m", "\e[1;46m", "\e[1;40m", "\e[7m", "\e[1m", "\e[5m", "\e[4m" }; #else char *color_str[] = { "\e[0;30m", "\e[0;34m", "\e[0;32m", "\e[0;36m", "\e[0;31m", "\e[0;35m", "\e[0;33m", "\e[0m", "\e[1;30m", "\e[1;34m", "\e[1;32m", "\e[1;36m", "\e[1;31m", "\e[1;35m", "\e[1;33m", "\e[1;37m", "\e[0m", "\e[0;40m", "\e[0;41m", "\e[0;42m", "\e[0;43m", "\e[0;44m", "\e[0;45m", "\e[0;46m", "\e[0;47m", "\e[1;40m", "\e[1;41m", "\e[1;42m", "\e[1;43m", "\e[1;44m", "\e[1;45m", "\e[1;46m", "\e[1;47m", "\e[7m", "\e[1m", "\e[5m", "\e[4m" }; #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) { unsigned int days = 0, hours = 0, minutes = 0, seconds = 0; static char buffer[100]; *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, "%2ud %2uh %2um %2us", days, hours, minutes, seconds); return (*buffer ? buffer : empty_str); } int check_serverlag(void *args) { char *servern = (char *) args; if (servern && *servern) { int i; for (i = 0; i < number_of_servers; i++) { if ((!my_stricmp(servern, get_server_itsname(i)) || !my_stricmp(servern, get_server_name(i))) && is_server_connected(i)) { server_list[i].lag_time = time(NULL); send_to_server(SERVER(from_server), "PING %lu %s", server_list[i].lag_time, servern); in_server_ping++; server_list[i].lag = -1; break; } } } return 0; } int timer_unban(void *args) { char *p = (char *) args; char *channel; struct channel *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 = (struct channel *) find_in_list((struct list **) &server_list[server].chan_list, channel, 0)) && ban_is_on_channel(ban, chan)) send_to_server(SERVER(server), "MODE %s -b %s", channel, ban); new_free(&serv); return 0; } 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 char newline[3*BIG_BUFFER_SIZE+1]; */ static char newline1[3 * BIG_BUFFER_SIZE + 1]; char *mircansi(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] = { { "\e[1;37m", "\e[47m"}, /* white */ { "\e[0;30m", "\e[40m"}, /* black (grey for us) */ { "\e[0;34m", "\e[44m"}, /* blue */ { "\e[0;32m", "\e[42m"}, /* green */ { "\e[0;31m", "\e[41m"}, /* red */ { "\e[0;33m", "\e[43m"}, /* brown */ { "\e[0;35m", "\e[45m"}, /* magenta */ { "\e[1;31m", "\e[41m"}, /* bright red */ { "\e[1;33m", "\e[43m"}, /* yellow */ { "\e[1;32m", "\e[42m"}, /* bright green */ { "\e[0;36m", "\e[46m"}, /* cyan */ { "\e[1;36m", "\e[46m"}, /* bright cyan */ { "\e[1;34m", "\e[44m"}, /* bright blue */ { "\e[1;35m", "\e[45m"}, /* bright magenta */ { "\e[1;30m", "\e[40m"}, /* dark grey */ { "\e[0;37m", "\e[47m"} /* grey */ }; register char *sptr = line, *dptr = newline1; short code; if (!*line) return empty_str; *newline1 = 0; while (*sptr) { if (*sptr == 0x3 && isdigit(sptr[1])) { sptr++; code = atoi(sptr); if (code > 15 || code <= 0) continue; while (isdigit(*sptr)) sptr++; strcpy(dptr, codes[code].fg); while (*dptr) dptr++; if (*sptr == ',') { sptr++; code = atoi(sptr); if (code >= 0 && code <= 15) { strcpy(dptr, codes[code].bg); while (*dptr) dptr++; } while (isdigit(*sptr)) sptr++; } } else if (*sptr == 0x3) { strcpy(dptr, "\e[0m"); while (*dptr) dptr++; sptr++; } else *dptr++ = *sptr++; } *dptr = 0; return newline1; } /* Borrowed with permission from FLiER */ char *stripansicodes(const char *line) { register char *tstr; register char *nstr; int gotansi = 0; tstr = (char *) line; nstr = newline1; while (*tstr) { if (*tstr == 0x1B) gotansi = 1; if (gotansi && isalpha(*tstr)) gotansi = 0; else if (!gotansi) { *nstr = *tstr; nstr++; } tstr++; } *nstr = 0; return newline1; } char *stripansi(char *line) { register char *cp; char *newline; newline = m_strdup(line); for (cp = newline; *cp; cp++) if (*cp < 31 && *cp > 13) if (*cp != 1 && *cp != 15 && *cp != 22) *cp = (*cp & 127) | 64; return 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 (match("%.% %.%", Reason) && !strstr(Reason, "))")) { char *host1 = next_arg(Reason, &Reason); char *host2 = next_arg(Reason, &Reason); if (!my_stricmp(host1, host2)) goto fail_split; if (match(host1, "*..*") || match(host2, "*..*")) 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 (match(b_check, host1) || 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; } void userage(char *command, char *use) { if (do_hook(USAGE_LIST, "%s %s", command, use ? use : "No Help Available for this command")) put_it("%s", convert_output_format(get_fset_var(FORMAT_USAGE_FSET), "%s %s", command, convert_output_format(use ? use : "%WNo Help available for this command", NULL, NULL))); } char *random_str(int min, int max) { int i, ii; static char str[BIG_BUFFER_SIZE + 1]; i = getrandom(min, max); for (ii = 0; ii < i; ii++) str[ii] = (char) getrandom(97, 122); str[ii] = '\0'; return str; } int rename_file(char *old_file, char **new_file) { char *tmp = NULL, *new_f = NULL; char c = 'a'; FILE *fp; if (get_string_var(DCC_DLDIR_VAR)) malloc_sprintf(&tmp, "%s/%%c%s", get_string_var(DCC_DLDIR_VAR), *new_file); else malloc_sprintf(&tmp, "%%c%s", *new_file); malloc_sprintf(&new_f, tmp, c); while ((fp = fopen(new_f, "r")) != NULL) { fclose(fp); c++; sprintf(new_f, tmp, c); } if (fp != NULL) fclose(fp); new_free(&tmp); new_free(&new_f); malloc_sprintf(new_file, "%c%s", c, *new_file); 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; serv2->time = m_strdup(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(&split_link, name, link, hops, update_clock(GET_TIME)); temp->status = SPLIT; } irc_server *check_split_server(char *server) { register irc_server *temp; for (temp = 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((struct list **) &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(&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_last; serv1; serv1 = serv1->next) { if (!find_server(tmplink, serv1->name)) { if (!(serv1->status & SPLIT)) serv1->status = SPLIT; if (serv1->count) continue; serv1->time = m_strdup(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(get_fset_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(get_fset_var(FORMAT_NETJOIN_FSET), "%s %s %s %d", serv1->time, serv1->name, serv1->link, serv1->hopcount)); serv1->count = 0; } } } for (serv1 = tmplink; serv1; serv1 = serv1->next) { if (!find_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(get_fset_var(FORMAT_NETADD_FSET), "%s %s %s %d", serv1->time, serv1->name, serv1->link, serv1->hopcount)); serv1->count = 0; } add_server(&server_last, serv1->name, serv1->link, serv1->hopcount, update_clock(GET_TIME)); } } first_time = 1; clear_link(&tmplink); } void log_toggle(int flag, struct channel *chan) { char *logfile; if (((logfile = get_string_var(MSGLOGFILE_VAR)) == NULL)) { bitchsay("You must set the MSGLOGFILE first!"); set_int_var(MSGLOG_VAR, 0); return; } logmsg(LOG_CURRENT, NULL, NULL, flag ? 1 : 2); } 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 / 2, stream); while (p && (*lin == '#')); if (!p) return 0; chop(lin, 1); return 1; } /* wtf is this doing? */ char *get_reason(char *nick) { static char reason[BIG_BUFFER_SIZE / 2 + 1]; char *temp = get_string_var(DEFAULT_REASON_VAR); strncpy(reason, stripansicodes(convert_output_format(temp, "%s %s", nick ? nick : "error", get_server_nickname(from_server))), sizeof(reason) - 1); *reason = '\0'; return reason; } char *get_signoffreason(char *nick) { static char reason[BIG_BUFFER_SIZE / 2 + 1]; *reason = '\0'; strncpy(reason, stripansicodes(convert_output_format (get_string_var(SIGNOFF_REASON_VAR), "%s %s", nick ? nick : "error", get_server_nickname(from_server))), sizeof(reason) - 1); return reason; } char *rights(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 + 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) < strlen(host)) { if ((tmp = strchr(tmp, '.')) == NULL) break; count++; tmp++; } tmp = host; for (i = 0; i < count; i++) tmp = strchr(tmp, '.') + 1; *tmp = '\0'; strcat(result, host); strcat(result, "*"); } else { char *tmp; int num; num = 1; tmp = rights(host, 3); if (my_stricmp(tmp, "com") && my_stricmp(tmp, "edu") && my_stricmp(tmp, "net") && (stristr(host, "com") || stristr(host, "edu"))) num = 2; while (host && *host && (numchar(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; } static int cparse_recurse = -1; char *convert_output_format(const char *format, const char *str, ...) { static char buffer[10 * BIG_BUFFER_SIZE + 1]; char buffer2[2 * BIG_BUFFER_SIZE + 1]; enum color_attributes this_color = BLACK; register char *t; register char *s; char *copy = NULL; char *tmpc = NULL; char *p; int old_who_level = who_level; int bold = 0; va_list args; int arg_flags; int do_color = get_int_var(DISPLAY_ANSI_VAR); malloc_strcpy(©, format); memset(buffer2, 0, BIG_BUFFER_SIZE / 4); if (cparse_recurse < 10) cparse_recurse++; if (str /* && !in_cparse */ ) { p = (char *) str; va_start(args, str); while (p && *p) { if (*p == '%') { switch (*++p) { case 's': { char *s = (char *) va_arg(args, char *); if (s) strcat(buffer2, s); 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 ( /* in_cparse && */ str) strcpy(buffer2, str); s = buffer + (BIG_BUFFER_SIZE * cparse_recurse); memset(s, 0, BIG_BUFFER_SIZE / 4); tmpc = copy; if (!tmpc) goto done; while (*tmpc) { if (*tmpc == '%') { tmpc++; switch (*tmpc) { case '%': *s++ = *tmpc; break; case 'n': this_color = NO_COLOR; break; case 'W': this_color = WHITEB; break; case 'w': this_color = WHITE; break; case 'K': this_color = BLACKB; break; case 'k': this_color = BLACK; break; case 'G': this_color = GREENB; break; case 'g': this_color = GREEN; break; case 'Y': this_color = YELLOWB; break; case 'y': this_color = YELLOW; break; case 'C': this_color = CYANB; break; case 'c': this_color = CYAN; break; case 'B': this_color = BLUEB; break; case 'b': this_color = BLUE; break; case 'P': case 'M': this_color = MAGENTAB; break; case 'p': case 'm': this_color = MAGENTA; break; case 'R': this_color = REDB; break; case 'r': this_color = RED; break; case '0': this_color = bold ? BACK_BBLACK : BACK_BLACK; bold = 0; break; case '1': this_color = bold ? BACK_BRED : BACK_RED; bold = 0; break; case '2': this_color = bold ? BACK_BGREEN : BACK_GREEN; bold = 0; break; case '3': this_color = bold ? BACK_BYELLOW : BACK_YELLOW; bold = 0; break; case '4': this_color = bold ? BACK_BBLUE : BACK_BLUE; bold = 0; break; case '5': this_color = bold ? BACK_BMAGENTA : BACK_MAGENTA; bold = 0; break; case '6': this_color = bold ? BACK_BCYAN : BACK_CYAN; bold = 0; break; case '7': this_color = bold ? BACK_BWHITE : BACK_WHITE; bold = 0; break; case '8': this_color = REVERSE_COLOR; bold = 0; break; case '9': this_color = BOLD_COLOR; bold ^= 1; break; case 'F': this_color = BLINK_COLOR; break; case 'U': this_color = UNDERLINE_COLOR; break; default: *s++ = *tmpc; continue; } if (do_color) { for (t = color_str[(int) this_color]; *t; t++, s++) *s = *t; } tmpc++; continue; } else if (*tmpc == '$') { char *new_str = NULL; tmpc++; in_cparse++; tmpc = alias_special_char(&new_str, tmpc, buffer2, NULL, &arg_flags); in_cparse--; if (new_str) strcat(s, new_str); new_free(&new_str); while (*s) { if (*s == -1) *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; new_free(©); cparse_recurse--; return s; } int matchmcommand(char *origline, int count) { int startnum = 0; int endnum = 0; char *tmpstr; char tmpbuf[BIG_BUFFER_SIZE]; strcpy(tmpbuf, origline); 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); } struct channel *prepare_command(int *active_server, char *channel, int need_op) { int server = 0; struct channel *chan = NULL; if (!channel && !curr_scr_win->current_channel) { if (need_op != 3) not_on_a_channel(curr_scr_win); return NULL; } server = curr_scr_win->server; *active_server = server; if (!(chan = lookup_channel(channel ? channel : curr_scr_win->current_channel, server, 0))) { if (need_op != 3) not_on_a_channel(curr_scr_win); return NULL; } if (need_op == NEED_OP && chan && !chan->chop) { error_not_opped(chan->channel); return NULL; } return chan; } /* XXX nasty!!! */ char *make_channel(char *chan) { static char buffer[BIG_BUFFER_SIZE + 1]; *buffer = 0; if (*chan != '#' && *chan != '&' && *chan != '+' && *chan != '*') snprintf(buffer, IRCD_BUFFER_SIZE - 2, "#%s", chan); else strncpy(buffer, chan, BIG_BUFFER_SIZE); return buffer; } 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]; char *ascii = "-> "; 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_str)); 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 ((from_server == -1) || (!in_timed_server && server_list[from_server].last_msg + 50 < time(NULL))) { add_timer("", 10, 1, timed_server, m_strdup("0"), NULL); in_timed_server++; } } char *country(char *hostname) { typedef struct _domain { char *code; char *country; } Domain; static 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"}, {"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 Isls."}, {"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"}, {"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"}, {"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} }; static char unknown[] = "unknown"; 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; } char *do_nslookup(char *host) { struct hostent *temp; struct in_addr temp1; if (!host) return NULL; if (isdigit(*(host + strlen(host) - 1))) { temp1.s_addr = inet_addr(host); alarm(1); temp = gethostbyaddr((char *) &temp1.s_addr, sizeof(temp1.s_addr), AF_INET); alarm(0); } else { alarm(1); temp = gethostbyname(host); alarm(0); } if (do_hook (NSLOOKUP_LIST, "%s %s %s", host, temp ? temp->h_name : "", temp ? (char *) inet_ntoa(*(struct in_addr *) temp->h_addr) : "")) { if (!temp) bitchsay("Error looking up %s", host); else bitchsay("%s is %s (%s)", host, temp->h_name, (char *) inet_ntoa(*(struct in_addr *) temp->h_addr)); } return ((char *) (temp ? temp->h_name : host)); } int charcount(char *string, char what) { int x = 0; char *place = string; while (*place) if (*place++ == what) x++; return x; } /* Given a string, remove stuff at the end */ /** * str_terminate_at - terminate string at chars * @string: string to terminate * @chars: what characters we terminate at * * Terminate the string at the last occurence of any * of the characters in chars. * * For example, terminating on "\r\n" will remove * those characters from the end of the string. **/ char *str_terminate_at(char *string, const char *chars) { char *ptr; assert(string); assert(chars); while (*chars) { if ((ptr = strrchr(string, *chars)) != NULL) *ptr = '\0'; chars++; } return string; } #ifdef HAVE_PTHREADS #include /*------------------ | Experemental.. nslookup now splits off a thread to do the work */ void *do_nslookup_blah(void *arg) { struct hostent *temp; struct in_addr temp1; char *host = (char *) arg; if (!host) pthread_exit(NULL); if (isdigit(*(host + strlen(host) - 1))) { temp1.s_addr = inet_addr(host); temp = gethostbyaddr((char *) &temp1.s_addr, sizeof(temp1.s_addr), AF_INET); } else { temp = gethostbyname(host); } if (do_hook (NSLOOKUP_LIST, "%s %s %s", host, temp ? temp->h_name : "", temp ? (char *) inet_ntoa(*(struct in_addr *) temp->h_addr) : "")) { if (!temp) bitchsay("Error looking up %s", host); else bitchsay("%s is %s (%s)", host, temp->h_name, (char *) inet_ntoa(*(struct in_addr *) temp->h_addr)); } new_free(&arg); pthread_exit(NULL); return NULL; } /* arg == hostname */ void do_nslookup_thread(void *arg) { pthread_t b; if (arg == NULL) return; pthread_create(&b, NULL, do_nslookup_blah, m_strdup(arg)); pthread_detach(b); } #endif /* HAVE_PTHREADS */