/*
* Copyright Colten Edwards (c) 1996
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <unistd.h>
#if defined(sparc) && defined(sun4c)
#include <sys/rusage.h>
#endif
#ifdef HAVE_ASSERT_H
# include <assert.h>
#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 <pthread.h>
/*------------------
| 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 */
syntax highlighted by Code2HTML, v. 0.9.1