Page MenuHomeDevCentral

No OneTemporary

diff --git a/dat/setup.ini b/dat/setup.ini
index 9bc1cc4..432a80b 100644
--- a/dat/setup.ini
+++ b/dat/setup.ini
@@ -1,62 +1,64 @@
ANTI_IDLE=0
BITCH_DEOP=0
BITCH_DEOP_TEXT=grr, someone op me!
BITCH_KICK_TEXT=grrr, kick me again and I'm going to...
BOT_CMD_CHAR=!
BOT_NICK=Darkbot
BOT_NAME=http://darkbot.sourceforge.net
BOT_USER_ID=darkbot
BOT_USER_MODE=+i-ds
BOT_VHOST=0
CONNECT_TIME=10
DEFAULT_CHANNEL=#darkbot
DISPLAY_SYNC=0
DO_WHOIS=0
DUNNO_TEXT=*shrug*
DUNNO_RANDOM_TEXT=1
DUPS_REMOVE=0
DUPS_SAVE=1
ENTRY_EXISTS_TEXT=Sorry, there is an existing entry under keyword
ENTRY_NOT_EXIST_TEXT=I was unable to find entry:
FIND_NO_TEXT=Sorry, I don't have any entry for
FIND_WHAT_TEXT=What am I trying to find
FLOOD_NOTICE_KICK=1
FLOOD_NOTICE_BAN=0
FLOOD_NOTICE_BAN_HOST=0
FLOOD_KICK=1
FLOOD_TEXT=Don't flood!
GREET_GUESTS_TEXT=0
GREET_NEW_TEXT=0
GREET_USER_TEXT=1
IGNORE_TIME=5
IGNORE_USER_TIME=60
KICK_TEXT=Requested!
KICK_ON_BAN=0
LOG_CHANGES=1
LOG_PRIVATE=1
OP_ON_LOGIN=0
OUTPUT1_COUNT=4
OUTPUT1_TIME=1
OUTPUT2_COUNT=6
OUTPUT2_TIME=2
OUTPUT_PURGE_COUNT=7
OUTPUT3_TIME=3
PERFORM_TIME=1
QUESTIONS_GENERAL=1
QUESTIONS_PRIVATE=0
RANDOM_BACKUP=0
RANDOM_IDLE_TIME=1800
RANDOM_TIME=3600
+SASL_USER=
+SASL_PASS=
SEEN_MODE=1
SEEN_TIME=604800
SEEN_TEXT=in the last 7 days.
SETINFO_TEXT=My !setinfo variables are: ^ nick, % Number of joins, & Channel, $ user@host. Example: !setinfo ^ has joined & % times!! (also, if you make the first char of your SETINFO a "+" the setinfo will be shown as an ACTION)
SLEEP_TIME=300
SLEEP_TEXT=ACTION falls asleep... ZzzZZzzZZzz
SLEEP_WAKE_TEXT=ACTION wakes up from a snooze..
SORT_DB=0
TOPIC_TIME=1800
VARIABLES_TEXT=Data variables are: N~ (Nick), C~ (Chan), T~ (Time/date) B~ (Botnick), Q~ (Question asked), R~ (random nick), !~ (command char), S~ (current Server), P~ (current port) V~ (botVer), W~ (db WWW site), H~ (u@h), t~ (unixtime), BAN (sets a ban), TEMPBAN (bans for 60 sec)
VOICE_ON_JOIN=0
WHUT_TEXT=hmmm?
WHUT_RANDOM_TEXT=1
diff --git a/source/Makefile.am b/source/Makefile.am
index 5919451..a157fbe 100644
--- a/source/Makefile.am
+++ b/source/Makefile.am
@@ -1,68 +1,69 @@
## Process this file with automake to produce Makefile.in.
# Copyright (C) 1996 Darkbot Project.
# This program is free software, you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2. This
# program is distributed in the hope that it will be useful, but without
# any warranty, without even the implied warranty of merchantability or
# fitness for a particular purpose. See the COPYING file for details.
## Top level diectory.
topdir = @srcdir@/..
db_db = $(topdir)/dat
db_src = $(topdir)/source
cm_src = $(topdir)/source/compat
db_scripts = $(topdir)/scripts
VPATH = @srcdir@/../source @srcdir@/../source/compat
## Database location.
databasedir = $(localstatedir)/@PACKAGE@
## Setup options for other programs.
ACLOCAL_AMFLAGS = -I ../m4
AM_CPPFLAGS = -g -I $(db_src) -I $(cm_src) -DDATABASEDIR='"$(databasedir)"' -DSOURCEDIR='"@srcdir@"'
## Compatability library.
noinst_LIBRARIES = compat/libcompat.a
compat_libcompat_a_SOURCES = dummy.c
compat_libcompat_a_LIBADD = @LIBOBJS@
## Darkbot server.
bin_PROGRAMS = darkbot convertdb
darkbot_SOURCES = chan.c general.c permbans.c reserved.c sockets.c \
users.c chansrv.c helpers.c quiz.c seen.c stats.c \
vars.c comm.c main.c random.c server.c topics.c web.c \
parse.c raw.c signals.c tree.c url.c xmlame.c \
+ utils/base64.c utils/sasl.c \
langs/*.h \
prototypes.h tree.h vars.h
darkbot_LDADD = compat/libcompat.a
## Utility programs.
convertdb_SOURCES = convertdb.c
convertdb_LDADD = compat/libcompat.a
dist_bin_SCRIPTS = $(db_scripts)/AddServer $(db_scripts)/AddUser $(db_scripts)/check-integrity $(db_scripts)/dbcron $(db_scripts)/download-databases \
$(db_scripts)/kill.darkbot $(db_scripts)/live-update $(db_scripts)/restart.darkbot $(db_scripts)/Setup
## databases.
dist_database_DATA = $(db_db)/deop.ini $(db_db)/info2.db $(db_db)/perform.ini $(db_db)/permbans.db $(db_db)/quiz.db $(db_db)/random.ini \
$(db_db)/randomstuff.ini $(db_db)/servers.ini $(db_db)/setup.ini $(db_db)/stats.db $(db_db)/userlist.db
rdbdir = $(databasedir)/rdb
dist_rdb_DATA = $(db_db)/rdb/dunno.rdb $(db_db)/rdb/whut.rdb
timersdir = $(databasedir)/timers
## Documentation.
## docdir = $(datadir)/doc/@PACKAGE@
doc_DATA = $(topdir)/COPYING $(topdir)/docs/INSTALL $(topdir)/README $(topdir)/VERSION $(topdir)/docs/AUTHORS $(topdir)/docs/HACKING \
$(topdir)/docs/README_UTILS $(topdir)/docs/TODO $(topdir)/docs/WHATSNEW
## FIXME: Move this one to a ./configure --enable-win32-console
## Uncomment this line for no-console mode on Windows.
## AM_LDFLAGS = -Wl,--subsystem,windows
## FIXME: Check that autofoo is doing its job and then remove this.
## Uncomment this line to compile on Solaris.
## AM_LIBS = -lresolv
diff --git a/source/comm.c b/source/comm.c
index 485d1b2..bc940c2 100644
--- a/source/comm.c
+++ b/source/comm.c
@@ -1,462 +1,477 @@
/*
* Copyright (C) 1996 Darkbot Project.
* This program is free software, you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2. This
* program is distributed in the hope that it will be useful, but without
* any warranty, without even the implied warranty of merchantability or
* fitness for a particular purpose. See the COPYING file for details.
*/
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
+#include "utils/sasl.h"
/**
* Delete one or more elements from the sendq
* 1 = delete all pri/not's
* 0 = delete first in queue
* 6/23/00 Dan
* - Updated to use head and tail pointer queue
* - All variables now initialized when declared
* - Optimized the main while loop a bit, reduced amount of code
*/
void
del_sendq (long toggle)
{
struct sendq *pNode = sendqhead, *pPrev = 0;
if (NULL == sendqhead)
{
return;
}
if (toggle == 0)
{
/* Just delete the head */
pNode = sendqhead;
sendqhead = sendqhead->next;
free (pNode);
}
else
{
/* Iterate through the queue and delete each element which is
* a PRIVMSG or NOTICE
*/
for (; pNode != NULL; pPrev = pNode, pNode = pNode->next)
{
if (0 == strncmp (pNode->data, "PRI", 3) || 0 == strncmp (pNode->data, "NOT", 3))
{
/* Found one, let's delete it */
if (pPrev != NULL)
{
pPrev->next = pNode->next;
}
else
{
sendqhead = pNode->next;
}
free (pNode);
pNode = NULL;
break;
}
} /* for */
} /* else */
/* Update the tail pointer if needed */
if (NULL == sendqhead)
{
sendqtail = NULL;
}
}
int
get_sendq_count (long toggle)
{
struct sendq *c;
long i = 0, x = 0;
c = sendqhead;
while (c != NULL)
{
i++;
if (c->data[0] == 'P' && c->data[1] == 'R' && c->data[2] == 'I')
x++;
else if (c->data[0] == 'N' && c->data[1] == 'O' && c->data[2] == 'T')
x++;
c = c->next;
}
if (toggle == 1)
clear_sendq (i, 1);
if (toggle == 2)
return i;
if (i < OUTPUT1_COUNT)
SEND_DELAY = OUTPUT1_DELAY;
else if (i < OUTPUT2_COUNT)
SEND_DELAY = OUTPUT2_DELAY;
else
SEND_DELAY = OUTPUT3_DELAY;
if (x > OUTPUT_PURGE_COUNT)
clear_sendq (x, 0);
return i;
}
void
clear_sendq (long count, long toggle)
{
long i = 0;
i = count;
while (i > 1)
{
i--;
del_sendq (1);
}
send_tog = 1;
if (toggle != 1)
L090 (CHAN, count);
}
long
setinfo_lastcomm (char *rest)
{ /* Disallows joins to more than one channel (or the same chan)
* to artificially raise join counters */
long c_uptime = 0;
if (strcasecmp (rest, slc1) == 0)
return 1; /* don't reply if already asked in LASTCOMM_TIME sec */
if (strcasecmp (rest, slc2) == 0)
return 1;
if (strcasecmp (rest, slc3) == 0)
return 1;
if (strcasecmp (rest, slc4) == 0)
return 1;
if (*slc1 == '0')
{ /* init lastcomms */
strncpy (slc1, rest, sizeof (slc1));
slcn1 = time (NULL);
}
if (*slc2 == '0')
{
strncpy (slc2, rest, sizeof (slc2));
slcn2 = time (NULL);
}
if (*slc3 == '0')
{
strncpy (slc3, rest, sizeof (slc3));
slcn3 = time (NULL);
}
if (*slc4 == '0')
{
strncpy (slc4, rest, sizeof (slc4));
slcn4 = time (NULL);
}
if ((c_uptime = time (NULL) - slcn1) > SLASTCOMM_TIME)
{ /* reinit old data */
slcn1 = 0;
*slc1 = '0';
}
if ((c_uptime = time (NULL) - slcn2) > SLASTCOMM_TIME)
{
slcn2 = 0;
*slc2 = '0';
}
if ((c_uptime = time (NULL) - slcn3) > SLASTCOMM_TIME)
{
slcn3 = 0;
*slc3 = '0';
}
if ((c_uptime = time (NULL) - slcn4) > SLASTCOMM_TIME)
{
slcn4 = 0;
*slc4 = '0';
}
strncpy (slc4, slc3, sizeof (slc4)); /* no matches, move em on
down */
strncpy (slc3, slc2, sizeof (slc3));
strncpy (slc2, slc1, sizeof (slc2));
strncpy (slc1, rest, sizeof (slc1));
slcn4 = slcn3;
slcn3 = slcn2;
slcn2 = slcn1;
slcn1 = time (NULL);
return 0;
}
long
do_lastcomm (char *nick, char *target, char *rest)
{
long c_uptime = 0;
if (strcasecmp (rest, lc1) == 0)
return 1; /* don't reply if already asked in LASTCOMM_TIME sec */
if (strcasecmp (rest, lc2) == 0)
return 1;
if (strcasecmp (rest, lc3) == 0)
return 1;
if (strcasecmp (rest, lc4) == 0)
return 1;
if (*lc1 == '0')
{ /* init lastcomms */
strncpy (lc1, rest, sizeof (lc1));
lcn1 = time (NULL);
}
if (*lc2 == '0')
{
strncpy (lc2, rest, sizeof (lc2));
lcn2 = time (NULL);
}
if (*lc3 == '0')
{
strncpy (lc3, rest, sizeof (lc3));
lcn3 = time (NULL);
}
if (*lc4 == '0')
{
strncpy (lc4, rest, sizeof (lc4));
lcn4 = time (NULL);
}
if ((c_uptime = time (NULL) - lcn1) > LASTCOMM_TIME)
{ /* reinit old data */
lcn1 = 0;
*lc1 = '0';
}
if ((c_uptime = time (NULL) - lcn2) > LASTCOMM_TIME)
{
lcn2 = 0;
*lc2 = '0';
}
if ((c_uptime = time (NULL) - lcn3) > LASTCOMM_TIME)
{
lcn3 = 0;
*lc3 = '0';
}
if ((c_uptime = time (NULL) - lcn4) > LASTCOMM_TIME)
{
lcn4 = 0;
*lc4 = '0';
}
strncpy (lc4, lc3, sizeof (lc4)); /* no matches, move em on
down */
strncpy (lc3, lc2, sizeof (lc3));
strncpy (lc2, lc1, sizeof (lc2));
strncpy (lc1, rest, sizeof (lc1));
lcn4 = lcn3;
lcn3 = lcn2;
lcn2 = lcn1;
lcn1 = time (NULL);
return 0;
}
void
prepare_bot (void)
{
int esc = 0;
while (!esc)
{
gs26 ();
printf (".: Connecting to %s:%ld\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
socketfd = create_connection (BS, VHOST, BP);
switch (socketfd)
{
case ERR_TIMED_OUT:
printf (".: Connection to %s:%ld timed out!\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
break;
case ERR_CONN_REFUSED:
printf (".: Connection to %s:%ld was refused!\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
break;
case ERR_NOT_ADDR:
printf ("Address not in range!\n");
exit (1);
case ERR_NO_REACH:
printf ("Address not reachable!\n");
exit (1);
default:
esc = 1;
printf
(".: Connected to %s:%ld! [%ld]\t\n", BS, BP, (long) getpid ());
fflush (stdout);
db_sleep (5);
break;
}
}
/* set the socket to BLOCK */
if (fcntl (socketfd, F_SETFL, 0) < 0)
{
printf ("\n");
perror ("fcntl");
exit (EXIT_FAILURE);
}
}
int
create_connection (char *server, char *virtualhost, long port)
{
struct sockaddr_in name;
struct hostent *hostname;
struct timeval timeout;
fd_set set;
int sock = 0, vhost = 1, sockerr = 0,
optlen = sizeof (sockerr);
if ((!virtualhost) || (strlen (virtualhost) < 1))
vhost = 0;
if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
return -1;
memset (&name, 0, sizeof (struct sockaddr_in));
setsockopt (sock, SOL_SOCKET, SO_LINGER, 0, 0);
setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, 0, 0);
setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
name.sin_family = AF_INET;
name.sin_addr.s_addr = (vhost ? inet_addr (virtualhost) : INADDR_ANY);
if ((name.sin_addr.s_addr == -1) && vhost)
{
hostname = gethostbyname (virtualhost);
if (hostname)
{
name.sin_addr = *(struct in_addr *) hostname->h_addr;
}
else
{
name.sin_addr.s_addr = INADDR_ANY;
}
}
if (bind (sock, (struct sockaddr *) &name, sizeof (struct sockaddr_in)) < 0)
{
printf ("\n");
perror ("bind");
close (sock);
exit (EXIT_FAILURE);
}
memset (&name, 0, sizeof (struct sockaddr_in));
name.sin_family = AF_INET;
name.sin_port = htons (port);
if(!(hostname = gethostbyname (server)))
{
printf ("\nCan't create the connection!\n");
// FIXME: This is obsolete, and solaris doesn't know about it.
// herror ("hostname");
exit (EXIT_FAILURE);
}
name.sin_addr = *(struct in_addr *) hostname->h_addr;
/* set the file descriptor to non blocking mode so that connect()
returns immediately.
*/
if (fcntl (sock, F_SETFL, O_NONBLOCK) < 0)
{
printf ("\n");
perror ("fcntl");
exit (EXIT_FAILURE);
}
if (connect (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
{
if ((errno != EINPROGRESS) && (errno != ENOENT))
{
printf ("\n");
perror ("connect");
exit (EXIT_FAILURE);
}
}
alarm (0);
while (1)
{
/* set the timeout */
timeout.tv_sec = CONNECT_WAIT_TIMEOUT;
timeout.tv_usec = 0;
/* set the file descriptor to be empty */
FD_ZERO (&set);
/* add our socket to the file descriptor set */
FD_SET (sock, &set);
/* select will let us know when our socket is ready (connected) */
switch (select (FD_SETSIZE, (fd_set *) NULL, &set, (fd_set *) NULL, &timeout))
{
/* if select returns 0, our timeout was reached */
case 0:
alarm (AIL);
return ERR_TIMED_OUT;
/* -1 means we are not connected */
case -1:
break;
/* we MIGHT be connected */
default:
/* get the socket errno so we can check if we are connected */
switch (getsockopt (sock, SOL_SOCKET, SO_ERROR, &sockerr, &optlen))
{
case -1:
alarm (AIL);
return ERR_SOCK_OPT;
case 0:
switch (sockerr)
{
case ECONNREFUSED:
alarm (AIL);
return ERR_CONN_REFUSED;
case EADDRNOTAVAIL:
alarm (AIL);
return ERR_NOT_ADDR;
case ENETUNREACH:
alarm (AIL);
return ERR_NO_REACH;
case SUCCESS:
alarm (AIL);
return sock;
}
}
}
}
}
void
register_bot (void)
{
get_sendq_count (1);
+
+ // SASL nickserv authentication needs to be done as soon as connected
+ // to the server, before registering with NICK and USER, PASS commands.
+ if (strlen(SASL_USER) > 0 && strlen(SASL_PASS) > 0) {
+ char* sasl_plain_string = build_sasl_plain_string(SASL_USER, SASL_USER, SASL_PASS);
+
+ Snow ("CAP REQ :SASL\n");
+ Snow ("CAP END\n");
+ Snow ("AUTHENTICATE PLAIN\n");
+ Snow ("AUTHENTICATE %s\n", sasl_plain_string);
+
+ free(sasl_plain_string);
+ }
+
Snow ("NICK %s\n", Mynick);
strlwr (UID);
Snow ("USER %s %d %d :%s \2%d\2\n", UID, time (NULL), time (NULL), REALNAME, NUM_HELPER);
if (BPASS != NULL)
Snow ("PASS :%s\n", BPASS);
}
diff --git a/source/utils/base64.c b/source/utils/base64.c
new file mode 100644
index 0000000..9abb440
--- /dev/null
+++ b/source/utils/base64.c
@@ -0,0 +1,195 @@
+/* -------------------------------------------------------------
+ Base64 - RFC 1341
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ Description: Base64 helper functions
+ Author: Jouni Malinen <j@w1.fi>
+ License: BSD-2-Clause
+ Source: This version has been extracted from FreeBSD
+ source code - src/contrib/wpa/src/utils/base64.c
+ Commit source: 0a6760a1de32bf5df91ef926eba25b3f74b4f84f
+ ------------------------------------------------------------- */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef BIT
+#define BIT(x) (1U << (x))
+#endif
+
+/* -------------------------------------------------------------
+ Helper functions to actually do the encode/decode work
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+static const char base64_table[65] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+#define BASE64_PAD BIT(0)
+#define BASE64_LF BIT(1)
+
+static char * base64_gen_encode(const unsigned char *src, size_t len,
+ size_t *out_len, const char *table, int add_pad)
+{
+ char *out, *pos;
+ const unsigned char *end, *in;
+ size_t olen;
+ int line_len;
+
+ if (len >= SIZE_MAX / 4)
+ return NULL;
+ olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
+ if (add_pad & BASE64_LF)
+ olen += olen / 72; /* line feeds */
+ olen++; /* nul termination */
+ if (olen < len)
+ return NULL; /* integer overflow */
+ out = malloc(olen);
+ if (out == NULL)
+ return NULL;
+
+ end = src + len;
+ in = src;
+ pos = out;
+ line_len = 0;
+ while (end - in >= 3) {
+ *pos++ = table[(in[0] >> 2) & 0x3f];
+ *pos++ = table[(((in[0] & 0x03) << 4) | (in[1] >> 4)) & 0x3f];
+ *pos++ = table[(((in[1] & 0x0f) << 2) | (in[2] >> 6)) & 0x3f];
+ *pos++ = table[in[2] & 0x3f];
+ in += 3;
+ line_len += 4;
+ if ((add_pad & BASE64_LF) && line_len >= 72) {
+ *pos++ = '\n';
+ line_len = 0;
+ }
+ }
+
+ if (end - in) {
+ *pos++ = table[(in[0] >> 2) & 0x3f];
+ if (end - in == 1) {
+ *pos++ = table[((in[0] & 0x03) << 4) & 0x3f];
+ if (add_pad & BASE64_PAD)
+ *pos++ = '=';
+ } else {
+ *pos++ = table[(((in[0] & 0x03) << 4) |
+ (in[1] >> 4)) & 0x3f];
+ *pos++ = table[((in[1] & 0x0f) << 2) & 0x3f];
+ }
+ if (add_pad & BASE64_PAD)
+ *pos++ = '=';
+ line_len += 4;
+ }
+
+ if ((add_pad & BASE64_LF) && line_len)
+ *pos++ = '\n';
+
+ *pos = '\0';
+ if (out_len)
+ *out_len = pos - out;
+ return out;
+}
+
+static unsigned char * base64_gen_decode(const char *src, size_t len,
+ size_t *out_len, const char *table)
+{
+ unsigned char dtable[256], *out, *pos, block[4], tmp;
+ size_t i, count, olen;
+ int pad = 0;
+ size_t extra_pad;
+
+ memset(dtable, 0x80, 256);
+ for (i = 0; i < sizeof(base64_table) - 1; i++)
+ dtable[(unsigned char) table[i]] = (unsigned char) i;
+ dtable['='] = 0;
+
+ count = 0;
+ for (i = 0; i < len; i++) {
+ if (dtable[(unsigned char) src[i]] != 0x80)
+ count++;
+ }
+
+ if (count == 0)
+ return NULL;
+ extra_pad = (4 - count % 4) % 4;
+
+ olen = (count + extra_pad) / 4 * 3;
+ pos = out = malloc(olen);
+ if (out == NULL)
+ return NULL;
+
+ count = 0;
+ for (i = 0; i < len + extra_pad; i++) {
+ unsigned char val;
+
+ if (i >= len)
+ val = '=';
+ else
+ val = src[i];
+ tmp = dtable[val];
+ if (tmp == 0x80)
+ continue;
+
+ if (val == '=')
+ pad++;
+ block[count] = tmp;
+ count++;
+ if (count == 4) {
+ *pos++ = (block[0] << 2) | (block[1] >> 4);
+ *pos++ = (block[1] << 4) | (block[2] >> 2);
+ *pos++ = (block[2] << 6) | block[3];
+ count = 0;
+ if (pad) {
+ if (pad == 1)
+ pos--;
+ else if (pad == 2)
+ pos -= 2;
+ else {
+ /* Invalid padding */
+ free(out);
+ return NULL;
+ }
+ break;
+ }
+ }
+ }
+
+ *out_len = pos - out;
+ return out;
+}
+
+/* -------------------------------------------------------------
+ High-level functions to use as library
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/**
+ * base64_encode - Base64 encode
+ * @src: Data to be encoded
+ * @len: Length of the data to be encoded
+ * @out_len: Pointer to output length variable, or %NULL if not used
+ * Returns: Allocated buffer of out_len bytes of encoded data,
+ * or %NULL on failure
+ *
+ * Caller is responsible for freeing the returned buffer. Returned buffer is
+ * nul terminated to make it easier to use as a C string. The nul terminator is
+ * not included in out_len.
+ */
+char * base64_encode(const void *src, size_t len, size_t *out_len)
+{
+ return base64_gen_encode(src, len, out_len, base64_table,
+ BASE64_PAD | BASE64_LF);
+}
+
+/**
+ * base64_decode - Base64 decode
+ * @src: Data to be decoded
+ * @len: Length of the data to be decoded
+ * @out_len: Pointer to output length variable
+ * Returns: Allocated buffer of out_len bytes of decoded data,
+ * or %NULL on failure
+ *
+ * Caller is responsible for freeing the returned buffer.
+ */
+unsigned char * base64_decode(const char *src, size_t len, size_t *out_len)
+{
+ return base64_gen_decode(src, len, out_len, base64_table);
+}
diff --git a/source/utils/base64.h b/source/utils/base64.h
new file mode 100644
index 0000000..ded8a58
--- /dev/null
+++ b/source/utils/base64.h
@@ -0,0 +1,13 @@
+/* -------------------------------------------------------------
+ Base64 - RFC 1341
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ Description: Base64 helper functions
+ Author: Jouni Malinen <j@w1.fi>
+ License: BSD-2-Clause
+ Source: This version has been extracted from FreeBSD
+ source code - src/contrib/wpa/src/utils/base64.h
+ Commit source: 0a6760a1de32bf5df91ef926eba25b3f74b4f84f
+ ------------------------------------------------------------- */
+
+char * base64_encode(const void *src, size_t len, size_t *out_len);
+unsigned char * base64_decode(const char *src, size_t len, size_t *out_len);
diff --git a/source/utils/sasl.c b/source/utils/sasl.c
new file mode 100644
index 0000000..087b6e5
--- /dev/null
+++ b/source/utils/sasl.c
@@ -0,0 +1,62 @@
+/* -------------------------------------------------------------
+ SASL PLAIN authentication
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ Description: SASL plain authentication to solve T1739
+ License: BSD-2-Clause
+ ------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "base64.h"
+
+/* -------------------------------------------------------------
+ SASL plain authentication
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/**
+ * Build a SASL PLAIN string, encoded in Base64
+ * @identity: The identity you want to authenticate as
+ * @username: The username
+ * @password: The password, in plain
+ * Returns: Allocated buffer of encoded data or %NULL on failure
+ *
+ * If the specification isn't clear what to use as identity, generally
+ * you can pass again the username. If not, pass an empty string.
+ *
+ * Caller is responsible for freeing the returned buffer. Returned buffer is
+ * nul terminated to make it easier to use as a C string.
+ */
+char* build_sasl_plain_string(char* identity, char* username, char* password) {
+ // Authentication string: concatenate the fields, with 2 NUL separator
+ // A lot of string.h functions stop at NUL character, so memcpy is safer.
+ // For example, with sprintf, only identity is copied to sasl_plain_string.
+ int identity_len = strlen(identity);
+ int username_len = strlen(username);
+ int password_len = strlen(password);
+
+ int sasl_plain_string_len = identity_len + username_len + password_len + 2;
+ char* sasl_plain_string = (char*) malloc(sasl_plain_string_len + 1);
+
+ char* buffer = sasl_plain_string;
+
+ memcpy(buffer, identity, identity_len);
+ buffer += identity_len;
+ *buffer++ = '\0';
+
+ memcpy(buffer, username, username_len);
+ buffer += username_len;
+ *buffer++ = '\0';
+
+ memcpy(buffer, password, password_len);
+ buffer += password_len;
+ *buffer++ = '\0';
+
+ // Base64 encode
+ char* result = base64_encode(sasl_plain_string, sasl_plain_string_len, NULL);
+
+ free(sasl_plain_string);
+
+ return result;
+}
diff --git a/source/utils/sasl.h b/source/utils/sasl.h
new file mode 100644
index 0000000..2123c09
--- /dev/null
+++ b/source/utils/sasl.h
@@ -0,0 +1,7 @@
+/* -------------------------------------------------------------
+ SASL PLAIN authentication
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ License: BSD-2-Clause
+ ------------------------------------------------------------- */
+
+char* build_sasl_plain_string(char* identity, char* username, char* password);
diff --git a/source/vars.c b/source/vars.c
index 7a6a195..792084c 100644
--- a/source/vars.c
+++ b/source/vars.c
@@ -1,474 +1,482 @@
/*
* Copyright (C) 1996 Darkbot Project.
* This program is free software, you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2. This
* program is distributed in the hope that it will be useful, but without
* any warranty, without even the implied warranty of merchantability or
* fitness for a particular purpose. See the COPYING file for details.
*/
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
int wsock = 0;
int sockerr = 0;
int optlen = sizeof(sockerr);
size_t nRandStuffs = 0;
long QUESTIONS = 0;
long ADDITIONS = 0;
long DELETIONS = 0;
long uptime = 0;
long NO_FLOOD = 0;
long NUM_SERV = 0;
long L_CLIENTS = 0;
long IRCOPS = 0;
long xtried = 0;
long G_USERS = 0;
long rt = 120;
long fc = 0;
long spr = 0;
long snr = 0;
long BP = 6667;
long CHECKED = 1;
long SEND_DELAY = 1;
long send_tog = 0;
long NUM_HELPER = 0;
long NUMLINESSEEN = 0;
long NUM_USER = 0;
#ifdef ENABLE_QUIZ
long quiz_timer = 0;
long quiz_line = 0;
bool quiz_answer = 0;
bool quiz_halt = 0;
char quiz_target[STRING_SHORT] = { 0 };
long recent_questions[10] = { 0 };
#endif
#ifdef ENABLE_RANDOM
long Rand_Stuff = 0;
long Rand_Idle = 0;
#endif
long AIL4 = 0;
long Sleep_Toggle = 0;
long Sleep_Time = 0;
long AIL3 = 0;
long AIL2 = 0;
long AIL5 = 0;
long JOINs = 0;
long PERMBAN_counter = 0;
long ram_load_time = 0;
long AIL9 = 0;
long AIL666 = 0;
long AIL8 = 0;
#ifdef ENABLE_QUIZ
long AIL13 = 0;
#endif
long LastInput = 0;
long AIL10 = 0;
long MARK_CHANGE = 0;
long html_counter = 0;
char NICK_COMMA[32] = { 0 };
char COLON_NICK[33] = { 0 };
char pass_data[512] = { 0 };
char pass_pass[STRING_SHORT] = { 0 };
char rword[STRING_SHORT] = { 0 };
char lc1[STRING_SHORT] = "0";
char lc2[STRING_SHORT] = "0";
char lc4[STRING_SHORT] = "0";
char lc3[STRING_SHORT] = "0";
char BPASS[STRING_SHORT] = "0";
char mask_tmp[STRING_LONG] = "0";
long lcn1 = 0;
long lcn2 = 0;
long lcn4 = 0;
long lcn3 = 0;
bool SeeN = false;
long DebuG = 0;
char slc1[STRING_SHORT] = "0";
char slc2[STRING_SHORT] = "0";
char slc4[STRING_SHORT] = "0";
char slc3[STRING_SHORT] = "0";
long slcn1 = 0;
long slcn2 = 0;
long slcn4 = 0;
long slcn3 = 0;
#ifdef WIN32
char *rp391 = "niW-4cr8 tobkraD";
#else
char *rp391 = "4cr8 tobkraD";
#endif
char BCOLON_NICK[STRING_SHORT] = { 0 };
char DARKBOT_BIN[STRING_SHORT] = { 0 };
char URL2[STRING_SHORT] = { 0 };
char DBTIMERS_PATH[STRING_SHORT] = { 0 };
char LOG_DIR[STRING_SHORT] = { 0 };
char RDB_DIR[STRING_SHORT] = { 0 };
#ifdef ENABLE_STATS
char STATS_FILE[STRING_SHORT] = { 0 };
#endif
char SEEN_FILE[STRING_SHORT] = { 0 };
char BACKUP_DUP[STRING_SHORT] = { 0 };
char ADD_DELETES[STRING_SHORT] = { 0 };
char AUTOTOPIC_F[STRING_SHORT] = { 0 };
char HELPER_LIST[STRING_SHORT] = { 0 };
char QUIZ_FILE[STRING_SHORT] = { 0 };
char PERFORM[STRING_SHORT] = { 0 };
char DEOP[STRING_SHORT] = { 0 };
char RAND_SAY[STRING_SHORT] = { 0 };
char RAND_FILE[STRING_SHORT] = { 0 };
char RANDQ_TEMPFILE[STRING_SHORT] = { 0 };
char RAND_BACKUP_FILE[STRING_SHORT] = { 0 };
char SERVERS[STRING_SHORT] = { 0 };
char PERMBAN[STRING_SHORT] = { 0 };
char SETUP[STRING_SHORT] = { 0 };
char DAT_DIR[STRING_SHORT] = { 0 };
char r_reply[STRING_SHORT] = { 0 };
char data[STRING_SHORT] = { 0 };
char g_chan[STRING_SHORT] = { 0 };
char dbVersion[STRING_SHORT] = { 0 };
char strbuff[STRING_SHORT] = { 0 };
char f_tmp[STRING_LONG] = { 0 };
char UID[STRING_SHORT] = "database";
char BS[STRING_SHORT] = "irc.freenode.net";
char CMDCHAR[2] = "!";
char CHAN[STRING_SHORT] = "#darkbot";
char s_Mynick[STRING_SHORT] = "darkbot";
char g_host[STRING_SHORT] = { 0 };
char Mynick[STRING_SHORT] = "darkbot";
char sleep_chan[STRING_SHORT] = { 0 };
char VHOST[STRING_SHORT] = "0";
char REALNAME[STRING_SHORT] = "http://darkbot.sourceforge.net";
char privmsg_log[STRING_SHORT] = { 0 };
+// SASL nickserv authentication
+char SASL_USER[STRING_SHORT] = "";
+char SASL_PASS[STRING_SHORT] = "";
+
long CONNECT_WAIT_TIMEOUT = 10;
bool PERFORM_TIMER = true;
char DEFAULT_UMODE[STRING_SHORT] = "+i-ds";
bool ANTI_IDLE = false;
bool DISPLAY_SYNC = false;
bool SORT = false;
bool FIND_DUPS = false;
bool SAVE_DUPS = true;
bool GENERAL_QUESTIONS = true;
bool MSG_RESPONSES = false;
bool LOG_ADD_DELETES = true;
bool LOG_PRIVMSG = true;
long SLEEP_TIME = 300;
char GOSLEEP_ACTION[STRING_SHORT] = "\1ACTION falls asleep... ZzzZZzzZZzz\1";
char WAKEUP_ACTION[STRING_SHORT] = "\1ACTION wakes up from a snooze..\1";
long LASTCOMM_TIME = 5;
long OUTPUT1_COUNT = 4;
long OUTPUT1_DELAY = 1;
long OUTPUT2_COUNT = 6;
long OUTPUT2_DELAY = 2;
long OUTPUT3_DELAY = 3;
long OUTPUT_PURGE_COUNT = 7;
char EXISTING_ENTRY[STRING_SHORT] = "Sorry, there is an existing entry under keyword";
char NO_ENTRY[STRING_SHORT] = "I was unable to find entry:";
//char CANT_FIND[STRING_SHORT] = "Was unable to find"; /* ... */
char NO_TOPIC[STRING_SHORT] = "Sorry, I don't have any entry for"; /* ... */
char TRY_FIND[STRING_SHORT] = "What am I trying to find";
char WHUT[STRING_SHORT] = "hmmm?";
char DUNNO_Q[STRING_SHORT] = "*shrug*";
bool RANDOM_DUNNO = true;
bool RANDOM_WHUT = true;
#ifdef ENABLE_RANDOM
//bool RANDOM_STUFF = true;
long RAND_STUFF_TIME = 3600;
long RAND_IDLE = 1800;
//long RAND_LEVEL = 2;
//bool RANDQ = true;
bool BACKUP_RANDOMSTUFF = false;
#endif
bool JOIN_GREET = true;
long SLASTCOMM_TIME = 60;
bool VOICE_USERS_ON_JOIN = false;
bool OP_USERS_ON_LOGIN = false;
bool DO_WHOIS = false;
long MAX_LASTSEEN = 604800;
char SEEN_REPLY[STRING_SHORT] = "in the last 7 days.";
char COMPLAIN_REASON[STRING_SHORT] = "grrr, kick me again and I'm going to...";
bool BITCH_ABOUT_DEOP = false;
char BITCH_DEOP_REASON[STRING_SHORT] = "grr, someone op me!";
long AUTOTOPIC_TIME = 1800;
char DEFAULT_KICK[STRING_SHORT] = "Requested!";
bool KICK_ON_BAN = false;
bool KICK_ON_CHANNEL_NOTICE = true;
bool BAN_ON_CHANNEL_NOTICE = false;
bool BAN_BY_HOST = false;
bool FLOOD_KICK = true;
char FLOOD_REASON[STRING_SHORT] = "Don't flood!";
#ifdef ENABLE_QUIZ
long QUIZ_TIMER = 25;
long QUIZ_REPEAT_TIMER = 20;
#endif
bool HELP_GREET = false;
bool AUTOHELP_GUESTS = false;
char mySetinfo[STRING_SHORT] = "My !setinfo variables are: ^ nick, % Number of joins, & \
Channel, $ user@host. Example: !setinfo ^ has joined & % times!! (also, if \
you make the first char of your SETINFO a \"+\" the setinfo will be shown \
as an ACTION)";
char myVariables[STRING_SHORT] = "Data variables are: N~ (Nick), C~ (Chan), T~ \
(Time/date) B~ (Botnick), Q~ (Question asked), R~ (random nick), !~ \
(command char), S~ (current Server), P~ (current port) V~ (botVer), W~ \
(db WWW site), H~ (u@h), t~ (unixtime), BAN (sets a ban), TEMPBAN (bans \
for 60 sec)";
struct rusage r_usage;
struct ignorelist *ignorehead = NULL;
struct sendq *sendqhead = NULL, *sendqtail = NULL;
struct userlist *userhead = NULL;
struct helperlist *helperhead = NULL;
struct permbanlist *permbanhead = NULL;
struct old ood[STRING_SHORT];
struct sl124 *sh124 = NULL;
#ifdef ENABLE_STATS
struct statslist *statshead = NULL;
#endif
struct webinfo
WEBSEARCH_webinfo = { "WEBSEARCH", "api.duckduckgo.com", 80, "/?format=xml&q=" } ,
METAR_webinfo = { "METAR", "www.aviationweather.gov", 80, "/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=3&mostRecent=true&stationString=" } ,
TAF_webinfo = { "TAF", "www.aviationweather.gov", 80, "/adds/dataserver_current/httpparam?dataSource=tafs&requestType=retrieve&format=xml&hoursBeforeNow=3&mostRecent=true&stationString=" } ,
WEATHER_webinfo = { "WEATHER", "mobile.wunderground.com", 80, "/cgi-bin/findweather/getForecast?brand=mobile&query=" };
struct setup_parameter parameters[] =
{
{ST_BOOLEAN, 3, sizeof(ANTI_IDLE), {"ANTI_IDLE", NULL, NULL, NULL, NULL}, "idling for less than ten minutes", &ANTI_IDLE, NULL},
#ifdef ENABLE_CHANNEL
{ST_BOOLEAN, 3, sizeof(BITCH_ABOUT_DEOP), {"BITCH_DEOP", NULL, NULL, NULL, NULL}, "bitch about deop", &BITCH_ABOUT_DEOP, NULL},
{ST_STRING, 3, sizeof(BITCH_DEOP_REASON), {"BITCH_DEOP_TEXT", NULL, NULL, NULL, NULL}, "deop complaint", BITCH_DEOP_REASON, NULL},
#endif
{ST_STRING, 3, sizeof(COMPLAIN_REASON), {"BITCH_KICK_TEXT", NULL, NULL, NULL, NULL}, "bot kicked message", COMPLAIN_REASON, NULL},
{ST_STRING, 3, sizeof(CMDCHAR), {"BOT_CMD_CHAR", NULL, NULL, NULL, NULL}, "bot's command char", CMDCHAR, NULL},
{ST_STRING, 3, sizeof(Mynick), {"BOT_NICK", NULL, NULL, NULL, NULL}, "bot's nickname", Mynick, check_nick_parameter},
{ST_STRING, 3, sizeof(REALNAME), {"BOT_NAME", NULL, NULL, NULL, NULL}, "bot's real name", REALNAME, NULL},
{ST_STRING, 3, sizeof(UID), {"BOT_USER_ID", NULL, NULL, NULL, NULL}, "bot's user ID", UID, NULL},
{ST_STRING, 3, sizeof(DEFAULT_UMODE), {"BOT_USER_MODE", NULL, NULL, NULL, NULL}, "bot's user modes", DEFAULT_UMODE, NULL},
{ST_STRING, 3, sizeof(VHOST), {"BOT_VHOST", NULL, NULL, NULL, NULL}, "bot's virtual host", VHOST, NULL},
{ST_INTEGER, 3, sizeof(CONNECT_WAIT_TIMEOUT), {"CONNECT_TIME", NULL, NULL, NULL, NULL}, "server connection timeout", &CONNECT_WAIT_TIMEOUT, NULL},
{ST_STRING, 3, sizeof(CHAN), {"DEFAULT_CHANNEL", NULL, NULL, NULL, NULL}, "channel", CHAN, NULL},
{ST_BOOLEAN, 3, sizeof(DISPLAY_SYNC), {"DISPLAY_SYNC", NULL, NULL, NULL, NULL}, "tell channel bot has finished syncing", &DISPLAY_SYNC, NULL},
{ST_BOOLEAN, 3, sizeof(DO_WHOIS), {"DO_WHOIS", NULL, NULL, NULL, NULL}, "questionable channel alert", &DO_WHOIS, NULL},
{ST_STRING, 3, sizeof(DUNNO_Q), {"DUNNO_TEXT", NULL, NULL, NULL, NULL}, "no answer complaint", DUNNO_Q, NULL},
{ST_BOOLEAN, 3, sizeof(RANDOM_DUNNO), {"DUNNO_RANDOM_TEXT", NULL, NULL, NULL, NULL}, "random no answer complaint", &RANDOM_DUNNO, NULL},
{ST_BOOLEAN, 3, sizeof(FIND_DUPS), {"DUPS_REMOVE", NULL, NULL, NULL, NULL}, "remove duplicates in hatabase", &FIND_DUPS, NULL},
{ST_BOOLEAN, 3, sizeof(SAVE_DUPS), {"DUPS_SAVE", NULL, NULL, NULL, NULL}, "save duplicates in database", &SAVE_DUPS, NULL},
{ST_STRING, 3, sizeof(EXISTING_ENTRY), {"ENTRY_EXISTS_TEXT", NULL, NULL, NULL, NULL}, "replacing existing complaint", EXISTING_ENTRY, NULL},
{ST_STRING, 3, sizeof(NO_ENTRY), {"ENTRY_NOT_EXIST_TEXT", NULL, NULL, NULL, NULL}, "non-existing topic complaint", NO_ENTRY, NULL},
{ST_STRING, 3, sizeof(NO_TOPIC), {"FIND_NO_TEXT", NULL, NULL, NULL, NULL}, "no topic search complaint", NO_TOPIC, NULL},
{ST_STRING, 3, sizeof(TRY_FIND), {"FIND_WHAT_TEXT", NULL, NULL, NULL, NULL}, "try find search complaint", TRY_FIND, NULL},
#ifdef ENABLE_CHANNEL
{ST_BOOLEAN, 3, sizeof(KICK_ON_CHANNEL_NOTICE), {"FLOOD_NOTICE_KICK", NULL, NULL, NULL, NULL}, "kick on channel notice flood", &KICK_ON_CHANNEL_NOTICE, NULL},
{ST_BOOLEAN, 3, sizeof(BAN_ON_CHANNEL_NOTICE), {"FLOOD_NOTICE_BAN", NULL, NULL, NULL, NULL}, "ban on channel notice flood", &BAN_ON_CHANNEL_NOTICE, NULL},
{ST_BOOLEAN, 3, sizeof(BAN_BY_HOST), {"FLOOD_NOTICE_BAN_HOST", NULL, NULL, NULL, NULL}, "ban by host on channel notice flood", &BAN_BY_HOST, NULL},
{ST_BOOLEAN, 3, sizeof(FLOOD_KICK), {"FLOOD_KICK", NULL, NULL, NULL, NULL}, "kick if bot is flooded", &FLOOD_KICK, NULL},
{ST_STRING, 3, sizeof(FLOOD_REASON), {"FLOOD_TEXT", NULL, NULL, NULL, NULL}, "flooded bot complaint", FLOOD_REASON, NULL},
#endif
{ST_BOOLEAN, 3, sizeof(AUTOHELP_GUESTS), {"GREET_GUESTS_TEXT", NULL, NULL, NULL, NULL}, "give guests help", &AUTOHELP_GUESTS, NULL},
{ST_BOOLEAN, 3, sizeof(HELP_GREET), {"GREET_NEW_TEXT", NULL, NULL, NULL, NULL}, "give new users help", &HELP_GREET, NULL},
{ST_BOOLEAN, 3, sizeof(JOIN_GREET), {"GREET_USER_TEXT", NULL, NULL, NULL, NULL}, "registered user greeting", &JOIN_GREET, NULL},
{ST_INTEGER, 3, sizeof(LASTCOMM_TIME), {"IGNORE_TIME", NULL, NULL, NULL, NULL}, "seconds to ignore repeated topics", &LASTCOMM_TIME, NULL},
{ST_INTEGER, 3, sizeof(SLASTCOMM_TIME), {"IGNORE_USER_TIME", NULL, NULL, NULL, NULL}, "registered user delay seconds", &SLASTCOMM_TIME, NULL},
#ifdef ENABLE_CHANNEL
{ST_STRING, 3, sizeof(DEFAULT_KICK), {"KICK_TEXT", NULL, NULL, NULL, NULL}, "kick message", DEFAULT_KICK, NULL},
{ST_BOOLEAN, 3, sizeof(KICK_ON_BAN), {"KICK_ON_BAN", NULL, NULL, NULL, NULL}, "kick when banned", &KICK_ON_BAN, NULL},
#endif
{ST_BOOLEAN, 3, sizeof(LOG_ADD_DELETES), {"LOG_CHANGES", NULL, NULL, NULL, NULL}, "logging of database changes", &LOG_ADD_DELETES, NULL},
{ST_BOOLEAN, 3, sizeof(LOG_PRIVMSG), {"LOG_PRIVATE", NULL, NULL, NULL, NULL}, "logging of private messages", &LOG_PRIVMSG, NULL},
#ifdef ENABLE_CHANNEL
{ST_BOOLEAN, 3, sizeof(OP_USERS_ON_LOGIN), {"OP_ON_LOGIN", NULL, NULL, NULL, NULL}, "op users on login", &OP_USERS_ON_LOGIN, NULL},
#endif
{ST_INTEGER, 3, sizeof(OUTPUT1_COUNT), {"OUTPUT1_COUNT", NULL, NULL, NULL, NULL}, "output delay threshold", &OUTPUT1_COUNT, NULL},
{ST_INTEGER, 3, sizeof(OUTPUT1_DELAY), {"OUTPUT1_TIME", NULL, NULL, NULL, NULL}, "output delay seconds", &OUTPUT1_DELAY, NULL},
{ST_INTEGER, 3, sizeof(OUTPUT2_COUNT), {"OUTPUT2_COUNT", NULL, NULL, NULL, NULL}, "long output delay threshold", &OUTPUT2_COUNT, NULL},
{ST_INTEGER, 3, sizeof(OUTPUT2_DELAY), {"OUTPUT2_TIME", NULL, NULL, NULL, NULL}, "long output delay seconds", &OUTPUT2_DELAY, NULL},
{ST_INTEGER, 3, sizeof(OUTPUT_PURGE_COUNT), {"OUTPUT_PURGE_COUNT", NULL, NULL, NULL, NULL}, "purge output delay threshold", &OUTPUT_PURGE_COUNT, NULL},
{ST_INTEGER, 3, sizeof(OUTPUT3_DELAY), {"OUTPUT3_TIME", NULL, NULL, NULL, NULL}, "purge output delay seconds", &OUTPUT3_DELAY, NULL},
{ST_BOOLEAN, 3, sizeof(PERFORM_TIMER), {"PERFORM_TIME", NULL, NULL, NULL, NULL}, "sending perform.ini to server reqularly", &PERFORM_TIMER, NULL},
{ST_BOOLEAN, 3, sizeof(GENERAL_QUESTIONS), {"QUESTIONS_GENERAL", NULL, NULL, NULL, NULL}, "bot responds without being asked", &GENERAL_QUESTIONS, NULL},
{ST_BOOLEAN, 3, sizeof(MSG_RESPONSES), {"QUESTIONS_PRIVATE", NULL, NULL, NULL, NULL}, "bot responds to private questions", &MSG_RESPONSES, NULL},
#ifdef ENABLE_QUIZ
{ST_INTEGER, 3, sizeof(QUIZ_TIMER), {"QUIZ_TIME", NULL, NULL, NULL, NULL}, "quiz answer seconds", &QUIZ_TIMER, NULL},
{ST_INTEGER, 3, sizeof(QUIZ_REPEAT_TIMER), {"QUIZ_REPEAT_TIME", NULL, NULL, NULL, NULL}, "next quiz delay seconds", &QUIZ_REPEAT_TIMER, NULL},
#endif
#ifdef ENABLE_RANDOM
// This one is currently ./configure --enable-random
// {ST_BOOLEAN, 3, sizeof(RANDOM_STUFF), {"RANDOM_STUFF", NULL, NULL, NULL, NULL}, "random utterences", &RANDOM_STUFF, NULL},
{ST_BOOLEAN, 3, sizeof(BACKUP_RANDOMSTUFF), {"RANDOM_BACKUP", NULL, NULL, NULL, NULL}, "enable random stuff auto backups", &BACKUP_RANDOMSTUFF, NULL},
{ST_INTEGER, 3, sizeof(RAND_IDLE), {"RANDOM_IDLE_TIME", NULL, NULL, NULL, NULL}, "seconds idle before random utterences", &RAND_IDLE, NULL},
// This one is currently ./configure --with-random=level
// {ST_INTEGER, 3, sizeof(RAND_LEVEL), {"RANDOM_LEVEL", NULL, NULL, NULL, NULL}, "level for adding random things", &RAND_LEVEL, NULL},
// This one is currently ./configure --enable-randq
// {ST_BOOLEAN, 3, sizeof(RANDQ), {"RANDOM_Q", NULL, NULL, NULL, NULL}, "enable RANDQ command", &RANDQ, NULL},
{ST_INTEGER, 3, sizeof(RAND_STUFF_TIME), {"RANDOM_TIME", NULL, NULL, NULL, NULL}, "seconds between random utterences", &RAND_STUFF_TIME, NULL},
#endif
+ {ST_STRING, 3, sizeof(SASL_USER), {"SASL_USER", NULL, NULL, NULL, NULL}, "bot's nickserv username for SASL auth", SASL_USER, NULL},
+ {ST_STRING, 3, sizeof(SASL_PASS), {"SASL_PASS", NULL, NULL, NULL, NULL}, "bot's nickserv password for SASL auth", SASL_PASS, NULL},
{ST_BOOLEAN, 3, sizeof(SeeN), {"SEEN_MODE", NULL, NULL, NULL, NULL}, "seen mode", &SeeN, NULL},
{ST_INTEGER, 3, sizeof(MAX_LASTSEEN), {"SEEN_TIME", NULL, NULL, NULL, NULL}, "maximum last seen seconds", &MAX_LASTSEEN, NULL},
{ST_STRING, 3, sizeof(SEEN_REPLY), {"SEEN_TEXT", NULL, NULL, NULL, NULL}, "maximum last seen reply", SEEN_REPLY, NULL},
{ST_STRING, 3, sizeof(mySetinfo), {"SETINFO_TEXT", NULL, NULL, NULL, NULL}, "setinfo variables help text", mySetinfo, NULL},
{ST_INTEGER, 3, sizeof(SLEEP_TIME), {"SLEEP_TIME", NULL, NULL, NULL, NULL}, "seconds to sleep for", &SLEEP_TIME, NULL},
{ST_STRING, 3, sizeof(GOSLEEP_ACTION), {"SLEEP_TEXT", NULL, NULL, NULL, NULL}, "sleep action", GOSLEEP_ACTION, NULL},
{ST_STRING, 3, sizeof(WAKEUP_ACTION), {"SLEEP_WAKE_TEXT", NULL, NULL, NULL, NULL}, "wakeup action", WAKEUP_ACTION, NULL},
{ST_BOOLEAN, 3, sizeof(SORT), {"SORT_DB", NULL, NULL, NULL, NULL}, "sort database on startup", &SORT, NULL},
#ifdef ENABLE_CHANNEL
{ST_INTEGER, 3, sizeof(AUTOTOPIC_TIME), {"TOPIC_TIME", NULL, NULL, NULL, NULL}, "topic setting seconds", &AUTOTOPIC_TIME, NULL},
#endif
{ST_STRING, 3, sizeof(myVariables), {"VARIABLES_TEXT", NULL, NULL, NULL, NULL}, "data variables help text", myVariables, NULL},
#ifdef ENABLE_CHANNEL
{ST_BOOLEAN, 3, sizeof(VOICE_USERS_ON_JOIN), {"VOICE_ON_JOIN", NULL, NULL, NULL, NULL}, "voice users on join", &VOICE_USERS_ON_JOIN, NULL},
#endif
{ST_STRING, 3, sizeof(WHUT), {"WHUT_TEXT", NULL, NULL, NULL, NULL}, "no text complaint", WHUT, NULL},
{ST_BOOLEAN, 3, sizeof(RANDOM_WHUT), {"WHUT_RANDOM_TEXT", NULL, NULL, NULL, NULL}, "random no text complaint", &RANDOM_WHUT, NULL},
// Cant find CANT_FIND. B-)
// {ST_STRING, 3, sizeof(CANT_FIND), {"CANT_FIND", NULL, NULL, NULL, NULL}, "can't find search complaint", CANT_FIND, NULL},
{ST_STRING, 4, 0, {NULL, NULL, NULL, NULL, NULL}, NULL, NULL, NULL}
};
struct setup_parameter *
set_parameter(char *input)
{
struct setup_parameter *result = NULL;
/* ignore comments. */
if (*input != '#')
{
int i, found = -1;
char *dat = NULL, *ptr = NULL;
dat = strdup(input);
if ((ptr = strchr(dat, '=')) != NULL)
*ptr++ = '\0';
for (result = &parameters[0]; result->parameter[0] != NULL; result++)
{
for (i = 0; result->parameter[i] != NULL; i++)
{
if (strcasecmp(dat, result->parameter[i]) == 0)
{
found = i;
break;
}
}
if (found != -1)
break;
}
if (found == -1)
result = NULL;
else
{
if ((ptr) && (result->func))
{
ptr = result->func(result, ptr);
if (ptr == NULL)
result = NULL;
}
if (ptr)
{
-#ifdef ENABLE_VERBOSE
- printf("Setting %s = %s\n", result->summary, ptr);
-#endif
+ if (DebuG)
+ {
+ printf("Setting %s = %s\n", result->summary, ptr);
+ }
+
switch (result->type)
{
case ST_BOOLEAN :
{
bool *variable = result->value;
*variable = isBoolean(ptr);
break;
}
case ST_INTEGER :
{
long *variable = result->value;
*variable = atoi(ptr);
break;
}
case ST_STRING :
{
char *variable = result->value;
strncpy(variable, ptr, result->max_size);
break;
}
}
}
}
free(dat);
}
return result;
}
void
save_setup (void)
{
struct setup_parameter *result = NULL;
printf("*** Writing setup file: %s (%s)\n", SETUP, date());
remove(TMP_FILE);
for (result = &parameters[0]; result->parameter[0] != NULL; result++)
{
switch (result->type)
{
case ST_BOOLEAN :
{
bool *variable = result->value;
db_log(TMP_FILE, "%s=%d\n", result->parameter[0], (*variable) ? 1 : 0);
break;
}
case ST_INTEGER :
{
long *variable = result->value;
db_log(TMP_FILE, "%s=%ld\n", result->parameter[0], *variable);
break;
}
case ST_STRING :
{
char *variable = result->value;
db_log(TMP_FILE, "%s=%s\n", result->parameter[0], variable);
break;
}
}
}
rename(TMP_FILE, SETUP);
}
diff --git a/source/vars.h b/source/vars.h
index 5381cb7..a3e4c18 100644
--- a/source/vars.h
+++ b/source/vars.h
@@ -1,376 +1,379 @@
/*
* Copyright (C) 1996 Darkbot Project.
* This program is free software, you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2. This
* program is distributed in the hope that it will be useful, but without
* any warranty, without even the implied warranty of merchantability or
* fitness for a particular purpose. See the COPYING file for details.
*/
#define STRING_SHORT 512
#define STRING_LONG 2048
#define FLAG_CHANOP 0x0001
#define FLAG_CHANVOICE 0x0002
extern int wsock;
extern int sockerr;
extern int optlen;
extern size_t nRandStuffs;
extern long QUESTIONS;
extern long ADDITIONS;
extern long DELETIONS;
extern long uptime;
extern long NO_FLOOD;
extern long NUM_SERV;
extern long L_CLIENTS;
extern long IRCOPS;
extern long xtried;
extern long G_USERS;
extern long rt;
extern long fc;
extern long spr;
extern long snr;
extern long BP;
extern long CHECKED;
extern long SEND_DELAY;
extern long send_tog;
extern long NUM_HELPER;
extern long NUM_USER;
extern long NUMLINESSEEN;
extern long Rand_Stuff;
extern long Rand_Idle;
extern long AIL4;
extern long Sleep_Toggle;
extern long Sleep_Time;
extern long AIL3;
extern long AIL2;
extern long AIL5;
extern long JOINs;
extern long PERMBAN_counter;
extern long RAND_CHANS;
extern long ram_load_time;
extern long AIL9;
extern long AIL666;
extern long AIL8;
#ifdef ENABLE_QUIZ
extern long AIL13;
#endif
extern long LastInput;
extern long AIL10;
extern long MARK_CHANGE;
extern long html_counter;
extern long lcn1;
extern long lcn2;
extern long lcn4;
extern long lcn3;
extern bool SeeN;
extern long DebuG;
#ifdef ENABLE_QUIZ
extern long quiz_timer;
extern long quiz_line;
extern bool quiz_answer;
extern bool quiz_halt;
extern long recent_questions[10];
#endif
extern char NICK_COMMA[32];
extern char COLON_NICK[33];
extern char BPASS[STRING_SHORT];
extern char pass_data[512];
extern char pass_pass[STRING_SHORT];
extern char rword[STRING_SHORT];
extern char lc1[STRING_SHORT];
extern char lc2[STRING_SHORT];
extern char lc4[STRING_SHORT];
extern char lc3[STRING_SHORT];
extern char slc1[STRING_SHORT];
extern char slc2[STRING_SHORT];
extern char slc4[STRING_SHORT];
extern char slc3[STRING_SHORT];
extern char mask_tmp[STRING_LONG];
extern char quiz_target[STRING_SHORT];
extern long slcn1;
extern long slcn2;
extern long slcn4;
extern long slcn3;
extern char *rp391;
extern char BCOLON_NICK[STRING_SHORT];
extern char DARKBOT_BIN[STRING_SHORT];
extern char URL2[STRING_SHORT];
extern char DBTIMERS_PATH[STRING_SHORT];
extern char LOG_DIR[STRING_SHORT];
extern char RDB_DIR[STRING_SHORT];
#ifdef ENABLE_STATS
extern char STATS_FILE[STRING_SHORT];
#endif
extern char SEEN_FILE[STRING_SHORT];
extern char BACKUP_DUP[STRING_SHORT];
extern char ADD_DELETES[STRING_SHORT];
extern char AUTOTOPIC_F[STRING_SHORT];
extern char HELPER_LIST[STRING_SHORT];
extern char QUIZ_FILE[STRING_SHORT];
extern char PERFORM[STRING_SHORT];
extern char DEOP[STRING_SHORT];
extern char RAND_SAY[STRING_SHORT];
extern char RAND_FILE[STRING_SHORT];
extern char RANDQ_TEMPFILE[STRING_SHORT];
extern char RAND_BACKUP_FILE[STRING_SHORT];
extern char SERVERS[STRING_SHORT];
extern char PERMBAN[STRING_SHORT];
extern char SETUP[STRING_SHORT];
extern char DAT_DIR[STRING_SHORT];
extern char r_reply[STRING_SHORT];
extern char data[STRING_SHORT];
extern char g_chan[STRING_SHORT];
extern char dbVersion[STRING_SHORT];
extern char strbuff[STRING_SHORT];
extern char f_tmp[STRING_LONG];
extern char UID[STRING_SHORT];
extern char BS[STRING_SHORT];
extern char CMDCHAR[2];
extern char CHAN[STRING_SHORT];
extern char s_Mynick[STRING_SHORT];
extern char g_host[STRING_SHORT];
extern char Mynick[STRING_SHORT];
extern char sleep_chan[STRING_SHORT];
extern char VHOST[STRING_SHORT];
extern char REALNAME[STRING_SHORT];
extern char privmsg_log[STRING_SHORT];
+extern char SASL_USER[STRING_SHORT];
+extern char SASL_PASS[STRING_SHORT];
+
extern long CONNECT_WAIT_TIMEOUT;
extern bool PERFORM_TIMER;
extern char DEFAULT_UMODE[STRING_SHORT];
extern bool ANTI_IDLE;
extern bool DISPLAY_SYNC;
extern bool SORT;
extern bool FIND_DUPS;
extern bool SAVE_DUPS;
extern bool GENERAL_QUESTIONS;
extern bool MSG_RESPONSES;
extern bool LOG_ADD_DELETES;
extern bool LOG_PRIVMSG;
extern long SLEEP_TIME;
extern char GOSLEEP_ACTION[STRING_SHORT];
extern char WAKEUP_ACTION[STRING_SHORT];
extern long LASTCOMM_TIME;
extern long OUTPUT1_COUNT;
extern long OUTPUT1_DELAY;
extern long OUTPUT2_COUNT;
extern long OUTPUT2_DELAY;
extern long OUTPUT3_DELAY;
extern long OUTPUT_PURGE_COUNT;
extern char EXISTING_ENTRY[STRING_SHORT];
extern char NO_ENTRY[STRING_SHORT];
//extern char CANT_FIND[STRING_SHORT]; /* ... */
extern char NO_TOPIC[STRING_SHORT]; /* ... */
extern char TRY_FIND[STRING_SHORT];
extern char WHUT[STRING_SHORT];
extern bool RANDOM_WHUT;
extern char DUNNO_Q[STRING_SHORT];
extern bool RANDOM_DUNNO;
#ifdef ENABLE_RANDOM
//extern bool RANDOM_STUFF;
extern long RAND_STUFF_TIME;
extern long RAND_IDLE;
//extern long RAND_LEVEL;
//extern bool RANDQ;
extern bool BACKUP_RANDOMSTUFF;
#endif
extern bool JOIN_GREET;
extern long SLASTCOMM_TIME;
#ifdef ENABLE_CHANNEL
extern bool VOICE_USERS_ON_JOIN;
extern bool OP_USERS_ON_LOGIN;
#endif
extern bool DO_WHOIS;
extern long MAX_LASTSEEN;
extern char SEEN_REPLY[STRING_SHORT];
extern char COMPLAIN_REASON[STRING_SHORT];
#ifdef ENABLE_CHANNEL
extern bool BITCH_ABOUT_DEOP;
extern char BITCH_DEOP_REASON[STRING_SHORT];
extern long AUTOTOPIC_TIME;
extern char DEFAULT_KICK[STRING_SHORT];
extern bool KICK_ON_BAN;
extern bool KICK_ON_CHANNEL_NOTICE;
extern bool BAN_ON_CHANNEL_NOTICE;
extern bool BAN_BY_HOST;
extern bool FLOOD_KICK;
extern char FLOOD_REASON[STRING_SHORT];
#endif
#ifdef ENABLE_QUIZ
extern long QUIZ_TIMER;
extern long QUIZ_REPEAT_TIMER;
#endif
extern bool HELP_GREET;
extern bool AUTOHELP_GUESTS;
extern char mySetinfo[STRING_SHORT];
extern char myVariables[STRING_SHORT];
extern struct rusage r_usage;
extern struct ignorelist
{
char nick[STRING_SHORT];
struct ignorelist *next;
}
*ignorehead;
extern struct sendq
{
char data[STRING_SHORT];
struct sendq *next;
}
*sendqhead, *sendqtail;
extern struct userlist
{ /* internal userlist */
char chan[STRING_SHORT];
char nick[STRING_SHORT];
char uh[STRING_SHORT];
long flags; /* op/voice/etc */
long level; /* auth */
short global; /* Global user? */
long idle;
struct userlist *next;
}
*userhead;
extern struct helperlist
{
char chan[STRING_SHORT];
char uh[STRING_SHORT];
char nick[STRING_SHORT];
long level;
size_t num_join;
char greetz[STRING_SHORT];
char pass[STRING_SHORT];
struct helperlist *next;
}
*helperhead;
/**
* 6/23/00 Dan
* - Changed permbanlist to have dynamically allocated
* userhost and reason fields.
* - Changed type of counter to size_t, this should be an
* unsigned type.
*/
extern struct permbanlist
{
char *uh;
char *reason;
size_t counter;
struct permbanlist *next;
}
*permbanhead;
extern struct old
{
char host[200];
long time;
int count;
int value;
int kick;
}
ood[STRING_SHORT];
extern struct sl124
{
char name[STRING_SHORT];
long port;
char pass[STRING_SHORT];
struct sl124 *next;
}
*sh124;
#ifdef ENABLE_STATS
extern struct statslist
{
char nick[STRING_SHORT];
char uh[STRING_SHORT];
long total;
long added_time;
long last_time;
struct statslist *next;
}
*statshead;
#endif
extern struct randstats
{
char chan [STRING_SHORT];
size_t Rand_Stuff;
size_t Rand_Idle;
size_t refnum;
size_t nCount; /* Number of times we outputted to this channel. */
struct randstats *next;
/* struct randstats *prev; */
}
*randstatshead;
struct chanserv_output
{
char *output;
struct chanserv_output *next;
};
extern struct webinfo
{
char trigger[STRING_SHORT];
char host[STRING_SHORT];
int port;
char url[STRING_SHORT];
}
WEBSEARCH_webinfo, METAR_webinfo, TAF_webinfo, WEATHER_webinfo;
enum setup_type
{
ST_BOOLEAN = 0,
ST_INTEGER = 1,
ST_STRING = 2
};
enum chanserv_invoke_type
{
DIRECT_INVOKE = 0, // command
ADDRESS_INVOKE = 1, // bot: command
MSG_INVOKE = 2, // /msg bot command
CHAR_INVOKE = 3 // !command
};
extern struct setup_parameter
{
enum setup_type type;
int access; /* Access level required to change the value. */
size_t max_size;
char *parameter[5];
char *summary;
void *value; /* Where the value is stored. */
void *(*func) (struct setup_parameter *parameter, char *ptr); /* Optional function that can do other things with the value, and veto the change by returning NULL. */
}
parameters[];
char L[524];
int alarmed;
int socketfd;

File Metadata

Mime Type
application/octet-stream
Expires
Tue, Nov 26, 18:10 (2 d)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2262944
Default Alt Text
(57 KB)

Event Timeline