--- /dev/null
+
+#include "secure.h"
+
+/*****************************************************************/
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+typedef unsigned long word32;
+typedef unsigned char byte;
+
+struct xMD5Context {
+ word32 buf[4];
+ word32 bytes[2];
+ word32 in[16];
+};
+
+void xMD5Init(struct xMD5Context *context);
+void xMD5Update(struct xMD5Context *context, byte const *buf, int len);
+void xMD5Final(byte digest[16], struct xMD5Context *context);
+void xMD5Transform(word32 buf[4], word32 const in[16]);
+
+
+/*
+ * Shuffle the bytes into little-endian order within words, as per the
+ * MD5 spec. Note: this code works regardless of the byte order.
+ */
+void
+byteSwap(word32 *buf, unsigned words)
+{
+ byte *p = (byte *)buf;
+
+ do {
+ *buf++ = (word32)((unsigned)p[3] << 8 | p[2]) << 16 |
+ ((unsigned)p[1] << 8 | p[0]);
+ p += 4;
+ } while (--words);
+}
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+xMD5Init(struct xMD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bytes[0] = 0;
+ ctx->bytes[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+xMD5Update(struct xMD5Context *ctx, byte const *buf, int len)
+{
+ word32 t;
+
+ /* Update byte count */
+
+ t = ctx->bytes[0];
+ if ((ctx->bytes[0] = t + len) < t)
+ ctx->bytes[1]++; /* Carry from low to high */
+
+ t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
+ if ((unsigned)t > len) {
+ bcopy(buf, (byte *)ctx->in + 64 - (unsigned)t, len);
+ return;
+ }
+ /* First chunk is an odd size */
+ bcopy(buf,(byte *)ctx->in + 64 - (unsigned)t, (unsigned)t);
+ byteSwap(ctx->in, 16);
+ xMD5Transform(ctx->buf, ctx->in);
+ buf += (unsigned)t;
+ len -= (unsigned)t;
+
+ /* Process data in 64-byte chunks */
+ while (len >= 64) {
+ bcopy(buf, ctx->in, 64);
+ byteSwap(ctx->in, 16);
+ xMD5Transform(ctx->buf, ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+ bcopy(buf, ctx->in, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+xMD5Final(byte digest[16], struct xMD5Context *ctx)
+{
+ int count = (int)(ctx->bytes[0] & 0x3f); /* Bytes in ctx->in */
+ byte *p = (byte *)ctx->in + count; /* First unused byte */
+
+ /* Set the first char of padding to 0x80. There is always room. */
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 56 bytes (-8..55) */
+ count = 56 - 1 - count;
+
+ if (count < 0) { /* Padding forces an extra block */
+ bzero(p, count+8);
+ byteSwap(ctx->in, 16);
+ xMD5Transform(ctx->buf, ctx->in);
+ p = (byte *)ctx->in;
+ count = 56;
+ }
+ bzero(p, count+8);
+ byteSwap(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ctx->in[14] = ctx->bytes[0] << 3;
+ ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
+ xMD5Transform(ctx->buf, ctx->in);
+
+ byteSwap(ctx->buf, 4);
+ bcopy(ctx->buf, digest, 16);
+ bzero(ctx,sizeof(ctx));
+}
+
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f,w,x,y,z,in,s) \
+ (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+xMD5Transform(word32 buf[4], word32 const in[16])
+{
+ register word32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+
+void MD5(void *dest, void *orig, int len)
+{
+ struct xMD5Context context;
+
+ xMD5Init(&context);
+ xMD5Update(&context, orig, len);
+ xMD5Final(dest, &context);
+}
+
+void secure_nick(char *result, char *user, char *host, char *key, int time)
+{
+ int k;
+ char *s, *t;
+ char *code = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ char src[SECURE_BUFFER_SIZE], dst[16];
+
+ sprintf(src, "%s%s%s%d", user, host, key, time);
+ MD5(dst, src, strlen(src));
+
+ s = dst; t = result;
+ for(k=0; k<NICK_LENGTH; k++) *t++ = code[((unsigned int) *s++)%52];
+ *t = '\0';
+
+ cout<<"RESULT=>"<<result
+ <<"< USER=>"<<user
+ <<"< HOST=>"<<host
+ <<"< KEY=>"<<key
+ <<"< time="<<time<<"\n";
+
+};
/*-----------------------------------------------------------------------------
- TropBot, a small IRC bot, v2.6 Dec 95 - Oct 96
+ TropBot, a small IRC bot, v2.9 Dec 95 - Oct 96
Witten by Francois Fleuret.
Contact <francois.fleuret@inria.fr> for comments & bug reports
Check http://www.eleves.ens.fr:8080/home/fleuret for latest version
-----------------------------------------------------------------------------*/
-#define VERSION "v2.6.3a"
-#define OPTIONS " + patch for mode -ko stuff"
+#define VERSION "v2.9.2d"
+#define OPTIONS ""
#include <time.h>
#include <fstream.h>
//-----------------------------------------------------------------------------
#define SCREEN_OUTPUT
+#define ERROR_OUTPUT
+
+//#define ANTI_SPOOF
+#define ANTI_SPOOF_MAX_TIME 300
//-----------------------------------------------------------------------------
#define HISTORY_SIZE 3
-enum { FL_NOTICE, FL_PUBLIC, FL_CTCP, FL_NICK, FL_PART, FL_JOIN };
+enum { FL_NOTICE, FL_PUBLIC, FL_CTCP, FL_NICK, FL_PART, FL_JOIN, FL_KICK };
+
+//-----------------------------------------------------------------------------
+
+// More than 3 kicks in 5 minutes -> 30 mins shit
+
+#define COP_NB_KICKS 3
+#define COP_NB_BANS 3
+#define COP_DELAY 300
+#define COP_DURATION 1800
+#define COP_DELAY_BEETWEEN_KICKS 2
//-----------------------------------------------------------------------------
int deban_delay = DEFAULT_DEBAN_DELAY;
char control_char = DEFAULT_CONTROL_CHAR;
+int cop_mode;
+
int delay;
timeval delay_pause;
time_t current_time, time_killed, time_last_datas, last_answer_time,
template class List<Person *>;
template class List<Welcome *>;
template class List<WaitInfos *>;
+template class List<WaitPing *>;
template class List<DelayModeChange *>;
template class List<char *>;
List<Person *> level_list;
List<Welcome *> shit_list;
List<WaitInfos *> wait_list;
+List<WaitPing *> wait_ping;
List<DelayModeChange *> mode_change_list;
ListChar present_people, banid_list, restricted_list, history;
// I'd like to know why do I have to do such a cast ?!?!
if((int) write(socket_irc, stuff, strlen(stuff)) < 0)
{
+#ifdef ERROR_OUTPUT
cerr<<"KILLING CONNECTION : write_irc error\n";
cerr.flush();
+#endif
kill_connection();
}
else
sprintf(IRC_buffer, "Shit %s for %s (%s)\n",
pattern, string_duration, comment);
tell(chat, nick, IRC_buffer);
- delete string_duration;
+ delete[] string_duration;
}
}
else if((nick != NULL) || (chat != NULL))
{
nick = cut_nick_from_prefix(node->body);
add_mode(channel, "+o", nick);
- delete nick;
+ delete[] nick;
}
}
//-----------------------------------------------------------------------------
+ListChar already_kicked;
+
void filter_kick(char *where, char *pattern, char *comment)
{
NodeList<char *> *node;
char *nick;
- for(node = present_people.first; node != NULL; node = node->next)
+
+ if(already_kicked.Contains(pattern)) return;
+
+ already_kicked.Add(pattern);
+ for(node = present_people.first; node != NULL;
+ node = node->next)
{
if(match_pattern(pattern, node->body))
if(level_person(node->body, NULL) == 0)
nick = cut_nick_from_prefix(node->body);
sprintf(IRC_buffer, "KICK %s %s :%s\n", where, nick, comment);
write_irc(IRC_buffer);
- delete nick;
+ delete[] nick;
}
}
}
weigth = w;
}
- ~FloodLine() { delete prefix; }
+ ~FloodLine() { delete[] prefix; }
void Reset() { individual = 0; site = 0; }
};
template class List<FloodLine *>;
-List<FloodLine *> flood_list;
+List<FloodLine *> flood_list, kick_list;
//-----------------------------------------------------------------------------
{
duration = DEFAULT_SHIT_TIME;
r = pattern;
- *r++ = '*'; *r++ = '!'; *r++ = '*'; *r++ = '@';
+ concat(r, "*!*@");
concat_pattern_from_host(r, guilty_site);
add_mode(where, "+m", NULL);
smart_shit(NULL, NULL, pattern, "Alert", duration);
mode_change_list.Insert(new DelayModeChange(current_channel,
"-b", banid,
BAN_FLOOD_DELAY));
- delete banid;
- delete pattern;
+ delete[] banid;
+ delete[] pattern;
}
#endif
nick = cut_nick_from_prefix(node->body->prefix);
sprintf(IRC_buffer, "KICK %s %s :%s\n", current_channel, nick, "Flood");
write_irc(IRC_buffer);
- delete nick;
+ delete[] nick;
for(son = flood_list.first; son != NULL; son = son->next)
{
while(node != NULL)
{
next = node->next;
- if(node->body->time >= current_time - FLOOD_DELAY)
+ if(current_time <= node->body->time + FLOOD_DELAY)
{
nb_lines += node->body->weigth;
if((node->body->kind == FL_CTCP) && !node->body->alreadykicked)
flood_list.Insert(new FloodLine(prefix, kind, weigth));
}
+int bad_line(char *line, char *comment)
+{
+ int length, nb_art_chars, longest_word, nb_caps, nb_letters, nb_ctrl;
+ int l, bad;
+ unsigned char *s;
+ char *t;
+
+ nb_ctrl = 0;
+ nb_art_chars = 0;
+ nb_caps = 0;
+ nb_letters = 0;
+ length = 0;
+ l = 0;
+ longest_word = 0;
+
+ for(s=(unsigned char *)line; *s != '\0'; s++)
+ {
+ if((*s >= 'A') && (*s <= 'Z')) nb_caps++;
+ if(((*s >= 'A') && (*s <= 'Z')) ||
+ ((*s >= 'a') && (*s <= 'z'))) nb_letters++;
+ if((*s > 2) && (*s < 31)) nb_ctrl++;
+ if((*s != ' ') && (*s != '?') && (*s != '!') &&
+ (((*s >= 32) && (*s <= 47)) ||
+ ((*s >= 58) && (*s <= 63)) ||
+ ((*s >= 91) && (*s <= 96)) ||
+ (*s >= 123))) nb_art_chars++;
+
+ if(s > (unsigned char *) line)
+ {
+ if(*s == *(s-1)) l++;
+ else
+ {
+ if(l > longest_word) longest_word = l;
+ l = 0;
+ }
+ }
+
+ length++;
+ }
+ if(l > longest_word) longest_word = l;
+
+ t = comment;
+
+ bad = 0;
+ if(longest_word > 60)
+ {
+ bad = 1;
+ concat(t, "repeated chars");
+ }
+
+ if(nb_ctrl > 0)
+ {
+ if(bad) concat(t, " + ");
+ concat(t, "control chars");
+ bad = 1;
+ }
+
+ if((nb_art_chars > nb_letters) && (nb_art_chars >= 20))
+ {
+ if(bad) concat(t, " + ");
+ concat(t, "art chars");
+ bad = 1;
+ }
+
+ if((nb_caps*4 > nb_letters*3) && (nb_caps >= 10))
+ {
+ if(bad) concat(t, " + ");
+ concat(t, "caps");
+ bad = 1;
+ }
+
+ *t = '\0';
+
+ return bad;
+}
+
+void test_kick(char *prefix)
+{
+ int nb_kicks;
+ int last_kick_time;
+ NodeList<FloodLine *> *node, *next, *pred;
+ char *pattern, *banid, *loginathost;
+
+ loginathost = reach_loginathost(prefix);
+
+ nb_kicks = 0;
+ last_kick_time = current_time + COP_DELAY_BEETWEEN_KICKS + 1;
+ pred = NULL;
+ node = kick_list.first;
+ while(node != NULL)
+ {
+ next = node->next;
+ if(current_time <= node->body->time + COP_DELAY)
+ {
+ if(strcmp(loginathost, reach_loginathost(node->body->prefix)) == 0)
+ {
+ if(node->body->time < last_kick_time - COP_DELAY_BEETWEEN_KICKS)
+ {
+ nb_kicks += node->body->weigth;
+ last_kick_time = node->body->time;
+ }
+ }
+ pred = node;
+ }
+ else
+ {
+ if(pred == NULL) kick_list.first = next;
+ else pred->next = next;
+ delete node->body;
+ delete node;
+ }
+ node = next;
+ }
+
+ if(nb_kicks >= COP_NB_KICKS)
+ {
+ pattern = pattern_from_prefix(prefix, 0);
+ banid = clean_banid(pattern);
+
+ smart_shit(NULL, NULL,
+ pattern, "cop : too many kicks", COP_DURATION + deban_delay);
+ smart_ban(current_channel, pattern);
+ send_mode(current_channel);
+ filter_kick(current_channel, pattern, "cop : too many kicks");
+
+ delete[] banid;
+ delete[] pattern;
+ }
+}
+
+inline void add_kick(char *prefix)
+{
+ if(level_person(prefix, NULL) >= LEVEL_FRIEND) return;
+ kick_list.Insert(new FloodLine(prefix, FL_KICK, 1));
+ test_kick(prefix);
+}
+
//-----------------------------------------------------------------------------
// This function is called for all mode changes
{
char *c, *banid;
char buffer[3];
+ int check_ban, nb_bans, ok;
+ NodeList<char *> *node;
+ char pattern[SMALL_BUFFER_SIZE];
+ char *adr_param;
if(signe < 0) buffer[0] = '-'; else buffer[0] = '+';
buffer[1] = mode;
if(signe > 0)
{
+ check_ban = 1;
banid_list.Add(param);
- banid = clean_banid(param);
- if(strcmp(banid, param) != 0) smart_ban(where, banid);
- delete banid;
+
+ if(cop_mode && !is_hostname(who))
+ {
+ adr_param = adr_beginning(param);
+ nb_bans = 0;
+
+ for(node = banid_list.first; node != NULL; node = node->next)
+ if(are_same_site(adr_param, adr_beginning(node->body)))
+ nb_bans++;
+
+ if(nb_bans >= COP_NB_BANS)
+ {
+ check_ban = 0;
+ c = pattern;
+ concat(c, "*!*@");
+ concat(c, adr_param);
+ *c++ = '\0';
+
+ ok = 1;
+
+ for(node = present_people.first;
+ (node != NULL) && ok; node = node->next)
+ if(match_pattern(pattern, node->body))
+ if(level_person(node->body, NULL) >= LEVEL_FRIEND)
+ ok = 0;
+
+ if(ok)
+ {
+ smart_shit(NULL, NULL,
+ pattern,
+ "cop : too many bans on one site",
+ COP_DURATION + deban_delay);
+ smart_ban(where, pattern);
+ }
+ }
+ }
+
+ if(check_ban)
+ {
+ banid = clean_banid(param);
+ if(strcmp(banid, param) != 0) smart_ban(where, banid);
+ delete[] banid;
+ }
}
else banid_list.Remove(param);
break;
c = cut_nick_from_prefix(who);
add_mode(where, "-o", c);
add_mode(where, "+o", param);
- delete c;
+ delete[] c;
}
break;
else add_mode(where, "+m", NULL);
c = cut_nick_from_prefix(who);
add_mode(where, "-o", c);
- delete c;
+ delete[] c;
}
}
break;
*c = '\0';
}
-int LoadConfigFile(char *name)
+#define MAX_INCLUDE_RECURSE 3
+
+int LoadConfigFile(char *name, int recurse)
{
ifstream *file;
int duration, level, error;
{
r = IRC_buffer;
r = next_word(buffer, r, SMALL_BUFFER_SIZE);
- if(strcmp(buffer, "FRIEND") == 0)
+
+ if(strcmp(buffer, "INCLUDE") == 0)
+ {
+ if(r != NULL)
+ {
+ if(recurse < MAX_INCLUDE_RECURSE)
+ {
+ r = next_word(buffer, r, SMALL_BUFFER_SIZE);
+ LoadConfigFile(buffer, recurse+1);
+ }
+#ifdef ERROR_OUTPUT
+ else cerr<<"Can't include "
+ <<buffer<<" : too many recursion.\n";
+#endif
+ }
+ }
+ else if(strcmp(buffer, "FRIEND") == 0)
{
if(r != NULL)
{
if(r != NULL)
{
r = next_word(buffer, r, SMALL_BUFFER_SIZE);
+#ifdef SCREEN_OUTPUT
cout<<"RESTRICTED->"<<buffer<<"\n";
+#endif
restricted_list.Insert(strdup(buffer));
}
}
if(r == NULL) r = "Shit";
banid = clean_banid(pattern);
smart_shit(NULL, NULL, banid, r, duration);
- delete banid;
+ delete[] banid;
}
}
}
buf = IRC_buffer;
- cerr<<"PATTERN=>"<<pattern<<"<\n";
-
if(pattern != NULL)
{
concat(buf, "\002");
while(node1 != NULL)
{
- cout<<" =>"<<node1->body<<"\n";
-
if((pattern == NULL) || match_pattern(pattern, node1->body))
{
c = adr_beginning(node1->body);
nb_person[LEVEL_MASTER]);
tell(chat, nick, IRC_buffer);
- delete ok;
+ delete[] ok;
}
//-----------------------------------------------------------------------------
string_duration,
node->body->comment);
tell(chat, nick, IRC_buffer);
- delete string_duration;
+ delete[] string_duration;
}
if(n == 0) tell(chat, nick, "\002No corresponding shits\002\n");
{
if(pred == NULL) history.first = next;
else pred->next = next;
- delete node->body;
+ delete[] node->body;
delete node;
}
else pred = node;
sprintf(IRC_buffer, "PRIVMSG %s :\002[msg to %s]\002 %s\n",
nick_user, pattern, msg);
write_irc(IRC_buffer);
- delete nick_user;
+ delete[] nick_user;
}
}
{
if(dont_flood_server()) notice_shit_list(chat, nick, prefix, 0);
}
+ else if(eq("write", buffer) || eq("wr", buffer))
+ {
+ if(level >= LEVEL_MASTER)
+ {
+ if(r != NULL)
+ {
+ sprintf(IRC_buffer, "PRIVMSG %s :%s\n", current_channel, r);
+ write_irc(IRC_buffer);
+ }
+ }
+ else no_authorized = 1;
+ }
else if(eq("sl", buffer) || eq("shitlist", buffer))
{
if(level >= LEVEL_FRIEND)
r = next_word(buffer, r, SMALL_BUFFER_SIZE);
uncap(buffer);
- if(is_pattern(buffer)) notice_shit_list(chat, nick, buffer, 1);
+ if(is_pattern(buffer))
+ notice_shit_list(chat, nick, buffer, 1);
else
{
wait_list.Insert(new WaitInfos(buffer, NULL, chat, nick,
write_irc(IRC_buffer);
}
}
- else notice_shit_list(chat, nick, "*", 1);
+ else
+ {
+ int s1, s2, s3, s4, d;
+ NodeList<Welcome *> *node;
+ s1 = 0; s2 = 0; s3 = 0; s4 = 0;
+ for(node=shit_list.first; node != NULL; node=node->next)
+ {
+ d = node->body->time_max - current_time;
+ if(d < 1800) s1++;
+ else if(d < 4*3600) s2++;
+ else if(d < 24*3600) s3++;
+ else s4++;
+ }
+
+ sprintf(IRC_buffer,
+ "%d entries "
+ "\002%d\002 < 30min < \002%d\002 < "
+ "4h < \002%d\002 < 24h < \002%d\002\n",
+ s1+s2+s3+s4, s1, s2, s3, s4);
+ tell(chat, nick, IRC_buffer);
+ }
}
else no_authorized = 1;
}
else while(r != NULL)
{
r = next_word(buffer, r, SMALL_BUFFER_SIZE);
- /*
- if(!is_pattern(buffer))
- {
- s = buffer;
- while(*s != '\0') s++;
- concat(s, "!*");
- *s++ == '\0';
- }
- */
uncap(buffer);
notice_list_by_sites(chat, nick, buffer);
}
}
else if(eq("ao", buffer) || eq("antifloodoff", buffer))
{
- if(r != NULL)
- {
- r = next_word(buffer_time, r, SMALL_BUFFER_SIZE);
- duration = string_to_seconds(buffer_time);
- anti_flood_off_until = current_time + duration;
- }
- if(anti_flood_off_until > current_time)
+ if(level >= LEVEL_OP)
{
- string_duration = seconds_to_string(anti_flood_off_until -
- current_time);
- sprintf(IRC_buffer, "Anti-flood off for %s\n",
- string_duration);
- delete string_duration;
-
- tell(chat, nick, IRC_buffer);
+ if(r != NULL)
+ {
+ r = next_word(buffer_time, r, SMALL_BUFFER_SIZE);
+ duration = string_to_seconds(buffer_time);
+ anti_flood_off_until = current_time + duration;
+ }
+ if(anti_flood_off_until > current_time)
+ {
+ string_duration = seconds_to_string(anti_flood_off_until -
+ current_time);
+ sprintf(IRC_buffer, "Anti-flood off for %s\n",
+ string_duration);
+ delete[] string_duration;
+
+ tell(chat, nick, IRC_buffer);
+ }
+ else tell(chat, nick, "Anti-flood on\n");
}
- else tell(chat, nick, "Anti-flood on\n");
+ else no_authorized = 1;
}
else if(eq("msg", buffer) || eq("message", buffer))
{
}
else no_authorized = 1;
}
- else if(eq("help", buffer))
+ else if(eq("mode", buffer))
{
if(dont_flood_server() || (level >= LEVEL_FRIEND))
{
+ char *a;
+ if(cop_mode) a = "ON"; else a = "OFF";
if(father)
{
sprintf(IRC_buffer,
- "control_char '%c' op_delay %ds deban_delay %ds"
+ "control_char '%c' op_delay %ds deban_delay %ds "
+ "cop-mode %s"
" your level is %d. I am a father with %d sons.\n",
- control_char, op_delay, deban_delay,
+ control_char, op_delay, deban_delay, a,
level, nb_sons);
tell(chat, nick, IRC_buffer);
}
else
{
sprintf(IRC_buffer,
- "control_char '%c' op_delay %ds deban_delay %ds"
+ "control_char '%c' op_delay %ds deban_delay %ds "
+ "cop-mode %s"
" your level is %d. I'm a clone.\n",
- control_char, op_delay, deban_delay, level);
+ control_char, op_delay, deban_delay, a,
+ level);
tell(chat, nick, IRC_buffer);
}
}
-
+ }
+ else if(eq("help", buffer))
+ {
if(level >= LEVEL_FRIEND)
{
tell(chat, nick, "\002help\002 \002www\002 \002\037s\037\002hit\037l\037\002ist\002 [<nick>!<pattern>] \002level\002 [<nick>] \002\037w\037\002ho\002 \002\037m\037\002y\037s\037\002hit\002\n");
if(level >= LEVEL_OP)
{
- tell(chat, nick, "\002\037a\037\002ntiflood\037o\037\002ff\002 [<duration>] \002\037a\037\002lert\002 \002home\002 \002op\002 [{<nick> list}] \002join\002 <#channel> \002nick\002 <nick> \002\037p\037\002rune\037b\037\002an\002 <number> \002\037d\037\002e\037b\037\002an\002 {<pattern> list} \002\037f\037\002ilter\037k\037\002ick\002 <pattern>!<nick> [<comment>] \002\037s\037\002hit/\037s\037\002hit\037s\037\002ite/\037s\037\002hit\037h\037\002ost\002 <pattern>!<nick> [<duration> [<comment>]] \002\037u\037\002n\037s\037\002hit\002 {<pattern>!<nick> list} \002\037pu\037\002n\037s\037\002hit\002 {<pattern> list} \002\037b\037\002an/\037s\037\002ite\037b\037\002an\002 <pattern>!<nick> \002synch\002 \002\037h\037\002istory\002\n \002\037m\037\002es\037s\037\002a\037g\037\002e\002 <nick>!<pattern> <msg>\n");
+ tell(chat, nick, "\002\037a\037\002ntiflood\037o\037\002ff\002 [<duration>] \002\037a\037\002lert\002 \002home\002 \002cop\002 \002op\002 [{<nick> list}] \002join\002 <#channel> \002nick\002 <nick> \002\037p\037\002rune\037b\037\002an\002 <number> \002\037d\037\002e\037b\037\002an\002 {<pattern> list} \002\037f\037\002ilter\037k\037\002ick\002 <pattern>!<nick> [<comment>] \002\037s\037\002hit/\037s\037\002hit\037s\037\002ite/\037s\037\002hit\037h\037\002ost\002 <pattern>!<nick> [<duration> [<comment>]] \002\037u\037\002n\037s\037\002hit\002 {<pattern>!<nick> list} \002\037pu\037\002n\037s\037\002hit\002 {<pattern> list} \002\037b\037\002an/\037s\037\002ite\037b\037\002an\002 <pattern>!<nick> \002synch\002 \002\037h\037\002istory\002\n \002\037m\037\002es\037s\037\002a\037g\037\002e\002 <nick>!<pattern> <msg>\n");
}
if(level >= LEVEL_MASTER)
}
else if(eq("db", buffer) || eq("deban", buffer))
{
- if(level >= LEVEL_FRIEND)
+ if(level >= LEVEL_OP)
{
while(r != NULL)
{
{
banid = clean_banid(buffer);
smart_ban(current_channel, banid);
- delete banid;
+ delete[] banid;
}
else
{
if(level >= LEVEL_OP) synch(current_channel);
else no_authorized = 1;
}
+ else if(eq("cop", buffer))
+ {
+ if(level >= LEVEL_OP)
+ {
+ cop_mode = !cop_mode;
+ if(cop_mode) tell(chat, nick, "cop mode ON\n");
+ else tell(chat, nick, "cop mode OFF\n");
+ }
+ else no_authorized = 1;
+ }
else if(eq("s", buffer) || eq("shit", buffer))
{
if(level >= LEVEL_OP)
uncap(buffer);
banid = clean_banid(buffer);
smart_shit(chat, nick, banid, r, duration);
- delete banid;
+ delete[] banid;
}
else
{
if((od>=0) && (od <= 60))
{
op_delay = od;
- sprintf(IRC_buffer,"Oping delay set to %ds\n", op_delay);
+ sprintf(IRC_buffer,"Op delay set to %ds\n", op_delay);
tell(chat, nick, IRC_buffer);
}
}
sprintf(IRC_buffer, "QUIT :Changing server\n");
write_irc(IRC_buffer);
+#ifdef ERROR_OUTPUT
cerr<<"KILLING CONNECTION : Changing server\n";
cerr.flush();
+#endif
kill_connection();
}
}
if(level >= LEVEL_MASTER)
{
if(r != NULL) r = next_word(config_file, r, SMALL_BUFFER_SIZE);
- if(LoadConfigFile(config_file))
+ if(LoadConfigFile(config_file, 0))
{
sprintf(IRC_buffer,
"Can't load the %s configuration file\n",
{
sprintf(IRC_buffer, "QUIT :reset command sent by %s\n", nick);
write_irc(IRC_buffer);
+#ifdef ERROR_OUTPUT
cerr<<"KILLING CONNECTION : Die\n";
cerr.flush();
+#endif
kill_connection();
}
else no_authorized = 1;
//-----------------------------------------------------------------------------
-// This function is called after a NOTICE
+void pong_reply(char *nick, char *value)
+{
+ NodeList<WaitPing *> *node, *next, *pred;
+
+ cout<<"pong_reply : nick >"<<nick<<"< value >"<<value<<"<\n";
+
+ pred = NULL;
+ node = wait_ping.first;
+ while(node != NULL)
+ {
+ next = node->next;
+ if(current_time > node->body->time_max)
+ {
+ if(pred == NULL) wait_ping.first = next;
+ else pred->next = next;
+ delete node->body;
+ delete node;
+ }
+ if(strcmp(nick, node->body->nick) == 0)
+ {
+ if(strcmp(value, node->body->value) == 0)
+ add_mode(current_channel, "+o", nick);
+ if(pred == NULL) wait_ping.first = next;
+ else pred->next = next;
+ delete node->body;
+ delete node;
+ }
+ else pred = node;
+ node = next;
+ }
+}
+
+// This function is called after a NOTICE
void IRC_NOTICE(char *prefix,
char *who, char *msg, char **slice_ctcp, int n_ctcp)
{
+ int k;
+ char word[SMALL_BUFFER_SIZE], *r, *nick;
uncap(who);
if(strcmp(who, current_channel) == 0) add_flood_line(prefix, FL_NOTICE, 1);
+#ifdef ANTI_SPOOF
+ else if(strcmp(who, real_nick) == 0)
+ for(k=0; k<n_ctcp; k++)
+ {
+ cout<<"ctcp >"<<slice_ctcp[k]<<"<\n";
+ r = slice_ctcp[k];
+ r = next_word(word, r, SMALL_BUFFER_SIZE);
+ if(strcmp(word, "PING") == 0)
+ {
+ nick = cut_nick_from_prefix(prefix);
+ r = next_word(word, r, SMALL_BUFFER_SIZE);
+ pong_reply(nick, word);
+ delete nick;
+ }
+ }
+#endif
}
void IRC_PRIVMSG(char *prefix,
char *who, char *msg, char **slice_ctcp, int n_ctcp)
{
- int k, version, ping, level;
- char *nick, *r;
+ int k, version, ping, level, ctcp, kick;
+ char *nick, *r, *pattern, *banid;
char buffer[SMALL_BUFFER_SIZE];
uncap(who);
nick = cut_nick_from_prefix(prefix);
+
+ level = level_person(prefix, NULL);
+
+ kick = 0;
if(strcmp(who, current_channel) == 0)
{
add_flood_line(prefix, FL_PUBLIC, 1);
- if(n_ctcp > 0) add_flood_line(prefix, FL_CTCP, n_ctcp);
- }
+ if(n_ctcp > 0)
+ {
+ add_flood_line(prefix, FL_CTCP, n_ctcp);
+
+ if((cop_mode) && (level < LEVEL_FRIEND))
+ {
+ ctcp = 0;
+ for(k = 0; (k<n_ctcp) && !ctcp; k++)
+ {
+ r = slice_ctcp[k];
+ r = next_word(buffer, r, SMALL_BUFFER_SIZE);
+ if(strcmp(buffer, "ACTION") != 0) ctcp =1;
+ else
+ {
+ if(!kick && (r != NULL) && (bad_line(r, buffer)))
+ {
+ sprintf(IRC_buffer,"KICK %s %s :cop : %s\n",
+ current_channel, nick, buffer);
+ write_irc(IRC_buffer);
+ }
+ kick = 1;
+ }
+ }
+
+ if(!kick) if(ctcp) if(level < LEVEL_FRIEND)
+ {
+ pattern = pattern_from_prefix(prefix, 0);
+ banid = clean_banid(pattern);
+ smart_shit(NULL, NULL, pattern, "cop : no ctcp",
+ COP_DURATION + deban_delay);
+ smart_ban(current_channel, pattern);
+ send_mode(current_channel);
+ sprintf(IRC_buffer, "KICK %s %s :cop : no ctcp\n",
+ current_channel, nick);
+ write_irc(IRC_buffer);
+ kick = 1;
+ delete[] banid;
+ delete[] pattern;
+ }
+ }
+ }
+ else if(cop_mode) if(level < LEVEL_FRIEND)
+ if(!kick) if((msg != NULL) && bad_line(msg, buffer))
+ {
+ sprintf(IRC_buffer, "KICK %s %s :cop : %s\n",
+ current_channel, nick, buffer);
+ write_irc(IRC_buffer);
+ }
+ }
+
if(msg != NULL) if(strlen(msg)>0)
{
if(msg[0] == control_char) tropbot_cmd(NULL, prefix, nick, msg+1);
- else if(strcmp(who, real_nick) == 0) tropbot_cmd(NULL, prefix, nick, msg);
+ else if(strcmp(who, real_nick) == 0)
+ tropbot_cmd(NULL, prefix, nick, msg);
}
-
-
version = 0;
ping = 0;
for(k=0; k<n_ctcp; k++)
{
r = slice_ctcp[k];
r = next_word(buffer, r, SMALL_BUFFER_SIZE);
-
+
// Reply the CTCP VERSION
if(eq("VERSION", buffer) && !version)
{
sprintf(IRC_buffer, "NOTICE %s :"
"\001VERSION \002TropBot\002 " VERSION OPTIONS
", " SYSTEM " system, " DATE ". "
- "Contact THX-1138 on IRC, or <francois.fleuret@inria.fr>"
+ "Contact THX-1138 on IRCNet, or <francois.fleuret@inria.fr>"
"\001\n",
nick);
write_irc(IRC_buffer);
// DCC (chat)
else if(eq("DCC", buffer))
{
- level = level_person(prefix, NULL);
if(level >= LEVEL_OP)
{
if(r != NULL)
}
}
}
- delete nick;
+ delete[] nick;
}
//-----------------------------------------------------------------------------
present_people.Clear();
in_channel = 0;
}
- delete nick;
+ delete[] nick;
}
//-----------------------------------------------------------------------------
void IRC_KICK(char *prefix, char *where, char *victim_nick)
{
- char *c;
+ char *c, *d;
uncap(victim_nick);
if(strcmp(victim_nick, real_nick) == 0)
write_irc(IRC_buffer);
}
+ c = strdup(prefix_from_nick(victim_nick));
+
if((level_person(prefix, NULL) < level_person(prefix_from_nick(victim_nick), NULL)) &&
(level_person(prefix_from_nick(victim_nick), NULL) > 0))
{
- c = cut_nick_from_prefix(prefix);
- add_mode(where, "-o", c);
- delete c;
+ d = cut_nick_from_prefix(prefix);
+ add_mode(where, "-o", d);
+ delete[] d;
}
+ else if(cop_mode && (c != NULL)) add_kick(c);
- c = prefix_from_nick(victim_nick);
if(c != NULL) present_people.Remove(c);
+#ifdef ERROR_OUTPUT
else cerr<<"** ERROR : non present person has been kicked out **\n";
+#endif
+
+ delete[] c;
}
//-----------------------------------------------------------------------------
concat(s, "*!*@");
concat(s, p);
*s++ = '\0';
- duration = DEFAULT_RESTRICTED_TIME;
+ duration = DEFAULT_RESTRICTED_TIME + deban_delay;
smart_shit(NULL, NULL, pattern, "Restricted site : no clones", duration);
smart_ban(where, pattern);
send_mode(where);
void IRC_JOIN(char *prefix, char *where)
{
char *nick;
- int l, restricted;
+ int k, l, restricted;
NodeList<Welcome *> *node;
+ char buffer[SMALL_BUFFER_SIZE];
nick = cut_nick_from_prefix(prefix);
uncap(where);
present_people.Add(prefix);
- if(restricted_list.Matches(prefix))
+ l = level_person(prefix, NULL);
+
+ if((l < LEVEL_FRIEND) && (restricted_list.Matches(prefix)))
restricted = check_restricted(where, prefix);
else restricted = 0;
if(!restricted)
{
- l = level_person(prefix, NULL);
-
+#ifdef ANTI_SPOOF
+ if(l >= LEVEL_FRIEND)
+ {
+ for(k=0; k<10; k++) buffer[k] = 'a'+int(rand()%26);
+ buffer[10] = '\0';
+ wait_ping.Insert(new WaitPing(nick, buffer,
+ current_time+ANTI_SPOOF_MAX_TIME));
+ sprintf(IRC_buffer, "PRIVMSG %s :\001PING %s\001\n",
+ nick, buffer);
+ write_irc(IRC_buffer);
+ }
+#endif
+
if(l >= LEVEL_OP)
{
+#ifndef ANTI_SPOOF
if(l >= LEVEL_DEFENCE) add_mode(where, "+o", nick);
else
mode_change_list.Insert(new DelayModeChange(where, "+o",
nick, op_delay));
+#endif
}
else
{
}
}
- delete nick;
+ delete[] nick;
}
//-----------------------------------------------------------------------------
}
- delete banid;
+ delete[] banid;
if(pred == NULL) wait_list.first = next;
else pred->next = next;
*s++ = '\0';
present_people.Add(IRC_buffer);
}
+#ifdef ERROR_OUTPUT
else cerr<<where<<"!="<<current_channel<<"\n";
+#endif
}
void IRC_RPL_ENDOFWHO(char *prefix, char *name)
cmd = slice_cmd[0];
#ifdef SCREEN_OUTPUT
+
cout<<"from "<<prefix<<" ";
int k;
for(k=0; k<n_cmd; k++) cout<<"["<<slice_cmd[k]<<"]";
if(n_ctcp > 0) for(k=0; k<n_ctcp; k++) cout<<"<"<<slice_ctcp[k]<<">";
cout<<"\n";
+ for(k=0; k<n_cmd; k++) cout<<"["<<(void *) slice_cmd[k]<<"]";
+ if(n_ctcp > 0) for(k=0; k<n_ctcp; k++) cout<<"<"<<(void *) slice_ctcp[k]<<">";
+ cout<<"\n";
#endif
if(prefix != NULL) uncap(prefix);
{
if(n_cmd > 0) if(eq("PING", cmd))
{
- if(n_cmd > 2) sprintf(IRC_buffer, "PONG :%s\n", slice_cmd[1]);
+ if(n_cmd >= 2) sprintf(IRC_buffer, "PONG :%s\n", slice_cmd[1]);
else sprintf(IRC_buffer, "PONG\n");
write_irc(IRC_buffer);
}
{
n++;
if(n<argc) default_port = atoi(argv[n]);
+#ifdef ERROR_OUTPUT
else cerr<<"*** No port parameter ***\n";
+#endif
}
else if(eq("-h", argv[n]))
{
n++;
if(n<argc) strncpy(default_server, argv[n], MAXHOSTNAME);
+#ifdef ERROR_OUTPUT
else cerr<<"*** No hostname parameter ***\n";
+#endif
}
else if(eq("-o", argv[n]))
{
if(n<argc)
{
strncpy(config_file, argv[n], SMALL_BUFFER_SIZE);
- LoadConfigFile(argv[n]);
+ LoadConfigFile(argv[n], 0);
}
+#ifdef ERROR_OUTPUT
else cerr<<"*** No friends list parameter ***\n";
+#endif
}
else if(eq("-c", argv[n]))
{
n++;
if(n<argc) strncpy(home_channel, argv[n], SMALL_BUFFER_SIZE);
+#ifdef ERROR_OUTPUT
else cerr<<"*** No channel parameter ***\n";
+#endif
}
else if(eq("-l", argv[n]))
{
n++;
if(n<argc) strncpy(user_login, argv[n], SMALL_BUFFER_SIZE);
+#ifdef ERROR_OUTPUT
else cerr<<"*** No username parameter ***\n";
+#endif
}
else if(eq("-n", argv[n]))
{
n++;
if(n<argc) strncpy(original_nick, argv[n], SMALL_BUFFER_SIZE);
+#ifdef ERROR_OUTPUT
else cerr<<"*** No nickname parameter ***\n";
+#endif
}
else if(eq("-j", argv[n]))
{
n++;
if(n<argc) strncpy(jam_nick, argv[n], SMALL_BUFFER_SIZE);
+#ifdef ERROR_OUTPUT
else cerr<<"*** No jam nickname parameter ***\n";
+#endif
+ }
+ else if(eq("-cop", argv[n]))
+ {
+ cop_mode = 1;
}
else if(eq("-d", argv[n]))
{
{
d = atoi(argv[n]);
if(d>=1) socket_delay = d;
+#ifdef ERROR_OUTPUT
else cerr<<"*** Delay error ***\n";
+#endif
}
+#ifdef ERROR_OUTPUT
else cerr<<"*** No delay parameter ***\n";
+#endif
}
else if(eq("-od", argv[n]))
{
{
d = atoi(argv[n]);
if(d>=1) op_delay = d;
+#ifdef ERROR_OUTPUT
else cerr<<"*** Op delay error ***\n";
+#endif
}
+#ifdef ERROR_OUTPUT
else cerr<<"*** No delay parameter ***\n";
+#endif
}
else if(eq("-dd", argv[n]))
{
{
d = atoi(argv[n]);
if(d>=1) deban_delay = d;
+#ifdef ERROR_OUTPUT
else cerr<<"*** Deban delay error ***\n";
+#endif
}
+#ifdef ERROR_OUTPUT
else cerr<<"*** No delay parameter ***\n";
+#endif
}
else if(eq("-?", argv[n])) help = 1;
else
{
+#ifdef ERROR_OUTPUT
cerr<<"*** Unknown option "<<argv[n]<<" ***\n";
+#endif
help = 1;
}
if(help)
{
+#ifdef SCREEN_OUTPUT
cout<<"Tropbot " VERSION " Written by Francois Fleuret.\n";
cout<<"Compiled the " DATE " on a " SYSTEM " system.\n";
cout<<"Contact <francois.fleuret@inria.fr>.\n";
cout<<"-p <port number> sets the server port\n";
cout<<"-? shows this help\n";
exit(0);
+#endif
}
n++;
}
strncpy(wanted_server, default_server, MAXHOSTNAME+1);
wanted_port = default_port;
+#ifdef ERROR_OUTPUT
cerr<<"*** Can't contact IRC server ***\n";
cerr<<"*** Next try in "<<delay<<" s\n";
+#endif
}
void got_connection()
// If the buffer is already full, purge it
if(endsrc >= buffer+BUFFER_SIZE)
{
+#ifdef ERROR_OUTPUT
cerr<<"*** Buffer full, erase it ***\n";
+#endif
endsrc = buffer;
}
if(s <= 0)
{
+#ifdef ERROR_OUTPUT
cerr<<"KILLING CONNECTION : Read error\n";
cerr.flush();
+#endif
kill_connection();
}
else
level_list.Insert(new Person("*!*jolibot@*.ens.fr", LEVEL_DEFENCE, NULL));
level_list.Insert(new Person("*!*jolibot@*.curie.fr", LEVEL_DEFENCE, NULL));
+#ifdef SCREEN_OUTPUT
cout<<"TropBot, written by Francois Fleuret,"
" contact <francois.fleuret@inria.fr>\n";
+#endif
get_options(argc, argv);
global_state = STATE_WAIT;
in_channel = 0;
mode_protect_on = DEFAULT_MODE_PROTECT;
-
+ cop_mode = 0;
+
FD_ZERO(&ready);
alive = 1;
delay = socket_delay;
struct sigaction action;
+ memset(&action, 0, sizeof(action));
action.sa_handler = SIG_IGN;
// We'll ignore the SIGPIPE signal, which will be catch somewhere else
{
if(current_time > time_last_datas+DELAY_DEAD_SERVER)
{
+#ifdef ERROR_OUTPUT
cerr<<"KILLING CONNECTION : Quiet server\n";
cerr.flush();
+#endif
kill_connection();
}
else if(!in_channel) if(global_state == STATE_WAIT)
}
if(IRC_connected) check_stuffs();
+ already_kicked.Clear();
}
#ifdef SCREEN_OUTPUT