Skip to content
Permalink
Browse files

Add addserver and delserver command

Patch by: Geo
Closes: #477

Add 'addserver' and 'delserver' commands. addserver requires space-separated fields (importantly, no :'s). Likewise for delserver. Error checks are present to prevent a hostname of my.irc.com:5555 from being used, but still allow IPv6 addresses. When removing a server with delserver, if only a hostname is specified it will remove the first matching server with that hostname, then exit. If a port is specified, it will skip a matching hostname that does not have a matching port.
  • Loading branch information...
vanosg committed Sep 17, 2019
2 parents 2caaa82 + d3d8bd6 commit 86ee5dd999441ee7008e3219aca7c51a289ba06c
@@ -164,6 +164,21 @@ cap <active/available/raw> [arg]

Module: server

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
addserver <ip/host> [port [password]]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Description: adds a server to the list of servers Eggdrop will connect to. A port value is required if password is to be specified.

Returns: nothing

Module: server

^^^^^^^^^^^^^^^^^^^^^^^^^^
delserver <ip/host> [[+]port]
^^^^^^^^^^^^^^^^^^^^^^^^^^

Description: removes a server from the list of servers Eggdrop will connect to. If no port is specified, Eggdrop will remove the first server matching the ip or hostname provided. The SSL status (+) of the provided port is matched against as well (ie, 7000 is not the same as +7000).

User Record Manipulation Commands
---------------------------------

@@ -1084,23 +1084,21 @@ set default-port 6667
# servers to YOUR network's servers.
#
# The format is:
# server[:port[:password]]
# addserver <server> [port [password]]
# Prefix the port with a plus sign to attempt a SSL connection:
# server:+port[:password]
# If you need to specify a numeric server IPv6 address, enclose it in square
# brackets.
#
# Both the port and password fields are optional; however, if you want to set a
# password or use SSL you must also set a port. If a port isn't specified it
# will default to your default-port setting. WARNING- placing a '#' in front of
# a server to skip it will not work; it must be completely removed from the
# servers list.
set servers {
you.need.to.change.this:6667
another.example.com:7000:password
[2001:db8:618:5c0:263::]:6669:password
ssl.example.net:+6697
}
# addserver <server> +port [password]
#
# Both the port and password fields are optional. If a port isn't specified,
# the default-port setting will be used. If you want to set a password or use
# SSL, you must specify a port.
#
# This format is new as of version 1.9.0. The previous method using
# set servers {} will still work for now, but is deprecated and will be removed
# in a future release.
addserver you.need.to.change.this 6667
addserver another.example.com 6669 password
addserver 2001:db8:618:5c0:263:: 6669 password
addserver ssl.example.net +7000

# Number of seconds to wait between transmitting queued lines to the server.
# Lower this value at your own risk. ircd is known to start flood control
@@ -20,12 +20,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <time.h>

static void cmd_servers(struct userrec *u, int idx, char *par)
{
struct server_list *x = serverlist;
int i;
time_t t;
struct tm *currtm;
int i, len = 0;
char buf[16];
char s[1024];
char setpass[11];

putlog(LOG_CMDS, "*", "#%s# servers", dcc[idx].nick);
if (!x) {
@@ -34,23 +39,40 @@ static void cmd_servers(struct userrec *u, int idx, char *par)
dprintf(idx, "Server list:\n");
i = 0;
for (; x; x = x->next) {
if ((i == curserv) && realservername)
len = 0;
/* Build server display line, section by section */
#ifdef IPV6
if (inet_pton(AF_INET6, x->name, buf) == 1) {
len += egg_snprintf(s, sizeof s, " [%s]:", x->name);
} else {
#endif
len += egg_snprintf(s, sizeof s, " %s:", x->name);
#ifdef IPV6
}
#endif

#ifdef TLS
egg_snprintf(s, sizeof s, " [%s]:%s%d (%s) <- I am here", x->name,
x->ssl ? "+" : "", x->port ? x->port : default_port,
realservername);
else
egg_snprintf(s, sizeof s, " [%s]:%s%d %s", x->name, x->ssl ? "+" : "",
x->port ? x->port : default_port,
(i == curserv) ? "<- I am here" : "");
#else
egg_snprintf(s, sizeof s, " [%s]:%d (%s) <- I am here", x->name,
x->port ? x->port : default_port, realservername);
else
egg_snprintf(s, sizeof s, " [%s]:%d %s", x->name,
x->port ? x->port : default_port,
(i == curserv) ? "<- I am here" : "");
len += egg_snprintf(s+len, sizeof s - len, "%s", x->ssl ? "+" : "");
#endif
if (x->pass) {
t = time(NULL);
currtm = *localtime(&t); /* ******* */
if ((currtm.tm_mon == 3) && (currtm.tm_mday == 1)) {
strlcpy(setpass, "(hunter2)", sizeof setpass);
} else {
strlcpy(setpass, "(password)", sizeof setpass);
}
} else {
strlcpy(setpass, "", sizeof setpass);
}
if ((i == curserv) && realservername) {
len += egg_snprintf(s+len, sizeof s - len, "%d (%s) <- I am here",
x->port ? x->port : default_port, setpass, realservername);
} else {
len += egg_snprintf(s+len, sizeof s - len, "%d %s",
x->port ? x->port : default_port, setpass,
(i == curserv) ? "<- I am here" : "");
}
dprintf(idx, "%s\n", s);
i++;
}
@@ -120,6 +120,9 @@ static int deq_kick(int);
static void msgq_clear(struct msgq_head *qh);
static int stack_limit;
static char *realservername;
static int add_server(const char *, const char *, const char *);
static int del_server(const char *, const char *);
static void free_server(struct server_list *);

static int sasl = 0;

@@ -982,26 +985,40 @@ static void queue_server(int which, char *msg, int len)
deq_msg(); /* DP_MODE needs to be sent ASAP, flush if possible. */
}


/* This is used to split the 'old' server lists prior to sending to the new
add_server as of v1.9.0. It can be removed if the 'old' server method is
removed from Eggdrop.
*/
static void old_add_server(const char *ss) {
char name[121] = "";
char port[7] = "";
char pass[121] = "";
if (!sscanf(ss, "[%255[0-9.A-F:a-f]]:%10[+0-9]:%120[^\r\n]", name, port, pass) &&
!sscanf(ss, "%255[^:]:%10[+0-9]:%120[^\r\n]", name, port, pass))
return;
add_server(name, port, pass);
}

/* Add a new server to the server_list.
*/
static void add_server(const char *ss)
static int add_server(const char *name, const char *port, const char *pass)
{
struct server_list *x, *z;
char name[256] = "", port[11] = "", pass[121] = "";
char *ret;

for (z = serverlist; z && z->next; z = z->next);

/* Allow IPv6 and IPv4-mapped addresses in [] */
if (!sscanf(ss, "[%255[0-9.A-F:a-f]]:%10[+0-9]:%120[^\r\n]", name, port, pass) &&
!sscanf(ss, "%255[^:]:%10[+0-9]:%120[^\r\n]", name, port, pass))
return;
if ((ret = strchr(name, ':'))) {
if (!strchr(ret+1, ':')) {
return 1;
}
}

#ifndef TLS
if (port[0] == '+') {
putlog(LOG_MISC, "*", "ERROR: Attempted to add SSL-enabled server, but \
Eggdrop was not compiled with SSL libraries. Skipping...");
sslserver = 1;
return;
return 2;
}
#endif

@@ -1026,6 +1043,81 @@ Eggdrop was not compiled with SSL libraries. Skipping...");
#ifdef TLS
x->ssl = (port[0] == '+') ? 1 : 0;
#endif
return 0;
}

/* Remove a server from the server list.
* Checks based on IP and then the port, if one is provided. If no port is
* provided, remove only the first matching host.
*/
static int del_server(const char *name, const char *port)
{
struct server_list *z, *curr, *prev;
char *ret;

if (!serverlist) {
return 2;
}
if ((ret = strchr(name, ':'))) {
if (!strchr(ret+1, ':')) {
return 1;
}
}
if (!strcasecmp(name, serverlist->name)) {
z = serverlist;
if (strlen(port)) {
if ((atoi(port) != serverlist->port)
#ifdef TLS
|| ((port[0] != '+') && serverlist->ssl )) {
#else
) {
#endif
serverlist = serverlist->next;
free_server(z);
}
} else {
serverlist = serverlist->next;
free_server(z);
}
return 0;
}
curr = serverlist->next;
prev = serverlist;
while (curr != NULL && prev != NULL) {
if (!strcasecmp(name, curr->name)) {
if (strlen(port)) {
if ((atoi(port) != curr->port)
#ifdef TLS
|| ((port[0] != '+') && curr->ssl )) {
#else
) {
#endif
prev = curr;
curr = curr->next;
continue;
}
}
z = curr;
prev->next = curr->next;
free_server(z);
return 0;
}
prev = curr;
curr = curr->next;
}
return 3;
}

/* Free a single removed server from server link list */
static void free_server(struct server_list *z) {
if (z->name)
nfree(z->name);
if (z->pass)
nfree(z->pass);
if (z->realname)
nfree(z->realname);
nfree(z);
return;
}


@@ -1507,7 +1599,7 @@ static char *tcl_eggserver(ClientData cdata, Tcl_Interp *irp,
if (code == TCL_ERROR)
return "variable must be a list";
for (i = 0; i < lc && i < 50; i++)
add_server((char *) list[i]);
old_add_server((char *) list[i]);

/* Tricky way to make the bot reset its server pointers
* perform part of a '.jump <current-server>':
@@ -1987,7 +2079,9 @@ static Function server_table[] = {
(Function) check_tcl_notc,
(Function) & exclusive_binds, /* int */
/* 40 - 43 */
(Function) & H_out /* p_tcl_bind_list */
(Function) & H_out, /* p_tcl_bind_list */
(Function) add_server,
(Function) del_server
};

char *server_start(Function *global_funcs)
@@ -80,6 +80,8 @@
#define exclusive_binds (*(int *)(server_funcs[39]))
/* 40 - 43 */
#define H_out (*(p_tcl_bind_list *)(server_funcs[40]))
#define addserver ((void(*)(char *))server_funcs[41])
#define delserver ((void(*)(char *))server_funcs[42])
#else /* MAKING_SERVER */

/* Macros for commonly used commands. */
@@ -1536,8 +1536,8 @@ static void server_resolve_failure(int);
*/
static void connect_server(void)
{
char pass[121], botserver[UHOSTLEN];
int servidx;
char pass[121], botserver[UHOSTLEN], buf[16], s[1024];
int servidx, len = 0;
unsigned int botserverport = 0;

lastpingcheck = 0;
@@ -1577,14 +1577,24 @@ static void connect_server(void)
do_tcl("connect-server", connectserver);
check_tcl_event("connect-server");
next_server(&curserv, botserver, &botserverport, pass);

#ifdef IPV6
if (inet_pton(AF_INET6, botserver, buf)) {
len += egg_snprintf(s, sizeof s, "%s [%s]", IRC_SERVERTRY, botserver);
} else {
#endif
len += egg_snprintf(s, sizeof s, "%s %s", IRC_SERVERTRY, botserver);
#ifdef IPV6
}
#endif

#ifdef TLS
putlog(LOG_SERV, "*", "%s [%s]:%s%d", IRC_SERVERTRY, botserver,
use_ssl ? "+" : "", botserverport);
dcc[servidx].ssl = use_ssl;
len += egg_snprintf(s + len, sizeof s - len, ":%s%d",
use_ssl ? "+" : "", botserverport);
#else
putlog(LOG_SERV, "*", "%s [%s]:%d", IRC_SERVERTRY, botserver,
botserverport);
len += egg_snprintf(s + len, sizeof s - len, ":%d", botserverport);
#endif
putlog(LOG_SERV, "*", "%s", s);
dcc[servidx].port = botserverport;
strcpy(dcc[servidx].nick, "(server)");
strlcpy(dcc[servidx].host, botserver, UHOSTLEN);

0 comments on commit 86ee5dd

Please sign in to comment.
You can’t perform that action at this time.