From 80c3eeb9bc5794e46142cbdc7af86e533713f4d0 Mon Sep 17 00:00:00 2001
From: Thomas Sader
Date: Sun, 18 Sep 2022 21:02:59 +0200
Subject: [PATCH 01/92] Move account bind to irc.mod and normalize account
bind.
accountname being "" means unknown, accountname being "*" is not logged into services.
Account bind is triggered whenever a known account changes.
Patch by: thommey
---
doc/sphinx_source/using/tcl-commands.rst | 8 +-
src/mod/irc.mod/chan.c | 110 +++++++++++------------
src/mod/irc.mod/irc.c | 105 +++++++++++++++-------
src/mod/irc.mod/irc.h | 1 +
src/mod/irc.mod/tclirc.c | 2 +-
src/mod/server.mod/server.c | 19 +---
src/mod/server.mod/server.h | 4 +-
src/mod/server.mod/servmsg.c | 45 ----------
8 files changed, 143 insertions(+), 151 deletions(-)
diff --git a/doc/sphinx_source/using/tcl-commands.rst b/doc/sphinx_source/using/tcl-commands.rst
index e928d0f61..715d28806 100644
--- a/doc/sphinx_source/using/tcl-commands.rst
+++ b/doc/sphinx_source/using/tcl-commands.rst
@@ -1157,7 +1157,9 @@ accounttracking
getaccount [channel]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Returns: the services account name associated with nickname (if Eggdrop is configured to track account status), and "" if they are not logged in or Eggdrop is not able to determine the account status. WARNING: this account list may not be accurate depending on the server and configuration. This command is only accurate if a server supports (and Eggdrop has enabled) the account-notify and extended-join capabilities, and the server understands WHOX requests (also known as raw 354 responses).
+ Returns: the services account name associated with nickname, "*" if the user is not logged into services, or "" if eggdrop does not know the account status of the user.
+
+ NOTE: the three required IRC components for account tracking are: the WHOX feature, the extended-join IRCv3 capability and the account-notify IRCv3 capability. if only some of the three feature are available, eggdrop provides best-effort account tracking. please see doc/ACCOUNTS for additional information.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
nick2hand [channel]
@@ -3526,7 +3528,9 @@ The following is a list of bind types and how they work. Below each bind type is
procname
- Description: triggered when Eggdrop detects a change in a service account status. The change could be initiated by receiving an IRCv3 ACCOUNT message, receiving IRCv3 extended-join information when a user on an existing channel joins a new channel, or detecting an IRCv3 account-tag in a PRIVMSG. The mask for the bind is in the format "#channel nick!user@hostname.com account" where channel is the channel the user was found on when the bind was triggered, the hostmask is the user's hostmask, and account is the account name the user is logging in to, or "" for logging out. The mask argument can accept wildcards. For the proc, nick is the nickname of the user logging into/out of an account, user is the user@host.com hostmask, hand is the handle of the user (or * if none), and account is the name of the account the user logged in to (or "" if the user logged out of an account).
+ Description: this bind will trigger when eggdrop detects a change in the authentication status of a user's service account. The mask for the bind is in the format "#channel nick!user@hostname.com account" and accepts :ref:`Match Characters`. account is either the account name the user is logging in to or "*" if the user is not logged in to an account.
+
+ NOTE: the three required IRC components for account tracking are: the WHOX feature, the extended-join IRCv3 capability and the account-notify IRCv3 capability. if only some of the three feature are available, eggdrop provides best-effort account tracking but this bind could be triggered late or never on account changes. Please see doc/ACCOUNTS for additional information.
(54) ISUPPORT (stackable)
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index bdd6924d7..bba3be9b7 100644
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
@@ -212,6 +212,32 @@ static void update_idle(char *chname, char *nick)
}
}
+/* set user account on all members on all channels,
+ * trigger account bind if account state was not "unknown" (empty string)
+ */
+static void setaccount(char *nick, char *account)
+{
+ memberlist *m;
+ struct chanset_t *chan;
+
+ for (chan = chanset; chan; chan = chan->next) {
+ if ((m = ismember(chan, nick))) {
+ if (rfc_casecmp(m->account, account)) {
+ /* account was known */
+ if (m->account[0]) {
+ if (!strcmp(account, "*")) {
+ putlog(LOG_JOIN, chan->dname, "%s!%s has logged out of their account", nick, m->userhost);
+ } else {
+ putlog(LOG_JOIN, chan->dname, "%s!%s logged in to their account %s", nick, m->userhost, account);
+ }
+ check_tcl_account(m->nick, m->userhost, m->user, chan->dname, account);
+ }
+ strlcpy(m->account, account, sizeof m->account);
+ }
+ }
+ }
+}
+
/* Returns the current channel mode.
*/
static char *getchanmode(struct chanset_t *chan)
@@ -1163,10 +1189,8 @@ static int got324(char *from, char *msg)
static int got352or4(struct chanset_t *chan, char *user, char *host,
char *nick, char *flags, char *account)
{
- char userhost[UHOSTLEN], mask[CHANNELLEN+UHOSTLEN+NICKMAX+2];
- struct chanset_t *acctchan;
+ char userhost[UHOSTLEN];
memberlist *m;
- int empty_accounts;
m = ismember(chan, nick); /* In my channel list copy? */
if (!m) { /* Nope, so update */
@@ -1216,25 +1240,11 @@ static int got352or4(struct chanset_t *chan, char *user, char *host,
/* Update accountname in channel records, 0 means logged out */
/* A 0 is not a change from "" */
if (account) {
- empty_accounts = (!strcmp(account, "0") && (!strcmp(m->account, "")));
- /* If the account has changed... */
- if (strcmp(account, m->account) && !empty_accounts) {
- for (acctchan = chanset; acctchan; acctchan = acctchan->next) {
- if ((m = ismember(chan, nick))) {
- if (strcmp(account, "0")) {
- strlcpy(m->account, account, sizeof(m->account));
- snprintf(mask, sizeof mask, "%s %s", acctchan->dname, userhost);
- if (strcasecmp(chan->dname, acctchan->dname)) {
- }
- } else { /* Explicitly clear, in case someone deauthenticated? */
- m->account[0] = 0;
- snprintf(mask, sizeof mask, "%s %s", acctchan->dname, userhost);
- if (strcasecmp(chan->dname, acctchan->dname)) {
- }
- }
- }
- }
+ if (!strcmp(account, "0")) {
+ /* normalize "logged out" to "*" */
+ account = "*";
}
+ setaccount(nick, account);
}
return 0;
}
@@ -2046,12 +2056,11 @@ static void set_delay(struct chanset_t *chan, char *nick)
*/
static int gotjoin(char *from, char *channame)
{
- char *nick, *p, buf[UHOSTLEN], account[NICKMAX], *uhost = buf, *chname;
- char *ch_dname = NULL, mask[CHANNELLEN+UHOSTLEN+NICKMAX+2];
+ char *nick, *p, buf[UHOSTLEN], *uhost = buf, *chname;
+ char *ch_dname = NULL;
int extjoin = 0;
struct chanset_t *chan;
- struct chanset_t *extchan;
- memberlist *m, *n;
+ memberlist *m;
masklist *b;
struct capability *current;
struct userrec *u;
@@ -2183,42 +2192,23 @@ static int gotjoin(char *from, char *channame)
strlcpy(m->userhost, uhost, sizeof m->userhost);
m->user = u;
m->flags |= STOPWHO;
+
if (extjoin) {
- /* Update account for all channels the nick is on, not just this one */
- strlcpy(account, newsplit(&channame), sizeof account);
- for (extchan = chanset; extchan; extchan = extchan->next) {
- if ((n = ismember(extchan, nick))) {
- if (strcmp(account, "*")) {
- strlcpy (n->account, account, sizeof n->account);
- } else {
- n->account[0] = 0;
- }
- /* Don't trigger for the channel the user joined, but do trigger
- * for other channels the user is already in
- */
- if (strcasecmp(chname, extchan->dname)) {
- snprintf(mask, sizeof mask, "%s %s", chname, from);
- //check_tcl_account(nick, from, mask, u, extchan->dname, account);
- }
- }
+ /* calls check_tcl_account which can delete the channel */
+ setaccount(nick, newsplit(&channame));
+
+ if (!(chan = findchan(chname)) && !(chan = findchan_by_dname(ch_dname ? ch_dname : chname))) {
+ /* The channel doesn't exist anymore, so get out of here. */
+ goto exit;
}
}
+
check_tcl_join(nick, uhost, u, chan->dname);
- /* The tcl binding might have deleted the current user and the
- * current channel, so we'll now have to re-check whether they
- * both still exist.
- */
- chan = findchan(chname);
- if (!chan) {
- if (ch_dname)
- chan = findchan_by_dname(ch_dname);
- else
- chan = findchan_by_dname(chname);
- }
- if (!chan)
+ if (!(chan = findchan(chname)) && !(chan = findchan_by_dname(ch_dname ? ch_dname : chname))) {
/* The channel doesn't exist anymore, so get out of here. */
goto exit;
+ }
/* The record saved in the channel record always gets updated,
* so we can use that. */
@@ -2891,6 +2881,15 @@ static int gotnotice(char *from, char *msg)
return 0;
}
+/* Got ACCOUNT message; only valid for account-notify capability */
+static int gotaccount(char *from, char *msg) {
+ char *nick = splitnick(&from);
+ fixcolon(msg);
+ /* nick!ident@host ACCOUNT xxx */
+ setaccount(nick, msg);
+ return 0;
+}
+
static int parse_maxlist(const char *value)
{
int tmpsum = 0, addtosum;
@@ -3019,7 +3018,8 @@ static cmd_t irc_raw[] = {
{"347", "", (IntFunc) got347, "irc:347"},
{"348", "", (IntFunc) got348, "irc:348"},
{"349", "", (IntFunc) got349, "irc:349"},
- {NULL, NULL, NULL, NULL}
+ {"ACCOUNT", "", (IntFunc) gotaccount, "irc:account"},
+ {NULL, NULL, NULL, NULL}
};
static cmd_t irc_isupport_binds[] = {
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index 3d36394bc..e60aad444 100644
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
@@ -33,7 +33,7 @@
static p_tcl_bind_list H_topc, H_splt, H_sign, H_rejn, H_part, H_pub, H_pubm;
static p_tcl_bind_list H_nick, H_mode, H_kick, H_join, H_need, H_invt, H_ircaway;
-static p_tcl_bind_list H_monitor;
+static p_tcl_bind_list H_monitor, H_account;
static Function *global = NULL, *channels_funcs = NULL, *server_funcs = NULL;
@@ -981,6 +981,22 @@ static void check_tcl_need(char *chname, char *type)
MATCH_MASK | BIND_STACKABLE);
}
+static void check_tcl_account(char *nick, char *uhost, struct userrec *u, char *chan, char *account)
+{
+ char mask[1024];
+ struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
+
+ snprintf(mask, sizeof mask, "%s %s!%s %s", chan, nick, uhost, account);
+ Tcl_SetVar(interp, "_acnt1", nick, 0);
+ Tcl_SetVar(interp, "_acnt2", uhost, 0);
+ Tcl_SetVar(interp, "_acnt3", u ? u->handle : "*", 0);
+ Tcl_SetVar(interp, "_acnt4", chan, 0);
+ Tcl_SetVar(interp, "_acnt5", account, 0);
+ check_tcl_bind(H_account, mask, &fr,
+ " $_acnt1 $_acnt2 $_acnt3 $_acnt4 $_acnt5", MATCH_MASK | BIND_STACKABLE);
+}
+
+
static tcl_strings mystrings[] = {
{"opchars", opchars, 7, 0},
{NULL, NULL, 0, 0}
@@ -1045,13 +1061,66 @@ static void flush_modes()
}
}
+static void tell_account_tracking_status(int idx, int details)
+{
+ struct capability *current;
+ int extjoin = 0, notify = 0, tag = 0, whox = use_354;
+ /* List status of account tracking. For 100% accuracy, this requires
+ * WHOX ability (354 messages) and the extended-join and account-notify
+ * capabilities to be enabled.
+ */
+ /* Check if CAPs are enabled */
+ current = cap;
+ while (current != NULL) {
+ if (!strcasecmp("extended-join", current->name) && current->enabled) {
+ extjoin = 1;
+ } else if (!strcasecmp("account-notify", current->name) && current->enabled) {
+ notify = 1;
+ } else if (!strcasecmp("account-tag", current->name) && current->enabled) {
+ tag = 1;
+ }
+ current = current->next;
+ }
+
+ if (whox && notify && extjoin) {
+ dprintf(idx, "%s", " Account tracking: Enabled\n");
+ } else {
+ if (!details) {
+ dprintf(idx, " Account tracking: Best-effort (Missing capabilities:%s%s%s%s)\n",
+ whox ? "" : " WHOX", notify ? "" : " account-notify", extjoin ? "" : " extended-join",
+ details ? "" : ", see .status all for details");
+ } else {
+ dprintf(idx, " Account tracking: Best-effort\n");
+ if (!whox) {
+ dprintf(idx, "%s", " - WHOX missing => Accounts will NOT be known after Eggdrop joins a channel (raw 315)\n");
+ } else {
+ dprintf(idx, "%s", " - WHOX enabled => Accounts will be known after Eggdrop joins a channel (raw 315)\n");
+ }
+
+ if (!notify) {
+ dprintf(idx, "%s", " - account-notify missing => Accounts will NOT update immediately when users log in or out\n");
+ } else {
+ dprintf(idx, "%s", " - account-notify enabled => Accounts will update immediately when users log in or out\n");
+ }
+ if (!extjoin) {
+ dprintf(idx, "%s", " - extended-join missing => Accounts will NOT be known immediately when a user joins (bind join)\n");
+ } else {
+ dprintf(idx, "%s", " - extended-join enabled => Accounts will be known immediately when a user joins (bind join)\n");
+ }
+ if (tag && (!whox || !notify || !extjoin)) {
+ dprintf(idx, "%s", " - account-tag enabled => Accounts will update whenever someone messages a channel or this bot\n");
+ }
+ dprintf(idx, "%s", " See doc/ACCOUNT for more details\n");
+ }
+ }
+}
+
static void irc_report(int idx, int details)
{
struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
char ch[1024], q[256], *p;
- int k, l, extjoin, acctnotify;
+ int k, l;
struct chanset_t *chan;
- struct capability *current;
strcpy(q, "Channels: ");
k = 10;
@@ -1084,33 +1153,7 @@ static void irc_report(int idx, int details)
q[k - 2] = 0;
dprintf(idx, " %s\n", q);
}
- /* List status of account tracking. For 100% accuracy, this requires
- * WHOX ability (354 messages) and the extended-join and account-notify
- * capabilities to be enabled.
- */
- /* Check if CAPs are enabled */
- current = cap;
- extjoin = 0;
- acctnotify = 0;
- while (current != NULL) {
- if (!strcasecmp("extended-join", current->name)) {
- extjoin = current->enabled ? 1 : 0;
- }
- if (!strcasecmp("account-notify", current->name)) {
- acctnotify = current->enabled ? 1 : 0;
- }
- current = current->next;
- }
-
- if (use_354 && extjoin && acctnotify) {
- dprintf(idx, " Account tracking: Enabled\n");
- } else {
- dprintf(idx, " Account tracking: Disabled\n"
- " (Missing capabilities:%s%s%s)\n",
- use_354 ? "" : " use-354",
- extjoin ? "" : " extended-join",
- acctnotify ? "" : " account-notify");
- }
+ tell_account_tracking_status(idx, details);
}
/* Many networks either support max_bans/invite/exempts/ *or*
@@ -1296,6 +1339,7 @@ static char *irc_close()
del_bind_table(H_need);
del_bind_table(H_ircaway);
del_bind_table(H_monitor);
+ del_bind_table(H_account);
rem_tcl_strings(mystrings);
rem_tcl_ints(myints);
rem_builtins(H_dcc, irc_dcc);
@@ -1426,6 +1470,7 @@ char *irc_start(Function *global_funcs)
H_need = add_bind_table("need", HT_STACKABLE, channels_2char);
H_ircaway = add_bind_table("ircaway", HT_STACKABLE, channels_5char);
H_monitor = add_bind_table("monitor", HT_STACKABLE, monitor_2char);
+ H_account = add_bind_table("account", HT_STACKABLE, channels_5char);
do_nettype();
return NULL;
}
diff --git a/src/mod/irc.mod/irc.h b/src/mod/irc.mod/irc.h
index 423617e35..737eb400f 100644
--- a/src/mod/irc.mod/irc.h
+++ b/src/mod/irc.mod/irc.h
@@ -48,6 +48,7 @@ static int check_tcl_pub(char *, char *, char *, char *);
static int check_tcl_ircaway(char *, char *, char *, struct userrec *, char *,
char*);
static int check_tcl_monitor(char *, int);
+static void check_tcl_account(char *nick, char *uhost, struct userrec *u, char *chan, char *account);
static int me_op(struct chanset_t *);
static int me_halfop(struct chanset_t *);
static int me_voice(struct chanset_t *);
diff --git a/src/mod/irc.mod/tclirc.c b/src/mod/irc.mod/tclirc.c
index e622a1885..ea5bef5fe 100644
--- a/src/mod/irc.mod/tclirc.c
+++ b/src/mod/irc.mod/tclirc.c
@@ -587,7 +587,7 @@ static int tcl_accounttracking STDVAR
acctnotify = 1;
}
Tcl_SetResult(irp, use_354 && extjoin && acctnotify ? "1" : "0", NULL);
- return TCL_OK;
+ return TCL_OK;
}
static int tcl_getchanhost STDVAR
diff --git a/src/mod/server.mod/server.c b/src/mod/server.mod/server.c
index 8e40be533..a1721ff00 100644
--- a/src/mod/server.mod/server.c
+++ b/src/mod/server.mod/server.c
@@ -105,7 +105,7 @@ static char sslserver = 0;
#endif
static p_tcl_bind_list H_wall, H_raw, H_notc, H_msgm, H_msg, H_flud, H_ctcr,
- H_ctcp, H_out, H_rawt, H_account;
+ H_ctcp, H_out, H_rawt;
static void empty_msgq(void);
static void next_server(int *, char *, unsigned int *, char *);
@@ -1279,17 +1279,6 @@ static int server_msg STDVAR
return TCL_OK;
}
-static int server_account STDVAR
-{
- Function F = (Function) cd;
-
- BADARGS(6, 6, " nick uhost hand chan account");
-
- CHECKVALIDITY(server_account);
- F(argv[1], argv[2], get_user_by_handle(userlist, argv[3]), argv[4], argv[5]);
- return TCL_OK;
-}
-
static int server_raw STDVAR
{
Function F = (Function) cd;
@@ -2139,7 +2128,6 @@ static char *server_close()
isupport_fini();
/* Restore original commands. */
del_bind_table(H_wall);
- del_bind_table(H_account);
del_bind_table(H_raw);
del_bind_table(H_rawt);
del_bind_table(H_notc);
@@ -2246,7 +2234,7 @@ static Function server_table[] = {
/* 40 - 43 */
(Function) & H_out, /* p_tcl_bind_list */
(Function) & net_type_int, /* int */
- (Function) & H_account, /* p_tcl_bind)list */
+ (Function) NULL, /* was H_account, now irc.mod */
(Function) & cap, /* capability_t */
/* 44 - 47 */
(Function) & extended_join, /* int */
@@ -2255,7 +2243,7 @@ static Function server_table[] = {
(Function) & isupport_get, /* */
/* 48 - 52 */
(Function) & isupport_parseint,/* */
- (Function) check_tcl_account,
+ (Function) NULL, /* was check_tcl_account, now irc.mod */
(Function) & find_capability,
(Function) encode_msgtags
};
@@ -2358,7 +2346,6 @@ char *server_start(Function *global_funcs)
TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
traced_nicklen, NULL);
H_wall = add_bind_table("wall", HT_STACKABLE, server_2char);
- H_account = add_bind_table("account", HT_STACKABLE, server_account);
H_raw = add_bind_table("raw", HT_STACKABLE, server_raw);
H_rawt = add_bind_table("rawt", HT_STACKABLE, server_rawt);
H_notc = add_bind_table("notc", HT_STACKABLE, server_5char);
diff --git a/src/mod/server.mod/server.h b/src/mod/server.mod/server.h
index ba7817525..9c523751d 100644
--- a/src/mod/server.mod/server.h
+++ b/src/mod/server.mod/server.h
@@ -86,7 +86,7 @@
/* 40 - 43 */
#define H_out (*(p_tcl_bind_list *)(server_funcs[40]))
#define net_type_int (*(int *)(server_funcs[41]))
-#define H_account (*(p_tcl_bind_list *)(server_funcs[42]))
+/* #define H_account unused */
#define cap (*(capability_t **)(server_funcs[43]))
/* 44 - 47 */
#define extended_join (*(int *)(server_funcs[44]))
@@ -95,7 +95,7 @@
#define isupport_get ((struct isupport *(*)(const char *, size_t))(server_funcs[47]))
/* 48 - 51 */
#define isupport_parseint ((int (*)(const char *, const char *, int, int, int, int, int *))(server_funcs[48]))
-#define check_tcl_account ((int (*)(char *,char *,char *,struct userrec *,char *,char *))server_funcs[49])
+/* #define check_tcl_account NULL */
#define find_capability ((struct capability *(*)(char *))(server_funcs[50]))
#define encode_msgtags ((char *(*)(Tcl_Obj *))(server_funcs[51]))
#endif /* MAKING_SERVER */
diff --git a/src/mod/server.mod/servmsg.c b/src/mod/server.mod/servmsg.c
index 09ef62f9c..2c34d6340 100644
--- a/src/mod/server.mod/servmsg.c
+++ b/src/mod/server.mod/servmsg.c
@@ -259,22 +259,6 @@ static int check_tcl_wall(char *from, char *msg)
return 1;
}
-static int check_tcl_account(char *nick, char *uhost, char *mask,
- struct userrec *u, char *chan, char *account)
-{
- struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
- int x;
-
- Tcl_SetVar(interp, "_acnt1", nick, 0);
- Tcl_SetVar(interp, "_acnt2", uhost, 0);
- Tcl_SetVar(interp, "_acnt3", u ? u->handle : "*", 0);
- Tcl_SetVar(interp, "_acnt4", chan, 0);
- Tcl_SetVar(interp, "_acnt5", account, 0);
- x = check_tcl_bind(H_account, mask, &fr,
- " $_acnt1 $_acnt2 $_acnt3 $_acnt4 $_acnt5", MATCH_MASK | BIND_STACKABLE);
- return (x == BIND_EXEC_LOG);
-}
-
static int check_tcl_flud(char *nick, char *uhost, struct userrec *u,
char *ftype, char *chname)
{
@@ -1646,34 +1630,6 @@ static int handle_sasl_timeout()
return sasl_error("timeout");
}
-/* Got ACCOUNT message; only valid for account-notify capability */
-static int gotaccount(char *from, char *msg) {
- struct chanset_t *chan;
- struct userrec *u;
- memberlist *m;
- char *nick, *chname, mask[CHANNELLEN+UHOSTLEN+NICKMAX+2];
-
- u = get_user_by_host(from);
- nick = splitnick(&from);
- for (chan = chanset; chan; chan = chan->next) {
- chname = chan->dname;
- if ((m = ismember(chan, nick))) {
- strlcpy (m->account, msg[0] == '*' ? "" : msg, sizeof m->account);
- snprintf(mask, sizeof mask, "%s %s", chname, from);
- if (!strcasecmp(msg, "*")) {
- msg[0] = '\0';
- putlog(LOG_JOIN, chname, "%s!%s has logged out of their "
- "account", nick, from);
- } else {
- putlog(LOG_JOIN, chname, "%s!%s has logged into account %s",
- nick, from, msg);
- }
- check_tcl_account(nick, from, mask, u, chname, msg[0] == '*' ? "" : msg);
- }
- }
- return 0;
-}
-
/*
* 465 ERR_YOUREBANNEDCREEP :You are banned from this server
*/
@@ -2085,7 +2041,6 @@ static cmd_t my_raw_binds[] = {
{"KICK", "", (IntFunc) gotkick, NULL},
{"CAP", "", (IntFunc) gotcap, NULL},
{"AUTHENTICATE", "", (IntFunc) gotauthenticate, NULL},
- {"ACCOUNT", "", (IntFunc) gotaccount, NULL},
{"CHGHOST", "", (IntFunc) gotchghost, NULL},
{"SETNAME", "", (IntFunc) gotsetname, NULL},
{NULL, NULL, NULL, NULL}
From f6703baa574d7c34acef43ddb3ab1bee1140d94a Mon Sep 17 00:00:00 2001
From: Thomas Sader
Date: Sun, 18 Sep 2022 21:04:52 +0200
Subject: [PATCH 02/92] Raw and rawt bind now support wildcards, necessary for
account-tag usage
---
doc/sphinx_source/using/tcl-commands.rst | 12 ++++++------
src/mod/server.mod/servmsg.c | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/doc/sphinx_source/using/tcl-commands.rst b/doc/sphinx_source/using/tcl-commands.rst
index 715d28806..5a41089a0 100644
--- a/doc/sphinx_source/using/tcl-commands.rst
+++ b/doc/sphinx_source/using/tcl-commands.rst
@@ -3137,13 +3137,13 @@ The following is a list of bind types and how they work. Below each bind type is
(17) RAW (stackable)
- bind raw
+ bind raw
procname
- IMPORTANT: While not necessarily deprecated, this bind has been supplanted by the RAWT bind as of 1.9.0. You probably want to be using RAWT, not RAW.
+ IMPORTANT: While not necessarily deprecated, this bind has been supplanted by the RAWT bind, which supports the IRCv3 message-tags capability, as of 1.9.0. You probably want to be using RAWT, not RAW.
- Description: previous versions of Eggdrop required a special compile option to enable this binding, but it's now standard. The keyword is either a numeric, like "368", or a keyword, such as "PRIVMSG". "from" will be the server name or the source user (depending on the keyword); flags are ignored. The order of the arguments is identical to the order that the IRC server sends to the bot. The pre-processing only splits it apart enough to determine the keyword. If the proc returns 1, Eggdrop will not process the line any further (this could cause unexpected behavior in some cases), although RAWT binds are processed before RAW binds (and thus, a RAW bind cannot block a RAWT bind). The RAW bind does not support the IRCv3 message-tags capability, please see RAWT for more information.
+ Description: The mask can contain wildcards and is matched against the keyword, which is either a numeric, like "368", or a keyword, such as "PRIVMSG". "from" will be the server name or the source nick!ident@host (depending on the keyword); flags are ignored. If the proc returns 1, Eggdrop will not process the line any further (this could cause unexpected behavior in some cases), although RAWT binds are processed before RAW binds (and thus, a RAW bind cannot block a RAWT bind).
Module: server
@@ -3516,11 +3516,11 @@ The following is a list of bind types and how they work. Below each bind type is
(52) RAWT (stackable)
- bind rawt
+ bind rawt
- procname
+ procname
- Description: similar to the RAW bind, but allows an extra field for the IRCv3 message-tags capability. The keyword is either a numeric, like "368", or a keyword, such as "PRIVMSG" or "TAGMSG". "from" will be the server name or the source user (depending on the keyword); flags are ignored. "tag" will be the contents, if any, of the entire tag message prefixed to the server message in a dict format, such as "msgid 890157217279768 aaa bbb". The order of the arguments is identical to the order that the IRC server sends to the bot. If the proc returns 1, Eggdrop will not process the line any further, to include not being processed by a RAW bind (this could cause unexpected behavior in some cases). As of 1.9.0, it is recommended to use the RAWT bind instead of the RAW bind.
+ Description: similar to the RAW bind, but allows an extra field for the IRCv3 message-tags capability. The mask can contain wildcards and is matched against the keyword which is either a numeric, like "368", or a keyword, such as "PRIVMSG" or "TAGMSG". "from" will be the server name or the source nick!ident@host (depending on the keyword); flags are ignored. "tag" is a dictionary (flat key/value list) of the message tags with "" for empty values (e.g. "account eggdrop realname LamestBot"). If the proc returns 1, Eggdrop will not process the line any further, to include not being processed by a RAW bind (this could cause unexpected behavior in some cases). As of 1.9.0, it is recommended to use the RAWT bind instead of the RAW bind.
(53) ACCOUNT (stackable)
diff --git a/src/mod/server.mod/servmsg.c b/src/mod/server.mod/servmsg.c
index 2c34d6340..56089f1ed 100644
--- a/src/mod/server.mod/servmsg.c
+++ b/src/mod/server.mod/servmsg.c
@@ -196,7 +196,7 @@ static int check_tcl_raw(char *from, char *code, char *msg)
Tcl_SetVar(interp, "_raw2", code, 0);
Tcl_SetVar(interp, "_raw3", msg, 0);
x = check_tcl_bind(H_raw, code, 0, " $_raw1 $_raw2 $_raw3",
- MATCH_EXACT | BIND_STACKABLE | BIND_WANTRET);
+ MATCH_MASK | BIND_STACKABLE | BIND_WANTRET);
/* Return 1 if processed */
return (x == BIND_EXEC_LOG);
@@ -212,7 +212,7 @@ static int check_tcl_rawt(char *from, char *code, char *msg, char *tagdict)
Tcl_SetVar(interp, "_rawt3", msg, 0);
Tcl_SetVar(interp, "_rawt4", tagdict, 0);
x = check_tcl_bind(H_rawt, code, 0, " $_rawt1 $_rawt2 $_rawt3 $_rawt4",
- MATCH_EXACT | BIND_STACKABLE | BIND_WANTRET);
+ MATCH_MASK | BIND_STACKABLE | BIND_WANTRET);
return (x == BIND_EXEC_LOG);
}
From 098b459ab592e2fa2402b27309ca561c3d0a630c Mon Sep 17 00:00:00 2001
From: Thomas Sader
Date: Sun, 18 Sep 2022 21:05:21 +0200
Subject: [PATCH 03/92] Document how to wildcard match against an asterisk (*)
---
doc/sphinx_source/using/tcl-commands.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/doc/sphinx_source/using/tcl-commands.rst b/doc/sphinx_source/using/tcl-commands.rst
index 5a41089a0..ea19d7869 100644
--- a/doc/sphinx_source/using/tcl-commands.rst
+++ b/doc/sphinx_source/using/tcl-commands.rst
@@ -3718,6 +3718,9 @@ are the four special characters:
+-----+--------------------------------------------------------------------------+
| ~ | matches 1 or more space characters (can be used for whitespace between |
| | words) (This char only works in binds, not in regular matching) |
++-----+--------------------------------------------------------------------------+
+| \\* | matches a literal \*, but please note that Tcl needs escaping as well, |
+| | so a bind would have to use "\\*" or {\*} for a mask argument |
+-----+--------------------------------------------------------------------------+
Copyright (C) 1999 - 2022 Eggheads Development Team
From a9048c3e03d05fe849792e284e4d854614714d6d Mon Sep 17 00:00:00 2001
From: Thomas Sader
Date: Sun, 18 Sep 2022 21:06:08 +0200
Subject: [PATCH 04/92] Eggdrop no longer interprets WHO response it didn't
request in the WHOX case
The response could have different arguments, so we now validate our query type
parameter is in the response. Tcl scripts wanting to poll WHO and eggdrop
to parse it, must send query type 222 in the same format as eggdrop requests it.
Found by: Geo
Patch by: thommey
---
src/mod/irc.mod/chan.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index bba3be9b7..63a75f2ab 100644
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
@@ -1311,9 +1311,10 @@ static int got354(char *from, char *msg)
if (use_354) {
newsplit(&msg); /* Skip my nick - efficiently */
- if (!strncmp(msg, "222", strlen("222"))) {
- newsplit(&msg); /* Skip our query-type magic number" */
+ if (strncmp(msg, "222", strlen("222"))) {
+ return 0; /* ignore request without our query type, could be different arguments */
}
+ newsplit(&msg); /* Skip our query-type magic number" */
if (msg[0] && (strchr(CHANMETA, msg[0]) != NULL)) {
chname = newsplit(&msg); /* Grab the channel */
chan = findchan(chname); /* See if I'm on channel */
From d7169ac55d5daeaef4a3bb06415c82d1b1429248 Mon Sep 17 00:00:00 2001
From: Thomas Sader
Date: Sun, 18 Sep 2022 21:07:17 +0200
Subject: [PATCH 05/92] Offer the option to use account-tag for imperfect
tracking
It must be explicitely enabled in the configuration. The requirements for
perfect tracking are now enabled by default.
Patch by: thommey
---
eggdrop.conf | 13 +++++++++----
src/mod/irc.mod/chan.c | 17 +++++++++++++++++
src/mod/irc.mod/irc.c | 1 +
src/mod/server.mod/server.c | 1 +
src/mod/server.mod/servmsg.c | 5 ++++-
5 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/eggdrop.conf b/eggdrop.conf
index 8464bfcee..f1ccfd7b8 100755
--- a/eggdrop.conf
+++ b/eggdrop.conf
@@ -1158,18 +1158,23 @@ server add ssl.example.net +7000
#set sasl-timeout 15
# To request the account-notify feature via CAP, set this to 1
-#set account-notify 0
+set account-notify 1
# To request the extended-join feature via CAP, set this to 1
-#set extended-join 0
+set extended-join 1
# To request the invite-notify feature via CAP, set this to 1
#set invite-notify 0
-# To request the message-tags feature via CAP, set this to 1. NOTE: Enabling
-# this feature may interfere with RAW binds in scripts.
+# To request the message-tags feature via CAP, set this to 1
#set message-tags 0
+# To request the account-tag feature via CAP, set this to 1
+# This can be enabled if necessary for imperfect account tracking if you don't
+# have the WHOX (use_354), account-notify and extended-join features available
+# see doc/ACCOUNT for details
+#set account-tag 0
+
# If you have any additional CAP features you would like to request at
# registration but are not listed above, set them here as space separated
# strings. Setting features here does not guarantee Eggdrop's ability to support
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index 63a75f2ab..52d385190 100644
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
@@ -2982,6 +2982,18 @@ static int irc_isupport(char *key, char *isset_str, char *value)
return 0;
}
+static int gotrawt(char *from, char *msg, Tcl_Obj *tags) {
+ Tcl_Obj *valueobj;
+ if (TCL_OK != Tcl_DictObjGet(interp, tags, Tcl_NewStringObj("account", -1), &valueobj)) {
+ putlog(LOG_MISC, "*", "ERROR: irc:rawt called with invalid dictionary");
+ return 0;
+ }
+ if (valueobj) {
+ setaccount(splitnick(&from), Tcl_GetString(valueobj));
+ }
+ return 0;
+}
+
static cmd_t irc_raw[] = {
{"324", "", (IntFunc) got324, "irc:324"},
{"352", "", (IntFunc) got352, "irc:352"},
@@ -3023,6 +3035,11 @@ static cmd_t irc_raw[] = {
{NULL, NULL, NULL, NULL}
};
+static cmd_t irc_rawt[] = {
+ {"*", "", (IntFunc) gotrawt, "irc:rawt"},
+ {NULL, NULL, NULL, NULL}
+};
+
static cmd_t irc_isupport_binds[] = {
{"*", "", (IntFunc) irc_isupport, "irc:isupport"},
{NULL, NULL, NULL, NULL}
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index e60aad444..ae5eeaa87 100644
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
@@ -1452,6 +1452,7 @@ char *irc_start(Function *global_funcs)
add_builtins(H_dcc, irc_dcc);
add_builtins(H_msg, C_msg);
add_builtins(H_raw, irc_raw);
+ add_builtins(H_rawt, irc_rawt);
add_builtins(H_isupport, irc_isupport_binds);
add_tcl_commands(tclchan_cmds);
add_help_reference("irc.help");
diff --git a/src/mod/server.mod/server.c b/src/mod/server.mod/server.c
index a1721ff00..7453c6386 100644
--- a/src/mod/server.mod/server.c
+++ b/src/mod/server.mod/server.c
@@ -1661,6 +1661,7 @@ static tcl_ints my_tcl_ints[] = {
{"message-tags", &message_tags, 0},
{"extended-join", &extended_join, 0},
{"account-notify", &account_notify, 0},
+ {"account-tag", &account_tag, 0},
{NULL, NULL, 0}
};
diff --git a/src/mod/server.mod/servmsg.c b/src/mod/server.mod/servmsg.c
index 56089f1ed..9b029f22b 100644
--- a/src/mod/server.mod/servmsg.c
+++ b/src/mod/server.mod/servmsg.c
@@ -40,7 +40,7 @@ static int multistatus = 0, count_ctcp = 0;
static char altnick_char = 0;
struct capability *cap;
struct capability *find_capability(char *capname);
-int account_notify, extended_join;
+int account_notify = 1, extended_join = 1, account_tag = 0;
Tcl_Obj *ncapeslist;
/* We try to change to a preferred unique nick here. We always first try the
@@ -1843,6 +1843,9 @@ static int gotcap(char *from, char *msg) {
} else if (!strcmp(current->name, "account-notify") && (account_notify)
&& (!current->enabled)) {
add_req(current->name);
+ } else if (!strcmp(current->name, "account-tag") && (account_tag)
+ && (!current->enabled)) {
+ add_req(current->name);
} else if (!strcmp(current->name, "extended-join") && (extended_join)
&& (!current->enabled)) {
add_req(current->name);
From 0f036d59eb88d112405a17a19541fe1fa1cf2f15 Mon Sep 17 00:00:00 2001
From: Thomas Sader
Date: Sun, 18 Sep 2022 21:08:03 +0200
Subject: [PATCH 06/92] Format fix for .channel
---
src/mod/irc.mod/cmdsirc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/mod/irc.mod/cmdsirc.c b/src/mod/irc.mod/cmdsirc.c
index 0db64e93c..66179ba6d 100644
--- a/src/mod/irc.mod/cmdsirc.c
+++ b/src/mod/irc.mod/cmdsirc.c
@@ -853,11 +853,11 @@ static void cmd_channel(struct userrec *u, int idx, char *par)
else
chanflag = ' ';
if (chan_issplit(m)) {
- dprintf(idx, "%c%-*s %-*s %-*s %-6s %c <- netsplit, %fs\n",
+ dprintf(idx, "%c%-*s %-*s %-*s %-6s %c <- netsplit, %fs\n",
chanflag, maxnicklen, m->nick, maxhandlen, handle, maxnicklen,
m->account, s, atrflag, difftime(now, m->split));
} else if (!rfc_casecmp(m->nick, botname)) {
- dprintf(idx, "%c%-*s %-*s %-*s %-6s %c <- it's me!\n", chanflag,
+ dprintf(idx, "%c%-*s %-*s %-*s %-6s %c <- it's me!\n", chanflag,
maxnicklen, m->nick, maxhandlen, handle, maxnicklen, m->account,
s, atrflag);
} else {
From 0a741bdad116a876d59e7051ff0d32422eafa6a0 Mon Sep 17 00:00:00 2001
From: Thomas Sader
Date: Sun, 18 Sep 2022 21:26:51 +0200
Subject: [PATCH 07/92] Move away and account change logs from console +j to +m
Found by: Geo
Patch by: Geo, thommey
---
src/mod/irc.mod/chan.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index 52d385190..94776aed6 100644
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
@@ -226,9 +226,9 @@ static void setaccount(char *nick, char *account)
/* account was known */
if (m->account[0]) {
if (!strcmp(account, "*")) {
- putlog(LOG_JOIN, chan->dname, "%s!%s has logged out of their account", nick, m->userhost);
+ putlog(LOG_MODES, chan->dname, "%s!%s has logged out of their account", nick, m->userhost);
} else {
- putlog(LOG_JOIN, chan->dname, "%s!%s logged in to their account %s", nick, m->userhost, account);
+ putlog(LOG_MODES, chan->dname, "%s!%s logged in to their account %s", nick, m->userhost, account);
}
check_tcl_account(m->nick, m->userhost, m->user, chan->dname, account);
}
@@ -1415,10 +1415,10 @@ static int gotaway(char *from, char *msg)
if (strlen(msg)) {
m->flags |= IRCAWAY;
fixcolon(msg);
- putlog(LOG_JOIN, chan->dname, "%s is now away: %s", from, msg);
+ putlog(LOG_MODES, chan->dname, "%s is now away: %s", from, msg);
} else {
m->flags &= ~IRCAWAY;
- putlog(LOG_JOIN, chan->dname, "%s has returned from away status", from);
+ putlog(LOG_MODES, chan->dname, "%s has returned from away status", from);
}
}
}
@@ -3043,4 +3043,4 @@ static cmd_t irc_rawt[] = {
static cmd_t irc_isupport_binds[] = {
{"*", "", (IntFunc) irc_isupport, "irc:isupport"},
{NULL, NULL, NULL, NULL}
-};
\ No newline at end of file
+};
From 1191c7599c3b5f4206a90f0b4f10553f05664fbe Mon Sep 17 00:00:00 2001
From: Geo
Date: Sun, 18 Sep 2022 17:32:54 -0400
Subject: [PATCH 08/92] Add ACCOUNTS doc
Patch by: Geo
---
doc/html/using/accounts.html | 219 +++++++++++++++++++++++
doc/sphinx_source/index.rst | 1 +
doc/sphinx_source/using/accounts.rst | 81 +++++++++
doc/sphinx_source/using/tcl-commands.rst | 36 ++--
eggdrop.conf | 2 +-
misc/generatedocs | 1 +
src/mod/irc.mod/irc.c | 2 +-
7 files changed, 324 insertions(+), 18 deletions(-)
create mode 100644 doc/html/using/accounts.html
create mode 100644 doc/sphinx_source/using/accounts.rst
diff --git a/doc/html/using/accounts.html b/doc/html/using/accounts.html
new file mode 100644
index 000000000..3ac3b9b4b
--- /dev/null
+++ b/doc/html/using/accounts.html
@@ -0,0 +1,219 @@
+
+
+
+
+
+
+
+ Account tracking in Eggdrop — Eggdrop 1.9.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
In Eggdrop 1.9.3, Eggdrop added the ability to associate nicknames with the service accounts they are logged into. It is IMPORTANT to note that Eggdrop’s ability to do this is dependent on an IRC server’s implementation of three features- the IRCv3 extended-join capability, the IRCv3 account-notify capability, and WHOX support. All three of these features must be supported by the server and, in the case of extended-join and account-notify, requested by Eggdrop in order for Eggdrop to maintain “perfect” association between nicknames and account statuses.
You’re going to see this repeated a lot- the IRC server must support three features in order for Eggdrop to accurately associate accounts with nicknames. These three features allow Eggdrop to always know the current association between an account and a nickname by getting account statuses of users already on a channel when it joins, new users joining a channel, and users who authenticate while on a channel.
extended-join is an IRCv3-defined capability that adds the account name of a user to the JOIN message sent by the IRC server, alerting clients that a new member has joined a channel. Enabling this capability allows Eggdrop to immediately determine the account name associated with a user joining a channel
account-notify is an IRCv3-defined capability that sends a message to a channel when a member of the channel either authenticates or deauthenticates from their account. Enabling this capability allows Eggdrop to immediately associate an account to a channel member when they authenticate or deauthenticate.
‘WHOX <https://ircv3.net/specs/extensions/whox>`_ is a server feature that allows a client to request custom fields to be returned in a WHO response. If a server supports this capability, Eggdrop sends a WHOX query to the server when it joins a channel, allowing it to immediately determine accounts associated with channel members when Eggdrop joins a channel.
By default, the Eggdrop config file will attempt to enable all the capabilities required for account tracking. There are two settings to pay attention to
+
# To request the account-notify feature via CAP, set this to 1
+setaccount-notify1
+
+# To request the extended-join feature via CAP, set this to 1
+setextended-join1
+
+
+
The ability of a server to support WHOX queries is determined via a server’s ISUPPORT (005) reply. If a server supports WHOX queries, Eggdrop will automatically enable this feature.
While Eggdrop is running, join the partyline and type .status. If account-tracking is enabled (both the server supports and Eggdrop has requested), you’ll see this line
Determining if a Server Supports Account Capabilities¶
+
A server announces the capabilities it supports via a CAP request. If you have Tcl enabled on the partyline (or via a raw message from a client), you can send .tcl cap ls and see if the extended-join and account-notify capabilities are supported by the server. If they are not listed, the server does not support it.
+
A server announces if it supports WHOX via its ISUPPORT (005) announcement. If you have Tcl enabled on the partyline, you can send .tcl issupport isset WHOX and if it returns ‘1’, WHOX is supported by the server.
If a server only supports some, but not all, of the required capabilities, Eggdrop will switch to ‘best effort’ account tracking. This means Eggdrop will update account statuses whenever it sees account information, but Eggdrop cannnot guarantee the accuracy of account association at any given time.
+
If a server does not support extended-join, Eggdrop will not be able to determine the account associated with a user when they join. Eggdrop can update this information by sending a WHOX to the server.
+
If a server does not support account-notify, Eggdrop will not be able to determine the account assoicated with a user if they authenticate/deauthenticate from their account after joining a channel. Eggdrop can update this information by sending a WHOX to the server.
+
If a server does not support WHOX, Eggdrop will not be able to determine the accounts associated with users already on a channel before Eggdrop joined. There is no reliable way to update this information.
+
One workaround to significantly increase the accuracy of account tracking for scripts in a ‘best effort’ scenario would be to issue a WHOX query (assuming the server supports it), wait for the reply from the eserver, and then query for the account information.
One supplementary capability that can assist a best-effort account tracking scenario is the IRCv3-defined account-tag capability. The account-tag capability attaches a tag with the account name associated with the user sending a command. Enabling this capability allows Eggdrop to update its account tracking every time a user talks in channel, sets a mode, sends a kick, etc. While still not able to offer the same level of accuracy as enabling the “main three” account tracking features, it can increase the accuracy and can help with scripts that react to user commands/messages.
The Eggdrop Tcl ACCOUNT bind is triggered whenver an existing account record stored by Eggdrop is modified, such as a user de/authenticating to their account while in a channel, or information such as an account-tag being seen that updates an existing user. However, the ACCOUNT bind will NOT be triggered for the creation of a new user record, such as a user joining a channel. The bind is triggered for every channel the user is seen on- this means if a user is present with Eggdrop on four channels, the bind will be executed four times, each time with a different channel variable being passed to the associated Tcl procedure. Additionally, in a best-effort account tracking situation, Eggdrop will update the account associated with a user on all channels, not just the channel the event is seen on (and thus resulting in a bind trigger for each channel the user is on).
+
In order to trigger Tcl script events to cover all instances where a user logs in, you need to pair an ACCOUNT bind with a JOIN bind. This will allow you to execute account-based events when a user joins as well as if they authenticate after joining.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/doc/sphinx_source/index.rst b/doc/sphinx_source/index.rst
index 3f3eae599..dca64902a 100644
--- a/doc/sphinx_source/index.rst
+++ b/doc/sphinx_source/index.rst
@@ -61,6 +61,7 @@ The Eggheads development team can be found lurking on #eggdrop on the Libera net
using/ipv6
using/tls
using/ircv3
+ using/accounts
using/pbkdf2info
using/twitchinfo
using/tricks
diff --git a/doc/sphinx_source/using/accounts.rst b/doc/sphinx_source/using/accounts.rst
new file mode 100644
index 000000000..9791ca847
--- /dev/null
+++ b/doc/sphinx_source/using/accounts.rst
@@ -0,0 +1,81 @@
+Account tracking in Eggdrop
+===========================
+
+In Eggdrop 1.9.3, Eggdrop added the ability to associate nicknames with the service accounts they are logged into. It is IMPORTANT to note that Eggdrop's ability to do this is dependent on an IRC server's implementation of three features- the IRCv3 extended-join capability, the IRCv3 account-notify capability, and WHOX support. All three of these features must be supported by the server and, in the case of extended-join and account-notify, requested by Eggdrop in order for Eggdrop to maintain "perfect" association between nicknames and account statuses.
+
+Required Server Capabilities
+----------------------------
+You're going to see this repeated a lot- the IRC server must support three features in order for Eggdrop to accurately associate accounts with nicknames. These three features allow Eggdrop to always know the current association between an account and a nickname by getting account statuses of users already on a channel when it joins, new users joining a channel, and users who authenticate while on a channel.
+
+extended-join
+^^^^^^^^^^^^^
+`extended-join `_ is an IRCv3-defined capability that adds the account name of a user to the JOIN message sent by the IRC server, alerting clients that a new member has joined a channel. Enabling this capability allows Eggdrop to immediately determine the account name associated with a user joining a channel
+
+account-notify
+^^^^^^^^^^^^^^
+`account-notify `_ is an IRCv3-defined capability that sends a message to a channel when a member of the channel either authenticates or deauthenticates from their account. Enabling this capability allows Eggdrop to immediately associate an account to a channel member when they authenticate or deauthenticate.
+
+WHOX
+^^^^
+'WHOX `_ is a server feature that allows a client to request custom fields to be returned in a WHO response. If a server supports this capability, Eggdrop sends a WHOX query to the server when it joins a channel, allowing it to immediately determine accounts associated with channel members when Eggdrop joins a channel.
+
+Enabling Eggdrop Account Tracking
+---------------------------------
+By default, the Eggdrop config file will attempt to enable all the capabilities required for account tracking. There are two settings to pay attention to
+::
+
+ # To request the account-notify feature via CAP, set this to 1
+ set account-notify 1
+
+ # To request the extended-join feature via CAP, set this to 1
+ set extended-join 1
+
+The ability of a server to support WHOX queries is determined via a server's ISUPPORT (005) reply. If a server supports WHOX queries, Eggdrop will automatically enable this feature.
+
+Checking Account-tracking Status
+--------------------------------
+While Eggdrop is running, join the partyline and type `.status`. If account-tracking is enabled (both the server supports and Eggdrop has requested), you'll see this line
+::
+
+ Loaded module information:
+ #eggdroptest : (not on channel)
+ Channels: #eggdroptest (trying)
+ Account tracking: Enabled <--- This line
+ Online as: BeerBot (BeerBot)
+
+Otherwise, the prompt will tell you which required capability is missing/not enabled
+::
+
+ Loaded module information:
+ #eggdroptest : 2 members, enforcing "+tn" (greet)
+ Channels: #eggdroptest (need ops)
+ Account tracking: Best-effort (Missing capabilities: extended-join, see .status all for details) <---- This line
+ Online as: Eggdrop (Eggdrop)
+
+Determining if a Server Supports Account Capabilities
+-----------------------------------------------------
+A server announces the capabilities it supports via a CAP request. If you have Tcl enabled on the partyline (or via a raw message from a client), you can send `.tcl cap ls` and see if the extended-join and account-notify capabilities are supported by the server. If they are not listed, the server does not support it.
+
+A server announces if it supports WHOX via its ISUPPORT (005) announcement. If you have Tcl enabled on the partyline, you can send `.tcl issupport isset WHOX` and if it returns '1', WHOX is supported by the server.
+
+Best-Effort Account Tracking
+----------------------------
+If a server only supports some, but not all, of the required capabilities, Eggdrop will switch to 'best effort' account tracking. This means Eggdrop will update account statuses whenever it sees account information, but in this mode Eggdrop cannnot guarantee that all account associations are up to date.
+
+If a server does not support extended-join, Eggdrop will not be able to determine the account associated with a user when they join. Eggdrop can update this information by sending a WHOX to the server.
+
+If a server does not support account-notify, Eggdrop will not be able to determine the account assoicated with a user if they authenticate/deauthenticate from their account after joining a channel. Eggdrop can update this information by sending a WHOX to the server.
+
+If a server does not support WHOX, Eggdrop will not be able to determine the accounts associated with users already on a channel before Eggdrop joined. There is no reliable way to update this information.
+
+One workaround to significantly increase the accuracy of account tracking for scripts in a 'best effort' scenario would be to issue a WHOX query (assuming the server supports it), wait for the reply from the server, and then query for the account information.
+
+account-tag
+^^^^^^^^^^^
+One supplementary capability that can assist a best-effort account tracking scenario is the IRCv3-defined `account-tag capability `_. The account-tag capability attaches a tag with the account name associated with the user sending a command. Enabling this capability allows Eggdrop to update its account tracking every time a user talks in channel, sets a mode, sends a kick, etc. While still not able to offer the same level of accuracy as enabling the "main three" account tracking features, it can increase the overall accuracy of the account list. Additionally, binds that react to user activity (pub, kick, mode, etc) containing account-tag will update the internal account list prior to executing the associated callback, so looking up the account name in the callback can be considered accurate.
+
+Using Accounts with Tcl Scripts
+-------------------------------
+The Eggdrop Tcl ACCOUNT bind is triggered whenver an existing account record stored by Eggdrop is modified, such as a user de/authenticating to their account while in a channel, or information such as an account-tag being seen that updates an existing user. However, the ACCOUNT bind will NOT be triggered for the creation of a new user record, such as a user joining a channel. The bind is triggered for every channel the user is seen on- this means if a user is present with Eggdrop on four channels, the bind will be executed four times, each time with a different channel variable being passed to the associated Tcl procedure. Additionally, in a best-effort account tracking situation, Eggdrop will update the account associated with a user on all channels, not just the channel the event is seen on (and thus resulting in a bind trigger for each channel the user is on).
+
+In order to trigger Tcl script events to cover all instances where a user logs in, you need to pair an ACCOUNT bind with a JOIN bind. This will allow you to execute account-based events when a user joins as well as if they authenticate after joining.
diff --git a/doc/sphinx_source/using/tcl-commands.rst b/doc/sphinx_source/using/tcl-commands.rst
index ea19d7869..5d8aaa9ec 100644
--- a/doc/sphinx_source/using/tcl-commands.rst
+++ b/doc/sphinx_source/using/tcl-commands.rst
@@ -367,6 +367,8 @@ botattr [changes [channel]]
Module: core
+.. _matchattr:
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
matchattr [channel]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1372,7 +1374,7 @@ onchansplit [channel]
chanlist [flags][<&|>chanflags]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Description: flags are any global flags; the '&' or '\|' denotes to look for channel specific flags, where '&' will return users having ALL chanflags and '|' returns users having ANY of the chanflags (See matchattr above for additional examples).
+ Description: flags are any global flags; the '&' or '\|' denotes to look for channel specific flags, where '&' will return users having ALL chanflags and '|' returns users having ANY of the chanflags (See matchattr_ above for additional examples).
Returns: Searching for flags optionally preceded with a '+' will return a list of nicknames that have all the flags listed. Searching for flags preceded with a '-' will return a list of nicknames that do not have have any of the flags (differently said, '-' will hide users that have all flags listed). If no flags are given, all of the nicknames on the channel are returned.
@@ -2357,8 +2359,7 @@ timer [count [timerName]]
utimer [count [timerName]]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Description: executes the given Tcl command after a certain number of seconds have passed. If count is specified, the command will be executed count times with the given interval in between. If you specify a count of 0, the utimer will repeat until it's removed with killutimer or until the bot is restarted. If timerName is specified, it will become the unique identifier for the timer. If no timer
-Name is specified, Eggdrop will assign a timerName in the format of "timer".
+ Description: executes the given Tcl command after a certain number of seconds have passed. If count is specified, the command will be executed count times with the given interval in between. If you specify a count of 0, the utimer will repeat until it's removed with killutimer or until the bot is restarted. If timerName is specified, it will become the unique identifier for the timer. If no timerName is specified, Eggdrop will assign a timerName in the format of "timer".
Returns: a timerName
@@ -2908,23 +2909,24 @@ language
Binds
-----
-You can use the 'bind' command to attach Tcl procedures to certain events.
-For example, you can write a Tcl procedure that gets called every time a
-user says "danger" on the channel.
+You can use the 'bind' command to attach Tcl procedures to certain events. For example, you can write a Tcl procedure that gets called every time a user says "danger" on the channel. When a bind is triggered, ALL of the Tcl procs that are bound to it will be called. Raw binds are triggered before builtin binds, as a builtin bind has the potential to modify args.
-Some bind types are marked as "stackable". That means that you can bind
-multiple commands to the same trigger. Normally, for example, a bind such
-as 'bind msg - stop msg:stop' (which makes a msg-command "stop" call the
-Tcl proc "msg:stop") will overwrite any previous binding you had for the
-msg command "stop". With stackable bindings, like 'msgm' for example,
-you can bind the same command to multiple procs. When the bind is triggered,
-ALL of the Tcl procs that are bound to it will be called. Raw binds are
-triggered before builtin binds, as a builtin bind has the potential to
-modify args.
+^^^^^^^^^^^^^^^
+Stackable binds
+^^^^^^^^^^^^^^^
+Some bind types are marked as "stackable". That means that you can bind multiple commands to the same trigger. Normally, for example, a bind such as 'bind msg - stop msg:stop' (which makes a msg-command "stop" call the Tcl proc "msg:stop") will overwrite any previous binding you had for the msg command "stop". With stackable bindings, like 'msgm' for example, you can bind the same command to multiple procs.
+^^^^^^^^^^^^^^^
+Removing a bind
+^^^^^^^^^^^^^^^
To remove a bind, use the 'unbind' command. For example, to remove the
bind for the "stop" msg command, use 'unbind msg - stop msg:stop'.
+^^^^^^^^^^
+Flag Masks
+^^^^^^^^^^
+In the next section, you will see several references to "flags". The "flags" argument is a value that represents the type of user that is allowed to trigger the procedure associated to that bind. The flags can be any of the standard Eggdrop flags (o, m, v, etc), or a "-" or "*" can be used to denote "any user". For example, a flag mask of "ov" would allow a bind to be triggered by a user added to Eggdrop with either the o or v global flags. A flag mask of of "-\|m" would allow a bind to be triggered by a user with the m channel flag. For more advanced information on how flag matching works, please see the matchattr_ description.
+
^^^^^^^^^^
Bind Types
^^^^^^^^^^
@@ -3528,7 +3530,7 @@ The following is a list of bind types and how they work. Below each bind type is
procname
- Description: this bind will trigger when eggdrop detects a change in the authentication status of a user's service account. The mask for the bind is in the format "#channel nick!user@hostname.com account" and accepts :ref:`Match Characters`. account is either the account name the user is logging in to or "*" if the user is not logged in to an account.
+ Description: this bind will trigger when eggdrop detects a change in the authentication status of a user's service account. The mask for the bind is in the format "#channel nick!user@hostname.com account" and accepts wildcards_. account is either the account name the user is logging in to or "*" if the user is not logged in to an account.
NOTE: the three required IRC components for account tracking are: the WHOX feature, the extended-join IRCv3 capability and the account-notify IRCv3 capability. if only some of the three feature are available, eggdrop provides best-effort account tracking but this bind could be triggered late or never on account changes. Please see doc/ACCOUNTS for additional information.
@@ -3702,6 +3704,8 @@ Secure connection can be also established after a connection is active. You can
The best way to learn how to use these commands is to find a script that uses them and follow it carefully. However, hopefully this has given you a good start.
+.. _wildcards:
+
Match Characters
----------------
diff --git a/eggdrop.conf b/eggdrop.conf
index f1ccfd7b8..81e35bfe9 100755
--- a/eggdrop.conf
+++ b/eggdrop.conf
@@ -1172,7 +1172,7 @@ set extended-join 1
# To request the account-tag feature via CAP, set this to 1
# This can be enabled if necessary for imperfect account tracking if you don't
# have the WHOX (use_354), account-notify and extended-join features available
-# see doc/ACCOUNT for details
+# see doc/ACCOUNTS for details
#set account-tag 0
# If you have any additional CAP features you would like to request at
diff --git a/misc/generatedocs b/misc/generatedocs
index 11c09761c..fd07980ac 100755
--- a/misc/generatedocs
+++ b/misc/generatedocs
@@ -143,6 +143,7 @@ mv tmpdocs/tls.txt $BASEDIR/../doc/TLS
mv tmpdocs/tricks.txt $BASEDIR/../doc/TRICKS
mv tmpdocs/twitchinfo.txt $BASEDIR/../doc/TWITCH
mv tmpdocs/users.txt $BASEDIR/../doc/USERS
+mv tmpdocs/accounts.txt $BASEDIR/../doc/ACCOUNTS
rm -rf tmpdocs
rm -rf $BASEDIR/../doc/html/_sources
rm -rf $BASEDIR/../doc/doctrees/
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index ae5eeaa87..c7677706a 100644
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
@@ -1110,7 +1110,7 @@ static void tell_account_tracking_status(int idx, int details)
if (tag && (!whox || !notify || !extjoin)) {
dprintf(idx, "%s", " - account-tag enabled => Accounts will update whenever someone messages a channel or this bot\n");
}
- dprintf(idx, "%s", " See doc/ACCOUNT for more details\n");
+ dprintf(idx, "%s", " See doc/ACCOUNTS for more details\n");
}
}
}
From 8441b39d19f717544ea02a4a76afdebd7dd0aa22 Mon Sep 17 00:00:00 2001
From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com>
Date: Tue, 27 Sep 2022 01:19:53 +0000
Subject: [PATCH 09/92] Fix format specifier for intptr_t
Found by: michaelortmann
Patch by: michaelortmann
Fix format specifier for intptr_t with c99 PRIdPTR that were shadowed by the use of egg_snprintf() and simple_sprintf() / use snprintf() for all getudef()
---
src/mod/channels.mod/tclchan.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/mod/channels.mod/tclchan.c b/src/mod/channels.mod/tclchan.c
index 66143963e..06b33b8d3 100644
--- a/src/mod/channels.mod/tclchan.c
+++ b/src/mod/channels.mod/tclchan.c
@@ -974,14 +974,14 @@ static int tcl_channel_info(Tcl_Interp *irp, struct chanset_t *chan)
continue;
if (ul->type == UDEF_FLAG) {
- simple_sprintf(s, "%c%s", getudef(ul->values, chan->dname) ? '+' : '-',
- ul->name);
+ snprintf(s, sizeof s, "%c%s",
+ getudef(ul->values, chan->dname) ? '+' : '-', ul->name);
Tcl_AppendElement(irp, s);
} else if (ul->type == UDEF_INT) {
char *x;
egg_snprintf(a, sizeof a, "%s", ul->name);
- egg_snprintf(b, sizeof b, "%d", getudef(ul->values, chan->dname));
+ snprintf(b, sizeof b, "%" PRIdPTR, getudef(ul->values, chan->dname));
args[0] = a;
args[1] = b;
x = Tcl_Merge(2, args);
@@ -1120,7 +1120,7 @@ static int tcl_channel_getlist(Tcl_Interp *irp, struct chanset_t *chan)
APPEND_KEYVAL(ul->name, argv[0]);
Tcl_Free((char *) argv);
} else {
- simple_sprintf(s, "%d", getudef(ul->values, chan->dname));
+ snprintf(s, sizeof s, "%" PRIdPTR, getudef(ul->values, chan->dname));
APPEND_KEYVAL(ul->name, s);
}
}
@@ -1228,7 +1228,7 @@ static int tcl_channel_get(Tcl_Interp *irp, struct chanset_t *chan,
Tcl_Free((char *) argv);
} else {
/* Flag or int, all the same. */
- simple_sprintf(s, "%d", getudef(ul->values, chan->dname));
+ snprintf(s, sizeof s, "%" PRIdPTR, getudef(ul->values, chan->dname));
Tcl_AppendResult(irp, s, NULL);
}
return TCL_OK;
From 36f0b83d6b6fb735d457794ee82c0aef9b6da165 Mon Sep 17 00:00:00 2001
From: Jonathan Rudolph
Date: Mon, 26 Sep 2022 18:25:00 -0700
Subject: [PATCH 10/92] doc typo
Found by: SpiKe^^
Patch by: simple
---
doc/sphinx_source/using/tcl-commands.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx_source/using/tcl-commands.rst b/doc/sphinx_source/using/tcl-commands.rst
index 5d8aaa9ec..360997675 100644
--- a/doc/sphinx_source/using/tcl-commands.rst
+++ b/doc/sphinx_source/using/tcl-commands.rst
@@ -2359,7 +2359,7 @@ timer [count [timerName]]
utimer [count [timerName]]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Description: executes the given Tcl command after a certain number of seconds have passed. If count is specified, the command will be executed count times with the given interval in between. If you specify a count of 0, the utimer will repeat until it's removed with killutimer or until the bot is restarted. If timerName is specified, it will become the unique identifier for the timer. If no timerName is specified, Eggdrop will assign a timerName in the format of "timer".
+ Description: executes the given Tcl command after a certain number of seconds have passed. If count is specified, the command will be executed count times with the given interval in between. If you specify a count of 0, the utimer will repeat until it's removed with killutimer or until the bot is restarted. If timerName is specified, it will become the unique identifier for the timer. If timerName is not specified, Eggdrop will assign a timerName in the format of "timer".
Returns: a timerName
From 9067ae8e7b8be46f85cfda65e7b1cde6c8a38a4b Mon Sep 17 00:00:00 2001
From: crazycatdevs <44431938+crazycatdevs@users.noreply.github.com>
Date: Tue, 27 Sep 2022 03:26:26 +0200
Subject: [PATCH 11/92] Update doc typo
A botnet needs at least 2 eggdrops!
---
doc/sphinx_source/using/botnet.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/sphinx_source/using/botnet.rst b/doc/sphinx_source/using/botnet.rst
index 748f38649..7dea0d324 100644
--- a/doc/sphinx_source/using/botnet.rst
+++ b/doc/sphinx_source/using/botnet.rst
@@ -12,7 +12,7 @@ Botnet Sharing and Linking
What is a botnet?
-----------------
- A botnet consists of one or more bots linked together. This can allow bots to op each other securely, control floods efficiently, and share user lists, ban lists, exempt/invite lists, and ignore lists (if sharing is enabled).
+ A botnet consists of two or more bots linked together. This can allow bots to op each other securely, control floods efficiently, and share user lists, ban lists, exempt/invite lists, and ignore lists (if sharing is enabled).
Terms
-----
@@ -20,7 +20,7 @@ Terms
The following are some common terms used in this document:
**Botnet**
- A botnet consists of one or more bots connected together.
+ A botnet consists of two or more bots connected together.
**Link**
Link is the term used to describe a bot connecting to another bot.
From 9bf8ad4955cbcc294382527393bc94f0e8cc2dc1 Mon Sep 17 00:00:00 2001
From: crazycatdevs <44431938+crazycatdevs@users.noreply.github.com>
Date: Tue, 27 Sep 2022 03:32:33 +0200
Subject: [PATCH 12/92] Update install doc
Found by: CrazyCatDevs
Patch by: CrazyCatDevs
step 5 must be done in source directory, not in eggdrop directory
---
doc/sphinx_source/install/install.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/sphinx_source/install/install.rst b/doc/sphinx_source/install/install.rst
index c571908ad..4425949be 100644
--- a/doc/sphinx_source/install/install.rst
+++ b/doc/sphinx_source/install/install.rst
@@ -56,8 +56,6 @@ Eggdrop uses the GNU autoconfigure scripts to make things easier.
Note that you must use full path for every file to be correctly
installed.
- [The following is performed from the directory installed above.]
-
5. Since version 1.8, Eggdrop can use SSL to protect botnet links. If you intend on protecting botnet traffic between Eggdrops, you must generate SSL certificates by running::
make sslcert
@@ -74,6 +72,8 @@ Eggdrop uses the GNU autoconfigure scripts to make things easier.
Read docs/TLS for more info on this process.
+[The following steps are performed in the directory you just installed Eggdrop into from the preevious step]
+
6. Edit your config file completely.
7. Start the bot with the "-m" option to create a user file, i.e. ::
From 28539baa33eb18f385a389b25759a408e287ff6f Mon Sep 17 00:00:00 2001
From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com>
Date: Tue, 27 Sep 2022 01:36:02 +0000
Subject: [PATCH 13/92] Fix typos
---
NEWS | 2 +-
doc/html/install/upgrading.html | 2 +-
doc/sphinx_source/modules/mod/filesys.rst | 2 +-
doc/sphinx_source/modules/mod/irc.rst | 2 +-
src/language.c | 2 +-
src/mod/filesys.mod/help/filesys.help | 2 +-
src/mod/irc.mod/chan.c | 2 +-
src/mod/irc.mod/irc.c | 2 +-
src/tclhash.c | 2 +-
9 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/NEWS b/NEWS
index f465fa4e1..e0dbe26b2 100644
--- a/NEWS
+++ b/NEWS
@@ -204,7 +204,7 @@ Eggdrop v1.9.0:
with 'refreshchan w', described above.
- Added the hand2nicks command, an alternative to the hand2nick command.
hand2nicks returns ALL nicks matching a handle, not just the first one.
- - Aded the socklist command, an update to the dcclist command. Returns
+ - Added the socklist command, an update to the dcclist command. Returns
similar info as a Tcl dict, and adds the IP to the information.
- Use the system's strftime formatting instead of Eggdrop-provided
GNU version/extensions. This could cause formatting differences
diff --git a/doc/html/install/upgrading.html b/doc/html/install/upgrading.html
index a2789a6a6..3ad768398 100644
--- a/doc/html/install/upgrading.html
+++ b/doc/html/install/upgrading.html
@@ -105,7 +105,7 @@
It is easy to upgrade Eggdrop to a new version! To have a full picture of the changes made since your last upgrade, we recommed reading the NEWS file. Upgrades from the 1.6 and 1.8 lines of Eggdrop should take place with little to no issues. The config file, user files, and channel files can all be reused.
+
It is easy to upgrade Eggdrop to a new version! To have a full picture of the changes made since your last upgrade, we recommend reading the NEWS file. Upgrades from the 1.6 and 1.8 lines of Eggdrop should take place with little to no issues. The config file, user files, and channel files can all be reused.
For support, feel free to visit us on Libera #eggdrop.
diff --git a/doc/sphinx_source/modules/mod/filesys.rst b/doc/sphinx_source/modules/mod/filesys.rst
index 310f444a5..460b2e39c 100644
--- a/doc/sphinx_source/modules/mod/filesys.rst
+++ b/doc/sphinx_source/modules/mod/filesys.rst
@@ -222,7 +222,7 @@ rm [files] ...
Cleans up the current directory's database. If you have a large
directory with many files you may want to use this command if
you experience slow-downs/delays over time. Normally, the db
- should clean up itsself though.
+ should clean up itself though.
^^^^^^^
.unhide
diff --git a/doc/sphinx_source/modules/mod/irc.rst b/doc/sphinx_source/modules/mod/irc.rst
index 14397d4b4..1955d3174 100644
--- a/doc/sphinx_source/modules/mod/irc.rst
+++ b/doc/sphinx_source/modules/mod/irc.rst
@@ -84,7 +84,7 @@ There are also some variables you can set in your config file:
| bind msg - myword \*msg:hello
Many IRCops find bots by seeing if they reply to 'hello' in a msg. You
- can change this to another word by un-commenting thse two lines and
+ can change this to another word by un-commenting these two lines and
changing "myword" to the word wish to use instead of'hello'. It must be
a single word.
diff --git a/src/language.c b/src/language.c
index 7a7b4fb53..252f7a43f 100644
--- a/src/language.c
+++ b/src/language.c
@@ -44,7 +44,7 @@
* FILE FORMAT: language.lang
* ,
* TEXT MESSAGE USAGE:
- * get_language( [,])
+ * get_language( [,])
*
* ADDING LANGUAGES:
* o Copy an existing ..lang to a
diff --git a/src/mod/filesys.mod/help/filesys.help b/src/mod/filesys.mod/help/filesys.help
index e7188d397..bcd7f0760 100644
--- a/src/mod/filesys.mod/help/filesys.help
+++ b/src/mod/filesys.mod/help/filesys.help
@@ -167,7 +167,7 @@ see also: unshare, lsa, ln
cleans up the current directory's database. if you have a large
directory with many files you may want to use this command if
you experience slow-downs/delays over time. normally, the db
- should clean up itsself though.
+ should clean up itself though.
%{help=filesys/sort}%{+j}
### %bsort%b
this command is obsolete, because the directory is always
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index 94776aed6..e16e85527 100644
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
@@ -1892,7 +1892,7 @@ static int gotinvite(char *from, char *msg)
check_tcl_invite(nick, from, msg, invitee);
/* Because who needs RFCs? Freakin IRCv3... */
if (!match_my_nick(invitee)) {
- putlog(LOG_DEBUG, "*", "Received invite notifiation for %s to %s by %s.",
+ putlog(LOG_DEBUG, "*", "Received invite notification for %s to %s by %s.",
invitee, msg, nick);
return 1;
}
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index c7677706a..3d1c96153 100644
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
@@ -460,7 +460,7 @@ void reset_chan_info(struct chanset_t *chan, int reset, int do_reset)
}
/* Leave the specified channel and notify registered Tcl procs. This
- * should not be called by itsself.
+ * should not be called by itself.
*/
static void do_channel_part(struct chanset_t *chan)
{
diff --git a/src/tclhash.c b/src/tclhash.c
index 5266cfcb7..71d35f6c2 100644
--- a/src/tclhash.c
+++ b/src/tclhash.c
@@ -935,7 +935,7 @@ int check_tcl_bind(tcl_bind_list_t *tl, const char *match,
if (tm_p && tm_p->next) {
tm = tm_p->next; /* Move mask to front of bind's mask list. */
tm_p->next = tm->next; /* Unlink mask from list. */
- tm->next = tl->first; /* Readd mask to front of list. */
+ tm->next = tl->first; /* Re-add mask to front of list. */
tl->first = tm;
}
From d50aa08b39603b4be0fd0179db7f94da48e03720 Mon Sep 17 00:00:00 2001
From: PeGaSuS
Date: Sat, 1 Oct 2022 16:01:03 +0200
Subject: [PATCH 14/92] Fix typo
---
doc/sphinx_source/install/install.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx_source/install/install.rst b/doc/sphinx_source/install/install.rst
index 4425949be..ece05c0e4 100644
--- a/doc/sphinx_source/install/install.rst
+++ b/doc/sphinx_source/install/install.rst
@@ -72,7 +72,7 @@ Eggdrop uses the GNU autoconfigure scripts to make things easier.
Read docs/TLS for more info on this process.
-[The following steps are performed in the directory you just installed Eggdrop into from the preevious step]
+[The following steps are performed in the directory you just installed Eggdrop into from the previous step]
6. Edit your config file completely.
From b3b658b26e5442762f22423ab013a28b481d759d Mon Sep 17 00:00:00 2001
From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com>
Date: Sat, 1 Oct 2022 14:03:20 +0000
Subject: [PATCH 15/92] Fix typos
---
doc/sphinx_source/using/accounts.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/sphinx_source/using/accounts.rst b/doc/sphinx_source/using/accounts.rst
index 9791ca847..6d1b96128 100644
--- a/doc/sphinx_source/using/accounts.rst
+++ b/doc/sphinx_source/using/accounts.rst
@@ -60,11 +60,11 @@ A server announces if it supports WHOX via its ISUPPORT (005) announcement. If y
Best-Effort Account Tracking
----------------------------
-If a server only supports some, but not all, of the required capabilities, Eggdrop will switch to 'best effort' account tracking. This means Eggdrop will update account statuses whenever it sees account information, but in this mode Eggdrop cannnot guarantee that all account associations are up to date.
+If a server only supports some, but not all, of the required capabilities, Eggdrop will switch to 'best effort' account tracking. This means Eggdrop will update account statuses whenever it sees account information, but in this mode Eggdrop cannot guarantee that all account associations are up to date.
If a server does not support extended-join, Eggdrop will not be able to determine the account associated with a user when they join. Eggdrop can update this information by sending a WHOX to the server.
-If a server does not support account-notify, Eggdrop will not be able to determine the account assoicated with a user if they authenticate/deauthenticate from their account after joining a channel. Eggdrop can update this information by sending a WHOX to the server.
+If a server does not support account-notify, Eggdrop will not be able to determine the account associated with a user if they authenticate/deauthenticate from their account after joining a channel. Eggdrop can update this information by sending a WHOX to the server.
If a server does not support WHOX, Eggdrop will not be able to determine the accounts associated with users already on a channel before Eggdrop joined. There is no reliable way to update this information.
@@ -76,6 +76,6 @@ One supplementary capability that can assist a best-effort account tracking scen
Using Accounts with Tcl Scripts
-------------------------------
-The Eggdrop Tcl ACCOUNT bind is triggered whenver an existing account record stored by Eggdrop is modified, such as a user de/authenticating to their account while in a channel, or information such as an account-tag being seen that updates an existing user. However, the ACCOUNT bind will NOT be triggered for the creation of a new user record, such as a user joining a channel. The bind is triggered for every channel the user is seen on- this means if a user is present with Eggdrop on four channels, the bind will be executed four times, each time with a different channel variable being passed to the associated Tcl procedure. Additionally, in a best-effort account tracking situation, Eggdrop will update the account associated with a user on all channels, not just the channel the event is seen on (and thus resulting in a bind trigger for each channel the user is on).
+The Eggdrop Tcl ACCOUNT bind is triggered whenever an existing account record stored by Eggdrop is modified, such as a user de/authenticating to their account while in a channel, or information such as an account-tag being seen that updates an existing user. However, the ACCOUNT bind will NOT be triggered for the creation of a new user record, such as a user joining a channel. The bind is triggered for every channel the user is seen on- this means if a user is present with Eggdrop on four channels, the bind will be executed four times, each time with a different channel variable being passed to the associated Tcl procedure. Additionally, in a best-effort account tracking situation, Eggdrop will update the account associated with a user on all channels, not just the channel the event is seen on (and thus resulting in a bind trigger for each channel the user is on).
In order to trigger Tcl script events to cover all instances where a user logs in, you need to pair an ACCOUNT bind with a JOIN bind. This will allow you to execute account-based events when a user joins as well as if they authenticate after joining.
From 55595ab28935a1c2f29ed558a89b225e9ea31bce Mon Sep 17 00:00:00 2001
From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com>
Date: Wed, 5 Oct 2022 23:41:41 +0000
Subject: [PATCH 16/92] Avoid freeaddrinfo(NULL)
Found by: Release_
Patch by: michaelortmann
Fixes: #1329
The behavior of freeadrinfo(NULL) is left unspecified by RFC 3493. Some Operating Systems like FreeBSD handle this for compatibility / portability but others like OpenBSD do not (as reported in #1329), so let eggdrop avoid calling freeadrinfo(NULL).
---
src/dns.c | 27 +++++++++++++++++----------
src/tcldcc.c | 20 ++++++++++++++------
2 files changed, 31 insertions(+), 16 deletions(-)
diff --git a/src/dns.c b/src/dns.c
index 39fb49973..6d5c67f79 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -503,6 +503,7 @@ void *thread_dns_hostbyip(void *arg)
i = getnameinfo((const struct sockaddr *) &addr->addr.sa, addr->addrlen,
dtn->host, sizeof dtn->host, NULL, 0, 0);
if (i) {
+ debug1("dns: thread_dns_hostbyip(): getnameinfo(): error = %s", gai_strerror(i));
#ifdef IPV6
if (addr->family == AF_INET6)
inet_ntop(AF_INET6, &addr->addr.s6.sin6_addr, dtn->host, sizeof dtn->host);
@@ -520,13 +521,13 @@ void *thread_dns_hostbyip(void *arg)
void *thread_dns_ipbyhost(void *arg)
{
struct dns_thread_node *dtn = (struct dns_thread_node *) arg;
- struct addrinfo *res0, *res;
- int i;
+ struct addrinfo *res0 = NULL, *res;
+ int error;
sockname_t *addr = &dtn->addr;
- i = getaddrinfo(dtn->host, NULL, NULL, &res0);
+ error = getaddrinfo(dtn->host, NULL, NULL, &res0);
memset(addr, 0, sizeof *addr);
- if (!i) {
+ if (!error) {
#ifdef IPV6
for (res = res0; res; res = res->ai_next) {
if (res == res0 || res->ai_family == (pref_af ? AF_INET6 : AF_INET)) {
@@ -538,21 +539,27 @@ void *thread_dns_ipbyhost(void *arg)
}
}
#else
- i = 1;
+ error = 1;
for (res = res0; res; res = res->ai_next) {
if (res->ai_family == AF_INET) {
addr->family = res->ai_family;
addr->addrlen = res->ai_addrlen;
memcpy(&addr->addr.sa, res->ai_addr, res->ai_addrlen);
- i = 0;
+ error = 0;
break;
}
}
#endif
- freeaddrinfo(res0);
+ if (res0) /* The behavior of freeadrinfo(NULL) is left unspecified by RFCs
+ * 2553 and 3493. Avoid to be compatible with all OSes. */
+ freeaddrinfo(res0);
}
+ else if (error == EAI_NONAME)
+ debug1("dns: thread_dns_ipbyhost(): getaddrinfo(): hostname %s not known", dtn->host);
+ else
+ debug1("dns: thread_dns_ipbyhost(): getaddrinfo(): error = %s", gai_strerror(error));
pthread_mutex_lock(&dtn->mutex);
- dtn->ok = !i;
+ dtn->ok = !error;
close(dtn->fildes[1]);
pthread_mutex_unlock(&dtn->mutex);
return NULL;
@@ -661,7 +668,7 @@ void core_dns_hostbyip(sockname_t *addr)
sizeof (struct sockaddr_in), host, sizeof host, NULL, 0, 0);
alarm(0);
if (i)
- debug1("dns: getnameinfo(): error = %s", gai_strerror(i));
+ debug1("dns: core_dns_hostbyip(): getnameinfo(): error = %s", gai_strerror(i));
}
if (i)
inet_ntop(AF_INET, &addr->addr.s4.sin_addr.s_addr, host, sizeof host);
@@ -673,7 +680,7 @@ void core_dns_hostbyip(sockname_t *addr)
sizeof (struct sockaddr_in6), host, sizeof host, NULL, 0, 0);
alarm(0);
if (i)
- debug1("dns: getnameinfo(): error = %s", gai_strerror(i));
+ debug1("dns: core_dns_hostbyip(): getnameinfo(): error = %s", gai_strerror(i));
}
if (i)
inet_ntop(AF_INET6, &addr->addr.s6.sin6_addr, host, sizeof host);
diff --git a/src/tcldcc.c b/src/tcldcc.c
index e54fec2de..6a7702b29 100644
--- a/src/tcldcc.c
+++ b/src/tcldcc.c
@@ -1028,13 +1028,12 @@ static int tcl_connect STDVAR
}
static int setlisten(Tcl_Interp *irp, char *ip, char *portp, char *type, char *maskproc, char *flag) {
- int i, idx = -1, port, realport, found=0, ipv4=1;
+ int i, idx = -1, port, realport, found=0, ipv4=1, error;
char s[11], msg[256], newip[EGG_INET_ADDRSTRLEN];
struct portmap *pmap = NULL, *pold = NULL;
sockname_t name;
struct in_addr ipaddr4;
struct addrinfo hint, *ipaddr = NULL;
- int ret;
#ifdef IPV6
struct in6_addr ipaddr6;
#endif
@@ -1056,8 +1055,8 @@ static int setlisten(Tcl_Interp *irp, char *ip, char *portp, char *type, char *m
strlcpy(newip, ip, sizeof newip);
}
/* Return addrinfo struct ipaddr containing family... */
- ret = getaddrinfo(newip, NULL, &hint, &ipaddr);
- if (!ret) {
+ error = getaddrinfo(newip, NULL, &hint, &ipaddr);
+ if (!error) {
/* Load network address to in(6)_addr struct for later byte comparisons */
if (ipaddr->ai_family == AF_INET) {
inet_pton(AF_INET, newip, &ipaddr4);
@@ -1068,8 +1067,17 @@ static int setlisten(Tcl_Interp *irp, char *ip, char *portp, char *type, char *m
ipv4 = 0;
}
#endif
+ if (ipaddr) /* The behavior of freeadrinfo(NULL) is left unspecified by RFCs
+ * 2553 and 3493. Avoid to be compatible with all OSes. */
+ freeaddrinfo(ipaddr);
}
- freeaddrinfo(ipaddr);
+ else if (error == EAI_NONAME)
+ /* currently setlisten() handles only ip not hostname */
+ putlog(LOG_MISC, "*",
+ "tcldcc: setlisten(): getaddrinfo(): ip %s not known", newip);
+ else
+ putlog(LOG_MISC, "*", "tcldcc: setlisten(): getaddrinfo(): error = %s",
+ gai_strerror(error));
port = realport = atoi(portp);
for (pmap = root; pmap; pold = pmap, pmap = pmap->next) {
if (pmap->realport == port) {
@@ -1282,7 +1290,7 @@ static int tcl_listen STDVAR
strlcpy(ip, argv[1], sizeof(ip));
i++;
} else {
- Tcl_AppendResult(irp, "invalid ip address", NULL);
+ Tcl_AppendResult(irp, "invalid IP address argument", NULL);
return TCL_ERROR;
}
}
From d0cb5ff0b9eac51fa84cb189b633b3948ed14b6d Mon Sep 17 00:00:00 2001
From: Thomas Sader
Date: Thu, 10 Nov 2022 18:06:04 +0100
Subject: [PATCH 17/92] Fix matchattr without flags
Fixes: #1267
The matchattr/bind flag string "-" or "-|-" is commonly used to match "anyone".
It isn't a real match because there are no flags specified so there is nothing
to match. - and | are just meta-characters that don't parse to modes that can match.
Found by: crazycatdevs
Patch by: thommey
---
src/tcluser.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/tcluser.c b/src/tcluser.c
index 85e5587aa..987a0e6dc 100644
--- a/src/tcluser.c
+++ b/src/tcluser.c
@@ -269,8 +269,9 @@ static int tcl_matchattr STDVAR
nom = 1;
if (!plus.global && !plus.udef_global && !plus.chan &&
!plus.udef_chan && !plus.bot) {
- Tcl_AppendResult(irp, "Unknown flag specified for matching", NULL);
- return TCL_ERROR;
+ /* No flags (e.g. "-" or "+" or "-|-" matches anyone */
+ Tcl_AppendResult(irp, "1", NULL);
+ return TCL_OK;
}
}
if (flagrec_eq(&plus, &user)) {
From 56c00e51e5e668543fe539cc001b30c7c2dc812a Mon Sep 17 00:00:00 2001
From: Geo
Date: Thu, 10 Nov 2022 12:07:00 -0500
Subject: [PATCH 18/92] redo matching docs
Linked to #1334
---
doc/sphinx_source/using/tcl-commands.rst | 89 +++++++++++++-----------
src/flags.c | 2 +-
2 files changed, 49 insertions(+), 42 deletions(-)
diff --git a/doc/sphinx_source/using/tcl-commands.rst b/doc/sphinx_source/using/tcl-commands.rst
index 360997675..e4dacf9ea 100644
--- a/doc/sphinx_source/using/tcl-commands.rst
+++ b/doc/sphinx_source/using/tcl-commands.rst
@@ -367,8 +367,6 @@ botattr [changes [channel]]
Module: core
-.. _matchattr:
-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
matchattr [channel]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -377,43 +375,7 @@ matchattr [channel]
[+/-][&/|[&/|]]
- Either | or & can be used as a separator between global, channel, and bot flags, but only one separator can be used per flag section. A '+' is used to check if a user has the subsequent flags, and a '-' is used to check if a user does NOT have the subsequent flags.
-
-+------------+-----------------------------------------------------------------+
-| Flag Mask | Action |
-+============+=================================================================+
-| +m + Checks if the user has the m global flag |
-+------------+-----------------------------------------------------------------+
-| +mn | Checks if the user has the m OR n global flag |
-+------------+-----------------------------------------------------------------+
-| \|+mn | Checks if the user has the m OR n global flag |
-+------------+-----------------------------------------------------------------+
-| \|+mn #foo | Checks if the user has the m OR n channel flag for #foo |
-+------------+-----------------------------------------------------------------+
-| &+mn | Checks if the user has the m AND n global flag |
-+------------+-----------------------------------------------------------------+
-| &mn #foo | Checks if the user has the m AND n channel flag for #foo |
-+------------+-----------------------------------------------------------------+
-| \|+o #foo | Checks if the user has the o channel flag for #foo |
-+------------+-----------------------------------------------------------------+
-| +o|+n #foo | Checks if the user has the o global flag OR the n channel flag |
-| | for #foo |
-+------------+-----------------------------------------------------------------+
-| +m&+v #foo | Checks if the user has the m global flag AND the v channel flag |
-| | for #foo |
-+------------+-----------------------------------------------------------------+
-| -m | Checks if the user does not have the m global flag |
-+------------+-----------------------------------------------------------------+
-| \|-n #foo | Checks if the user does not have the n channel flag for #foo |
-+------------+-----------------------------------------------------------------+
-| +m|-n #foo | Checks if the user has the global m flag OR does not have a |
-| | channel n flag for #foo |
-+------------+-----------------------------------------------------------------+
-| -n&-m #foo | Checks if the user does not have the global n flag AND does |
-| | not have the channel m flag for #foo |
-+------------+-----------------------------------------------------------------+
-| ||+b | Checks if the user has the bot flag b |
-+------------+-----------------------------------------------------------------+
+ Either | or & can be used as a separator between global, channel, and bot flags, but only one separator can be used per flag section. A '+' is used to check if a user has the subsequent flags, and a '-' is used to check if a user does NOT have the subsequent flags. Please see `Flag Masks`_ for additional information on flag usage.
Returns: 1 if the specified user has the flags matching the provided mask; 0 otherwise
@@ -1374,7 +1336,7 @@ onchansplit [channel]
chanlist [flags][<&|>chanflags]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Description: flags are any global flags; the '&' or '\|' denotes to look for channel specific flags, where '&' will return users having ALL chanflags and '|' returns users having ANY of the chanflags (See matchattr_ above for additional examples).
+ Description: flags are any global flags; the '&' or '\|' denotes to look for channel specific flags, where '&' will return users having ALL chanflags and '|' returns users having ANY of the chanflags (See `Flag Masks`_ for additional information).
Returns: Searching for flags optionally preceded with a '+' will return a list of nicknames that have all the flags listed. Searching for flags preceded with a '-' will return a list of nicknames that do not have have any of the flags (differently said, '-' will hide users that have all flags listed). If no flags are given, all of the nicknames on the channel are returned.
@@ -2922,10 +2884,55 @@ Removing a bind
To remove a bind, use the 'unbind' command. For example, to remove the
bind for the "stop" msg command, use 'unbind msg - stop msg:stop'.
+
^^^^^^^^^^
Flag Masks
^^^^^^^^^^
-In the next section, you will see several references to "flags". The "flags" argument is a value that represents the type of user that is allowed to trigger the procedure associated to that bind. The flags can be any of the standard Eggdrop flags (o, m, v, etc), or a "-" or "*" can be used to denote "any user". For example, a flag mask of "ov" would allow a bind to be triggered by a user added to Eggdrop with either the o or v global flags. A flag mask of of "-\|m" would allow a bind to be triggered by a user with the m channel flag. For more advanced information on how flag matching works, please see the matchattr_ description.
+In the `Bind Types`_ section (and other commands, such as `matchattr`_), you will see several references to the "flags" argument. The "flags" argument takes a flag mask, which is a value that represents the type of user that is allowed to trigger the procedure associated to that bind. The flags can be any of the standard Eggdrop flags (o, m, v, etc). Additionally, when used by itself, a "-" or "*" can be used to skip processing for a flag type. A flag mask has three sections to it- global, channel, and bot flag sections. Each section is separated by the | or & logical operators ( the | means "OR" and the & means "AND; if nothing proceeds the flag then Eggdrop assumes it to be an OR). Additionally, a '+' and '-' can be used in front of a flag to check if the user does (+) have it, or does not (-) have it.
+
+The easiest way to explain how to build a flag mask is by demonstration. A flag mask of "v" by itself means "has a global v flag". To also check for a channel flag, you would use the flag mask "v|v". This checks if the user has a global "v" flag, OR a channel "v" flag (again, the | means "OR" and ties the two types of flags together). You could change this mask to be "v&v", which would check if the user has a global "v" flag AND a channel "v" flag. Lastly, to check if a user ONLY has a channel flag, you would use "\*|v" as a mask, which would not check global flags but does check if the user had a channel "v" flag.
+
+You will commonly see flag masks for global flags written "ov"; this is the same as "\|ov" or "\*\|ov".
+
+Some additional examples:
+
++------------+-----------------------------------------------------------------+
+| Flag Mask | Action |
++============+=================================================================+
+| m, +m, m|* | Checks if the user has the m global flag |
++------------+-----------------------------------------------------------------+
+| +mn | Checks if the user has the m OR n global flag |
++------------+-----------------------------------------------------------------+
+| \|+mn | Checks if the user has the m OR n channel flag |
++------------+-----------------------------------------------------------------+
+| \|+mn #foo | Checks if the user has the m OR n channel flag for #foo |
++------------+-----------------------------------------------------------------+
+| &+mn | Checks if the user has the m AND n channel flag |
++------------+-----------------------------------------------------------------+
+| &mn #foo | Checks if the user has the m AND n channel flag for #foo |
++------------+-----------------------------------------------------------------+
+| \|+o #foo | Checks if the user has the o channel flag for #foo |
++------------+-----------------------------------------------------------------+
+| +o|+n #foo | Checks if the user has the o global flag OR the n channel flag |
+| | for #foo |
++------------+-----------------------------------------------------------------+
+| +m&+v #foo | Checks if the user has the m global flag AND the v channel flag |
+| | for #foo |
++------------+-----------------------------------------------------------------+
+| -m | Checks if the user does not have the m global flag |
++------------+-----------------------------------------------------------------+
+| \|-n #foo | Checks if the user does not have the n channel flag for #foo |
++------------+-----------------------------------------------------------------+
+| +m|-n #foo | Checks if the user has the global m flag OR does not have a |
+| | channel n flag for #foo |
++------------+-----------------------------------------------------------------+
+| -n&-m #foo | Checks if the user does not have the global n flag AND does |
+| | not have the channel m flag for #foo |
++------------+-----------------------------------------------------------------+
+| ||+b | Checks if the user has the bot flag b |
++------------+-----------------------------------------------------------------+
+
+As a side note, Tcl scripts historically have used a '-' to skip processing of a flag type (Example: -|o). It is unknown where and why this practice started, but as a style tip, Eggdrop developers recommend using a '*' to skip processing, so as not to confuse a single "-" meaning "skip processing" with a preceding "-ov" which means "not these flags".
^^^^^^^^^^
Bind Types
diff --git a/src/flags.c b/src/flags.c
index ce60b2e3d..26285fdbd 100644
--- a/src/flags.c
+++ b/src/flags.c
@@ -1133,7 +1133,7 @@ static int flag2str(char *string, int bot, int udef)
x++;
}
if (string == old)
- *string++ = '-';
+ *string++ = '*';
return string - old;
}
From e9482fbe33af4462bf222bea4625451f8dd4f7df Mon Sep 17 00:00:00 2001
From: Geo
Date: Thu, 10 Nov 2022 17:26:28 -0500
Subject: [PATCH 19/92] Update NEWS
---
NEWS | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/NEWS b/NEWS
index e0dbe26b2..44a6d3594 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,32 @@ Last revised: December 4, 2021
_________________________________________________________________
+Eggdrop v1.9.4:
+
+ General changes:
+ - Fixed a DNS bug causing Eggdrop to often hang on DCC or telnet
+ connections
+ - Reverted matchattr match syntax to previous functionality. Matching
+ against "-" as a flag will once again successfully match against "no"
+ flags, instead of returning an error.
+ - Fixed some inaccurate log messages
+ - Fixed some format specifiers that could cause crashes in certain
+ situations
+ - Fixed logging of TAGMSG messages
+ - Fixed unspecified behavior of freeaddrinfo() on some BSD systems
+
+ Botnet changes:
+ - None
+
+ Tcl API changes:
+ - Moved the 'gotmsg' function back as a raw bind. It was inadvertantly
+ moved to a rawt bind in 1.9.3, causing issuse with scripts attempting to
+ unbind this internal reference
+
+Eggdrop config changes:
+ - None
+
+
Eggdrop v1.9.3:
General changes:
From e4e914276d8eccdc7ae891072174faeec40fb532 Mon Sep 17 00:00:00 2001
From: Geo
Date: Thu, 10 Nov 2022 17:26:52 -0500
Subject: [PATCH 20/92] Update version strings to 1.9.4
---
configure.ac | 2 +-
doc/sphinx_source/conf.py | 4 ++--
doc/sphinx_source/using/tcl-commands.rst | 2 +-
doc/sphinx_source/using/text-sub.rst | 4 ++--
src/mod/compress.mod/configure.ac | 2 +-
src/mod/dns.mod/configure.ac | 2 +-
src/version.h | 6 +++---
7 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/configure.ac b/configure.ac
index 96e906230..f6c66bbae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
dnl configure.ac: this file is processed by autoconf to produce ./configure.
AC_PREREQ(2.61)
-AC_INIT([Eggdrop],[1.9.3],[bugs@eggheads.org])
+AC_INIT([Eggdrop],[1.9.4],[bugs@eggheads.org])
AC_COPYRIGHT([Copyright (C) 1999 - 2022 Eggheads Development Team])
AC_LANG([C])
AC_REVISION([m4_esyscmd([misc/getcommit])])
diff --git a/doc/sphinx_source/conf.py b/doc/sphinx_source/conf.py
index bcb0d64ed..77f7b8fe7 100644
--- a/doc/sphinx_source/conf.py
+++ b/doc/sphinx_source/conf.py
@@ -51,9 +51,9 @@
# built documents.
#
# The short X.Y version.
-version = '1.9.3'
+version = '1.9.4'
# The full version, including alpha/beta/rc tags.
-release = '1.9.3'
+release = '1.9.4'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/doc/sphinx_source/using/tcl-commands.rst b/doc/sphinx_source/using/tcl-commands.rst
index e4dacf9ea..2f9132808 100644
--- a/doc/sphinx_source/using/tcl-commands.rst
+++ b/doc/sphinx_source/using/tcl-commands.rst
@@ -13,7 +13,7 @@ of the normal Tcl built-in commands are still there, of course, but you
can also use these to manipulate features of the bot. They are listed
according to category.
-This list is accurate for Eggdrop v1.9.3. Scripts written for v1.3, v1.4,
+This list is accurate for Eggdrop v1.9.4. Scripts written for v1.3, v1.4,
1.6 and 1.8 series of Eggdrop should probably work with a few minor modifications
depending on the script. Scripts which were written for v0.9, v1.0, v1.1
or v1.2 will probably not work without modification. Commands which have
diff --git a/doc/sphinx_source/using/text-sub.rst b/doc/sphinx_source/using/text-sub.rst
index 70bab7fff..92dfaf013 100644
--- a/doc/sphinx_source/using/text-sub.rst
+++ b/doc/sphinx_source/using/text-sub.rst
@@ -25,9 +25,9 @@ respective values:
+------+---------------------------------------------------------+
| %B | bot's nickname (i.e. "LamestBot") |
+------+---------------------------------------------------------+
-| %V | current Eggdrop version (i.e. "eggdrop v1.9.3") |
+| %V | current Eggdrop version (i.e. "eggdrop v1.9.4") |
+------+---------------------------------------------------------+
-| %E | long form of %V (i.e. "Eggdrop v1.9.3 (C) 1997 Robey |
+| %E | long form of %V (i.e. "Eggdrop v1.9.4 (C) 1997 Robey |
| | Pointer (C) 2010 Eggheads Development Team") |
+------+---------------------------------------------------------+
| %C | channels the bot is on (i.e. "#lamest, #botnetcentral") |
diff --git a/src/mod/compress.mod/configure.ac b/src/mod/compress.mod/configure.ac
index 8602d757a..aa6c416e4 100644
--- a/src/mod/compress.mod/configure.ac
+++ b/src/mod/compress.mod/configure.ac
@@ -4,7 +4,7 @@ AC_PREREQ(2.58)
sinclude(../eggmod.m4)
-AC_INIT([Eggdrop Compress Module],[1.9.3],[bugs@eggheads.org])
+AC_INIT([Eggdrop Compress Module],[1.9.4],[bugs@eggheads.org])
AC_CONFIG_SRCDIR(compress.c)
AC_CONFIG_AUX_DIR(../../../misc)
diff --git a/src/mod/dns.mod/configure.ac b/src/mod/dns.mod/configure.ac
index 0b850a53d..cbb695e5b 100644
--- a/src/mod/dns.mod/configure.ac
+++ b/src/mod/dns.mod/configure.ac
@@ -4,7 +4,7 @@ AC_PREREQ(2.60)
sinclude(../eggmod.m4)
-AC_INIT([Eggdrop DNS Module],[1.9.3],[bugs@eggheads.org])
+AC_INIT([Eggdrop DNS Module],[1.9.4],[bugs@eggheads.org])
AC_CONFIG_SRCDIR(coredns.c)
AC_CONFIG_AUX_DIR(../../../misc)
diff --git a/src/version.h b/src/version.h
index f173917d1..202b920d1 100644
--- a/src/version.h
+++ b/src/version.h
@@ -26,6 +26,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#define EGG_STRINGVER "1.9.3"
-#define EGG_NUMVER 1090303
-#define EGG_PATCH "gotmsg"
+#define EGG_STRINGVER "1.9.4"
+#define EGG_NUMVER 1090400
+#define EGG_PATCH "alpha"
From 13ab01706a8a782dc46fb163aeca2a31c5f02bdf Mon Sep 17 00:00:00 2001
From: Geo
Date: Thu, 10 Nov 2022 17:27:04 -0500
Subject: [PATCH 21/92] Generate docs with 1.9.4 version
---
INSTALL | 5 +-
doc/BOTNET | 4 +-
doc/PBKDF2 | 2 -
doc/html/_static/documentation_options.js | 2 +-
doc/html/about/about.html | 7 +-
doc/html/about/legal.html | 7 +-
doc/html/index.html | 16 +-
doc/html/install/install.html | 13 +-
doc/html/install/readme.html | 7 +-
doc/html/install/upgrading.html | 7 +-
doc/html/modules/included.html | 7 +-
doc/html/modules/index.html | 7 +-
doc/html/modules/mod/assoc.html | 7 +-
doc/html/modules/mod/blowfish.html | 7 +-
doc/html/modules/mod/channels.html | 7 +-
doc/html/modules/mod/compress.html | 7 +-
doc/html/modules/mod/console.html | 7 +-
doc/html/modules/mod/ctcp.html | 7 +-
doc/html/modules/mod/dns.html | 7 +-
doc/html/modules/mod/filesys.html | 9 +-
doc/html/modules/mod/ident.html | 7 +-
doc/html/modules/mod/irc.html | 9 +-
doc/html/modules/mod/notes.html | 7 +-
doc/html/modules/mod/pbkdf2.html | 7 +-
doc/html/modules/mod/seen.html | 7 +-
doc/html/modules/mod/server.html | 7 +-
doc/html/modules/mod/share.html | 7 +-
doc/html/modules/mod/transfer.html | 7 +-
doc/html/modules/mod/twitch.html | 7 +-
doc/html/modules/mod/uptime.html | 7 +-
doc/html/modules/mod/woobie.html | 7 +-
doc/html/modules/writing.html | 7 +-
doc/html/objects.inv | Bin 1234 -> 1279 bytes
doc/html/search.html | 7 +-
doc/html/searchindex.js | 2 +-
doc/html/tutorials/firstscript.html | 7 +-
doc/html/tutorials/firststeps.html | 7 +-
doc/html/tutorials/setup.html | 7 +-
doc/html/tutorials/tlssetup.html | 7 +-
doc/html/using/accounts.html | 16 +-
doc/html/using/bans.html | 7 +-
doc/html/using/botnet.html | 11 +-
doc/html/using/core.html | 7 +-
doc/html/using/features.html | 7 +-
doc/html/using/ipv6.html | 7 +-
doc/html/using/ircv3.html | 13 +-
doc/html/using/partyline.html | 7 +-
doc/html/using/patch.html | 7 +-
doc/html/using/pbkdf2info.html | 20 +-
doc/html/using/tcl-commands.html | 195 +++++++++---------
doc/html/using/text-sub.html | 11 +-
doc/html/using/tls.html | 7 +-
doc/html/using/tricks.html | 7 +-
doc/html/using/twitch-tcl-commands.html | 7 +-
doc/html/using/twitchinfo.html | 7 +-
doc/html/using/users.html | 7 +-
doc/modules/mod.filesys | 2 +-
doc/modules/mod.irc | 2 +-
doc/tcl-commands.doc | 240 +++++++++++++---------
59 files changed, 477 insertions(+), 375 deletions(-)
diff --git a/INSTALL b/INSTALL
index 44e691dbd..064b9ea37 100644
--- a/INSTALL
+++ b/INSTALL
@@ -64,8 +64,6 @@ Eggdrop uses the GNU autoconfigure scripts to make things easier.
Note that you must use full path for every file to be correctly
installed.
- [The following is performed from the directory installed above.]
-
5. Since version 1.8, Eggdrop can use SSL to protect botnet links. If
you intend on protecting botnet traffic between Eggdrops, you must
generate SSL certificates by running:
@@ -84,6 +82,9 @@ Eggdrop uses the GNU autoconfigure scripts to make things easier.
Read docs/TLS for more info on this process.
+[The following steps are performed in the directory you just installed
+Eggdrop into from the previous step]
+
6. Edit your config file completely.
7. Start the bot with the "-m" option to create a user file, i.e. :
diff --git a/doc/BOTNET b/doc/BOTNET
index d44584818..d3e700766 100644
--- a/doc/BOTNET
+++ b/doc/BOTNET
@@ -7,7 +7,7 @@ Botnet Sharing and Linking
WHAT IS A BOTNET?
- A botnet consists of one or more bots linked together. This can allow
+ A botnet consists of two or more bots linked together. This can allow
bots to op each other securely, control floods efficiently, and share
user lists, ban lists, exempt/invite lists, and ignore lists (if
sharing is enabled).
@@ -18,7 +18,7 @@ The following are some common terms used in this document:
Botnet
- A botnet consists of one or more bots connected together.
+ A botnet consists of two or more bots connected together.
Link
diff --git a/doc/PBKDF2 b/doc/PBKDF2
index dd5b1a058..cbb4e5e81 100644
--- a/doc/PBKDF2
+++ b/doc/PBKDF2
@@ -66,8 +66,6 @@ there).
1. Ensure
-::
-
loadmodule pbkdf2
is uncommented in the config file (or added, if this is a config file
diff --git a/doc/html/_static/documentation_options.js b/doc/html/_static/documentation_options.js
index aec678252..c0721a95a 100644
--- a/doc/html/_static/documentation_options.js
+++ b/doc/html/_static/documentation_options.js
@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
- VERSION: '1.9.3',
+ VERSION: '1.9.4',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
diff --git a/doc/html/about/about.html b/doc/html/about/about.html
index 7949b3d1c..aaa966ae2 100644
--- a/doc/html/about/about.html
+++ b/doc/html/about/about.html
@@ -6,7 +6,7 @@
- About Eggdrop — Eggdrop 1.9.2 documentation
+ About Eggdrop — Eggdrop 1.9.4 documentation
@@ -24,7 +24,7 @@
Many IRCops find bots by seeing if they reply to ‘hello’ in a msg. You
-can change this to another word by un-commenting thse two lines and
+can change this to another word by un-commenting these two lines and
changing “myword” to the word wish to use instead of’hello’. It must be
a single word.
If a server only supports some, but not all, of the required capabilities, Eggdrop will switch to ‘best effort’ account tracking. This means Eggdrop will update account statuses whenever it sees account information, but Eggdrop cannnot guarantee the accuracy of account association at any given time.
+
If a server only supports some, but not all, of the required capabilities, Eggdrop will switch to ‘best effort’ account tracking. This means Eggdrop will update account statuses whenever it sees account information, but in this mode Eggdrop cannot guarantee that all account associations are up to date.
If a server does not support extended-join, Eggdrop will not be able to determine the account associated with a user when they join. Eggdrop can update this information by sending a WHOX to the server.
-
If a server does not support account-notify, Eggdrop will not be able to determine the account assoicated with a user if they authenticate/deauthenticate from their account after joining a channel. Eggdrop can update this information by sending a WHOX to the server.
+
If a server does not support account-notify, Eggdrop will not be able to determine the account associated with a user if they authenticate/deauthenticate from their account after joining a channel. Eggdrop can update this information by sending a WHOX to the server.
If a server does not support WHOX, Eggdrop will not be able to determine the accounts associated with users already on a channel before Eggdrop joined. There is no reliable way to update this information.
-
One workaround to significantly increase the accuracy of account tracking for scripts in a ‘best effort’ scenario would be to issue a WHOX query (assuming the server supports it), wait for the reply from the eserver, and then query for the account information.
+
One workaround to significantly increase the accuracy of account tracking for scripts in a ‘best effort’ scenario would be to issue a WHOX query (assuming the server supports it), wait for the reply from the server, and then query for the account information.
One supplementary capability that can assist a best-effort account tracking scenario is the IRCv3-defined account-tag capability. The account-tag capability attaches a tag with the account name associated with the user sending a command. Enabling this capability allows Eggdrop to update its account tracking every time a user talks in channel, sets a mode, sends a kick, etc. While still not able to offer the same level of accuracy as enabling the “main three” account tracking features, it can increase the accuracy and can help with scripts that react to user commands/messages.
+
One supplementary capability that can assist a best-effort account tracking scenario is the IRCv3-defined account-tag capability. The account-tag capability attaches a tag with the account name associated with the user sending a command. Enabling this capability allows Eggdrop to update its account tracking every time a user talks in channel, sets a mode, sends a kick, etc. While still not able to offer the same level of accuracy as enabling the “main three” account tracking features, it can increase the overall accuracy of the account list. Additionally, binds that react to user activity (pub, kick, mode, etc) containing account-tag will update the internal account list prior to executing the associated callback, so looking up the account name in the callback can be considered accurate.
The Eggdrop Tcl ACCOUNT bind is triggered whenver an existing account record stored by Eggdrop is modified, such as a user de/authenticating to their account while in a channel, or information such as an account-tag being seen that updates an existing user. However, the ACCOUNT bind will NOT be triggered for the creation of a new user record, such as a user joining a channel. The bind is triggered for every channel the user is seen on- this means if a user is present with Eggdrop on four channels, the bind will be executed four times, each time with a different channel variable being passed to the associated Tcl procedure. Additionally, in a best-effort account tracking situation, Eggdrop will update the account associated with a user on all channels, not just the channel the event is seen on (and thus resulting in a bind trigger for each channel the user is on).
+
The Eggdrop Tcl ACCOUNT bind is triggered whenever an existing account record stored by Eggdrop is modified, such as a user de/authenticating to their account while in a channel, or information such as an account-tag being seen that updates an existing user. However, the ACCOUNT bind will NOT be triggered for the creation of a new user record, such as a user joining a channel. The bind is triggered for every channel the user is seen on- this means if a user is present with Eggdrop on four channels, the bind will be executed four times, each time with a different channel variable being passed to the associated Tcl procedure. Additionally, in a best-effort account tracking situation, Eggdrop will update the account associated with a user on all channels, not just the channel the event is seen on (and thus resulting in a bind trigger for each channel the user is on).
In order to trigger Tcl script events to cover all instances where a user logs in, you need to pair an ACCOUNT bind with a JOIN bind. This will allow you to execute account-based events when a user joins as well as if they authenticate after joining.
A botnet consists of one or more bots linked together. This can allow bots to op each other securely, control floods efficiently, and share user lists, ban lists, exempt/invite lists, and ignore lists (if sharing is enabled).
+
A botnet consists of two or more bots linked together. This can allow bots to op each other securely, control floods efficiently, and share user lists, ban lists, exempt/invite lists, and ignore lists (if sharing is enabled).
diff --git a/doc/html/using/partyline.html b/doc/html/using/partyline.html
index 34d6ef5ca..93dc1ec45 100644
--- a/doc/html/using/partyline.html
+++ b/doc/html/using/partyline.html
@@ -6,7 +6,7 @@
- The Party Line — Eggdrop 1.9.3 documentation
+ The Party Line — Eggdrop 1.9.4 documentation
@@ -24,7 +24,7 @@
Either | or & can be used as a separator between global, channel, and bot flags, but only one separator can be used per flag section. A ‘+’ is used to check if a user has the subsequent flags, and a ‘-‘ is used to check if a user does NOT have the subsequent flags.
-
-
-
-
-
-
-
-
Flag Mask
-
Action
-
-
-
-
+m
-
Checks if the user has the m global flag
-
-
-
+mn
-
Checks if the user has the m OR n global flag
-
-
|+mn
-
Checks if the user has the m OR n global flag
-
-
|+mn #foo
-
Checks if the user has the m OR n channel flag for #foo
-
-
&+mn
-
Checks if the user has the m AND n global flag
-
-
&mn #foo
-
Checks if the user has the m AND n channel flag for #foo
-
-
|+o #foo
-
Checks if the user has the o channel flag for #foo
-
-
+o|+n #foo
-
Checks if the user has the o global flag OR the n channel flag
-for #foo
-
-
+m&+v #foo
-
Checks if the user has the m global flag AND the v channel flag
-for #foo
-
-
-m
-
Checks if the user does not have the m global flag
-
-
|-n #foo
-
Checks if the user does not have the n channel flag for #foo
-
-
+m|-n #foo
-
Checks if the user has the global m flag OR does not have a
-channel n flag for #foo
-
-
-n&-m #foo
-
Checks if the user does not have the global n flag AND does
-not have the channel m flag for #foo
-
-
||+b
-
Checks if the user has the bot flag b
-
-
-
-
-
Returns: 1 if the specified user has the flags matching the provided mask; 0 otherwise
+
Either | or & can be used as a separator between global, channel, and bot flags, but only one separator can be used per flag section. A ‘+’ is used to check if a user has the subsequent flags, and a ‘-‘ is used to check if a user does NOT have the subsequent flags. Please see Flag Masks for additional information on flag usage.
+
Returns: 1 if the specified user has the flags matching the provided mask; 0 otherwise
Returns: the services account name associated with nickname (if Eggdrop is configured to track account status), and “” if they are not logged in or Eggdrop is not able to determine the account status. WARNING: this account list may not be accurate depending on the server and configuration. This command is only accurate if a server supports (and Eggdrop has enabled) the account-notify and extended-join capabilities, and the server understands WHOX requests (also known as raw 354 responses).
+
Returns: the services account name associated with nickname, “*” if the user is not logged into services, or “” if eggdrop does not know the account status of the user.
+
NOTE: the three required IRC components for account tracking are: the WHOX feature, the extended-join IRCv3 capability and the account-notify IRCv3 capability. if only some of the three feature are available, eggdrop provides best-effort account tracking. please see doc/ACCOUNTS for additional information.
Description: flags are any global flags; the ‘&’ or ‘|’ denotes to look for channel specific flags, where ‘&’ will return users having ALL chanflags and ‘|’ returns users having ANY of the chanflags (See matchattr above for additional examples).
+
Description: flags are any global flags; the ‘&’ or ‘|’ denotes to look for channel specific flags, where ‘&’ will return users having ALL chanflags and ‘|’ returns users having ANY of the chanflags (See Flag Masks for additional information).
Returns: Searching for flags optionally preceded with a ‘+’ will return a list of nicknames that have all the flags listed. Searching for flags preceded with a ‘-‘ will return a list of nicknames that do not have have any of the flags (differently said, ‘-‘ will hide users that have all flags listed). If no flags are given, all of the nicknames on the channel are returned.
Please note that if you’re executing chanlist after a part or sign bind, the gone user will still be listed, so you can check for wasop, isop, etc.
Description: executes the given Tcl command after a certain number of seconds have passed. If count is specified, the command will be executed count times with the given interval in between. If you specify a count of 0, the utimer will repeat until it’s removed with killutimer or until the bot is restarted. If timerName is specified, it will become the unique identifier for the timer. If no timer
-
Name is specified, Eggdrop will assign a timerName in the format of “timer<integer>”.
-
-
Returns: a timerName
+
Description: executes the given Tcl command after a certain number of seconds have passed. If count is specified, the command will be executed count times with the given interval in between. If you specify a count of 0, the utimer will repeat until it’s removed with killutimer or until the bot is restarted. If timerName is specified, it will become the unique identifier for the timer. If timerName is not specified, Eggdrop will assign a timerName in the format of “timer<integer>”.
You can use the ‘bind’ command to attach Tcl procedures to certain events.
-For example, you can write a Tcl procedure that gets called every time a
-user says “danger” on the channel.
-
Some bind types are marked as “stackable”. That means that you can bind
-multiple commands to the same trigger. Normally, for example, a bind such
-as ‘bind msg - stop msg:stop’ (which makes a msg-command “stop” call the
-Tcl proc “msg:stop”) will overwrite any previous binding you had for the
-msg command “stop”. With stackable bindings, like ‘msgm’ for example,
-you can bind the same command to multiple procs. When the bind is triggered,
-ALL of the Tcl procs that are bound to it will be called. Raw binds are
-triggered before builtin binds, as a builtin bind has the potential to
-modify args.
+
You can use the ‘bind’ command to attach Tcl procedures to certain events. For example, you can write a Tcl procedure that gets called every time a user says “danger” on the channel. When a bind is triggered, ALL of the Tcl procs that are bound to it will be called. Raw binds are triggered before builtin binds, as a builtin bind has the potential to modify args.
Some bind types are marked as “stackable”. That means that you can bind multiple commands to the same trigger. Normally, for example, a bind such as ‘bind msg - stop msg:stop’ (which makes a msg-command “stop” call the Tcl proc “msg:stop”) will overwrite any previous binding you had for the msg command “stop”. With stackable bindings, like ‘msgm’ for example, you can bind the same command to multiple procs.
In the Bind Types section (and other commands, such as `matchattr`_), you will see several references to the “flags” argument. The “flags” argument takes a flag mask, which is a value that represents the type of user that is allowed to trigger the procedure associated to that bind. The flags can be any of the standard Eggdrop flags (o, m, v, etc). Additionally, when used by itself, a “-” or “*” can be used to skip processing for a flag type. A flag mask has three sections to it- global, channel, and bot flag sections. Each section is separated by the | or & logical operators ( the | means “OR” and the & means “AND; if nothing proceeds the flag then Eggdrop assumes it to be an OR). Additionally, a ‘+’ and ‘-‘ can be used in front of a flag to check if the user does (+) have it, or does not (-) have it.
+
The easiest way to explain how to build a flag mask is by demonstration. A flag mask of “v” by itself means “has a global v flag”. To also check for a channel flag, you would use the flag mask “v|v”. This checks if the user has a global “v” flag, OR a channel “v” flag (again, the | means “OR” and ties the two types of flags together). You could change this mask to be “v&v”, which would check if the user has a global “v” flag AND a channel “v” flag. Lastly, to check if a user ONLY has a channel flag, you would use “*|v” as a mask, which would not check global flags but does check if the user had a channel “v” flag.
+
You will commonly see flag masks for global flags written “ov”; this is the same as “|ov” or “*|ov”.
+
Some additional examples:
+
+
+
+
+
+
+
Flag Mask
+
Action
+
+
+
+
m, +m, m|*
+
Checks if the user has the m global flag
+
+
+mn
+
Checks if the user has the m OR n global flag
+
+
|+mn
+
Checks if the user has the m OR n channel flag
+
+
|+mn #foo
+
Checks if the user has the m OR n channel flag for #foo
+
+
&+mn
+
Checks if the user has the m AND n channel flag
+
+
&mn #foo
+
Checks if the user has the m AND n channel flag for #foo
+
+
|+o #foo
+
Checks if the user has the o channel flag for #foo
+
+
+o|+n #foo
+
Checks if the user has the o global flag OR the n channel flag
+for #foo
+
+
+m&+v #foo
+
Checks if the user has the m global flag AND the v channel flag
+for #foo
+
+
-m
+
Checks if the user does not have the m global flag
+
+
|-n #foo
+
Checks if the user does not have the n channel flag for #foo
+
+
+m|-n #foo
+
Checks if the user has the global m flag OR does not have a
+channel n flag for #foo
+
+
-n&-m #foo
+
Checks if the user does not have the global n flag AND does
+not have the channel m flag for #foo
+
+
||+b
+
Checks if the user has the bot flag b
+
+
+
+
As a side note, Tcl scripts historically have used a ‘-‘ to skip processing of a flag type (Example: -|o). It is unknown where and why this practice started, but as a style tip, Eggdrop developers recommend using a ‘*’ to skip processing, so as not to confuse a single “-” meaning “skip processing” with a preceding “-ov” which means “not these flags”.
The following is a list of bind types and how they work. Below each bind type is the format of the bind command, the list of arguments sent to the Tcl proc, and an explanation.
@@ -3122,10 +3124,10 @@
Bind Typesnick!ident@host (depending on the keyword); flags are ignored. If the proc returns 1, Eggdrop will not process the line any further (this could cause unexpected behavior in some cases), although RAWT binds are processed before RAW binds (and thus, a RAW bind cannot block a RAWT bind).
Module: server
@@ -3464,9 +3466,9 @@
Bind Typesnick!ident@host (depending on the keyword); flags are ignored. “tag” is a dictionary (flat key/value list) of the message tags with “” for empty values (e.g. “account eggdrop realname LamestBot”). If the proc returns 1, Eggdrop will not process the line any further, to include not being processed by a RAW bind (this could cause unexpected behavior in some cases). As of 1.9.0, it is recommended to use the RAWT bind instead of the RAW bind.
ACCOUNT (stackable)
@@ -3474,7 +3476,8 @@
Bind Typesnick!user@hostname.com account” where channel is the channel the user was found on when the bind was triggered, the hostmask is the user’s hostmask, and account is the account name the user is logging in to, or “” for logging out. The mask argument can accept wildcards. For the proc, nick is the nickname of the user logging into/out of an account, user is the user@host.com hostmask, hand is the handle of the user (or * if none), and account is the name of the account the user logged in to (or “” if the user logged out of an account).
+
Description: this bind will trigger when eggdrop detects a change in the authentication status of a user’s service account. The mask for the bind is in the format “#channel nick!user@hostname.com account” and accepts wildcards. account is either the account name the user is logging in to or “*” if the user is not logged in to an account.
+
NOTE: the three required IRC components for account tracking are: the WHOX feature, the extended-join IRCv3 capability and the account-notify IRCv3 capability. if only some of the three feature are available, eggdrop provides best-effort account tracking but this bind could be triggered late or never on account changes. Please see doc/ACCOUNTS for additional information.
diff --git a/doc/modules/mod.filesys b/doc/modules/mod.filesys
index 34290d2b5..49ea3ee1c 100644
--- a/doc/modules/mod.filesys
+++ b/doc/modules/mod.filesys
@@ -176,7 +176,7 @@ rm [files] ...
Cleans up the current directory's database. If you have a large
directory with many files you may want to use this command if you
experience slow-downs/delays over time. Normally, the db should clean
- up itsself though.
+ up itself though.
.unhide
diff --git a/doc/modules/mod.irc b/doc/modules/mod.irc
index ace9404cb..cff7c251b 100644
--- a/doc/modules/mod.irc
+++ b/doc/modules/mod.irc
@@ -94,7 +94,7 @@ There are also some variables you can set in your config file:
bind msg - myword *msg:hello
Many IRCops find bots by seeing if they reply to 'hello' in a msg.
- You can change this to another word by un-commenting thse two lines
+ You can change this to another word by un-commenting these two lines
and changing "myword" to the word wish to use instead of'hello'. It
must be a single word.
diff --git a/doc/tcl-commands.doc b/doc/tcl-commands.doc
index bf4d5db3b..8b73f3b70 100644
--- a/doc/tcl-commands.doc
+++ b/doc/tcl-commands.doc
@@ -7,7 +7,7 @@ of the normal Tcl built-in commands are still there, of course, but you
can also use these to manipulate features of the bot. They are listed
according to category.
-This list is accurate for Eggdrop v1.9.3. Scripts written for v1.3,
+This list is accurate for Eggdrop v1.9.4. Scripts written for v1.3,
v1.4, 1.6 and 1.8 series of Eggdrop should probably work with a few
minor modifications depending on the script. Scripts which were written
for v0.9, v1.0, v1.1 or v1.2 will probably not work without
@@ -404,44 +404,8 @@ matchattr [channel]
Either | or & can be used as a separator between global, channel, and
bot flags, but only one separator can be used per flag section. A '+'
is used to check if a user has the subsequent flags, and a '-' is used
- to check if a user does NOT have the subsequent flags.
-
- -----------------------------------------------------------------------
- Flag Mask Action
- ----------- -----------------------------------------------------------
- +m + Checks if the user has the m global flag
-
- +mn Checks if the user has the m OR n global flag
-
- |+mn Checks if the user has the m OR n global flag
-
- |+mn #foo Checks if the user has the m OR n channel flag for #foo
-
- &+mn Checks if the user has the m AND n global flag
-
- &mn #foo Checks if the user has the m AND n channel flag for #foo
-
- |+o #foo Checks if the user has the o channel flag for #foo
-
- +o|+n #foo Checks if the user has the o global flag OR the n channel
- flag for #foo
-
- +m&+v #foo Checks if the user has the m global flag AND the v channel
- flag for #foo
-
- -m Checks if the user does not have the m global flag
-
- |-n #foo Checks if the user does not have the n channel flag for
- #foo
-
- +m|-n #foo Checks if the user has the global m flag OR does not have a
- channel n flag for #foo
-
- -n&-m #foo Checks if the user does not have the global n flag AND does
- not have the channel m flag for #foo
-
- ||+b Checks if the user has the bot flag b
- -----------------------------------------------------------------------
+ to check if a user does NOT have the subsequent flags. Please see Flag
+ Masks for additional information on flag usage.
Returns: 1 if the specified user has the flags matching the provided
mask; 0 otherwise
@@ -1223,14 +1187,15 @@ accounttracking
getaccount [channel]
- Returns: the services account name associated with nickname (if
- Eggdrop is configured to track account status), and "" if they are not
- logged in or Eggdrop is not able to determine the account status.
- WARNING: this account list may not be accurate depending on the server
- and configuration. This command is only accurate if a server supports
- (and Eggdrop has enabled) the account-notify and extended-join
- capabilities, and the server understands WHOX requests (also known as
- raw 354 responses).
+ Returns: the services account name associated with nickname, "*" if
+ the user is not logged into services, or "" if eggdrop does not know
+ the account status of the user.
+
+ NOTE: the three required IRC components for account tracking are: the
+ WHOX feature, the extended-join IRCv3 capability and the
+ account-notify IRCv3 capability. if only some of the three feature are
+ available, eggdrop provides best-effort account tracking. please see
+ doc/ACCOUNTS for additional information.
nick2hand [channel]
@@ -1455,7 +1420,7 @@ chanlist [flags][<&|>chanflags]
Description: flags are any global flags; the '&' or '|' denotes to
look for channel specific flags, where '&' will return users having
ALL chanflags and '|' returns users having ANY of the chanflags (See
- matchattr above for additional examples).
+ Flag Masks for additional information).
Returns: Searching for flags optionally preceded with a '+' will
return a list of nicknames that have all the flags listed. Searching
@@ -2447,10 +2412,9 @@ utimer [count [timerName]]
executed count times with the given interval in between. If you
specify a count of 0, the utimer will repeat until it's removed with
killutimer or until the bot is restarted. If timerName is specified,
- it will become the unique identifier for the timer. If no timer
-
-Name is specified, Eggdrop will assign a timerName in the format of
-"timer".
+ it will become the unique identifier for the timer. If timerName is
+ not specified, Eggdrop will assign a timerName in the format of
+ "timer".
Returns: a timerName
@@ -2478,7 +2442,7 @@ utimers
Module: core
-^^^^^^^^^^^^^^^^^^^ killtimer ^^^^^^^^^^^^^^^^^^^
+killtimer
Description: removes the timerName minutely timer from the timer list.
@@ -2486,7 +2450,7 @@ utimers
Module: core
-^^^^^^^^^^^^^^^^^^^^ killutimer ^^^^^^^^^^^^^^^^^^^^
+killutimer
Description: removes the timerName secondly timer from the timer list.
@@ -2994,21 +2958,98 @@ BINDS
You can use the 'bind' command to attach Tcl procedures to certain
events. For example, you can write a Tcl procedure that gets called
-every time a user says "danger" on the channel.
+every time a user says "danger" on the channel. When a bind is
+triggered, ALL of the Tcl procs that are bound to it will be called. Raw
+binds are triggered before builtin binds, as a builtin bind has the
+potential to modify args.
+
+Stackable binds
Some bind types are marked as "stackable". That means that you can bind
multiple commands to the same trigger. Normally, for example, a bind
such as 'bind msg - stop msg:stop' (which makes a msg-command "stop"
call the Tcl proc "msg:stop") will overwrite any previous binding you
had for the msg command "stop". With stackable bindings, like 'msgm' for
-example, you can bind the same command to multiple procs. When the bind
-is triggered, ALL of the Tcl procs that are bound to it will be called.
-Raw binds are triggered before builtin binds, as a builtin bind has the
-potential to modify args.
+example, you can bind the same command to multiple procs.
+
+Removing a bind
To remove a bind, use the 'unbind' command. For example, to remove the
bind for the "stop" msg command, use 'unbind msg - stop msg:stop'.
+Flag Masks
+
+In the Bind Types section (and other commands, such as matchattr), you
+will see several references to the "flags" argument. The "flags"
+argument takes a flag mask, which is a value that represents the type of
+user that is allowed to trigger the procedure associated to that bind.
+The flags can be any of the standard Eggdrop flags (o, m, v, etc).
+Additionally, when used by itself, a "-" or "*" can be used to skip
+processing for a flag type. A flag mask has three sections to it-
+global, channel, and bot flag sections. Each section is separated by the
+| or & logical operators ( the | means "OR" and the & means "AND; if
+nothing proceeds the flag then Eggdrop assumes it to be an OR).
+Additionally, a '+' and '-' can be used in front of a flag to check if
+the user does (+) have it, or does not (-) have it.
+
+The easiest way to explain how to build a flag mask is by demonstration.
+A flag mask of "v" by itself means "has a global v flag". To also check
+for a channel flag, you would use the flag mask "v means "OR" and ties
+the two types of flags together). You could change this mask to be
+"v&v", which would check if the user has a global "v" flag AND a channel
+"v" flag. Lastly, to check if a user ONLY has a channel flag, you would
+use "*|v" as a mask, which would not check global flags but does check
+if the user had a channel "v" flag.
+
+You will commonly see flag masks for global flags written "ov"; this is
+the same as "|ov" or "*|ov".
+
+Some additional examples:
+
+ -----------------------------------------------------------------------
+ Flag Mask Action
+ ----------- -----------------------------------------------------------
+ m, +m, m|* Checks if the user has the m global flag
+
+ +mn Checks if the user has the m OR n global flag
+
+ |+mn Checks if the user has the m OR n channel flag
+
+ |+mn #foo Checks if the user has the m OR n channel flag for #foo
+
+ &+mn Checks if the user has the m AND n channel flag
+
+ &mn #foo Checks if the user has the m AND n channel flag for #foo
+
+ |+o #foo Checks if the user has the o channel flag for #foo
+
+ +o|+n #foo Checks if the user has the o global flag OR the n channel
+ flag for #foo
+
+ +m&+v #foo Checks if the user has the m global flag AND the v channel
+ flag for #foo
+
+ -m Checks if the user does not have the m global flag
+
+ |-n #foo Checks if the user does not have the n channel flag for
+ #foo
+
+ +m|-n #foo Checks if the user has the global m flag OR does not have a
+ channel n flag for #foo
+
+ -n&-m #foo Checks if the user does not have the global n flag AND does
+ not have the channel m flag for #foo
+
+ ||+b Checks if the user has the bot flag b
+ -----------------------------------------------------------------------
+
+As a side note, Tcl scripts historically have used a '-' to skip
+processing of a flag type (Example: -|o). It is unknown where and why
+this practice started, but as a style tip, Eggdrop developers recommend
+using a '*' to skip processing, so as not to confuse a single "-"
+meaning "skip processing" with a preceding "-ov" which means "not these
+flags".
+
Bind Types
The following is a list of bind types and how they work. Below each bind
@@ -3295,26 +3336,22 @@ the Tcl proc, and an explanation.
(17) RAW (stackable)
- bind raw
+ bind raw
procname
IMPORTANT: While not necessarily deprecated, this bind has been
- supplanted by the RAWT bind as of 1.9.0. You probably want to be using
- RAWT, not RAW.
-
- Description: previous versions of Eggdrop required a special compile
- option to enable this binding, but it's now standard. The keyword is
- either a numeric, like "368", or a keyword, such as "PRIVMSG". "from"
- will be the server name or the source user (depending on the keyword);
- flags are ignored. The order of the arguments is identical to the
- order that the IRC server sends to the bot. The pre-processing only
- splits it apart enough to determine the keyword. If the proc returns
- 1, Eggdrop will not process the line any further (this could cause
- unexpected behavior in some cases), although RAWT binds are processed
- before RAW binds (and thus, a RAW bind cannot block a RAWT bind). The
- RAW bind does not support the IRCv3 message-tags capability, please
- see RAWT for more information.
+ supplanted by the RAWT bind, which supports the IRCv3 message-tags
+ capability, as of 1.9.0. You probably want to be using RAWT, not RAW.
+
+ Description: The mask can contain wildcards and is matched against the
+ keyword, which is either a numeric, like "368", or a keyword, such as
+ "PRIVMSG". "from" will be the server name or the source
+ nick!ident@host (depending on the keyword); flags are ignored. If the
+ proc returns 1, Eggdrop will not process the line any further (this
+ could cause unexpected behavior in some cases), although RAWT binds
+ are processed before RAW binds (and thus, a RAW bind cannot block a
+ RAWT bind).
Module: server
@@ -3824,22 +3861,21 @@ the Tcl proc, and an explanation.
(52) RAWT (stackable)
- bind rawt
+ bind rawt
- procname
+ procname
Description: similar to the RAW bind, but allows an extra field for
- the IRCv3 message-tags capability. The keyword is either a numeric,
- like "368", or a keyword, such as "PRIVMSG" or "TAGMSG". "from" will
- be the server name or the source user (depending on the keyword);
- flags are ignored. "tag" will be the contents, if any, of the entire
- tag message prefixed to the server message in a dict format, such as
- "msgid 890157217279768 aaa bbb". The order of the arguments is
- identical to the order that the IRC server sends to the bot. If the
- proc returns 1, Eggdrop will not process the line any further, to
- include not being processed by a RAW bind (this could cause unexpected
- behavior in some cases). As of 1.9.0, it is recommended to use the
- RAWT bind instead of the RAW bind.
+ the IRCv3 message-tags capability. The mask can contain wildcards and
+ is matched against the keyword which is either a numeric, like "368",
+ or a keyword, such as "PRIVMSG" or "TAGMSG". "from" will be the server
+ name or the source nick!ident@host (depending on the keyword); flags
+ are ignored. "tag" is a dictionary (flat key/value list) of the
+ message tags with "" for empty values (e.g. "account eggdrop realname
+ LamestBot"). If the proc returns 1, Eggdrop will not process the line
+ any further, to include not being processed by a RAW bind (this could
+ cause unexpected behavior in some cases). As of 1.9.0, it is
+ recommended to use the RAWT bind instead of the RAW bind.
(53) ACCOUNT (stackable)
@@ -3847,19 +3883,18 @@ the Tcl proc, and an explanation.
procname
- Description: triggered when Eggdrop detects a change in a service
- account status. The change could be initiated by receiving an IRCv3
- ACCOUNT message, receiving IRCv3 extended-join information when a user
- on an existing channel joins a new channel, or detecting an IRCv3
- account-tag in a PRIVMSG. The mask for the bind is in the format
- "#channel nick!user@hostname.com account" where channel is the channel
- the user was found on when the bind was triggered, the hostmask is the
- user's hostmask, and account is the account name the user is logging
- in to, or "" for logging out. The mask argument can accept wildcards.
- For the proc, nick is the nickname of the user logging into/out of an
- account, user is the user@host.com hostmask, hand is the handle of the
- user (or * if none), and account is the name of the account the user
- logged in to (or "" if the user logged out of an account).
+ Description: this bind will trigger when eggdrop detects a change in
+ the authentication status of a user's service account. The mask for
+ the bind is in the format "#channel nick!user@hostname.com account"
+ and accepts wildcards. account is either the account name the user is
+ logging in to or "*" if the user is not logged in to an account.
+
+ NOTE: the three required IRC components for account tracking are: the
+ WHOX feature, the extended-join IRCv3 capability and the
+ account-notify IRCv3 capability. if only some of the three feature are
+ available, eggdrop provides best-effort account tracking but this bind
+ could be triggered late or never on account changes. Please see
+ doc/ACCOUNTS for additional information.
(54) ISUPPORT (stackable)
@@ -4090,6 +4125,9 @@ the four special characters:
~ matches 1 or more space characters (can be used for whitespace
between words) (This char only works in binds, not in regular
matching)
+
+ \* matches a literal *, but please note that Tcl needs escaping as
+ well, so a bind would have to use "\*" or {*} for a mask argument
----- -----------------------------------------------------------------
Copyright (C) 1999 - 2022 Eggheads Development Team
From 272983c2c34dd25673ab8dcf1be9ce897f217c85 Mon Sep 17 00:00:00 2001
From: Geo
Date: Thu, 10 Nov 2022 17:27:05 -0500
Subject: [PATCH 22/92] Run autoconf
---
configure | 20 ++++++++++----------
src/mod/compress.mod/configure | 20 ++++++++++----------
src/mod/dns.mod/configure | 20 ++++++++++----------
3 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/configure b/configure
index ecfb818de..b7e1fb352 100755
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
#! /bin/sh
-# From configure.ac bc41b3ea.
+# From configure.ac 13ab0170.
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Eggdrop 1.9.3.
+# Generated by GNU Autoconf 2.69 for Eggdrop 1.9.4.
#
# Report bugs to .
#
@@ -583,8 +583,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='Eggdrop'
PACKAGE_TARNAME='eggdrop'
-PACKAGE_VERSION='1.9.3'
-PACKAGE_STRING='Eggdrop 1.9.3'
+PACKAGE_VERSION='1.9.4'
+PACKAGE_STRING='Eggdrop 1.9.4'
PACKAGE_BUGREPORT='bugs@eggheads.org'
PACKAGE_URL=''
@@ -1334,7 +1334,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Eggdrop 1.9.3 to adapt to many kinds of systems.
+\`configure' configures Eggdrop 1.9.4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1401,7 +1401,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Eggdrop 1.9.3:";;
+ short | recursive ) echo "Configuration of Eggdrop 1.9.4:";;
esac
cat <<\_ACEOF
@@ -1511,7 +1511,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Eggdrop configure 1.9.3
+Eggdrop configure 1.9.4
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2222,7 +2222,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Eggdrop $as_me 1.9.3, which was
+It was created by Eggdrop $as_me 1.9.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -10513,7 +10513,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Eggdrop $as_me 1.9.3, which was
+This file was extended by Eggdrop $as_me 1.9.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -10579,7 +10579,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Eggdrop config.status 1.9.3
+Eggdrop config.status 1.9.4
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/src/mod/compress.mod/configure b/src/mod/compress.mod/configure
index 356916e6d..29f9f2adc 100755
--- a/src/mod/compress.mod/configure
+++ b/src/mod/compress.mod/configure
@@ -1,7 +1,7 @@
#! /bin/sh
-# From configure.ac bc41b3ea.
+# From configure.ac 13ab0170.
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Eggdrop Compress Module 1.9.3.
+# Generated by GNU Autoconf 2.69 for Eggdrop Compress Module 1.9.4.
#
# Report bugs to .
#
@@ -583,8 +583,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='Eggdrop Compress Module'
PACKAGE_TARNAME='eggdrop-compress-module'
-PACKAGE_VERSION='1.9.3'
-PACKAGE_STRING='Eggdrop Compress Module 1.9.3'
+PACKAGE_VERSION='1.9.4'
+PACKAGE_STRING='Eggdrop Compress Module 1.9.4'
PACKAGE_BUGREPORT='bugs@eggheads.org'
PACKAGE_URL=''
@@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Eggdrop Compress Module 1.9.3 to adapt to many kinds of systems.
+\`configure' configures Eggdrop Compress Module 1.9.4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1303,7 +1303,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Eggdrop Compress Module 1.9.3:";;
+ short | recursive ) echo "Configuration of Eggdrop Compress Module 1.9.4:";;
esac
cat <<\_ACEOF
@@ -1383,7 +1383,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Eggdrop Compress Module configure 1.9.3
+Eggdrop Compress Module configure 1.9.4
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1687,7 +1687,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Eggdrop Compress Module $as_me 1.9.3, which was
+It was created by Eggdrop Compress Module $as_me 1.9.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3687,7 +3687,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Eggdrop Compress Module $as_me 1.9.3, which was
+This file was extended by Eggdrop Compress Module $as_me 1.9.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -3740,7 +3740,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Eggdrop Compress Module config.status 1.9.3
+Eggdrop Compress Module config.status 1.9.4
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/src/mod/dns.mod/configure b/src/mod/dns.mod/configure
index c14fa7a18..00072f073 100755
--- a/src/mod/dns.mod/configure
+++ b/src/mod/dns.mod/configure
@@ -1,7 +1,7 @@
#! /bin/sh
-# From configure.ac bc41b3ea.
+# From configure.ac 13ab0170.
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Eggdrop DNS Module 1.9.3.
+# Generated by GNU Autoconf 2.69 for Eggdrop DNS Module 1.9.4.
#
# Report bugs to .
#
@@ -582,8 +582,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='Eggdrop DNS Module'
PACKAGE_TARNAME='eggdrop-dns-module'
-PACKAGE_VERSION='1.9.3'
-PACKAGE_STRING='Eggdrop DNS Module 1.9.3'
+PACKAGE_VERSION='1.9.4'
+PACKAGE_STRING='Eggdrop DNS Module 1.9.4'
PACKAGE_BUGREPORT='bugs@eggheads.org'
PACKAGE_URL=''
@@ -1200,7 +1200,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Eggdrop DNS Module 1.9.3 to adapt to many kinds of systems.
+\`configure' configures Eggdrop DNS Module 1.9.4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1263,7 +1263,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Eggdrop DNS Module 1.9.3:";;
+ short | recursive ) echo "Configuration of Eggdrop DNS Module 1.9.4:";;
esac
cat <<\_ACEOF
@@ -1342,7 +1342,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Eggdrop DNS Module configure 1.9.3
+Eggdrop DNS Module configure 1.9.4
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1476,7 +1476,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Eggdrop DNS Module $as_me 1.9.3, which was
+It was created by Eggdrop DNS Module $as_me 1.9.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3119,7 +3119,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Eggdrop DNS Module $as_me 1.9.3, which was
+This file was extended by Eggdrop DNS Module $as_me 1.9.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -3172,7 +3172,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Eggdrop DNS Module config.status 1.9.3
+Eggdrop DNS Module config.status 1.9.4
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
From 2c493b66ba7dec041dbb3f85a2da5d32e4499245 Mon Sep 17 00:00:00 2001
From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com>
Date: Sun, 11 Dec 2022 20:48:59 +0000
Subject: [PATCH 23/92] Fix typo
---
doc/sphinx_source/tutorials/tlssetup.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx_source/tutorials/tlssetup.rst b/doc/sphinx_source/tutorials/tlssetup.rst
index 23e2ea636..6cc8fff3e 100644
--- a/doc/sphinx_source/tutorials/tlssetup.rst
+++ b/doc/sphinx_source/tutorials/tlssetup.rst
@@ -39,7 +39,7 @@ Eggdrop has the ability to protect botnet (direct bot to bot) communications wit
Configuration File Preparation - Generating Keys
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-If an Eggdrop is going to listen/accept connections on a TLS port (more on that in a moment), it must have a public/private certificate pair generated and configured. For most users, a self-signed certificate is sufficient for encryption (a certificate signed by a certificate authority would be more secure, but obtaining one is outside the scope of this tutorial. However, the implementatino of a signed keypair is no different than a self-signed pair). To generate a self-signed key pair, enter the Eggdrop source directory (the directory you first compiled Eggdrop from, usually named eggdrop-X.Y.Z) and type::
+If an Eggdrop is going to listen/accept connections on a TLS port (more on that in a moment), it must have a public/private certificate pair generated and configured. For most users, a self-signed certificate is sufficient for encryption (a certificate signed by a certificate authority would be more secure, but obtaining one is outside the scope of this tutorial. However, the implementation of a signed keypair is no different than a self-signed pair). To generate a self-signed key pair, enter the Eggdrop source directory (the directory you first compiled Eggdrop from, usually named eggdrop-X.Y.Z) and type::
make sslcert
From b2c9dae3f767c3942eda8b80c30e22ba6e9459fb Mon Sep 17 00:00:00 2001
From: Geo
Date: Sun, 11 Dec 2022 21:26:40 -0500
Subject: [PATCH 24/92] Add systemd option to autobotchk
Patch by: @PeGaSuS-Coder , Geo
Adds a -systemd option to the autobotchk script. Will be considered Beta for now, and based on user feedback go stable in the next release.
---
INSTALL | 8 +-
README | 30 +++++---
doc/html/tutorials/firststeps.html | 23 +++++-
doc/sphinx_source/install/install.rst | 6 +-
doc/sphinx_source/install/readme.rst | 17 +++--
doc/sphinx_source/tutorials/firststeps.rst | 42 +++++++++-
scripts/autobotchk | 89 ++++++++++++++++++----
7 files changed, 171 insertions(+), 44 deletions(-)
diff --git a/INSTALL b/INSTALL
index 064b9ea37..1b355fd85 100644
--- a/INSTALL
+++ b/INSTALL
@@ -115,8 +115,12 @@ Eggdrop into from the previous step]
automatically restart if the machine goes down or (heaven
forbid) the bot should crash. Eggdrop includes a helper script
- to generate a proper crontab script and entry. You can run this
- script by typing:
+ to auto-generate either a systemd or crontab entry. To add a
+ systemd job, run:
+
+ ./scripts/autobotchk [yourconfig.conf] -systemd
+
+ or to add a crontab job, run:
./scripts/autobotchk [yourconfig.conf]
diff --git a/README b/README
index 456773650..9e5bef168 100644
--- a/README
+++ b/README
@@ -156,28 +156,36 @@ COMMAND LINE
Most people never use any of the options except -m and you usually
only need to use that once.
-SETTING UP A CRONTAB
+AUTO-STARTING EGGDROP
Systems go down from time to time, taking your Eggdrop along with it.
You may not be not around to restart it manually, so you can instead use
-your host's crontab system to automatically restart Eggdrop should it
-quit for any reason. Eggdrop comes with an autobotchk shell script
-creates that both checks if your Eggdrop is still running, and a crontab
-entry to run the botchk script every 10 minutes.
+features of the operating system to automatically restart Eggdrop should
+it quit for any reason. Eggdrop comes with an autobotchk shell script
+that can create either a systemd or crontab entry. The systemd option
+will monitor your Eggdrop and a) start it when the machine boots and b)
+restart the Eggdrop if it crashes for any reason. The (older) crontab
+option will check (by default) every 10 minutes to see if your Eggdrop
+is still running, and attempt to restart it if it is not.
- Using autobotchk is probably the fastest way of creating your botchk
- and adding a crontab entry. From the install directory, simply run:
+ To auto-generate a systemd job, from the Eggdrop install directory,
+ simply run:
+
+ ./scripts/autobotchk -systemd
+
+ To auto-geneerate a script to check Eggdrop's status and run it via a
+ crontab entry, simply run:
./scripts/autobotchk
This will crontab your bot using the default setup. If you want a list
- of autobotchk options, type './autobotchk'. An example with options
- would be:
+ of autobotchk options, type './autobotchk'. A crontab example with
+ options would be:
./scripts/autobotchk -noemail -5
- This would setup crontab to run the botchk every 5 minutes and also to
- not send you email saying that it restarted your bot.
+ This would setup crontab to run the botchk every 5 minutes and not
+ send you an email saying that it restarted your bot.
DOCUMENTATION
diff --git a/doc/html/tutorials/firststeps.html b/doc/html/tutorials/firststeps.html
index a176fca34..4a8c80084 100644
--- a/doc/html/tutorials/firststeps.html
+++ b/doc/html/tutorials/firststeps.html
@@ -180,13 +180,15 @@
A common question asked by users is, how can I configure Eggdrop to automatically restart should it die, such as after a reboot? To do that, we use the system’s crontab daemon to run a script (called botchk) every ten minutes that checks if the eggdrop is running. If the eggdrop is not running, the script will restart the bot, with an optional email sent to the user informing them of the action. To make this process as simple as possible, we have included a script that can automatically configure your crontab and botchk scripts for you. To set up your crontab/botchk combo:
+
A common question asked by users is, how can I configure Eggdrop to automatically restart should it die, such as after a reboot? Historically, Eggdrop relied on the host’s crontab system to run a script (called botchk) every ten minutes to see if the eggdrop is running. If the eggdrop is not running, the script will restart the bot, with an optional email sent to the user informing them of the action. Newer systems come with systemd, which can provide better real-time monitoring of processes such as Eggdrop. You probably want to use systemd if your system has it.
diff --git a/doc/sphinx_source/install/install.rst b/doc/sphinx_source/install/install.rst
index ece05c0e4..2a1679844 100644
--- a/doc/sphinx_source/install/install.rst
+++ b/doc/sphinx_source/install/install.rst
@@ -96,7 +96,11 @@ Eggdrop uses the GNU autoconfigure scripts to make things easier.
9. It's advisable to run your bot via crontab, so that it will
automatically restart if the machine goes down or (heaven forbid)
- the bot should crash. Eggdrop includes a helper script to generate a proper crontab script and entry. You can run this script by typing::
+ the bot should crash. Eggdrop includes a helper script to auto-generate either a systemd or crontab entry. To add a systemd job, run::
+
+ ./scripts/autobotchk [yourconfig.conf] -systemd
+
+ or to add a crontab job, run::
./scripts/autobotchk [yourconfig.conf]
diff --git a/doc/sphinx_source/install/readme.rst b/doc/sphinx_source/install/readme.rst
index 385c76265..0a1593dc6 100644
--- a/doc/sphinx_source/install/readme.rst
+++ b/doc/sphinx_source/install/readme.rst
@@ -142,21 +142,24 @@ Command Line
Most people never use any of the options except -m and you usually only
need to use that once.
-Setting up a Crontab
---------------------
+Auto-starting Eggdrop
+---------------------
-Systems go down from time to time, taking your Eggdrop along with it. You may not be not around to restart it manually, so you can instead use your host's crontab system to automatically restart Eggdrop should it quit for any reason. Eggdrop comes with an autobotchk shell script creates that both checks if your Eggdrop is still running, and a crontab entry to run the botchk script every 10 minutes.
+Systems go down from time to time, taking your Eggdrop along with it. You may not be not around to restart it manually, so you can instead use features of the operating system to automatically restart Eggdrop should it quit for any reason. Eggdrop comes with an autobotchk shell script that can create either a systemd or crontab entry. The systemd option will monitor your Eggdrop and a) start it when the machine boots and b) restart the Eggdrop if it crashes for any reason. The (older) crontab option will check (by default) every 10 minutes to see if your Eggdrop is still running, and attempt to restart it if it is not.
- Using autobotchk is probably the fastest way of creating your botchk and adding a crontab entry. From the install directory, simply run::
+ To auto-generate a systemd job, from the Eggdrop install directory, simply run::
- ./scripts/autobotchk
+ ./scripts/autobotchk -systemd
+ To auto-geneerate a script to check Eggdrop's status and run it via a crontab entry, simply run::
+
+ ./scripts/autobotchk
- This will crontab your bot using the default setup. If you want a list of autobotchk options, type './autobotchk'. An example with options would be::
+ This will crontab your bot using the default setup. If you want a list of autobotchk options, type './autobotchk'. A crontab example with options would be::
./scripts/autobotchk -noemail -5
- This would setup crontab to run the botchk every 5 minutes and also to not send you email saying that it restarted your bot.
+ This would setup crontab to run the botchk every 5 minutes and not send you an email saying that it restarted your bot.
Documentation
-------------
diff --git a/doc/sphinx_source/tutorials/firststeps.rst b/doc/sphinx_source/tutorials/firststeps.rst
index c3c1c9043..71330a631 100644
--- a/doc/sphinx_source/tutorials/firststeps.rst
+++ b/doc/sphinx_source/tutorials/firststeps.rst
@@ -80,15 +80,18 @@ which will enforce the s, n, and t flags on a channel.
Automatically restarting an Eggdrop
-----------------------------------
-A common question asked by users is, how can I configure Eggdrop to automatically restart should it die, such as after a reboot? To do that, we use the system's crontab daemon to run a script (called botchk) every ten minutes that checks if the eggdrop is running. If the eggdrop is not running, the script will restart the bot, with an optional email sent to the user informing them of the action. To make this process as simple as possible, we have included a script that can automatically configure your crontab and botchk scripts for you. To set up your crontab/botchk combo:
+A common question asked by users is, how can I configure Eggdrop to automatically restart should it die, such as after a reboot? Historically, Eggdrop relied on the host's crontab system to run a script (called botchk) every ten minutes to see if the eggdrop is running. If the eggdrop is not running, the script will restart the bot, with an optional email sent to the user informing them of the action. Newer systems come with systemd, which can provide better real-time monitoring of processes such as Eggdrop. You probably want to use systemd if your system has it.
+
+Crontab Method (Old)
+^^^^^^^^^^^^^^^^^^^^
1. Enter the directory you installed your Eggdrop to. Most commonly, this is ~/eggdrop (also known as /home//eggdrop).
-2. Just humor us- run ``./scripts/autobotchk`` without any arguments and read the options available to you. They're listed there for a reason!
+2. Just humor us- run ``./scripts/autobotchk`` without any arguments and read the options available to you. They're listed there for a reason!
-3. If you don't want to customize anything via the options listed in #2, you can start the script simply by running::
+3. If you don't want to customize anything via the options listed in #2, you can install a crontab job to start Eggdrop simply by running::
- ./scripts/autobotchk yourEggdropConfigNameHere.conf
+ ./scripts/autobotchk yourEggdropConfigNameHere.conf
4. Review the output of the script, and verify your new crontab entry by typing::
@@ -100,6 +103,37 @@ By default, it should create an entry that looks similar to::
This will run the generated botchk script every ten minutes and restart your Eggdrop if it is not running during the check. Also note that if you run autobotchk from the scripts directory, you'll have to manually specify your config file location with the -dir option. To remove a crontab entry, use ``crontab -e`` to open the crontab file in your system's default editor and remove the crontab line.
+Systemd Method (Newer Systems)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+1. Enter the directory you installed your Eggdrop to. Most commonly, this is ~/eggdrop (also known as /home//eggdrop).
+
+2. Install the systemd job for Eggdrop simply by running::
+
+ ./scripts/autobotchk yourEggdropConfigNameHere.conf -systemd
+
+3. Note the output at the end of the script informing you of the command you can use to start/stop the Eggdrop in thee future. For example, to manually start the Eggdrop, use::
+
+ systemctl --user start .service
+
+To stop Eggdrop, use::
+
+ systemctl --user stop .service
+
+To rehash (not reload) Eggdrop, use::
+
+ systemctl --user reload .service
+
+(Yes, we acknowledge the confusion that the systemd reload command will execute the Eggdrop '.rehash' command, not the '.reload' command. Unfortunately, systemd did not consult us when choosing its commands!)
+
+To prevent Eggdrop from automatically running after a system start, use::
+
+ systemctl --user disable .service
+
+To re-enable Eggdrop automatically starting after a system start, use::
+
+ systemctl --user enable .service
+
Authenticating with NickServ
----------------------------
diff --git a/scripts/autobotchk b/scripts/autobotchk
index d517717f9..801b80dc5 100755
--- a/scripts/autobotchk
+++ b/scripts/autobotchk
@@ -3,6 +3,8 @@
# Copyright (C) 1999-2003 Jeff Fisher (guppy@eggheads.org)
# Copyright (C) 2004-2022 Eggheads Development Team
#
+# systemd formating contributed by PeGaSuS
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
@@ -89,11 +91,16 @@ exec tclsh$lastver "$0" ${1+"$@"}
# with len > handlen, for (botnet-)nicks with \[ \] and for
# $(botnet-)nick used in pidfile, userfile or (botnet-)nick
# 19Apr2017: Fix running this from a non-eggdrop dir.
+# 28Nov2023: Added -systemd option, to (duh) create a systemd job
if {$argc == 0} {
puts "\nusage: $argv0 \[options\] \[additional configs\]"
puts "Options:"
puts "--------"
+ puts " systemd options:"
+ puts " -systemd (install systemd job instead of cron)"
+ puts ""
+ puts " crontab options:"
puts " -dir (directory to run autobotchk in)"
puts " -noemail (discard crontab e-mails)"
puts " -5 (5 minute checks)"
@@ -126,7 +133,7 @@ proc newsplit {text {split " "}} {
}
puts "\nautobotchk 1.11, (C) 1999-2003 Jeff Fisher (guppy@eggheads.org)"
-puts "\n (C) 2004-2016 Eggheads Development Team"
+puts " (C) 2004-2022 Eggheads Development Team"
puts "------------------------------------------------------------\n"
set mainconf [newsplit argv]
@@ -134,12 +141,15 @@ set confs [list $mainconf]
set dir [pwd]
set delay 10
set email 1
+set systemd 0
+catch {exec which kill} kill
# If you renamed your eggdrop binary, you should change this variable
set binary "eggdrop"
while {[set opt [newsplit argv]] != ""} {
switch -- $opt {
+ "-systemd" { set systemd 1 }
"-time" -
"-1" { set delay 1 }
"-5" { set delay 5 }
@@ -257,17 +267,64 @@ foreach config $confs {
}
set nick [string range [subst -nocommands $nick] 0 $handlen]
set botnet-nick [string range [subst -nocommands ${botnet-nick}] 0 $handlen]
- if {![info exists pidfile]} {
- puts " Defaulting \$pidfile to \"pid.${botnet-nick}\""
- set pidfile "pid.${botnet-nick}"
+
+### systemd stuff
+if {$systemd} {
+ puts "Enabling user lingering..."
+ if {[catch {exec loginctl enable-linger} res]} {
+ puts "Oops, something went wrong. Is systemd running on this system?"
+ exit
}
- set pidfile [subst -nocommands $pidfile]
- if {[catch {open $dir/${botnet-nick}.botchk w} fd]} {
- puts " *** ERROR: unable to open '${botnet-nick}.botchk' for writing"
+ puts "Creating systemd directory..."
+ catch {file mkdir ~/.config/systemd/user } res
+ if {[catch {open ~/.config/systemd/user/${botnet-nick}.service w} fd]} {
+ puts " *** ERROR: unable to open '${botnet-nick}.service' for writing"
puts ""
exit
}
- puts $fd "#! /bin/sh
+ puts $fd "### Eggdrop systemd unit, generated by autosystemd"
+ puts $fd ""
+ puts $fd "\[Unit\]"
+ puts $fd "Description=${botnet-nick} (Eggdrop)"
+ puts $fd "After=default.target"
+ puts $fd ""
+ puts $fd "\[Service\]"
+ puts $fd "WorkingDirectory=${dir}"
+ puts $fd "ExecStart=${dir}/eggdrop ${config}"
+ puts $fd "ExecReload=${kill} -s HUP \$MAINPID"
+ puts $fd "Type=forking"
+ puts $fd "Restart=on-abnormal"
+ puts $fd ""
+ puts $fd "\[Install\]"
+ puts $fd "WantedBy=default.target"
+ close $fd
+
+ catch {exec systemctl --user enable ${botnet-nick}.service} res
+ puts $res
+ puts "systemd job successfully installed as '${botnet-nick}.service'."
+ puts "* Use 'systemctl --user ${botnet-nick}.service' to control your Eggdrop"
+ puts "Starting Eggdrop..."
+ if {[catch {exec systemctl --user start ${botnet-nick}.service} res]} {
+ puts "ERROR: Eggdrop did not start."
+ puts $res
+ } else {
+ puts "Success."
+ }
+ exit
+}
+
+
+if {![info exists pidfile]} {
+ puts " Defaulting \$pidfile to \"pid.${botnet-nick}\""
+ set pidfile "pid.${botnet-nick}"
+}
+set pidfile [subst -nocommands $pidfile]
+if {[catch {open $dir/${botnet-nick}.botchk w} fd]} {
+ puts " *** ERROR: unable to open '${botnet-nick}.botchk' for writing"
+ puts ""
+ exit
+}
+puts $fd "#! /bin/sh
#
# ${botnet-nick}.botchk (generated on [clock format [clock seconds] -format "%B %d, %Y @ %I:%M%p"])
#
@@ -360,14 +417,14 @@ fi
exit 0
"
- close $fd
- puts "Wrote '${botnet-nick}.botchk' successfully ([file size $dir/${botnet-nick}.botchk] bytes)"
- if {[catch {exec chmod u+x $dir/${botnet-nick}.botchk} 0]} {
- puts " *** ERROR: unable to 'chmod u+x' the output file"
- puts ""
- exit
- }
- puts -nonewline "Scanning crontab entries ... "
+close $fd
+puts "Wrote '${botnet-nick}.botchk' successfully ([file size $dir/${botnet-nick}.botchk] bytes)"
+if {[catch {exec chmod u+x $dir/${botnet-nick}.botchk} 0]} {
+ puts " *** ERROR: unable to 'chmod u+x' the output file"
+ puts ""
+ exit
+}
+puts -nonewline "Scanning crontab entries ... "
set tmp ".autobotchk[clock clicks].[pid]"
set cronbotchk [string map {\\ \\\\ \[ \\\[ \] \\\]} "${botnet-nick}.botchk"]
From c76182c8687715d440b4e25385e171fe5175c67e Mon Sep 17 00:00:00 2001
From: Geo
Date: Mon, 12 Dec 2022 17:32:00 -0500
Subject: [PATCH 25/92] Update NEWS for 1.9.4
---
NEWS | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/NEWS b/NEWS
index 44a6d3594..6dfe4de3d 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,8 @@ Eggdrop v1.9.4:
General changes:
- Fixed a DNS bug causing Eggdrop to often hang on DCC or telnet
connections
+ - BETA: Added -systemd option to autobotchk script to restart Eggdrop via
+ systemd instead of cron
- Reverted matchattr match syntax to previous functionality. Matching
against "-" as a flag will once again successfully match against "no"
flags, instead of returning an error.
@@ -36,6 +38,8 @@ Eggdrop v1.9.4:
- Moved the 'gotmsg' function back as a raw bind. It was inadvertantly
moved to a rawt bind in 1.9.3, causing issuse with scripts attempting to
unbind this internal reference
+ Module changes:
+ - None
Eggdrop config changes:
- None
From 15949fb0675bc6a17916022cd7b9f3b39c5b5e52 Mon Sep 17 00:00:00 2001
From: Geo
Date: Mon, 12 Dec 2022 17:43:41 -0500
Subject: [PATCH 26/92] update docs for 1.9.4
---
doc/html/about/about.html | 2 +-
doc/html/about/legal.html | 2 +-
doc/html/index.html | 4 ++--
doc/html/install/install.html | 12 +++++++++---
doc/html/install/readme.html | 20 +++++++++++--------
doc/html/install/upgrading.html | 2 +-
doc/html/modules/included.html | 2 +-
doc/html/modules/index.html | 2 +-
doc/html/modules/mod/assoc.html | 2 +-
doc/html/modules/mod/blowfish.html | 2 +-
doc/html/modules/mod/channels.html | 2 +-
doc/html/modules/mod/compress.html | 2 +-
doc/html/modules/mod/console.html | 2 +-
doc/html/modules/mod/ctcp.html | 2 +-
doc/html/modules/mod/dns.html | 2 +-
doc/html/modules/mod/filesys.html | 2 +-
doc/html/modules/mod/ident.html | 2 +-
doc/html/modules/mod/irc.html | 2 +-
doc/html/modules/mod/notes.html | 2 +-
doc/html/modules/mod/pbkdf2.html | 2 +-
doc/html/modules/mod/seen.html | 2 +-
doc/html/modules/mod/server.html | 2 +-
doc/html/modules/mod/share.html | 2 +-
doc/html/modules/mod/transfer.html | 2 +-
doc/html/modules/mod/twitch.html | 2 +-
doc/html/modules/mod/uptime.html | 2 +-
doc/html/modules/mod/woobie.html | 2 +-
doc/html/modules/writing.html | 2 +-
doc/html/objects.inv | Bin 1279 -> 1319 bytes
doc/html/search.html | 2 +-
doc/html/searchindex.js | 2 +-
doc/html/tutorials/firstscript.html | 2 +-
doc/html/tutorials/firststeps.html | 24 +++++++++++++++++++++--
doc/html/tutorials/setup.html | 2 +-
doc/html/tutorials/tlssetup.html | 4 ++--
doc/html/using/accounts.html | 2 +-
doc/html/using/bans.html | 2 +-
doc/html/using/botnet.html | 2 +-
doc/html/using/core.html | 2 +-
doc/html/using/features.html | 2 +-
doc/html/using/ipv6.html | 2 +-
doc/html/using/ircv3.html | 2 +-
doc/html/using/partyline.html | 2 +-
doc/html/using/patch.html | 2 +-
doc/html/using/pbkdf2info.html | 2 +-
doc/html/using/tcl-commands.html | 8 ++++----
doc/html/using/text-sub.html | 2 +-
doc/html/using/tls.html | 2 +-
doc/html/using/tricks.html | 2 +-
doc/html/using/twitch-tcl-commands.html | 2 +-
doc/html/using/twitchinfo.html | 2 +-
doc/html/using/users.html | 2 +-
doc/sphinx_source/using/tcl-commands.rst | 6 ++++--
doc/tcl-commands.doc | 13 ++++++------
54 files changed, 107 insertions(+), 74 deletions(-)
diff --git a/doc/html/about/about.html b/doc/html/about/about.html
index aaa966ae2..1da39cdbe 100644
--- a/doc/html/about/about.html
+++ b/doc/html/about/about.html
@@ -177,7 +177,7 @@
Systems go down from time to time, taking your Eggdrop along with it. You may not be not around to restart it manually, so you can instead use your host’s crontab system to automatically restart Eggdrop should it quit for any reason. Eggdrop comes with an autobotchk shell script creates that both checks if your Eggdrop is still running, and a crontab entry to run the botchk script every 10 minutes.
Systems go down from time to time, taking your Eggdrop along with it. You may not be not around to restart it manually, so you can instead use features of the operating system to automatically restart Eggdrop should it quit for any reason. Eggdrop comes with an autobotchk shell script that can create either a systemd or crontab entry. The systemd option will monitor your Eggdrop and a) start it when the machine boots and b) restart the Eggdrop if it crashes for any reason. The (older) crontab option will check (by default) every 10 minutes to see if your Eggdrop is still running, and attempt to restart it if it is not.
-
Using autobotchk is probably the fastest way of creating your botchk and adding a crontab entry. From the install directory, simply run:
+
To auto-generate a systemd job, from the Eggdrop install directory, simply run:
+
./scripts/autobotchk<Eggdropconfigfile>-systemd
+
+
+
To auto-geneerate a script to check Eggdrop’s status and run it via a crontab entry, simply run:
./scripts/autobotchk<Eggdropconfigfile>
-
This will crontab your bot using the default setup. If you want a list of autobotchk options, type ‘./autobotchk’. An example with options would be:
+
This will crontab your bot using the default setup. If you want a list of autobotchk options, type ‘./autobotchk’. A crontab example with options would be:
./scripts/autobotchk<Eggdropconfigfile>-noemail-5
-
This would setup crontab to run the botchk every 5 minutes and also to not send you email saying that it restarted your bot.
+
This would setup crontab to run the botchk every 5 minutes and not send you an email saying that it restarted your bot.
If an Eggdrop is going to listen/accept connections on a TLS port (more on that in a moment), it must have a public/private certificate pair generated and configured. For most users, a self-signed certificate is sufficient for encryption (a certificate signed by a certificate authority would be more secure, but obtaining one is outside the scope of this tutorial. However, the implementatino of a signed keypair is no different than a self-signed pair). To generate a self-signed key pair, enter the Eggdrop source directory (the directory you first compiled Eggdrop from, usually named eggdrop-X.Y.Z) and type:
+
If an Eggdrop is going to listen/accept connections on a TLS port (more on that in a moment), it must have a public/private certificate pair generated and configured. For most users, a self-signed certificate is sufficient for encryption (a certificate signed by a certificate authority would be more secure, but obtaining one is outside the scope of this tutorial. However, the implementation of a signed keypair is no different than a self-signed pair). To generate a self-signed key pair, enter the Eggdrop source directory (the directory you first compiled Eggdrop from, usually named eggdrop-X.Y.Z) and type:
In the Bind Types section (and other commands, such as `matchattr`_), you will see several references to the “flags” argument. The “flags” argument takes a flag mask, which is a value that represents the type of user that is allowed to trigger the procedure associated to that bind. The flags can be any of the standard Eggdrop flags (o, m, v, etc). Additionally, when used by itself, a “-” or “*” can be used to skip processing for a flag type. A flag mask has three sections to it- global, channel, and bot flag sections. Each section is separated by the | or & logical operators ( the | means “OR” and the & means “AND; if nothing proceeds the flag then Eggdrop assumes it to be an OR). Additionally, a ‘+’ and ‘-‘ can be used in front of a flag to check if the user does (+) have it, or does not (-) have it.
+
In the Bind Types section (and other commands, such as matchattr), you will see several references to the “flags” argument. The “flags” argument takes a flag mask, which is a value that represents the type of user that is allowed to trigger the procedure associated to that bind. The flags can be any of the standard Eggdrop flags (o, m, v, etc). Additionally, when used by itself, a “-” or “*” can be used to skip processing for a flag type. A flag mask has three sections to it- global, channel, and bot flag sections. Each section is separated by the | or & logical operators ( the | means “OR” and the & means “AND; if nothing proceeds the flag then Eggdrop assumes it to be an OR). Additionally, a ‘+’ and ‘-‘ can be used in front of a flag to check if the user does (+) have it, or does not (-) have it.
The easiest way to explain how to build a flag mask is by demonstration. A flag mask of “v” by itself means “has a global v flag”. To also check for a channel flag, you would use the flag mask “v|v”. This checks if the user has a global “v” flag, OR a channel “v” flag (again, the | means “OR” and ties the two types of flags together). You could change this mask to be “v&v”, which would check if the user has a global “v” flag AND a channel “v” flag. Lastly, to check if a user ONLY has a channel flag, you would use “*|v” as a mask, which would not check global flags but does check if the user had a channel “v” flag.
You will commonly see flag masks for global flags written “ov”; this is the same as “|ov” or “*|ov”.
Some additional examples:
@@ -2929,7 +2929,7 @@
Flag Masks|o). It is unknown where and why this practice started, but as a style tip, Eggdrop developers recommend using a ‘*’ to skip processing, so as not to confuse a single “-” meaning “skip processing” with a preceding “-ov” which means “not these flags”.
+
As a side note, Tcl scripts historically have used a ‘-‘ to skip processing of a flag type (Example: -|o). It is unknown where and why this practice started, but as a style tip, Eggdrop developers recommend using a ‘*’ to skip processing, so as not to confuse a single “-” meaning “skip processing” with a preceding “-ov” which means “not these flags”.
Writing an Eggdrop Scriptcore Tcl language commands, especially the string- and list-related commands, as well as Eggdrop’s own library of custom Tcl commands, located in tcl-commands.doc
+get familiar with the core Tcl language commands, especially the string- and list-related commands, as well as Eggdrop’s own library of custom Tcl commands, located in tcl-commands.doc
If you have the .tcl command enabled, you can load a script by typing
‘.tcl source script/file.tcl’ to load it. Otherwise, add it to your config
file like normal (examples to do so are at the bottom of the config file) and
@@ -176,7 +176,7 @@
This is a bind. This sets up an action that Eggdrop will react to. You can read all the binds that Eggdrop uses here. Generally, we like to place all binds towards the top of the script so that they are together and easy to find. Now, let’s look at documentation of the bind join together.
What the C handler does is explained later, because a lot happens before it is actually called. IntFunc is a generic function pointer that returns an int with arbitrary arguments.
+
H_dcc can be exported from core and imported into modules as any other variable or function. That should be explained in a separate document.
check_tcl_bind is used by all binds and does the following:
+
/* Generic function to call one/all matching binds
+ * @param[in] tcl_bind_list_t *tl Bind table (e.g. H_dcc)
+ * @param[in] const char *match String to match the bind-masks against
+ * @param[in] struct flag_record *atr Flags of the user calling the bind
+ * @param[in] const char *param Arguments to add to the bind callback proc (e.g. " $_dcc1 $_dcc2 $_dcc3")
+ * @param[in] int match_type Matchtype and various flags
+ * @returns int Match result code
+ */
+
+/* Source code changed, only illustrative */
+int check_tcl_bind(tcl_bind_list_t *tl, const char *match, struct flag_record *atr, const char *param, int match_type) {
+ int x = BIND_NOMATCH;
+ for (tm = tl->first; tm && !finish; tm_last = tm, tm = tm->next) {
+ /* Check if bind mask matches */
+ if (!check_bind_match(match, tm->mask, match_type))
+ continue;
+ for (tc = tm->first; tc; tc = tc->next) {
+ /* Check if the provided flags suffice for this command. */
+ if (check_bind_flags(&tc->flags, atr, match_type)) {
+ tc->hits++;
+ /* not much more than Tcl_Eval(interp, "<procname> <arguments>"); and grab the result */
+ x = trigger_bind(tc->func_name, param, tm->mask);
+ }
+ }
+ }
+ return x;
+}
+
+
+
The supplied flags to check_tcl_bind in check_tcl_dcc are what defines how matching is performed.
+
In the case of a DCC bind we had:
+
+
Matchtype MATCH_PARTIAL: Prefix-Matching if the command can be uniquely identified (e.g. dcc .help calls .help)
+
Additional flag BIND_USE_ATTR: Flags are checked
+
Additional flag BIND_HAS_BUILTINS: Something with flag matching, unsure
+
+
For details on the available match types (wildcard matching, exact matching, etc.) see src/tclegg.h. Additional flags are also described there as well as the return codes of check_tcl_bind (e.g. BIND_NOMATCH).
+
Note: For a bind type to be stackable it needs to be registered with HT_STACKABLE AND check_tcl_bind must be called with BIND_STACKABLE.
To create a C function that is called by the bind, Eggdrop provides the add_builtins function.
+
/* Add a list of C function callbacks to a bind
+ * @param[in] tcl_bind_list_t * the bind type (e.g. H_dcc)
+ * @param[in] cmd_t * a NULL-terminated table of binds:
+ * cmd_t *mycmds = {
+ * {char *name, char *flags, IntFunc function, char *tcl_name},
+ * ...,
+ * {NULL, NULL, NULL, NULL}
+ * };
+ */
+void add_builtins(tcl_bind_list_t *tl, cmd_t *cc) {
+ char p[1024];
+ cd_tcl_cmd tclcmd;
+
+ tclcmd.name = p;
+ tclcmd.callback = tl->func;
+ for (i = 0; cc[i].name; i++) {
+ /* Create Tcl command with automatic or given names *<bindtype>:<funcname>, e.g.
+ * - H_raw {"324", "", got324, "irc:324"} => *raw:irc:324
+ * - H_dcc {"boot", "t", cmd_boot, NULL} => *dcc:boot
+ */
+ egg_snprintf(p, sizeof p, "*%s:%s", tl->name, cc[i].funcname ? cc[i].funcname : cc[i].name);
+ /* arbitrary void * can be included, we include C function pointer */
+ tclcmd.cdata = (void *) cc[i].func;
+ add_cd_tcl_cmd(tclcmd);
+ bind_bind_entry(tl, cc[i].flags, cc[i].name, p);
+ }
+}
+
+
+
It automatically creates Tcl commands (e.g. *dcc:cmd_boot) that will call the C handler from add_bind_table in the first section Bind Table Creation and it gets a context (void *) argument with the C function it is supposed to call (e.g. cmd_boot()).
+
Now we can actually look at the C function handler for dcc as an example and what it has to implement.
This is finally the part where we see the arguments a C function gets for a DCC bind as opposed to a Tcl proc.
+
F(dcc[idx].user, idx, argv[3]):
+
+
User information as struct userrec *
+
IDX as int
+
The 3rd string argument from the Tcl call to *dcc:cmd_boot, which was $_dcc3 which was args to check_tcl_dcc which was everything after the dcc command
+
+
So this is how we register C callbacks for binds with the correct arguments:
An Eggdrop module is a piece of C code that can be loaded (or unloaded) onto the core Eggdrop code. A module differs from a Tcl script in that modules must be compiled and then loaded, whereas scripts can be edited and loaded directly. Importantly, a module can be written to create new Eggdrop-specific Tcl commands and binds that a user can then use in a Tcl script. For example, the server module loaded by Eggdrop is what creates the “jump” Tcl command, which causes tells the Eggdrop to jump to the next server in its server list.
+
There are a few required functions a module must perform in order to properly work with Eggdrop
A module should include license information. This tells other open source users how they are allowed to use the code. Eggdrop uses GPL 2.0 licensing, and our license information looks like this:
This creates a function table that is exported to Eggdrop. In other words, these are commands that are made available to the Eggdrop core and other modules. At minimum, the following functions must be exported:
At this point, you should have a module that compiles and can be loaded by Eggdrop- but dosen’t really do anything yet. We’ll change that in the next section!
A partyline command function accepts three arguments- a pointer to the user record of the user that called the command; the idx the user was on when calling the command; and a pointer to the arguments appended to the command. A command should immediately log that it was called to the LOG_CMDS log level, and then run its desired code. This simple example prints “WOOBIE” to the partyline idx of the user that called it:
Eggdrop uses the Tcl C API library to interact with the Tcl interpreter. Learning this API is outside the scope of this tutorial, but this example Tcl command will echo the provided argument:
A Tcl bind is a command that is activated when a certain condition is met. With Eggdrop, these are usually linked to receiving messages or other IRC events. To create a bind, you must first register the bind type with Eggdrop when the module is loaded (you added the woobie_start() and woobie_close functions earlier, you still need all that earlier code in here as well):
Here, “woobie” is the name of the bind (similar to the PUB, MSG, JOIN types of binds you already see in tcl-commands.doc). HT_STACKABLE means you can have multiple binds of this type. “woobie_2char” defines how many arguments the bind will take, and we’ll talk about that next.
Like before, BADARGS still checks that the number of arguments passed is correct, and outputs help text if it is not. The rest is boilerplate code to pass the arguments when the bind is called.
To call the bind, Eggdrop coding style it to name that function “check_tcl_bindname”. So here, whenever we reach a point in code that should trigger the bind, we’ll call check_tcl_woobie() and pass the arguments we defined- in this case, two arguments that woobie_2char was created to handle. Here is some sample code:
Now that we have encountered a condition that triggers the bind, we need to check it against the binds the user has loaded in scripts and see if it matches those conditions. This is done with check_tcl_bind(), called with the bind type, the userhost of the user, the flag record of the user if it exists, the bind arguments, and bind options.
Eggdrop was created around December 1993 to help stop the incessant wars
on #gayteen. It spawned from another bot that was in the process of being
@@ -139,19 +136,20 @@
The Eggdrop bot is Copyright (C) by Robey Pointer. As of January 1997, Eggdrop is distributed according to the GNU General Public License. There should be a copy of this license in the COPYING file. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As of Eggdrop 1.3.28, all changes made by the Eggheads Development Team to the Eggdrop source code and any related files are Copyright (C) by Eggheads Development Team. The source code will still be distributed according to the GNU General Public License as Robey Pointer did in the past. Releases previous to 1.0m were made using a different licensing scheme. You may, at your option, use the GNU General Public License on those versions (instead of the license packaged with them) with Robey’s blessing. For any versions bearing a copyright date of 1997 or later, you have no choice - you must use the GNU General Public License.
The files match.c, net.c and blowfish.c are exempt from the above restrictions. match.c is original code by Chris Fuller and has been placed by him into the public domain. net.c is by Robey has placed it in the public domain. blowfish.c is by various sources and is in the public domain as well. All 3 files contain useful functions that could easily be ported to other applications.
Tcl is by John Ousterhout and is in no way affiliated with Eggdrop. It likely has its own set of copyrights and what-nots.
There is no warranty, implied or whatever. You use this software at your own risk, no matter what purpose you put it to.
Eggdrop is a free, open source software program built to assist in managing an IRC channel. It is the world’s oldest actively-maintained IRC bot and was designed to be easily used and expanded on via it’s ability to run Tcl scripts. Eggdrop can join IRC channels and perorm automated tasks such as protecting the channel from abuse, assisting users obtain their op/voice status, provide information and greetings, host games, etc.
Eggdrop requires Tcl (and its development header files) to be present on the system it is compiled on. It is also strongly encouraged to install openssl (and its development header files) to enable TLS-protected network communication.
This is the quick install guide; if you have had little or no experience
with UNIX or Eggdrop, READ THE README FILE NOW! This file is best for
experienced users.
For more information on compiling Eggdrop, see the Compile Guide in
doc/COMPILE-GUIDE (and of course, the README FILE).
Eggdrop uses the GNU autoconfigure scripts to make things easier.
-
-
Type ‘./configure’ from the Eggdrop directory. The configure script
-
will determine how your system is set up and figure out how to
+
+
Type ‘./configure’ from the Eggdrop directory. The configure script
will determine how your system is set up and figure out how to
correctly compile Eggdrop. It will also try to find Tcl, which is
required to compile.
-
-
Type either ‘make config’ or ‘make iconfig’ to determine which
-
modules will be compiled. ‘make config’ compiles the default modules
+
+
Type either ‘make config’ or ‘make iconfig’ to determine which
modules will be compiled. ‘make config’ compiles the default modules
(everything but woobie.mod). If you want to choose which modules to
compile, use ‘make iconfig’.
-
-
Type ‘make’ from the Eggdrop directory, or to force a statically
-
linked module bot, type ‘make static’. Otherwise, the Makefile will
+
+
Type ‘make’ from the Eggdrop directory, or to force a statically
linked module bot, type ‘make static’. Otherwise, the Makefile will
compile whatever type of bot the configure script determined your
system will support. Dynamic is always the better way to go if
possible. There are also the ‘debug’ and ‘sdebug’ (static-debug)
@@ -145,9 +139,8 @@