From 6bec2d698c3c615dc5a1fca43a97affadc651cca Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Sat, 17 Dec 2022 19:11:33 +0000 Subject: [PATCH 01/35] increase logfile length --- src/tclmisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tclmisc.c b/src/tclmisc.c index 801ee4bce..f39e13322 100644 --- a/src/tclmisc.c +++ b/src/tclmisc.c @@ -73,7 +73,7 @@ int expmem_tclmisc() static int tcl_logfile STDVAR { int i; - char s[151]; + char s[256]; BADARGS(1, 4, " ?logModes channel logFile?"); @@ -81,7 +81,7 @@ static int tcl_logfile STDVAR /* They just want a list of the logfiles and modes */ for (i = 0; i < max_logs; i++) if (logs[i].filename != NULL) { - egg_snprintf(s, sizeof s, "%s %s %s", masktype(logs[i].mask), + snprintf(s, sizeof s, "%s %s %s", masktype(logs[i].mask), logs[i].chname, logs[i].filename); Tcl_AppendElement(interp, s); } From e3983abc36160237ba469478d52d567deb12147b Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Mon, 19 Dec 2022 15:41:20 +0000 Subject: [PATCH 02/35] Fix some year 2038 problems Found by: michaelortmann Patch by: michaelortmann and thommey Fix time_t handling (buffer size, type and format specifier) POSIX requires time_t to be an integer type, but does not mandate that it be signed or unsigned. time_t to string conversion used buffersize 11, 10 chars + NULL-terminator, would overflow with unixtime >9999999999 (year 2286) --- src/botcmd.c | 4 ++-- src/dns.c | 2 +- src/main.c | 5 +++-- src/mod/blowfish.mod/blowfish.c | 2 +- src/mod/channels.mod/tclchan.c | 14 +++----------- src/mod/irc.mod/cmdsirc.c | 18 +++++++++--------- src/mod/irc.mod/tclirc.c | 4 ++-- src/mod/share.mod/share.c | 7 ++++--- src/tcldcc.c | 18 ++++++------------ src/tclmisc.c | 4 ++-- src/tcluser.c | 12 +++--------- src/userrec.c | 6 +++--- 12 files changed, 39 insertions(+), 57 deletions(-) diff --git a/src/botcmd.c b/src/botcmd.c index 2757026a1..60871b197 100644 --- a/src/botcmd.c +++ b/src/botcmd.c @@ -837,8 +837,8 @@ static void bot_traced(int idx, char *par) if (*c == ':') j++; } - dprintf(i, "%s -> %s (%lu secs, %d hop%s)\n", BOT_TRACERESULT, p, - now - t, j, (j != 1) ? "s" : ""); + dprintf(i, "%s -> %s (%" PRId64 " secs, %d hop%s)\n", BOT_TRACERESULT, + p, (int64_t) (now - t), j, (j != 1) ? "s" : ""); } else dprintf(i, "%s -> %s\n", BOT_TRACERESULT, p); } diff --git a/src/dns.c b/src/dns.c index 6d5c67f79..48454742b 100644 --- a/src/dns.c +++ b/src/dns.c @@ -86,7 +86,7 @@ static void eof_dcc_dnswait(int idx) static void display_dcc_dnswait(int idx, char *buf) { - sprintf(buf, "dns waited %lis", (long) (now - dcc[idx].timeval)); + sprintf(buf, "dns waited %" PRId64 "s", (int64_t) (now - dcc[idx].timeval)); } static int expmem_dcc_dnswait(void *x) diff --git a/src/main.c b/src/main.c index d4bee020c..7fff6c6fe 100644 --- a/src/main.c +++ b/src/main.c @@ -651,13 +651,14 @@ static void core_secondly() /* In case for some reason more than 1 min has passed: */ while (nowmins != lastmin) { /* Timer drift, dammit */ - debug1("timer: drift (%f seconds)", difftime(nowmins, lastmin)); + debug1("timer: drift (%" PRId64 " seconds)", (int64_t) (nowmins - lastmin)); i++; ++lastmin; call_hook(HOOK_MINUTELY); } if (i > 1) - putlog(LOG_MISC, "*", "(!) timer drift -- spun %f minutes", difftime(nowmins, lastmin)/60); + putlog(LOG_MISC, "*", "(!) timer drift -- spun %" PRId64 " minutes", + ((int64_t) (nowmins - lastmin)) / 60); miltime = (nowtm.tm_hour * 100) + (nowtm.tm_min); if (((int) (nowtm.tm_min / 5) * 5) == (nowtm.tm_min)) { /* 5 min */ call_hook(HOOK_5MINUTELY); diff --git a/src/mod/blowfish.mod/blowfish.c b/src/mod/blowfish.mod/blowfish.c index af03c8f1a..867efc30d 100644 --- a/src/mod/blowfish.mod/blowfish.c +++ b/src/mod/blowfish.mod/blowfish.c @@ -153,7 +153,7 @@ static void blowfish_report(int idx, int details) dprintf(idx, " %d of %d boxes in use:", tot, BOXES); for (i = 0; i < BOXES; i++) if (box[i].P != NULL) { - dprintf(idx, " (age: %f)", difftime(now, box[i].lastuse)); + dprintf(idx, " (age: %" PRId64 ")", (int64_t) (now - box[i].lastuse)); } dprintf(idx, "\n"); } diff --git a/src/mod/channels.mod/tclchan.c b/src/mod/channels.mod/tclchan.c index 06b33b8d3..7f13f6197 100644 --- a/src/mod/channels.mod/tclchan.c +++ b/src/mod/channels.mod/tclchan.c @@ -1720,25 +1720,17 @@ static int tcl_channel_modify(Tcl_Interp *irp, struct chanset_t *chan, static int tcl_do_masklist(maskrec *m, Tcl_Interp *irp) { char ts[21], ts1[21], ts2[21], *p; - long tv; EGG_CONST char *list[6]; for (; m; m = m->next) { list[0] = m->mask; list[1] = m->desc; - - tv = m->expire; - sprintf(ts, "%lu", tv); + snprintf(ts, sizeof ts, "%" PRId64, (int64_t) m->expire); list[2] = ts; - - tv = m->added; - sprintf(ts1, "%lu", tv); + snprintf(ts1, sizeof ts1, "%" PRId64, (int64_t) m->added); list[3] = ts1; - - tv = m->lastactive; - sprintf(ts2, "%lu", tv); + snprintf(ts2, sizeof ts2, "%" PRId64, (int64_t) m->lastactive); list[4] = ts2; - list[5] = m->user; p = Tcl_Merge(6, list); Tcl_AppendElement(irp, p); diff --git a/src/mod/irc.mod/cmdsirc.c b/src/mod/irc.mod/cmdsirc.c index 66179ba6d..ccbb75657 100644 --- a/src/mod/irc.mod/cmdsirc.c +++ b/src/mod/irc.mod/cmdsirc.c @@ -853,21 +853,21 @@ 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", - chanflag, maxnicklen, m->nick, maxhandlen, handle, maxnicklen, - m->account, s, atrflag, difftime(now, m->split)); + dprintf(idx, "%c%-*s %-*s %-*s %-6s %c <- netsplit, %" PRId64 "s\n", + chanflag, maxnicklen, m->nick, maxhandlen, handle, maxnicklen, + m->account, s, atrflag, (int64_t) (now - m->split)); } else if (!rfc_casecmp(m->nick, botname)) { - dprintf(idx, "%c%-*s %-*s %-*s %-6s %c <- it's me!\n", chanflag, - maxnicklen, m->nick, maxhandlen, handle, maxnicklen, m->account, - s, atrflag); + dprintf(idx, "%c%-*s %-*s %-*s %-6s %c <- it's me!\n", + chanflag, maxnicklen, m->nick, maxhandlen, handle, maxnicklen, + m->account, s, atrflag); } else { /* Determine idle time */ if (now - (m->last) > 86400) - egg_snprintf(s1, sizeof s1, "%2lud", ((now - (m->last)) / 86400)); + snprintf(s1, sizeof s1, "%2" PRId64 "d", ((int64_t) (now - m->last)) / 86400); else if (now - (m->last) > 3600) - egg_snprintf(s1, sizeof s1, "%2luh", ((now - (m->last)) / 3600)); + snprintf(s1, sizeof s1, "%2" PRId64 "h", ((int64_t) (now - m->last)) / 3600); else if (now - (m->last) > 180) - egg_snprintf(s1, sizeof s1, "%2lum", ((now - (m->last)) / 60)); + snprintf(s1, sizeof s1, "%2" PRId64 "m", ((int64_t) (now - m->last)) / 60); else strlcpy(s1, " ", sizeof s1); if (chan_ircaway(m)) { diff --git a/src/mod/irc.mod/tclirc.c b/src/mod/irc.mod/tclirc.c index ea5bef5fe..0b6abd416 100644 --- a/src/mod/irc.mod/tclirc.c +++ b/src/mod/irc.mod/tclirc.c @@ -690,13 +690,13 @@ static int tcl_getchanidle STDVAR static int tcl_chanmasks(masklist *m, Tcl_Interp *irp) { - char work[20], *p; + char work[21], *p; EGG_CONST char *list[3]; for (; m && m->mask && m->mask[0]; m = m->next) { list[0] = m->mask; list[1] = m->who; - simple_sprintf(work, "%d", now - m->timer); + snprintf(work, sizeof work, "%" PRId64, (int64_t) (now - m->timer)); list[2] = work; p = Tcl_Merge(3, list); Tcl_AppendElement(irp, p); diff --git a/src/mod/share.mod/share.c b/src/mod/share.mod/share.c index 57d4c3292..dc8a1f1c7 100644 --- a/src/mod/share.mod/share.c +++ b/src/mod/share.mod/share.c @@ -1232,7 +1232,8 @@ static void share_ufsend(int idx, char *par) int i, sock; FILE *f; - egg_snprintf(s, sizeof s, ".share.%s.%li.users", botnetnick, now); + snprintf(s, sizeof s, ".share.%s.%" PRId64 ".users", botnetnick, + (int64_t) now); if (!(b_status(idx) & STAT_SHARE)) { dprintf(idx, "s e You didn't ask; you just started sending.\n"); dprintf(idx, "s e Ask before sending the userfile.\n"); @@ -2038,8 +2039,8 @@ static void start_sending_users(int idx) struct chanset_t *cst; char s[EGG_INET_ADDRSTRLEN]; - egg_snprintf(share_file, sizeof share_file, ".share.%s.%lu", dcc[idx].nick, - now); + snprintf(share_file, sizeof share_file, ".share.%s.%" PRId64, dcc[idx].nick, + (int64_t) now); if (dcc[idx].u.bot->uff_flags & UFF_OVERRIDE) { debug1("NOTE: Sharing aggressively with %s, overriding its local bots.", dcc[idx].nick); diff --git a/src/tcldcc.c b/src/tcldcc.c index 6a7702b29..3fd96e0f0 100644 --- a/src/tcldcc.c +++ b/src/tcldcc.c @@ -702,9 +702,8 @@ static void build_sock_list(Tcl_Interp *irp, Tcl_Obj *masterlist, char *idxstr, /* Gather information for dcclist or socklist */ static void dccsocklist(Tcl_Interp *irp, int argc, char *type, int src) { int i; - char idxstr[10], timestamp[11], other[160]; + char idxstr[10], timestamp[21], other[160]; char portstring[7]; /* ssl + portmax + NULL */ - long tv; char s[EGG_INET_ADDRSTRLEN]; socklen_t namelen; struct sockaddr_storage ss; @@ -718,8 +717,7 @@ static void dccsocklist(Tcl_Interp *irp, int argc, char *type, int src) { if (argc == 1 || ((argc == 2) && (dcc[i].type && !strcasecmp(dcc[i].type->name, type)))) { egg_snprintf(idxstr, sizeof idxstr, "%ld", dcc[i].sock); - tv = dcc[i].timeval; - egg_snprintf(timestamp, sizeof timestamp, "%ld", tv); + snprintf(timestamp, sizeof timestamp, "%" PRId64, (int64_t) dcc[i].timeval); if (dcc[i].type && dcc[i].type->display) dcc[i].type->display(i, other); else { @@ -785,8 +783,7 @@ static int tcl_dcclist STDVAR static int tcl_whom STDVAR { int chan, i; - char c[2], idle[32], work[20], *p; - long tv = 0; + char c[2], idle[21], work[20], *p; EGG_CONST char *list[7]; BADARGS(2, 2, " chan"); @@ -815,8 +812,7 @@ static int tcl_whom STDVAR if (dcc[i].u.chat->channel == chan || chan == -1) { c[0] = geticon(i); c[1] = 0; - tv = (now - dcc[i].timeval) / 60; - egg_snprintf(idle, sizeof idle, "%li", tv); + snprintf(idle, sizeof idle, "%" PRId64, (int64_t) ((now - dcc[i].timeval) / 60)); list[0] = dcc[i].nick; list[1] = botnetnick; list[2] = dcc[i].host; @@ -838,10 +834,8 @@ static int tcl_whom STDVAR c[1] = 0; if (party[i].timer == 0L) strcpy(idle, "0"); - else { - tv = (now - party[i].timer) / 60; - egg_snprintf(idle, sizeof idle, "%li", tv); - } + else + snprintf(idle, sizeof idle, "%" PRId64, (int64_t) ((now - party[i].timer) / 60)); list[0] = party[i].nick; list[1] = party[i].bot; list[2] = party[i].from ? party[i].from : ""; diff --git a/src/tclmisc.c b/src/tclmisc.c index f39e13322..f1270bc8d 100644 --- a/src/tclmisc.c +++ b/src/tclmisc.c @@ -404,12 +404,12 @@ static int tcl_duration STDVAR static int tcl_unixtime STDVAR { - char s[11]; + char s[21]; time_t now2 = time(NULL); BADARGS(1, 1, ""); - egg_snprintf(s, sizeof s, "%li", (long) now2); + snprintf(s, sizeof s, "%" PRId64, (int64_t) now2); Tcl_AppendResult(irp, s, NULL); return TCL_OK; } diff --git a/src/tcluser.c b/src/tcluser.c index 987a0e6dc..e94334ded 100644 --- a/src/tcluser.c +++ b/src/tcluser.c @@ -611,8 +611,7 @@ static int tcl_killignore STDVAR static int tcl_ignorelist STDVAR { - char expire[11], added[11], *p; - long tv; + char expire[21], added[21], *p; EGG_CONST char *list[5]; struct igrec *i; @@ -621,15 +620,10 @@ static int tcl_ignorelist STDVAR for (i = global_ign; i; i = i->next) { list[0] = i->igmask; list[1] = i->msg; - - tv = i->expire; - egg_snprintf(expire, sizeof expire, "%lu", tv); + snprintf(expire, sizeof expire, "%" PRId64, (int64_t) i->expire); list[2] = expire; - - tv = i->added; - egg_snprintf(added, sizeof added, "%lu", tv); + snprintf(added, sizeof added, "%" PRId64, (int64_t) i->added); list[3] = added; - list[4] = i->user; p = Tcl_Merge(5, list); Tcl_AppendElement(irp, p); diff --git a/src/userrec.c b/src/userrec.c index 9a8f19f49..fce760230 100644 --- a/src/userrec.c +++ b/src/userrec.c @@ -656,7 +656,7 @@ struct userrec *adduser(struct userrec *bu, char *handle, char *host, struct userrec *u, *x; struct xtra_key *xk; int oldshare = noshare; - long tv; + time_t tv; noshare = 1; u = nmalloc(sizeof *u); @@ -680,9 +680,9 @@ struct userrec *adduser(struct userrec *bu, char *handle, char *host, xk->key = nmalloc(8); strcpy(xk->key, "created"); tv = now; - l = snprintf(NULL, 0, "%li", tv); + l = snprintf(NULL, 0, "%" PRId64, (int64_t) tv); xk->data = nmalloc(l + 1); - sprintf(xk->data, "%li", tv); + sprintf(xk->data, "%" PRId64, (int64_t) tv); set_user(&USERENTRY_XTRA, u, xk); } /* Strip out commas -- they're illegal */ From 5cec6dbed0d6c68ac157e1da78d76d9d2cf28941 Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Mon, 19 Dec 2022 15:43:19 +0000 Subject: [PATCH 03/35] Update BUG-REEPORT --- doc/BUG-REPORT | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/doc/BUG-REPORT b/doc/BUG-REPORT index f1ceda1e8..3c279c599 100644 --- a/doc/BUG-REPORT +++ b/doc/BUG-REPORT @@ -26,7 +26,7 @@ DO NOT SEND HTML E-MAIL TO THE LISTS. 1) INFORMATION ABOUT YOUR EGGDROP 1.1) Eggdrop version: - 1.8.__ + 1.9._ 1.2) Make type: ( ) dynamic @@ -42,17 +42,13 @@ DO NOT SEND HTML E-MAIL TO THE LISTS. 2) INFORMATION ABOUT TCL 2.1) Tcl library version: - ( ) 8.3 - ( ) 8.4 - ( ) 8.5 - ( ) 8.6 + ( ) 8.3._ + ( ) 8.4._ + ( ) 8.5._ + ( ) 8.6._ ( ) Other - Which? ____ -2.2) Tcl library patchlevel: ___ - eg; p1, p2, etc for Tcl versions up to 8.0p2 - or the 3rd part of the version number for 8.0.3 and newer - -2.3) Tcl scripts used: +2.2) Tcl scripts used: [ ] alltools [ ] sentinel [ ] getops @@ -81,6 +77,7 @@ DO NOT SEND HTML E-MAIL TO THE LISTS. ( ) SINIX ( ) Solaris/SunOS/OpenIndiana ( ) Ultrix + ( ) Windows Subsystem for Linux (WSL) ( ) Other - Which? _____________ 3.2) OS Version/Release: _____________ @@ -110,8 +107,10 @@ DO NOT SEND HTML E-MAIL TO THE LISTS. useful if you could paste gdb's output during the following steps: First call gdb $ gdb eggdrop -c core + (systemd users could try coredumpctl) and then enter 'bt' on gdb's command line: (gdb) bt + (even more information could be obtained with 'bt full') Keep your core file for at least one week, so that the dev team can ask for further information if needed. However, don't send us the core file unless we ask for it. From 6eee0f54a7d53304321c42c506a6f58b7e69e376 Mon Sep 17 00:00:00 2001 From: Geo Date: Mon, 19 Dec 2022 15:39:27 -0500 Subject: [PATCH 04/35] Only update bothost on own chghost Found by: Geo Patch by: Geo Eggdrop incorrectly updated its own internally-tracked hostname with any host in a CHGHOST, whether it was intended for Eggdrop or not. --- src/mod/server.mod/servmsg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/server.mod/servmsg.c b/src/mod/server.mod/servmsg.c index e1f4a84c1..5bb4f31d2 100644 --- a/src/mod/server.mod/servmsg.c +++ b/src/mod/server.mod/servmsg.c @@ -1320,7 +1320,9 @@ static int got396orchghost(char *nick, char *user, char *uhost) m = ismember(chan, nick); if (m) { snprintf(m->userhost, sizeof m->userhost, "%s@%s", user, uhost); - strcpy(botuserhost, m->userhost); + if (!rfc_casecmp(m->nick, botname)) { + strcpy(botuserhost, m->userhost); + } } } return 0; From 22586b4dc9fd9fde5b5d0c97ec7d435a200937ae Mon Sep 17 00:00:00 2001 From: Simon Lyngshede Date: Fri, 30 Dec 2022 20:03:45 +0100 Subject: [PATCH 05/35] Fix doc links to binds Patch by: @slyngshede --- doc/html/tutorials/firstscript.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/html/tutorials/firstscript.html b/doc/html/tutorials/firstscript.html index fb00cb559..7097af445 100644 --- a/doc/html/tutorials/firstscript.html +++ b/doc/html/tutorials/firstscript.html @@ -113,7 +113,7 @@

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 @@

Writing an Eggdrop Script
bind join - * greet
 
-

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.

+

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.

@@ -270,4 +270,4 @@

Writing an Eggdrop Script Date: Sun, 12 Feb 2023 14:11:49 -0500 Subject: [PATCH 08/35] Update Tcl repo Found by: @robert-scheck Fixes: #1379 Confirmed with Tcl devs that they no longer maintain the FTP; updating suggested download repo in configure. --- configure | 4 ++-- configure.ac | 2 +- src/mod/compress.mod/configure | 2 +- src/mod/dns.mod/configure | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure b/configure index b7e1fb352..7372012d6 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac 13ab0170. +# From configure.ac 533f882a. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Eggdrop 1.9.4. # @@ -7985,7 +7985,7 @@ rm -f conftest.mmap conftest.txt # Tcl version to recommend if no Tcl is found, and the site where it can be # found for download. tclrecommendver="8.6.X" -tclrecommendsite="ftp://ftp.tcl.tk/pub/tcl/tcl8_6/" +tclrecommendsite="https://sourceforge.net/projects/tcl/files/Tcl/" # Tcl header filenames. tclheadernames="tcl.h" diff --git a/configure.ac b/configure.ac index f6c66bbae..c101fedf0 100644 --- a/configure.ac +++ b/configure.ac @@ -122,7 +122,7 @@ AC_FUNC_MMAP # Tcl version to recommend if no Tcl is found, and the site where it can be # found for download. tclrecommendver="8.6.X" -tclrecommendsite="ftp://ftp.tcl.tk/pub/tcl/tcl8_6/" +tclrecommendsite="https://sourceforge.net/projects/tcl/files/Tcl/" # Tcl header filenames. tclheadernames="tcl.h" diff --git a/src/mod/compress.mod/configure b/src/mod/compress.mod/configure index 29f9f2adc..3ea939674 100755 --- a/src/mod/compress.mod/configure +++ b/src/mod/compress.mod/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac 13ab0170. +# From configure.ac 533f882a. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Eggdrop Compress Module 1.9.4. # diff --git a/src/mod/dns.mod/configure b/src/mod/dns.mod/configure index 00072f073..84e203692 100755 --- a/src/mod/dns.mod/configure +++ b/src/mod/dns.mod/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac 13ab0170. +# From configure.ac 533f882a. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Eggdrop DNS Module 1.9.4. # From 0406c4b5ba42ac0a7e2a891b7267c845f1775fea Mon Sep 17 00:00:00 2001 From: Geo Date: Sun, 12 Feb 2023 14:12:47 -0500 Subject: [PATCH 09/35] Add TLS doc link to botnet doc Found by: @ZarTek-Creole Fixes: #1396 --- doc/sphinx_source/using/botnet.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/sphinx_source/using/botnet.rst b/doc/sphinx_source/using/botnet.rst index 7dea0d324..6757598b5 100644 --- a/doc/sphinx_source/using/botnet.rst +++ b/doc/sphinx_source/using/botnet.rst @@ -1,5 +1,4 @@ Botnet Sharing and Linking -Last revised: Nov 09, 2017 ========================== Botnet Sharing and Linking @@ -150,6 +149,10 @@ Here is an example scenario: At this point, you can link the two bots by typing '.link BotA' on BotB (or '.link BotB' on BotA). The bots will now give themselves random passwords which are *not* stored encrypted in the userfile. Note that you can link as many bots as you wish to your botnet. +Secure (TLS) Links +^^^^^^^^^^^^^^^^^^ +Since Eggdrop 1.8.0, the ability to encrypt bot links using TLS is possible. On the hub bot you would prefix the port given in the `listen` command with a +, and when you add the hub bot to the leaf, you would prefix the port used in the `.+bot` command with a +. In other words, you would set `listen +5555` in the hub config and use `.+bot hubbot 1.2.3.4 +5555` on the leaf bot. These settings are explained more thoroughly in the `TLS botnet documentation. `_ + Using botflags -------------- @@ -315,4 +318,8 @@ Making bots share user records |-+beldin `-+Lameshare +Using certificates to authenticate Eggdrops +------------------------------------------- +Eggdrops can use certificates to authenticate when linking to each other instead of a password. First, you must ensure you have set the appropriate certificates in the `ssl-privatekey` and `ssl-certificate` settings in the config file, and then enable the `ssl-cert-auth` setting. Next, add the certificate on the partyline by using `.fprint +` to add the fingerprint for the certificate currently in use, or `.fprint ` to manually add a fingerprint. Once the config file settings are set 0and fingerprints are added on the partyline, Eggdrops will attempt to use their certificates intead of passwords for authentication. + Copyright (C) 1999 - 2022 Eggheads Development Team From 7c6905000b8e0d8cdb65a4951efaae1977d684e5 Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Sun, 12 Feb 2023 19:15:00 +0000 Subject: [PATCH 10/35] Fix Twitch mod crash Found by: Lord255 Patch by: michaelortmann Fixes: #1380 --- src/mod/twitch.mod/twitch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/twitch.mod/twitch.c b/src/mod/twitch.mod/twitch.c index 7efc8cc71..542d5c3a9 100644 --- a/src/mod/twitch.mod/twitch.c +++ b/src/mod/twitch.mod/twitch.c @@ -843,6 +843,7 @@ static char *twitch_close() del_bind_table(H_rmst); del_bind_table(H_usst); del_bind_table(H_usrntc); + Tcl_UntraceVar(interp, "keep-nick", TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, traced_keepnick, NULL); module_undepend(MODULE_NAME); return NULL; } From 156c99d3bf7af1bec3291f12d1a6b20a23dad946 Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Sun, 12 Feb 2023 19:18:39 +0000 Subject: [PATCH 11/35] Make init_threaddata() return void Patch by: michaelortmann --- src/main.c | 2 +- src/proto.h | 2 +- src/tcl.c | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 7fff6c6fe..9ab60c6de 100644 --- a/src/main.c +++ b/src/main.c @@ -778,7 +778,7 @@ void check_static(char *, char *(*)()); #include "mod/static.h" #endif -int init_threaddata(int); +void init_threaddata(int); int init_mem(); int init_userent(); int init_misc(); diff --git a/src/proto.h b/src/proto.h index 054fe204d..f1940773b 100644 --- a/src/proto.h +++ b/src/proto.h @@ -302,7 +302,7 @@ void safe_write(int, const void *, size_t); /* tcl.c */ struct threaddata *threaddata(void); -int init_threaddata(int); +void init_threaddata(int); void protect_tcl(void); void unprotect_tcl(void); void do_tcl(char *, char *); diff --git a/src/tcl.c b/src/tcl.c index 770dbacbb..3e6265ae2 100644 --- a/src/tcl.c +++ b/src/tcl.c @@ -620,7 +620,7 @@ struct threaddata *threaddata() #endif /* REPLACE_NOTIFIER */ -int init_threaddata(int mainthread) +void init_threaddata(int mainthread) { struct threaddata *td = threaddata(); /* Nested evaluation (vwait/update) of the event loop only @@ -636,7 +636,6 @@ int init_threaddata(int mainthread) td->blocktime.tv_usec = 0; td->MAXSOCKS = 0; increase_socks_max(); - return 0; } /* Not going through Tcl's crazy main() system (what on earth was he From b06f20a951cbc1bd9d01bd737a85cac5314e4ba0 Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Sun, 12 Feb 2023 19:19:07 +0000 Subject: [PATCH 12/35] Cleanup: unused but set variable Patch by: michaelortmann --- src/mod/channels.mod/tclchan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mod/channels.mod/tclchan.c b/src/mod/channels.mod/tclchan.c index 7f13f6197..8f6b1c926 100644 --- a/src/mod/channels.mod/tclchan.c +++ b/src/mod/channels.mod/tclchan.c @@ -2282,7 +2282,7 @@ static int tcl_deludef STDVAR static int tcl_getudefs STDVAR { struct udef_struct *ul; - int type = 0, count = 0; + int type = 0; BADARGS(1, 2, " ?type?"); @@ -2302,7 +2302,6 @@ static int tcl_getudefs STDVAR for (ul = udef; ul; ul = ul->next) if (!type || (ul->type == type)) { Tcl_AppendElement(irp, ul->name); - count++; } return TCL_OK; From 45192be32c964c8aa5561014060e6ed1e40487f7 Mon Sep 17 00:00:00 2001 From: Thomas Sader Date: Sun, 12 Feb 2023 20:21:20 +0100 Subject: [PATCH 13/35] Workaround for TCL_UTF_MAX==3 Found by: Empus Patch by: thommey Fixes: #1163 Ugly workaround that does not break current usage of emoji in the Tcl API. Our usage of the Tcl API is not correct because Eggdrop is encoding agnostic, and processes byte arrays only. Those however get passed to Tcl as strings, when they are not. The real solution is fairly complex (decode all bytes into strings with the proper encoding guess from/to the Tcl API). If users are unable to recompile Tcl with increased TCL_UTF_MAX and are stuck with 8.6 stable (8.7 is not released as stable at the time of this PR), this should be a suitable, albeit ugly and complex, workaround that keeps emoji support alive. We do not wish to break the currently working emoji usage however, which mostly works in the current state, except for a crash if passed to [string tolower/toupper/totitle], other problematic call sites aren't known. So we overwrite Tcl's string tolower/toupper/totitle with our own version that: detects utf-8 sequences that are 4 bytes converts them into utf-8 encoded surrogate pairs before Tcl's string functions are called those remain untouched by case changes in Tcl convert the surrogate pairs back in the result to the original utf-8 4-byte code sequences Side effect is that we also convert surrogate pairs if they were sent as such, which should not have a negative impact on existing scripts. Single-byte encodings being valid 4-byte emoji sequences or 6-byte surrogate pairs is hopefully highly unlikely. --- src/tcl.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) diff --git a/src/tcl.c b/src/tcl.c index 3e6265ae2..6e02af9e2 100644 --- a/src/tcl.c +++ b/src/tcl.c @@ -96,6 +96,17 @@ int handlen = HANDLEN; extern Tcl_VarTraceProc traced_myiphostname, traced_natip, traced_remove_pass; +/* Unicode workaround for Tcl versions that only support BMP characters (3 byte utf-8) */ +#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 5 && TCL_MINOR_VERSION <= 6 && TCL_UTF_MAX < 4 +# define TCL_WORKAROUND_UNICODESUP 1 +struct tcl_unicodesup_info { + const char *subcmd; + Tcl_Obj *cmd; +}; +#endif + + + int expmem_tcl() { return strtot; @@ -638,6 +649,267 @@ void init_threaddata(int mainthread) increase_socks_max(); } +/* workaround for Tcl that does not support unicode outside BMP (3 byte utf-8 characters) */ +#ifdef TCL_WORKAROUND_UNICODESUP + +/* Based on https://github.com/skeeto/branchless-utf8 which is released into the public domain */ +/* 0 means not utf-8, so the length is still 1 but we can distinguish that case, + * that's why len = len + !len is used, to convert 0 to 1 and leave the rest as-is + */ +static const char utf8lengths[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0 +}; + +/* quick check if tricks are needed, only if 4-byte utf-8 characters are used */ +int needs_unicodesup(const char *str) +{ + while (*str) { + int len = utf8lengths[((unsigned char)str[0]) >> 3] + !utf8lengths[((unsigned char)str[0]) >> 3]; + + if (len == 4) { + return 1; + } + while (len--) { + if (*str++ == '\0') { + break; + } + } + } + return 0; +} + +/* return a new Tcl_StringObj with 4-byte utf-8 characters replaced by surrogate pairs + * - decode 4-byte utf-8 into unicode codepoint c + * - calculate high and low surrogate unicode codepoints high/low + * - encode high/low as 3-byte utf-8 strings + * the length of the result could be len/4*6 bytes long, so + * to avoid frequent reallocation/string appending, a temporary buffer is used + * for long strings (>512 characters, which does not apply to IRC lines) and assembled to a Tcl_DString + * for short strings the 512 character buffer is enough + */ +Tcl_Obj *egg_string_unicodesup_surrogate(const char *oldstr, int len) +{ + int stridx = 0, bufidx = 0; + char buf[512]; + Tcl_DString ds; + Tcl_Obj *result; + + /* chunked */ + if (len > sizeof buf) { + Tcl_DStringInit(&ds); + } + + while (stridx < len) { + int charlen = utf8lengths[((unsigned char)oldstr[stridx]) >> 3] + !utf8lengths[((unsigned char)oldstr[stridx])>> 3]; + + if (charlen == 4 && stridx + 4 <= len) { + uint32_t c; + uint16_t high, low; + + /* decode 4-byte utf-8 into unicode codepoint */ + c = (uint32_t)(oldstr[stridx++] & 0x07) << 18; + c |= (uint32_t)(oldstr[stridx++] & 0x3f) << 12; + c |= (uint32_t)(oldstr[stridx++] & 0x3f) << 6; + c |= (uint32_t)(oldstr[stridx++] & 0x3f) << 0; + + /* calculate high and low surrogate unicode codepoints */ + c -= 0x10000; + high = 0xD800 + ((c & 0xffc00) >> 10); + low = 0xDC00 + (c & 0x3ff); + + /* encode high surrogate as utf-8 */ + buf[bufidx++] = 0xe0 | ((high >> 12) & 0xf); + buf[bufidx++] = 0x80 | ((high >> 6) & 0x3f); + buf[bufidx++] = 0x80 | ((high >> 0) & 0x3f); + + /* encode low surrogate as utf-8 */ + buf[bufidx++] = 0xe0 | ((low >> 12) & 0xf); + buf[bufidx++] = 0x80 | ((low >> 6) & 0x3f); + buf[bufidx++] = 0x80 | ((low >> 0) & 0x3f); + } else { + /* copy everything else verbatim */ + while (charlen-- && stridx < len) { + buf[bufidx++] = oldstr[stridx++]; + } + } + if (len > sizeof buf && bufidx > sizeof buf - 6) { + Tcl_DStringAppend(&ds, buf, bufidx); + bufidx = 0; + } + } + if (len > sizeof buf && bufidx) { + Tcl_DStringAppend(&ds, buf, bufidx); + result = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); + } else { + result = Tcl_NewStringObj(buf, bufidx); + } + return result; +} + +/* decode 2 utf-8 sequences that are 3 bytes long and check if they are surrogate pairs */ +int decode_surrogates(const char *str, uint32_t *high, uint32_t *low) +{ + *high = (*str++ & 0xf) << 12; + *high |= (*str++ & 0x3f) << 6; + *high |= (*str++ & 0x3f) << 0; + if (*high < 0xD800 || *high > 0xDBFF) { + return 0; + } + *low = (*str++ & 0xf) << 12; + *low |= (*str++ & 0x3f) << 6; + *low |= (*str++ & 0x3f) << 0; + if (*low < 0xDC00 || *low > 0xDFFF) { + return 0; + } + return 1; +} + +/* returns a new Tcl_StringObj by replacing surrogate pairs back into 4-byte utf-8 sequences + * - for every 3-byte utf-8 sequence, check if it's a surrogate pair + * - decode into high/low codepoints + * - calculate original codepoint and write back a 4-byte utf-8 sequence instead of 3-byte surrogate pairs + * the length of the result is guaranteed to be equal or shorter than the original, so malloc(len) is sufficient space + */ +Tcl_Obj *egg_string_unicodesup_desurrogate(const char *oldstr, int len) +{ + int stridx = 0, bufidx = 0; + char *buf = nmalloc(len); + + while (stridx < len) { + uint32_t low, high; + int charlen = utf8lengths[((unsigned char)oldstr[stridx]) >> 3] + !utf8lengths[((unsigned char)oldstr[stridx]) >> 3]; + + if (charlen == 3 && stridx + 6 <= len && utf8lengths[((unsigned char)oldstr[stridx + 3]) >> 3] == 3 && decode_surrogates(oldstr + stridx, &high, &low)) { + uint32_t c = 0x10000 + (high - 0xD800) * 0x400 + (low - 0xDC00); + + buf[bufidx++] = 0xF0 | ((c >> 18) & 0x07); + buf[bufidx++] = 0x80 | ((c >> 12) & 0x3f); + buf[bufidx++] = 0x80 | ((c >> 6) & 0x3f); + buf[bufidx++] = 0x80 | ((c >> 0) & 0x3f); + + stridx += 6; + } else { + while (charlen-- && stridx < len) { + buf[bufidx++] = oldstr[stridx++]; + } + } + } + return Tcl_NewStringObj(buf, bufidx); +} + +/* C function called for ::egg_tcl_tolower/toupper/totitle + * context (original Tcl function and which conversion to do) is in cd + */ +int egg_string_unicodesup(void *cd, Tcl_Interp *interp, int objc, Tcl_Obj *const orig_objv[]) +{ + struct tcl_unicodesup_info *info = cd; + Tcl_Obj **new_objv; + int i; + int ret; + + /* impossible? */ + if (objc == 0) { + return Tcl_EvalObjv(interp, objc, orig_objv, 0); + } + /* new arguments to original Tcl string tolower/toupper/totitle */ + new_objv = nmalloc(objc * sizeof *new_objv); + + for (i = 0; i < objc; i++) { + if (i == 0) { + /* overwrite command objv[0] with original Tcl command instead of this function */ + new_objv[i] = info->cmd; + } else if (i == 1 && needs_unicodesup(Tcl_GetString(orig_objv[1]))) { + int len; + const char *oldstr = Tcl_GetStringFromObj(orig_objv[1], &len); + + /* overwrite string argument by replacing 4-byet utf-8 sequences with surrogate pairs */ + new_objv[1] = egg_string_unicodesup_surrogate(oldstr, len); + } else { + /* copy other arguments, e.g. string tolower test 1 2 */ + new_objv[i] = orig_objv[i]; + } + /* ref count of new objects must be increased before eval and decreased after, orig_objv is read-only */ + Tcl_IncrRefCount(new_objv[i]); + } + + /* call original Tcl function */ + ret = Tcl_EvalObjv(interp, objc, new_objv, 0); + + /* decrease ref count of new arguments */ + for (i = 0; i < objc; i++) { + Tcl_DecrRefCount(new_objv[i]); + } + nfree(new_objv); + /* overwrite Tcl's result by replacing surrogates back to 4-byte utf-8 sequences*/ + if (ret == TCL_OK) { + int len; + Tcl_Obj *resultobj = Tcl_GetObjResult(interp); + const char *str = Tcl_GetStringFromObj(resultobj, &len); + + Tcl_SetObjResult(interp, egg_string_unicodesup_desurrogate(str, len)); + } + return ret; +} + +/* register a single workaround command, making the namespace ensemble string call ::egg_string_ instead + * original command names are ::tcl::string:: + */ +void init_unicodesup_cmd(Tcl_Obj *ensdict, const char *subcmd, int index) +{ + Tcl_Obj *orig_cmd; + static struct tcl_unicodesup_info info[3]; + char buf[64]; + + if (Tcl_DictObjGet(interp, ensdict, Tcl_NewStringObj(subcmd, -1), &orig_cmd) != TCL_OK || !orig_cmd) { + putlog(LOG_MISC, "*", "ERROR: Tcl non-BMP unicodesup could not find string %s subcommand", subcmd); + return; + } + + info[index].subcmd = subcmd; + info[index].cmd = orig_cmd; + Tcl_IncrRefCount(orig_cmd); + + snprintf(buf, sizeof buf, "::egg_string_%s", subcmd); + Tcl_CreateObjCommand(interp, buf, egg_string_unicodesup, &info[index], NULL); + + if (Tcl_DictObjPut(interp, ensdict, Tcl_NewStringObj(subcmd, -1), Tcl_NewStringObj(buf, -1)) != TCL_OK) { + putlog(LOG_MISC, "*", "ERROR: Tcl non-BMP unicodesup could not set dictionary redirect"); + return; + } +} + +/* register all workaround functions */ +void init_unicodesup(void) +{ + Tcl_Obj *ensdict; + Tcl_Command enscmd = Tcl_FindEnsemble(interp, Tcl_NewStringObj("string", -1), 0); + + if (!enscmd) { + putlog(LOG_MISC, "*", "ERROR: Tcl non-BMP unicodesup could not find string command"); + return; + } + if (!Tcl_IsEnsemble(enscmd)) { + putlog(LOG_MISC, "*", "ERROR: Tcl non-BMP unicodesup is not a namespace ensemble"); + return; + } + if (Tcl_GetEnsembleMappingDict(interp, enscmd, &ensdict) != TCL_OK || !ensdict) { + putlog(LOG_MISC, "*", "ERROR: Tcl non-BMP unicodesup could not get namespace ensemble dictionary"); + return; + } + + init_unicodesup_cmd(ensdict, "tolower", 0); + init_unicodesup_cmd(ensdict, "toupper", 1); + init_unicodesup_cmd(ensdict, "totitle", 2); + + if (Tcl_SetEnsembleMappingDict(interp, enscmd, ensdict) != TCL_OK) { + putlog(LOG_MISC, "*", "ERROR: Tcl non-BMP unicodesup could not set namespace ensemble dictionary"); + return; + } +} +#endif /* TCL_WORKAROUND_UNICODESUP */ + /* Not going through Tcl's crazy main() system (what on earth was he * smoking?!) so we gotta initialize the Tcl interpreter */ @@ -768,6 +1040,9 @@ void init_tcl(int argc, char **argv) } Tcl_PkgProvide(interp, "eggdrop", pver); +#ifdef TCL_WORKAROUND_UNICODESUP + init_unicodesup(); +#endif /* Initialize binds and traces */ init_bind(); init_traces(); From aefed9945d8cb4d3fbad3884ee9807fec00bd4b1 Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Sun, 12 Feb 2023 21:26:51 +0000 Subject: [PATCH 14/35] Add ssl header version to .status Found by: wheel Patch by: michaelortmann Fixes: #1322 --- src/chanprog.c | 12 ++++++------ src/lang.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/chanprog.c b/src/chanprog.c index f5c5f6644..f20b6981e 100644 --- a/src/chanprog.c +++ b/src/chanprog.c @@ -336,22 +336,22 @@ void tell_verbose_status(int idx) dprintf(idx, "%s %s (%s %s)\n", MISC_TCLVERSION, ((interp) && (Tcl_Eval(interp, "info patchlevel") == TCL_OK)) ? tcl_resultstring() : (Tcl_Eval(interp, "info tclversion") == TCL_OK) ? - tcl_resultstring() : "*unknown*", MISC_TCLHVERSION, TCL_PATCH_LEVEL); + tcl_resultstring() : "*unknown*", MISC_HEADERVERSION, TCL_PATCH_LEVEL); if (tcl_threaded()) dprintf(idx, "Tcl is threaded.\n"); #ifdef TLS dprintf(idx, "TLS support is enabled.\n" #if defined HAVE_EVP_PKEY_GET1_EC_KEY && defined HAVE_OPENSSL_MD5 - "TLS library: %s\n", + "TLS library: %s (%s " OPENSSL_VERSION_TEXT ")\n", #elif !defined HAVE_EVP_PKEY_GET1_EC_KEY && defined HAVE_OPENSSL_MD5 - "TLS library: %s\n (no elliptic curve support)\n", + "TLS library: %s (%s " OPENSSL_VERSION_TEXT ")\n (no elliptic curve support)\n", #elif defined HAVE_EVP_PKEY_GET1_EC_KEY && !defined HAVE_OPENSSL_MD5 - "TLS library: %s\n (no MD5 support)\n", + "TLS library: %s (%s " OPENSSL_VERSION_TEXT ")\n (no MD5 support)\n", #elif !defined HAVE_EVP_PKEY_GET1_EC_KEY && !defined HAVE_OPENSSL_MD5 - "TLS library: %s\n (no elliptic curve or MD5 support)\n", + "TLS library: %s (%s " OPENSSL_VERSION_TEXT ")\n (no elliptic curve or MD5 support)\n", #endif - SSLeay_version(SSLEAY_VERSION)); + SSLeay_version(SSLEAY_VERSION), MISC_HEADERVERSION); #else dprintf(idx, "TLS support is not available.\n"); #endif diff --git a/src/lang.h b/src/lang.h index 8ce117c6f..8f9e391ca 100644 --- a/src/lang.h +++ b/src/lang.h @@ -122,7 +122,7 @@ #define MISC_JUPED get_language(0x542) #define MISC_NOFREESOCK get_language(0x543) #define MISC_TCLVERSION get_language(0x544) -#define MISC_TCLHVERSION get_language(0x545) +#define MISC_HEADERVERSION get_language(0x545) /* IRC */ #define IRC_BANNED get_language(0x600) From 7e8080e752b9d9c4a945aa1e758a5ac42fefd86c Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Sun, 12 Feb 2023 21:30:55 +0000 Subject: [PATCH 15/35] strftime doc update Patch by: michaelortmann --- doc/sphinx_source/install/install.rst | 2 +- doc/sphinx_source/modules/mod/server.rst | 4 ++-- doc/sphinx_source/using/core.rst | 5 ++--- doc/sphinx_source/using/tcl-commands.rst | 4 ++-- eggdrop.conf | 8 +++----- help/set/cmds1.help | 5 ++--- scripts/help/msg/userinfo.help | 16 ++++++++-------- src/mod/seen.mod/seen.c | 4 ++-- 8 files changed, 22 insertions(+), 26 deletions(-) diff --git a/doc/sphinx_source/install/install.rst b/doc/sphinx_source/install/install.rst index 2a1679844..c1af33284 100644 --- a/doc/sphinx_source/install/install.rst +++ b/doc/sphinx_source/install/install.rst @@ -37,7 +37,7 @@ Eggdrop uses the GNU autoconfigure scripts to make things easier. and will enlarge the binary a bit, but it's worth it if you want to support Eggdrop development. -4. Eggdrop must be installed in a directory somewhere. This is +4. Eggdrop must be installed in a directory somewhere. This is accomplished by entering the UNIX command:: make install diff --git a/doc/sphinx_source/modules/mod/server.rst b/doc/sphinx_source/modules/mod/server.rst index 6cdd4a968..bb7f55c60 100644 --- a/doc/sphinx_source/modules/mod/server.rst +++ b/doc/sphinx_source/modules/mod/server.rst @@ -103,8 +103,8 @@ There are also some variables you can set in your config file: set msg-rate 2 Number of seconds to wait between transmitting queued lines to the - server. Lower this value at your own risk. ircd is known to start - flood control at 512 bytes/2 seconds. + server. Lower this value at your own risk. ircd is known to start flood + control at 512 bytes/2 seconds. set ssl-verify-servers 0 Control certificate verification for servers. You can set this by adding diff --git a/doc/sphinx_source/using/core.rst b/doc/sphinx_source/using/core.rst index 8da7b993d..802b0c696 100644 --- a/doc/sphinx_source/using/core.rst +++ b/doc/sphinx_source/using/core.rst @@ -193,7 +193,7 @@ logfile "logs/logfile" set timestamp-format "[%H:%M:%S]" Set the following to the timestamp for the logfile entries. Popular times might be "[%H:%M]" (hour, min), or "[%H:%M:%S]" (hour, min, sec). - Read 'man strftime' for more formatting options. Keep it below 32 chars. + Read 'man strftime' for more formatting options. Keep it below 32 chars. set keep-all-logs 0 If you want to keep your logfiles forever, turn this setting on. All @@ -218,8 +218,7 @@ logfile "logs/logfile" If keep-all-logs is 1, this setting will define the suffix of the logfiles. The default will result in a suffix like "04May2000". "%Y%m%d" will produce the often used yyyymmdd format. Read the strftime manpages - for more options. NOTE: On systems which don't support strftime, the - default format will always be used. + for more options. Console Settings ---------------- diff --git a/doc/sphinx_source/using/tcl-commands.rst b/doc/sphinx_source/using/tcl-commands.rst index 904867221..888683d68 100644 --- a/doc/sphinx_source/using/tcl-commands.rst +++ b/doc/sphinx_source/using/tcl-commands.rst @@ -1079,7 +1079,7 @@ isidentified [channel] isaway [channel] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Description: determine if a user is marked as 'away' on a server. IMPORTANT: this command is only "mostly" reliable on its own when the IRCv3 away-notify capability is available and negotiated with the IRC server (if you didn't add this to your config file, it likely isn't enabled- you can confirm using the ``cap`` Tcl command). Additionally, there is no way for Eggdrop (or any client) to capture a user's away status when the user first joins a channel (they are assumed present by Eggdrop on join). To use this command without the away-notify capability negotiated, or to get a user's away status on join (via a JOIN bind), use ``refreshchan w`` on a channel the user is on, which will refresh the current away status stored by Eggdrop for all users on the channel. + Description: determine if a user is marked as 'away' on a server. IMPORTANT: this command is only "mostly" reliable on its own when the IRCv3 away-notify capability is available and negotiated with the IRC server (if you didn't add this to your config file, it likely isn't enabled- you can confirm using the ``cap`` Tcl command). Additionally, there is no way for Eggdrop (or any client) to capture a user's away status when the user first joins a channel (they are assumed present by Eggdrop on join). To use this command without the away-notify capability negotiated, or to get a user's away status on join (via a JOIN bind), use ``refreshchan w`` on a channel the user is on, which will refresh the current away status stored by Eggdrop for all users on the channel. Returns: 1 if Eggdrop is currently tracking someone by that nickname marked as 'away' (again, see disclaimer above) by an IRC server; 0 otherwise. @@ -2688,7 +2688,7 @@ matchcidr
matchstr ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Description: checks if pattern matches string. Only two wildcards are supported: '*' and '?'. Matching is case-insensitive. This command is intended as a simplified alternative to Tcl's string match. + Description: checks if pattern matches string. Only two wildcards are supported: '*' and '?'. Matching is case-insensitive. This command is intended as a simplified alternative to Tcl's string match. Returns: 1 if the pattern matches the string, 0 if it doesn't. diff --git a/eggdrop.conf b/eggdrop.conf index 81e35bfe9..ac0b8c297 100755 --- a/eggdrop.conf +++ b/eggdrop.conf @@ -188,7 +188,7 @@ set log-time 1 # Set the following to the timestamp for the logfile entries. Popular times # might be "[%H:%M]" (hour, min), or "[%H:%M:%S]" (hour, min, sec). -# Read `man strftime' for more formatting options. Keep it below 32 chars. +# Read `man strftime' for more formatting options. Keep it below 32 chars. set timestamp-format {[%H:%M:%S]} # If you want to keep your logfiles forever, turn this setting on. All @@ -200,8 +200,6 @@ set keep-all-logs 0 # If keep-all-logs is 1, this setting will define the suffix of the logfiles. # The default will result in a suffix like "04May2000". "%Y%m%d" will produce # the often used yyyymmdd format. Read the strftime manpages for more options. -# NOTE: On systems which don't support strftime, the default format will -# be used _always_. set logfile-suffix ".%d%b%Y" # You can specify when Eggdrop should switch logfiles and start fresh. You @@ -1184,8 +1182,8 @@ set extended-join 1 #### End of CAP features #### # Number of seconds to wait between transmitting queued lines to the server. -# Lower this value at your own risk. ircd is known to start flood control -# at 512 bytes/2 seconds. +# Lower this value at your own risk. ircd is known to start flood control at +# 512 bytes/2 seconds. set msg-rate 2 # This setting makes the bot try to get his original nickname back if its diff --git a/help/set/cmds1.help b/help/set/cmds1.help index 6f3a9addc..f6fead459 100644 --- a/help/set/cmds1.help +++ b/help/set/cmds1.help @@ -191,7 +191,7 @@ ### %bset timestamp-format%b Set the following to the timestamp for the logfile entries. Popular times might be "[%H:%M]" (hour,min), or "[%H:%M:%S]" (hour, min, sec). - Read `man strftime' for more formatting options. Keep it below 32 + Read `man strftime' for more formatting options. Keep it below 32 chars. %{help=set max-logsize}%{+n} ### %bset max-logsize%b @@ -211,8 +211,7 @@ If keep-all-logs is 1, this setting will define the suffix of the logfiles. The default will result in a suffix like "04May2000". "%Y%m%d" will produce the often used yyyymmdd format. Read the - strftime manpages for more options. NOTE: On systems which don't - support strftime, the default format will be used _always_. + strftime manpages for more options. %{help=set quiet-save}%{+n} ### %bset quiet-save%b <0/1/2/3> "Writing user file..." and "Writing channel file..." messages won't diff --git a/scripts/help/msg/userinfo.help b/scripts/help/msg/userinfo.help index ef1544314..51a0c4615 100644 --- a/scripts/help/msg/userinfo.help +++ b/scripts/help/msg/userinfo.help @@ -1,9 +1,9 @@ %{help=email} %b/MSG%b %B %bEMAIL%b - This will set your email address. It's shown when - someone does a WHOIS on you (see HELP WHOIS). If - you don't specify a email address, the bot will show - you the email address it currently has set for you (if any). + This will set your email address. It's shown when someone + does a WHOIS on you (see HELP WHOIS). If you don't specify a + email address, the bot will show you the email address it + currently has set for you (if any). %b/MSG%b %B %bEMAIL%b none This clears your email address. %{help=url} @@ -15,7 +15,7 @@ This clears your url address. %{help=bf} %b/MSG%b %B %bBF%b - This will set your boyfriend. some scripts (such as seen) + This will set your boyfriend. Some scripts (such as seen) use this information. If you don't specify a boyfriend, the bot will show you the boyfriend it currently has set for you (if any). @@ -23,7 +23,7 @@ This clears your boyfriend. %{help=gf} %b/MSG%b %B %bGF%b - This will set your girlfriend. some scripts (such as seen) + This will set your girlfriend. Some scripts (such as seen) use this information. If you don't specify a girlfriend, the bot will show you the girlfriend it currently has set for you (if any). @@ -31,14 +31,14 @@ This clears your girlfriend. %{help=irl} %b/MSG%b %B %bIRL%b - This will set your real name. just for the information + This will set your real name. Just for the information of others :). If you don't specify a real name, the bot will show you the real name it currently has set for you (if any). %b/MSG%b %B %bIRL%b none This clears your real name. %{help=dob} %b/MSG%b %B %bDOB%b - This will set your date of birth. now now, be honest :) + This will set your date of birth. Now, be honest :) If you don't specify a date of birth, the bot will show you the date of birth it currently has set for you (if any). %b/MSG%b %B %bDOB%b none diff --git a/src/mod/seen.mod/seen.c b/src/mod/seen.mod/seen.c index 66c834f8a..4e2182152 100644 --- a/src/mod/seen.mod/seen.c +++ b/src/mod/seen.mod/seen.c @@ -395,7 +395,7 @@ static void do_seen(int idx, char *prefix, char *nick, char *hand, prefix, whoredirect, whotarget); return; } - /* Target not on this channel. Check other channels */ + /* Target not on this channel. Check other channels */ chan = chanset; while (chan) { m = ismember(chan, whotarget); @@ -442,7 +442,7 @@ static void do_seen(int idx, char *prefix, char *nick, char *hand, } } } - /* Target known, but nowhere to be seen. Give last IRC and botnet time */ + /* Target known, but nowhere to be seen. Give last IRC and botnet time */ wordshift(word1, text); if (!strcasecmp(word1, "anywhere")) cr = NULL; From ac2c81a0222edb11c529b2165bbf1068a28e4bfc Mon Sep 17 00:00:00 2001 From: Geo Date: Sun, 12 Feb 2023 16:58:45 -0500 Subject: [PATCH 16/35] Revert bind char change ... but keep DCC output of * --- src/flags.c | 2 +- src/tclhash.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/flags.c b/src/flags.c index 26285fdbd..ce60b2e3d 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; } diff --git a/src/tclhash.c b/src/tclhash.c index 71d35f6c2..cb54cecdc 100644 --- a/src/tclhash.c +++ b/src/tclhash.c @@ -1316,6 +1316,10 @@ void tell_binds(int idx, char *par) continue; proc = tc->func_name; build_flags(flg, &(tc->flags), NULL); + if (!strcmp(flg, "-|-")) { + flg[0] = '*'; + flg[1] = '\0'; + } if (showall || proc[0] != '*') { int ok = 0; From a602590e54a30dca0982c43411d1abefeb606a4b Mon Sep 17 00:00:00 2001 From: Geo Date: Sun, 12 Feb 2023 19:47:13 -0500 Subject: [PATCH 17/35] Update woobie mod docs --- doc/html/index.html | 24 +- doc/html/modules/internals.html | 396 ++++++++++++++++++++++++ doc/html/tutorials/module.html | 373 ++++++++++++++++++++++ doc/sphinx_source/index.rst | 2 + doc/sphinx_source/modules/internals.rst | 264 ++++++++++++++++ doc/sphinx_source/modules/writing.rst | 6 +- doc/sphinx_source/tutorials/module.rst | 235 ++++++++++++++ 7 files changed, 1297 insertions(+), 3 deletions(-) create mode 100644 doc/html/modules/internals.html create mode 100644 doc/html/tutorials/module.html create mode 100644 doc/sphinx_source/modules/internals.rst create mode 100644 doc/sphinx_source/tutorials/module.rst diff --git a/doc/html/index.html b/doc/html/index.html index 412af9939..31d1e7456 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -68,12 +68,14 @@

Table of Contents

  • Common First Steps
  • Enabling TLS Security on Eggdrop
  • Writing an Eggdrop Script
  • +
  • Writing an Eggdrop Module
  • Eggdrop Modules

    About Eggdrop

    diff --git a/doc/html/modules/internals.html b/doc/html/modules/internals.html new file mode 100644 index 000000000..9faf08e66 --- /dev/null +++ b/doc/html/modules/internals.html @@ -0,0 +1,396 @@ + + + + + + + + Eggdrop Bind Internals — Eggdrop 1.9.4 documentation + + + + + + + + + + + + + +
    +
    + +
    + +
    +
    +
    + +
    +

    Eggdrop Bind Internals

    +

    This document is intended for C developers who want to understand how Eggdrop’s Tcl binds or C binds work.

    +

    For documentation purposes the “dcc” bind type is used as an example.

    +

    It already exists and is suitable to illustrate the details of bind handling in Eggdrop.

    +

    Note: All code snippets are altered for brevity and simplicity, see original source code for the full and current versions.

    +
    +

    Bind Table Creation

    +

    The bind table is added by calling, either at module initialization or startup:

    +
    /* Global symbol, available to other C files with
    + * extern p_tcl_bind_list H_dcc;
    + */
    +p_tcl_bind_list H_dcc;
    +
    +/* Creating the bind table:
    + * @param[in] const char *name Limited in length, see tclhash.h
    + * @param[in] int flags        HT_STACKABLE or 0
    + * @param[in] IntFunc          Function pointer to C handler
    + * @return    p_tcl_bind_list  aka (tcl_bind_list_t *)
    + */
    +H_dcc = add_bind_table("dcc", 0, builtin_dcc);
    +
    +
    +

    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.

    +
    +
    +

    Stackable Binds: HT_STACKABLE

    +

    HT_STACKABLE means that multiple binds can exist for the same mask.

    +
    bind dcc - test proc1; # not stackable
    +bind dcc - test proc2; # overwrites the first one, only proc2 will be called
    +
    +
    +

    It does not automatically call multiple binds that match, see later in the Triggering any Bind section for details.

    +
    +
    +

    Tcl Binding

    +

    After the bind table is created with add_bind_table, Tcl procs can already be registered to this bind by calling:

    +
    bind dcc -|- test myproc
    +proc myproc {args} {
    +  putlog "myproc was called, argument list: '[join $args ',']'"
    +  return 0
    +}
    +
    +
    +

    Of course it is not clear so far:

    +
      +
    • If flags -|- matter for this bind at all and what they are checked against
    • +
    • If channel flags have a meaning or global/bot only
    • +
    • What test is matched against to see if the bind should trigger
    • +
    • Which arguments myproc receives, the example just accepts all arguments
    • +
    +
    +
    +

    Triggering the Bind

    +

    To trigger the bind and call it with the desired arguments, a function is created.

    +
    int check_tcl_dcc(const char *cmd, int idx, const char *args) {
    +  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
    +  int x;
    +  char s[11];
    +
    +  get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.chat->con_chan);
    +  egg_snprintf(s, sizeof s, "%ld", dcc[idx].sock);
    +  Tcl_SetVar(interp, "_dcc1", (char *) dcc[idx].nick, 0);
    +  Tcl_SetVar(interp, "_dcc2", (char *) s, 0);
    +  Tcl_SetVar(interp, "_dcc3", (char *) args, 0);
    +  x = check_tcl_bind(H_dcc, cmd, &fr, " $_dcc1 $_dcc2 $_dcc3",
    +                  MATCH_PARTIAL | BIND_USE_ATTR | BIND_HAS_BUILTINS);
    +  /* snip ..., return code handling */
    +  return 0;
    +}
    +
    +
    +

    The global Tcl variables $_dcc1 $_dcc2 $_dcc3 are used as temporary string variables and passed as arguments to the registered Tcl proc.

    +

    This shows which arguments the callbacks in Tcl get:

    +
      +
    • the nickname of the DCC chat user (handle of the user)
    • +
    • the IDX (socket id) of the partyline so [putdcc] can respond back
    • +
    • another string argument that depends on the caller
    • +
    +

    The call to check_tcl_dcc can be found in the DCC parsing in src/dcc.c.

    +
    +
    +

    Triggering any Bind

    +

    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.

    +
    +
    +

    C Binding

    +

    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.

    +
    +
    +

    C Handler

    +

    The example handler for DCC looks as follows:

    +
    /* Typical Tcl_Command arguments, just like e.g. tcl_putdcc is a Tcl/C command for [putdcc] */
    +static int builtin_dcc (ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) {
    +  int idx;
    +  /* F: The C function we want to call, if the bind is okay, e.g. cmd_boot() */
    +  Function F = (Function) cd;
    +
    +  /* Task of C function: verify argument count and syntax as any Tcl command */
    +  BADARGS(4, 4, " hand idx param");
    +
    +  /* C Macro only used in C handlers for bind types, sanity checks the Tcl proc name
    +   * for *<bindtype>:<name> and that we are in the right C handler
    +   */
    +  CHECKVALIDITY(builtin_dcc);
    +
    +  idx = findidx(atoi(argv[2]));
    +  if (idx < 0) {
    +      Tcl_AppendResult(irp, "invalid idx", NULL);
    +      return TCL_ERROR;
    +  }
    +
    +  /* Call the desired C function, e.g. cmd_boot() with their arguments */
    +  F(dcc[idx].user, idx, argv[3]);
    +  Tcl_ResetResult(irp);
    +  Tcl_AppendResult(irp, "0", NULL);
    +  return TCL_OK;
    +}
    +
    +
    +

    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:

    +
    /* We know the return value is ignored because the return value of F
    + * in builtin_dcc is ignored, so it can be void, but for other binds
    + * it could be something else and used in the C handler for the bind.
    + */
    +void cmd_boot(struct userrec *u, int idx, char *par) { /* snip */ }
    +
    +cmd_t *mycmds = {
    +  {"boot", "t", (IntFunc) cmd_boot, NULL /* automatic name: *dcc:boot */},
    +  {NULL, NULL, NULL, NULL}
    +};
    +add_builtins(H_dcc, mycmds);
    +
    +
    +
    +
    +

    Summary

    +

    In summary, this is how the dcc bind is called:

    +
      +
    • check_tcl_dcc() creates Tcl variables $_dcc1 $_dcc2 $_dcc3 and lets check_tcl_bind call the binds
    • +
    • Tcl binds are done at this point
    • +
    • C binds mean the Tcl command associated with the bind is *dcc:boot which calls builtin_dcc which gets cmd_boot as ClientData cd argument
    • +
    • buildin_dcc performs some sanity checking to avoid crashes and then calls cmd_boot() aka F() with the arguments it wants C callbacks to have
    • +
    +

    Example edited and annotated gdb backtrace in cmd_boot after doing .boot test on the partyline as user thommey with typical owner flags.

    +
    #0  cmd_boot (u=0x55e8bd8a49b0, idx=4, par=0x55e8be6a0010 "test") at cmds.c:614
    +    *u = {next = 0x55e8bd8aec90, handle = "thommey", flags = 8977024, flags_udef = 0, chanrec = 0x55e8bd8aeae0, entries = 0x55e8bd8a4a10}
    +#1  builtin_dcc (cd=0x55e8bbf002d0 <cmd_boot>, irp=0x55e8bd59b1c0, argc=4, argv=0x55e8bd7e3e00) at tclhash.c:678
    +    idx = 4
    +    argv = {0x55e8be642fa0 "*dcc:boot", 0x55e8be9f6bd0 "thommey", 0x55e8be7d9020 "4", 0x55e8be6a0010 "test", 0x0}
    +    F = 0x55e8bbf002d0 <cmd_boot>
    +#5  Tcl_Eval (interp=0x55e8bd59b1c0, script = "*dcc:boot $_dcc1 $_dcc2 $_dcc3") from /usr/lib/x86_64-linux-gnu/libtcl8.6.so
    +    Tcl: return $_dcc1 = "thommey"
    +    Tcl: return $_dcc2 = "4"
    +    Tcl: return $_dcc3 = "test"
    +    Tcl: return $lastbind = "boot" (set automatically by trigger_bind)
    +#8  trigger_bind (proc=proc@entry=0x55e8bd5efda0 "*dcc:boot", param=param@entry=0x55e8bbf4112b " $_dcc1 $_dcc2 $_dcc3", mask=mask@entry=0x55e8bd5efd40 "boot") at tclhash.c:742
    +#9  check_tcl_bind (tl=0x55e8bd5eecb0 <H_dcc>, match=match@entry=0x7ffcf3f9dac1 "boot", atr=atr@entry=0x7ffcf3f9d100, param=param@entry=0x55e8bbf4112b " $_dcc1 $_dcc2 $_dcc3", match_type=match_type@entry=80) at tclhash.c:942
    +    proc = 0x55e8bd5efda0 "*dcc:boot"
    +    mask = 0x55e8bd5efd40 "boot"
    +    brkt = 0x7ffcf3f9dac6 "test"
    +#10 check_tcl_dcc (cmd=cmd@entry=0x7ffcf3f9dac1 "boot", idx=idx@entry=4, args=0x7ffcf3f9dac6 "test") at tclhash.c:974
    +    fr = {match = 5, global = 8977024, udef_global = 0, bot = 0, chan = 0, udef_chan = 0}
    +#11 dcc_chat (idx=idx@entry=4, buf=<optimized out>, i=<optimized out>) at dcc.c:1068
    +    v = 0x7ffcf3f9dac1 "boot"
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/doc/html/tutorials/module.html b/doc/html/tutorials/module.html new file mode 100644 index 000000000..b750801ea --- /dev/null +++ b/doc/html/tutorials/module.html @@ -0,0 +1,373 @@ + + + + + + + + Writing an Eggdrop Module — Eggdrop 1.9.4 documentation + + + + + + + + + + + + + +
    +
    + +
    + +
    +
    +
    + +
    +

    Writing an Eggdrop Module

    +

    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

    +
    +

    Module Header

    +

    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 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
    +* of the License, or (at your option) any later version.
    +*
    +* This program is distributed in the hope that it will be useful,
    +* but WITHOUT ANY WARRANTY; without even the implied warranty of
    +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +* GNU General Public License for more details.
    +*
    +* You should have received a copy of the GNU General Public License
    +* along with this program; if not, write to the Free Software
    +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    +*/
    +
    +
    +
    +
    +

    Required Code

    +

    For this section, you don’t necessarily need to understand what it is doing, but this code is required for a module to function.

    +

    You’ll next want to name your module:

    +
    #define MODULE_NAME "woobie"
    +
    +
    +

    Declare your own function tables (you don’t need to understand this part; you just need to copy/paste it):

    +
    #undef global
    +static Function *global = NULL, *server_funcs = NULL;
    +EXPORT_SCOPE char *woobie_start();
    +
    +
    +

    Next are two memory-related functions used by the core Eggdrop .status and .module commands:

    +
    static int woobie_expmem()
    +{
    +  int size = 0;
    +
    +  return size;
    +}
    +
    +static void woobie_report(int idx, int details)
    +{
    +  if (details) {
    +    int size = woobie_expmem();
    +
    +    dprintf(idx, "    Using %d byte%s of memory\n", size,
    +            (size != 1) ? "s" : "");
    +  }
    +}
    +
    +
    +

    This function is called when Eggdrop loads the module:

    +
    char *woobie_start(Function *global_funcs)
    +{
    +  global = global_funcs;
    +
    +  /* Register the module. */
    +  module_register(MODULE_NAME, woobie_table, 2, 1);
    +  /*                                            ^--- minor module version
    +   *                                         ^------ major module version
    +   *                           ^-------------------- module function table
    +   *              ^--------------------------------- module name
    +   */
    +
    +  if (!module_depend(MODULE_NAME, "eggdrop", 108, 0)) {
    +    module_undepend(MODULE_NAME);
    +    return "This module requires Eggdrop 1.8.0 or later.";
    +  }
    +
    +
    +

    This next function is used to unload the module:

    +
    static char *woobie_close()
    +{
    +  module_undepend(MODULE_NAME);
    +  return NULL;
    +}
    +
    +
    +

    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:

    +
    static Function woobie_table[] = {
    +  (Function) woobie_start,
    +  (Function) woobie_close,
    +  (Function) woobie_expmem,
    +  (Function) woobie_report,
    +};
    +
    +
    +

    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!

    +
    +
    +

    Adding a Partyline Command

    +

    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:

    +
    static int cmd_woobie(struct userrec *u, int idx, char *par)
    +{
    +  putlog(LOG_CMDS, "*", "#%s# woobie", dcc[idx].nick);
    +  dprintf(idx, "WOOBIE!\n");
    +  return 0;
    +}
    +
    +
    +

    If you add partyline commands, you need to create a table which links the new command name to the function it should call. This can be done like so:

    +
    static cmd_t mywoobie[] = {
    +  /* command  flags  function     tcl-name */
    +  {"woobie",  "",    cmd_woobie,  NULL},
    +  {NULL,      NULL,  NULL,        NULL}  /* Mark end. */
    +};
    +
    +
    +

    The tcl-name field can be a name for a Tcl command that will also call the partyline command, or it can be left as NULL.

    +
    +
    +

    Adding a Tcl Command

    +

    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:

    +
    static int tcl_echome STDVAR {
    +  BADARGS(2, 2, " arg");
    +
    +  if (strcmp(argv[1], "llama") {
    +    Tcl_AppendResult(irp, "You said: ", argv[1], NULL);
    +    return TCL_OK;
    +  } else {
    +    Tcl_AppendResult(irp, "illegal word!");
    +    return TCL_ERROR;
    +  }
    +}
    +
    +A few notes on this example. BADARGS is a macro that checks the input provided to the Tcl command. The first argument BADARGS accepts is the minimum number of paramters the Tcl command must accept (including the command itself). The second argument is the maximum number of parameters that BADARGS will accept. The third argument is the help text that will be displayed if these boundaries are exceeded. For example, BADARGS(2, 4, " name ?date? ?place?") requires at least one argument to be passed, and a maximum of three arguments. Eggdrop code style is to enclose optional arguments between qusetion marks in the help text.
    +
    +
    +

    Similar to adding a partyline command, you also have to create a function table for a new Tcl command:

    +
    static tcl_cmds mytcl[] = {
    +  {"echome",           tcl_echome},
    +  {NULL,                   NULL}   /* Required to mark end of table */
    +};
    +
    +
    +

    And now the newly-created Tcl command ‘echome’ is available for use in a script!

    +
    +
    +

    Adding a Tcl Bind

    +

    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):

    +
    static p_tcl_bind_list H_woob;
    +
    +...
    +
    +char *woobie_start(Function *global_funcs)
    +{
    +  ...
    +  H_woob = add_bind_table("woobie", HT_STACKABLE, woobie_2char);
    +}
    +
    +
    +

    And then remove the binds when the module is unloaded:

    +
    static char *woobie_close()
    +{
    +  ...
    +  del_bind_table(H_woob);
    +}
    +
    +
    +

    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.

    +
    +

    Defining bind arguments

    +

    The following code example defines a bind that will take two arguments:

    +
    static int woobie_2char STDVAR
    +{
    +  Function F = (Function) cd;
    +
    +  BADARGS(3, 3, " nick chan");
    +
    +  CHECKVALIDITY(woobie_2char);
    +  F(argv[1], argv[2]);
    +  return TCL_OK;
    +}
    +
    +
    +

    And this example defines a bind that will take three arguments:

    +
    static int woobie_3char STDVAR
    +{
    +  Function F = (Function) cd;
    +
    +  BADARGS(4, 4, " foo bar moo");
    +
    +  CHECKVALIDITY(woobie_3char);
    +  F(argv[1], argv[2], argv[3]);
    +  return TCL_OK;
    +}
    +
    +
    +

    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.

    +
    +
    +

    Calling the Bind

    +

    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:

    +
    check_tcl_woobie(chan, nick);
    +
    +
    +static int check_tcl_woobie(char *chan, char *nick, char *userhost) {
    +  int x;
    +  char mask[1024];
    +  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
    +
    +  snprintf(mask, sizeof mask, "%s %s!%s",
    +                                chan, nick, userhost);
    +  Tcl_SetVar(interp, "_woob1", nick ? (char *) nick : "", 0);
    +  Tcl_SetVar(interp, "_woob2", chan, 0);
    +  x = check_tcl_bind(H_woob, mask, &fr, " $_woob1 $_woob2",
    +        MATCH_MASK | BIND_STACKABLE);
    +  return (x == BIND_EXEC_LOG);
    +}
    +
    +
    +

    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.

    +
    +
    +
    +

    Exporting the Bind

    +

    Do we need to do this?

    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/doc/sphinx_source/index.rst b/doc/sphinx_source/index.rst index dca64902a..5e0178241 100644 --- a/doc/sphinx_source/index.rst +++ b/doc/sphinx_source/index.rst @@ -78,6 +78,7 @@ The Eggheads development team can be found lurking on #eggdrop on the Libera net tutorials/firststeps tutorials/tlssetup tutorials/firstscript + tutorials/module.rst .. toctree:: :caption: Eggdrop Modules @@ -86,6 +87,7 @@ The Eggheads development team can be found lurking on #eggdrop on the Libera net modules/index modules/included modules/writing + modules/internals.rst .. toctree:: :caption: About Eggdrop diff --git a/doc/sphinx_source/modules/internals.rst b/doc/sphinx_source/modules/internals.rst new file mode 100644 index 000000000..5e026a391 --- /dev/null +++ b/doc/sphinx_source/modules/internals.rst @@ -0,0 +1,264 @@ +Eggdrop Bind Internals +====================== + +This document is intended for C developers who want to understand how Eggdrop’s Tcl binds or C binds work. + +For documentation purposes the “dcc” bind type is used as an example. + +It already exists and is suitable to illustrate the details of bind handling in Eggdrop. + +Note: All code snippets are altered for brevity and simplicity, see original source code for the full and current versions. + +Bind Table Creation +------------------- + +The bind table is added by calling, either at module initialization or startup:: + + /* Global symbol, available to other C files with + * extern p_tcl_bind_list H_dcc; + */ + p_tcl_bind_list H_dcc; + + /* Creating the bind table: + * @param[in] const char *name Limited in length, see tclhash.h + * @param[in] int flags HT_STACKABLE or 0 + * @param[in] IntFunc Function pointer to C handler + * @return p_tcl_bind_list aka (tcl_bind_list_t *) + */ + H_dcc = add_bind_table("dcc", 0, builtin_dcc); + +What the :code:`C handler` does is explained later, because a lot happens before it is actually called. :code:`IntFunc` is a generic function pointer that returns an :code:`int` with arbitrary arguments. + +:code:`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. + +Stackable Binds: HT_STACKABLE +----------------------------- + +:code:`HT_STACKABLE` means that multiple binds can exist for the same mask. +:: + + bind dcc - test proc1; # not stackable + bind dcc - test proc2; # overwrites the first one, only proc2 will be called + +It does not automatically call multiple binds that match, see later in the `Triggering any Bind`_ section for details. + +Tcl Binding +----------- + +After the bind table is created with :code:`add_bind_table`, Tcl procs can already be registered to this bind by calling:: + + bind dcc -|- test myproc + proc myproc {args} { + putlog "myproc was called, argument list: '[join $args ',']'" + return 0 + } + +Of course it is not clear so far: + +* If flags :code:`-|-` matter for this bind at all and what they are checked against +* If channel flags have a meaning or global/bot only +* What :code:`test` is matched against to see if the bind should trigger +* Which arguments :code:`myproc` receives, the example just accepts all arguments + +Triggering the Bind +------------------- + +To trigger the bind and call it with the desired arguments, a function is created. +:: + + int check_tcl_dcc(const char *cmd, int idx, const char *args) { + struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; + int x; + char s[11]; + + get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.chat->con_chan); + egg_snprintf(s, sizeof s, "%ld", dcc[idx].sock); + Tcl_SetVar(interp, "_dcc1", (char *) dcc[idx].nick, 0); + Tcl_SetVar(interp, "_dcc2", (char *) s, 0); + Tcl_SetVar(interp, "_dcc3", (char *) args, 0); + x = check_tcl_bind(H_dcc, cmd, &fr, " $_dcc1 $_dcc2 $_dcc3", + MATCH_PARTIAL | BIND_USE_ATTR | BIND_HAS_BUILTINS); + /* snip ..., return code handling */ + return 0; + } + +The global Tcl variables :code:`$_dcc1 $_dcc2 $_dcc3` are used as temporary string variables and passed as arguments to the registered Tcl proc. + +This shows which arguments the callbacks in Tcl get: + +* the nickname of the DCC chat user (handle of the user) +* the IDX (socket id) of the partyline so :code:`[putdcc]` can respond back +* another string argument that depends on the caller + +The call to :code:`check_tcl_dcc` can be found in the DCC parsing in `src/dcc.c`. + +Triggering any Bind +------------------- + +`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, " "); and grab the result */ + x = trigger_bind(tc->func_name, param, tm->mask); + } + } + } + return x; + } + +The supplied flags to :code:`check_tcl_bind` in `check_tcl_dcc` are what defines how matching is performed. + +In the case of a DCC bind we had: + +* Matchtype :code:`MATCH_PARTIAL`: Prefix-Matching if the command can be uniquely identified (e.g. dcc .help calls .help) +* Additional flag :code:`BIND_USE_ATTR`: Flags are checked +* Additional flag :code:`BIND_HAS_BUILTINS`: Something with flag matching, unsure + +For details on the available match types (wildcard matching, exact matching, etc.) see :code:`src/tclegg.h`. Additional flags are also described there as well as the return codes of :code:`check_tcl_bind` (e.g. :code:`BIND_NOMATCH`). + +Note: For a bind type to be stackable it needs to be registered with :code:`HT_STACKABLE` AND :code:`check_tcl_bind` must be called with :code:`BIND_STACKABLE`. + +C Binding +--------- + +To create a C function that is called by the bind, Eggdrop provides the :code:`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 *:, 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. :code:`*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. + +C Handler +--------- + +The example handler for DCC looks as follows:: + + /* Typical Tcl_Command arguments, just like e.g. tcl_putdcc is a Tcl/C command for [putdcc] */ + static int builtin_dcc (ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) { + int idx; + /* F: The C function we want to call, if the bind is okay, e.g. cmd_boot() */ + Function F = (Function) cd; + + /* Task of C function: verify argument count and syntax as any Tcl command */ + BADARGS(4, 4, " hand idx param"); + + /* C Macro only used in C handlers for bind types, sanity checks the Tcl proc name + * for *: and that we are in the right C handler + */ + CHECKVALIDITY(builtin_dcc); + + idx = findidx(atoi(argv[2])); + if (idx < 0) { + Tcl_AppendResult(irp, "invalid idx", NULL); + return TCL_ERROR; + } + + /* Call the desired C function, e.g. cmd_boot() with their arguments */ + F(dcc[idx].user, idx, argv[3]); + Tcl_ResetResult(irp); + Tcl_AppendResult(irp, "0", NULL); + return TCL_OK; + } + +This is finally the part where we see the arguments a C function gets for a DCC bind as opposed to a Tcl proc. + +code:`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 :code:`$_dcc3` which was :code:`args` to :code:`check_tcl_dcc` which was everything after the dcc command + +So this is how we register C callbacks for binds with the correct arguments:: + + /* We know the return value is ignored because the return value of F + * in builtin_dcc is ignored, so it can be void, but for other binds + * it could be something else and used in the C handler for the bind. + */ + void cmd_boot(struct userrec *u, int idx, char *par) { /* snip */ } + + cmd_t *mycmds = { + {"boot", "t", (IntFunc) cmd_boot, NULL /* automatic name: *dcc:boot */}, + {NULL, NULL, NULL, NULL} + }; + add_builtins(H_dcc, mycmds); + +Summary +------- + +In summary, this is how the dcc bind is called: + +* :code:`check_tcl_dcc()` creates Tcl variables :code:`$_dcc1 $_dcc2 $_dcc3` and lets :code:`check_tcl_bind` call the binds +* Tcl binds are done at this point +* C binds mean the Tcl command associated with the bind is :code:`*dcc:boot` which calls :code:`builtin_dcc` which gets :code:`cmd_boot` as ClientData cd argument +* :code:`gbuildin_dcc` performs some sanity checking to avoid crashes and then calls :code:`cmd_boot()` aka :code:`F()` with the arguments it wants C callbacks to have + +Example edited and annotated gdb backtrace in :code::`cmd_boot` after doing :code:`.boot test` on the partyline as user :code:`thommey` with typical owner flags. +:: + + #0 cmd_boot (u=0x55e8bd8a49b0, idx=4, par=0x55e8be6a0010 "test") at cmds.c:614 + *u = {next = 0x55e8bd8aec90, handle = "thommey", flags = 8977024, flags_udef = 0, chanrec = 0x55e8bd8aeae0, entries = 0x55e8bd8a4a10} + #1 builtin_dcc (cd=0x55e8bbf002d0 , irp=0x55e8bd59b1c0, argc=4, argv=0x55e8bd7e3e00) at tclhash.c:678 + idx = 4 + argv = {0x55e8be642fa0 "*dcc:boot", 0x55e8be9f6bd0 "thommey", 0x55e8be7d9020 "4", 0x55e8be6a0010 "test", 0x0} + F = 0x55e8bbf002d0 + #5 Tcl_Eval (interp=0x55e8bd59b1c0, script = "*dcc:boot $_dcc1 $_dcc2 $_dcc3") from /usr/lib/x86_64-linux-gnu/libtcl8.6.so + Tcl: return $_dcc1 = "thommey" + Tcl: return $_dcc2 = "4" + Tcl: return $_dcc3 = "test" + Tcl: return $lastbind = "boot" (set automatically by trigger_bind) + #8 trigger_bind (proc=proc@entry=0x55e8bd5efda0 "*dcc:boot", param=param@entry=0x55e8bbf4112b " $_dcc1 $_dcc2 $_dcc3", mask=mask@entry=0x55e8bd5efd40 "boot") at tclhash.c:742 + #9 check_tcl_bind (tl=0x55e8bd5eecb0 , match=match@entry=0x7ffcf3f9dac1 "boot", atr=atr@entry=0x7ffcf3f9d100, param=param@entry=0x55e8bbf4112b " $_dcc1 $_dcc2 $_dcc3", match_type=match_type@entry=80) at tclhash.c:942 + proc = 0x55e8bd5efda0 "*dcc:boot" + mask = 0x55e8bd5efd40 "boot" + brkt = 0x7ffcf3f9dac6 "test" + #10 check_tcl_dcc (cmd=cmd@entry=0x7ffcf3f9dac1 "boot", idx=idx@entry=4, args=0x7ffcf3f9dac6 "test") at tclhash.c:974 + fr = {match = 5, global = 8977024, udef_global = 0, bot = 0, chan = 0, udef_chan = 0} + #11 dcc_chat (idx=idx@entry=4, buf=, i=) at dcc.c:1068 + v = 0x7ffcf3f9dac1 "boot" diff --git a/doc/sphinx_source/modules/writing.rst b/doc/sphinx_source/modules/writing.rst index da222fbe5..ceeabb4fe 100644 --- a/doc/sphinx_source/modules/writing.rst +++ b/doc/sphinx_source/modules/writing.rst @@ -1,5 +1,7 @@ -Writing an Eggdrop Module -========================= +.. _writing_module: + +How to Write an Eggdrop Module +============================== Note: This is for a simple module of 1 source file. diff --git a/doc/sphinx_source/tutorials/module.rst b/doc/sphinx_source/tutorials/module.rst new file mode 100644 index 000000000..b4743484f --- /dev/null +++ b/doc/sphinx_source/tutorials/module.rst @@ -0,0 +1,235 @@ +Writing a Basic Eggdrop Module +============================== + +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 + +Module Header +------------- + +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 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 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +Required Code +------------- + +For this section, you don't necessarily need to understand what it is doing, but this code is required for a module to function. If you want to learn more about this, check out :ref:`writing_module` + +You'll next want to name your module:: + + #define MODULE_NAME "woobie" + +Declare your own function tables (again, you don't need to understand this part; you just need to copy/paste it):: + + #undef global + static Function *global = NULL, *server_funcs = NULL; + EXPORT_SCOPE char *woobie_start(); + +Next are two memory-related functions used by the core Eggdrop .status and .module commands:: + + static int woobie_expmem() + { + int size = 0; + + return size; + } + + static void woobie_report(int idx, int details) + { + if (details) { + int size = woobie_expmem(); + + dprintf(idx, " Using %d byte%s of memory\n", size, + (size != 1) ? "s" : ""); + } + } + +This function is called when Eggdrop loads the module:: + + char *woobie_start(Function *global_funcs) + { + global = global_funcs; + + /* Register the module. */ + module_register(MODULE_NAME, woobie_table, 2, 1); + /* ^--- minor module version + * ^------ major module version + * ^-------------------- module function table + * ^--------------------------------- module name + */ + + if (!module_depend(MODULE_NAME, "eggdrop", 108, 0)) { + module_undepend(MODULE_NAME); + return "This module requires Eggdrop 1.8.0 or later."; + } + +This next function is used to unload the module:: + + static char *woobie_close() + { + module_undepend(MODULE_NAME); + return NULL; + } + +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:: + + static Function woobie_table[] = { + (Function) woobie_start, + (Function) woobie_close, + (Function) woobie_expmem, + (Function) woobie_report, + }; + +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! + +Adding a Partyline Command +-------------------------- + +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:: + + static int cmd_woobie(struct userrec *u, int idx, char *par) + { + putlog(LOG_CMDS, "*", "#%s# woobie", dcc[idx].nick); + dprintf(idx, "WOOBIE!\n"); + return 0; + } + +If you add partyline commands, you need to create a table which links the new command name to the function it should call. This can be done like so:: + + static cmd_t mywoobie[] = { + /* command flags function tcl-name */ + {"woobie", "", cmd_woobie, NULL}, + {NULL, NULL, NULL, NULL} /* Mark end. */ + }; + +The tcl-name field can be a name for a Tcl command that will also call the partyline command, or it can be left as NULL. + +Adding a Tcl Command +-------------------- + +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:: + + + static int tcl_echome STDVAR { + BADARGS(2, 2, " arg"); + + if (strcmp(argv[1], "llama") { + Tcl_AppendResult(irp, "You said: ", argv[1], NULL); + return TCL_OK; + } else { + Tcl_AppendResult(irp, "illegal word!"); + return TCL_ERROR; + } + } + + A few notes on this example. BADARGS is a macro that checks the input provided to the Tcl command. The first argument BADARGS accepts is the minimum number of paramters the Tcl command must accept (including the command itself). The second argument is the maximum number of parameters that BADARGS will accept. The third argument is the help text that will be displayed if these boundaries are exceeded. For example, BADARGS(2, 4, " name ?date? ?place?") requires at least one argument to be passed, and a maximum of three arguments. Eggdrop code style is to enclose optional arguments between qusetion marks in the help text. + +Similar to adding a partyline command, you also have to create a function table for a new Tcl command:: + + static tcl_cmds mytcl[] = { + {"echome", tcl_echome}, + {NULL, NULL} /* Required to mark end of table */ + }; + +And now the newly-created Tcl command 'echome' is available for use in a script! + +Adding a Tcl Bind +----------------- + +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):: + + static p_tcl_bind_list H_woob; + + ... + + char *woobie_start(Function *global_funcs) + { + ... + H_woob = add_bind_table("woobie", HT_STACKABLE, woobie_2char); + } + +And then remove the binds when the module is unloaded:: + + static char *woobie_close() + { + ... + del_bind_table(H_woob); + } + +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. + +Defining bind arguments +^^^^^^^^^^^^^^^^^^^^^^^ + +The following code example defines a bind that will take two arguments:: + + static int woobie_2char STDVAR + { + Function F = (Function) cd; + + BADARGS(3, 3, " nick chan"); + + CHECKVALIDITY(woobie_2char); + F(argv[1], argv[2]); + return TCL_OK; + } + +And this example defines a bind that will take three arguments:: + + static int woobie_3char STDVAR + { + Function F = (Function) cd; + + BADARGS(4, 4, " foo bar moo"); + + CHECKVALIDITY(woobie_3char); + F(argv[1], argv[2], argv[3]); + return TCL_OK; + } + +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. + +Calling the Bind +^^^^^^^^^^^^^^^^ + +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:: + + check_tcl_woobie(chan, nick); + + + static int check_tcl_woobie(char *chan, char *nick, char *userhost) { + int x; + char mask[1024]; + struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; + + snprintf(mask, sizeof mask, "%s %s!%s", + chan, nick, userhost); + Tcl_SetVar(interp, "_woob1", nick ? (char *) nick : "", 0); + Tcl_SetVar(interp, "_woob2", chan, 0); + x = check_tcl_bind(H_woob, mask, &fr, " $_woob1 $_woob2", + MATCH_MASK | BIND_STACKABLE); + return (x == BIND_EXEC_LOG); + } + +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. + +Exporting the Bind +------------------ + +Do we need to do this? From 23386ce96e1828c6b8f4dc5eee50467d8cf286ab Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Mon, 13 Feb 2023 00:50:05 +0000 Subject: [PATCH 18/35] Fix load of null pointer Found by: 0_o I am EMPTY, mister EMPTY, ZarTek-Creole Patch by: michaelortmann Fixes: #1389 --- src/net.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/net.c b/src/net.c index 7539500fe..30e1f4cb8 100644 --- a/src/net.c +++ b/src/net.c @@ -1700,6 +1700,12 @@ char *traced_natip(ClientData cd, Tcl_Interp *irp, EGG_CONST char *name1, int r; struct in_addr ia; + /* Recover trace in case of unset. */ + if (flags & TCL_TRACE_DESTROYED) { + Tcl_TraceVar2(irp, name1, name2, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, traced_natip, cd); + return NULL; + } + value = Tcl_GetVar2(irp, name1, name2, TCL_GLOBAL_ONLY); if (*value) { r = inet_pton(AF_INET, value, &ia); From ed12d430b88ff820eabdfa2fe6cdb081e13ff7d0 Mon Sep 17 00:00:00 2001 From: Thomas Sader Date: Mon, 13 Feb 2023 22:07:22 +0100 Subject: [PATCH 19/35] Raise Tcl requirement to 8.5 Found by: mortmann Patch by: thommey Fixes: #1403 Eggdrop will not compile with Tcl8.5 DictObj support since 1.9.0 (oops). --- aclocal.m4 | 14 ++------------ config.h.in | 4 ---- configure.ac | 1 - doc/BUG-REPORT | 2 -- src/main.c | 7 ------- src/main.h | 12 ++---------- src/tcl.c | 25 ++----------------------- 7 files changed, 6 insertions(+), 59 deletions(-) diff --git a/aclocal.m4 b/aclocal.m4 index fc810bc45..4e8aab300 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1087,14 +1087,14 @@ dnl AC_DEFUN([EGG_TCL_CHECK_VERSION], [ - if test "x$TCL_MAJOR_VERSION" = x || test "x$TCL_MINOR_VERSION" = x || test $TCL_MAJOR_VERSION -lt 8 || test $TCL_MAJOR_VERSION -eq 8 -a $TCL_MINOR_VERSION -lt 3; then + if test "x$TCL_MAJOR_VERSION" = x || test "x$TCL_MINOR_VERSION" = x || test $TCL_MAJOR_VERSION -lt 8 || test $TCL_MAJOR_VERSION -eq 8 -a $TCL_MINOR_VERSION -lt 5; then cat << EOF >&2 configure: error: Your Tcl version is much too old for Eggdrop to use. You should download and compile a more recent version. The most reliable current version is $tclrecommendver and can be downloaded from - ${tclrecommendsite}. We require at least Tcl 8.3. + ${tclrecommendsite}. We require at least Tcl 8.5. See doc/COMPILE-GUIDE's 'Tcl Detection and Installation' section for more information. @@ -1114,16 +1114,6 @@ dnl AC_DEFUN([EGG_CACHE_UNSET], [unset $1]) -dnl EGG_TCL_CHECK_NOTIFIER_INIT -dnl -AC_DEFUN([EGG_TCL_CHECK_NOTIFIER_INIT], -[ - if test $TCL_MAJOR_VERSION -gt 8 || test $TCL_MAJOR_VERSION -eq 8 -a $TCL_MINOR_VERSION -ge 4; then - AC_DEFINE(HAVE_TCL_NOTIFIER_INIT, 1, [Define for Tcl that has the Tcl_NotifierProcs struct member initNotifierProc (8.4 and later).]) - fi -]) - - dnl EGG_SUBST_EGGVERSION() dnl AC_DEFUN([EGG_SUBST_EGGVERSION], diff --git a/config.h.in b/config.h.in index a0f0bbfe1..4e56afd4a 100644 --- a/config.h.in +++ b/config.h.in @@ -296,10 +296,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H -/* Define for Tcl that has the Tcl_NotifierProcs struct member - initNotifierProc (8.4 and later). */ -#undef HAVE_TCL_NOTIFIER_INIT - /* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use `HAVE_STRUCT_TM_TM_ZONE' instead. */ #undef HAVE_TM_ZONE diff --git a/configure.ac b/configure.ac index c101fedf0..c90d97e56 100644 --- a/configure.ac +++ b/configure.ac @@ -136,7 +136,6 @@ EGG_TCL_WITH_TCLLIB EGG_TCL_WITH_TCLINC EGG_TCL_TCLCONFIG EGG_TCL_CHECK_VERSION -EGG_TCL_CHECK_NOTIFIER_INIT EGG_TCL_LUSH diff --git a/doc/BUG-REPORT b/doc/BUG-REPORT index 3c279c599..f60096f40 100644 --- a/doc/BUG-REPORT +++ b/doc/BUG-REPORT @@ -42,8 +42,6 @@ DO NOT SEND HTML E-MAIL TO THE LISTS. 2) INFORMATION ABOUT TCL 2.1) Tcl library version: - ( ) 8.3._ - ( ) 8.4._ ( ) 8.5._ ( ) 8.6._ ( ) Other - Which? ____ diff --git a/src/main.c b/src/main.c index 9ab60c6de..13976ae84 100644 --- a/src/main.c +++ b/src/main.c @@ -981,11 +981,7 @@ static void mainloop(int toplevel) if (!eggbusy) { /* Process all pending tcl events */ -# ifdef REPLACE_NOTIFIER Tcl_ServiceAll(); -# else - while (Tcl_DoOneEvent(TCL_DONT_WAIT | TCL_ALL_EVENTS)); -# endif /* REPLACE_NOTIFIER */ } } @@ -1119,9 +1115,6 @@ int main(int arg_c, char **arg_v) fatal("ERROR: Eggdrop will not run as root!", 0); #endif -#ifndef REPLACE_NOTIFIER - init_threaddata(1); -#endif init_userent(); init_misc(); init_bots(); diff --git a/src/main.h b/src/main.h index 2b11465d5..3dbe592f2 100644 --- a/src/main.h +++ b/src/main.h @@ -45,16 +45,8 @@ # define TCL_PATCH_LEVEL "*unknown*" #endif -#if defined(HAVE_TCL_NOTIFIER_INIT) -# define REPLACE_NOTIFIER -#endif - -#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8)) -# ifdef CONST -# define EGG_CONST CONST -# else -# define EGG_CONST -# endif +#ifdef CONST +# define EGG_CONST CONST #else # define EGG_CONST #endif diff --git a/src/tcl.c b/src/tcl.c index 6e02af9e2..ccc4cd8d0 100644 --- a/src/tcl.c +++ b/src/tcl.c @@ -96,8 +96,8 @@ int handlen = HANDLEN; extern Tcl_VarTraceProc traced_myiphostname, traced_natip, traced_remove_pass; -/* Unicode workaround for Tcl versions that only support BMP characters (3 byte utf-8) */ -#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 5 && TCL_MINOR_VERSION <= 6 && TCL_UTF_MAX < 4 +/* Unicode workaround for Tcl versions (8.5/8.6) that only support BMP characters (3 byte utf-8) */ +#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION <= 6 && TCL_UTF_MAX < 4 # define TCL_WORKAROUND_UNICODESUP 1 struct tcl_unicodesup_info { const char *subcmd; @@ -548,7 +548,6 @@ extern tcl_cmds tcluser_cmds[], tcldcc_cmds[], tclmisc_cmds[], extern tcl_cmds tcltls_cmds[]; #endif -#ifdef REPLACE_NOTIFIER /* The tickle_*() functions replace the Tcl Notifier * The tickle_*() functions can be called by Tcl threads */ @@ -619,18 +618,6 @@ struct threaddata *threaddata() return td; } -#else /* REPLACE_NOTIFIER */ - -int tclthreadmainloop() { return 0; } - -struct threaddata *threaddata() -{ - static struct threaddata tsd; - return &tsd; -} - -#endif /* REPLACE_NOTIFIER */ - void init_threaddata(int mainthread) { struct threaddata *td = threaddata(); @@ -915,15 +902,12 @@ void init_unicodesup(void) */ void init_tcl(int argc, char **argv) { -#ifdef REPLACE_NOTIFIER Tcl_NotifierProcs notifierprocs; -#endif /* REPLACE_NOTIFIER */ const char *encoding; int i, j; char *langEnv, pver[1024] = ""; -#ifdef REPLACE_NOTIFIER egg_bzero(¬ifierprocs, sizeof(notifierprocs)); notifierprocs.initNotifierProc = tickle_InitNotifier; notifierprocs.createFileHandlerProc = tickle_CreateFileHandler; @@ -934,7 +918,6 @@ void init_tcl(int argc, char **argv) notifierprocs.alertNotifierProc = tickle_AlertNotifier; Tcl_SetNotifier(¬ifierprocs); -#endif /* REPLACE_NOTIFIER */ /* This must be done *BEFORE* Tcl_SetSystemEncoding(), * or Tcl_SetSystemEncoding() will cause a segfault. @@ -1247,11 +1230,7 @@ int tcl_threaded() */ int fork_before_tcl() { -#ifndef REPLACE_NOTIFIER - return tcl_threaded(); -#else return 0; -#endif } time_t get_expire_time(Tcl_Interp * irp, const char *s) { From 98a53aa99121379bf4b7bf5f777666f153ee326f Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Tue, 14 Feb 2023 00:17:13 +0000 Subject: [PATCH 20/35] Fix tcl service mode crash Found by: MacinMan Patch by: michaelortmann Fixes: #1351 Fixes: #1352 Fix crash - add tcl service mode hook stub / enhance doc --- INSTALL | 6 ++++-- doc/COMPILE-GUIDE | 12 ++++++------ src/tcl.c | 13 +++++++++++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/INSTALL b/INSTALL index 1b355fd85..6304d2628 100644 --- a/INSTALL +++ b/INSTALL @@ -19,6 +19,8 @@ Eggdrop uses the GNU autoconfigure scripts to make things easier. correctly compile Eggdrop. It will also try to find Tcl, which is required to compile. + For macOS tcl and openssl see doc/COMPILE-GUIDE. + 2. Type either 'make config' or 'make iconfig' to determine which @@ -158,5 +160,5 @@ the README file. If not, then READ IT!&@#%@! Have fun with Eggdrop! - Copyright (C) 1997 Robey Pointer Copyright (C) 1999 - 2022 Eggheads - Development Team + Copyright (C) 1997 Robey Pointer + Copyright (C) 1999 - 2022 Eggheads Development Team diff --git a/doc/COMPILE-GUIDE b/doc/COMPILE-GUIDE index 54e98d32f..92ee2f4fb 100644 --- a/doc/COMPILE-GUIDE +++ b/doc/COMPILE-GUIDE @@ -1,5 +1,5 @@ Eggdrop Compile Guide and FAQ -Last revised: June 9, 2020 +Last revised: November 17, 2022 _____________________________________________________________________ Eggdrop Compile Guide and FAQ @@ -20,7 +20,7 @@ Last revised: June 9, 2020 A. Standard compile process (Linux, FreeBSD, NetBSD, OpenBSD, etc) B. HP-UX B.11.* C. Ultrix - D. Mac OS X + D. macOS (previously OS X and originally Mac OS X) E. AIX F. IRIX G. Solaris / SunOS @@ -187,7 +187,7 @@ Last revised: June 9, 2020 gmake install DEST=/home/user/otherdir - D. Mac OS X + D. macOS Follow the standard compile process in Section A. To compile dynamically (with module support), use 'make eggdrop' instead of 'make'. @@ -210,7 +210,7 @@ Last revised: June 9, 2020 If you notice a module that requires these changes, it would probably be a good idea to let the module's developer know, so it can be fixed. - Note that on Mac OS X, the DYLD_LIBRARY_PATH environment variable should + Note that on macOS, the DYLD_LIBRARY_PATH environment variable should be used instead of LD_LIBRARY_PATH. Install OpenSSL using homebrew: @@ -221,7 +221,7 @@ Last revised: June 9, 2020 Tell configure where to find tcl and openssl: - ./configure --with-tcl=/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Tcl.framework/tclConfig.sh --with-sslinc=/usr/local/opt/openssl/include --with-ssllib=/usr/local/opt/openssl/lib + ./configure --with-tcl=/System/Volumes/Data/Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Tcl.framework/tclConfig.sh -with-sslinc=/usr/local/Cellar/openssl@3/3.0.7/include --with-ssllib=/usr/local/Cellar/openssl@3/3.0.7/lib E. AIX Follow the standard compile process in Section A. To compile dynamically @@ -581,4 +581,4 @@ Last revised: June 9, 2020 _____________________________________________________________________ Copyright (C) 1997 Robey Pointer - Copyright (C) 1999 - 2021 Eggheads Development Team + Copyright (C) 1999 - 2022 Eggheads Development Team diff --git a/src/tcl.c b/src/tcl.c index ccc4cd8d0..ac37316b0 100644 --- a/src/tcl.c +++ b/src/tcl.c @@ -600,8 +600,16 @@ ClientData tickle_InitNotifier() void tickle_AlertNotifier(ClientData cd) { - if (cd) - putlog(LOG_MISC, "*", "stub tickle_AlertNotifier"); + if (cd) { + fatal("Error calling Tcl_AlertNotifier", 0); + } +} + +void tickle_ServiceModeHook(int mode) +{ + if (mode != TCL_SERVICE_ALL) { + fatal("Tcl_ServiceModeHook called with unsupported mode", 0); + } } int tclthreadmainloop(int zero) @@ -916,6 +924,7 @@ void init_tcl(int argc, char **argv) notifierprocs.waitForEventProc = tickle_WaitForEvent; notifierprocs.finalizeNotifierProc = tickle_FinalizeNotifier; notifierprocs.alertNotifierProc = tickle_AlertNotifier; + notifierprocs.serviceModeHookProc = tickle_ServiceModeHook; Tcl_SetNotifier(¬ifierprocs); From de8c50be1a5475afe725e736c7019f9e432e2ba3 Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Tue, 14 Feb 2023 00:19:06 +0000 Subject: [PATCH 21/35] Cleanup deprecated gethostbyname2 Replace deprecated / obsolete gethostbyname2() with POSIX.1-2001 getaddrinfo() --- aclocal.m4 | 1 - src/Makefile.in | 2 +- src/compat/Makefile.in | 16 +++------------ src/compat/compat.h | 1 - src/compat/gethostbyname2.c | 39 ------------------------------------- src/compat/gethostbyname2.h | 37 ----------------------------------- src/md5/Makefile.in | 2 +- src/net.c | 36 ++++++++++++++++++++++------------ src/tcldcc.c | 1 + 9 files changed, 30 insertions(+), 105 deletions(-) delete mode 100644 src/compat/gethostbyname2.c delete mode 100644 src/compat/gethostbyname2.h diff --git a/aclocal.m4 b/aclocal.m4 index 4e8aab300..1d8827d64 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1422,7 +1422,6 @@ dnl AC_DEFUN([EGG_IPV6_COMPAT], [ if test "$enable_ipv6" = "yes"; then - AC_CHECK_FUNCS([gethostbyname2]) AC_CHECK_TYPES([struct in6_addr], egg_cv_var_have_in6_addr="yes", egg_cv_var_have_in6_addr="no", [ #include #include diff --git a/src/Makefile.in b/src/Makefile.in index c9605a049..5ecc97d54 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -86,7 +86,7 @@ eggdrop.h: bg.o: bg.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h compat/gethostbyname2.h \ + ../src/main.h compat/snprintf.h \ compat/explicit_bzero.h compat/strlcpy.h bg.h botcmd.o: botcmd.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ diff --git a/src/compat/Makefile.in b/src/compat/Makefile.in index e2617fb5f..87012d46d 100644 --- a/src/compat/Makefile.in +++ b/src/compat/Makefile.in @@ -17,8 +17,7 @@ STRIP = @STRIP@ CFLAGS = @CFLAGS@ -I../.. -I$(top_srcdir) -I$(top_srcdir)/src @SSL_INCLUDES@ @DEFS@ $(CFLGS) CPPFLAGS = @CPPFLAGS@ -OBJS = base64.o explicit_bzero.o gethostbyname2.o in6.o inet_aton.o snprintf.o \ - strlcpy.o +OBJS = base64.o explicit_bzero.o in6.o inet_aton.o snprintf.o strlcpy.o doofus: @echo "" @@ -43,15 +42,6 @@ compat: $(OBJS) #safety hash base64.o: base64.c ../../config.h explicit_bzero.o: explicit_bzero.c ../../config.h -gethostbyname2.o: gethostbyname2.c gethostbyname2.h ../../src/main.h \ - ../../config.h ../../eggint.h ../../lush.h ../../src/lang.h \ - ../../src/eggdrop.h ../../src/compat/in6.h ../../src/flags.h \ - ../../src/proto.h ../../src/misc_file.h ../../src/cmdt.h \ - ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \ - ../../src/users.h ../../src/compat/compat.h ../../src/compat/base64.h \ - ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \ - ../../src/compat/gethostbyname2.h ../../src/compat/explicit_bzero.h \ - ../../src/compat/strlcpy.h in6.o: in6.c in6.h inet_aton.o: inet_aton.c ../../src/main.h ../../config.h ../../eggint.h \ ../../lush.h ../../src/lang.h ../../src/eggdrop.h ../../src/compat/in6.h \ @@ -59,7 +49,7 @@ inet_aton.o: inet_aton.c ../../src/main.h ../../config.h ../../eggint.h \ ../../src/cmdt.h ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \ ../../src/users.h ../../src/compat/compat.h ../../src/compat/base64.h \ ../../src/compat/inet_aton.h ../../src/main.h \ - ../../src/compat/snprintf.h ../../src/compat/gethostbyname2.h \ + ../../src/compat/snprintf.h \ ../../src/compat/explicit_bzero.h ../../src/compat/strlcpy.h inet_aton.h snprintf.o: snprintf.c ../../src/main.h ../../config.h ../../eggint.h \ ../../lush.h ../../src/lang.h ../../src/eggdrop.h ../../src/compat/in6.h \ @@ -67,6 +57,6 @@ snprintf.o: snprintf.c ../../src/main.h ../../config.h ../../eggint.h \ ../../src/cmdt.h ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \ ../../src/users.h ../../src/compat/compat.h ../../src/compat/base64.h \ ../../src/compat/inet_aton.h ../../src/main.h \ - ../../src/compat/snprintf.h ../../src/compat/gethostbyname2.h \ + ../../src/compat/snprintf.h \ ../../src/compat/explicit_bzero.h ../../src/compat/strlcpy.h snprintf.h strlcpy.o: strlcpy.c ../../config.h diff --git a/src/compat/compat.h b/src/compat/compat.h index 75eb1753c..63b35ebc4 100644 --- a/src/compat/compat.h +++ b/src/compat/compat.h @@ -26,7 +26,6 @@ #include "base64.h" #include "inet_aton.h" #include "snprintf.h" -#include "gethostbyname2.h" #include "explicit_bzero.h" #include "strlcpy.h" diff --git a/src/compat/gethostbyname2.c b/src/compat/gethostbyname2.c deleted file mode 100644 index 6f1ec80d9..000000000 --- a/src/compat/gethostbyname2.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * gethostbyname2.c -- provide a dummy gethostbyname2 replacement - */ -/* - * Copyright (C) 2010 - 2022 Eggheads Development Team - * - * 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 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "gethostbyname2.h" - -#if defined IPV6 && !defined HAVE_GETHOSTBYNAME2 -struct hostent *gethostbyname2(const char *name, int af) -{ - struct hostent *h; - - h = gethostbyname(name); - if (!h) - return NULL; - if (h->h_addrtype != af) { - h_errno = NO_RECOVERY; - return NULL; - } - - return h; -} -#endif diff --git a/src/compat/gethostbyname2.h b/src/compat/gethostbyname2.h deleted file mode 100644 index 0f59f6e0e..000000000 --- a/src/compat/gethostbyname2.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * gethostbyname2.h - * prototypes for gethostbyname2.c - */ -/* - * Copyright (C) 2010 - 2022 Eggheads Development Team - * - * 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 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _EGG_COMPAT_GETHOSTBYNAME2 -#define _EGG_COMPAT_GETHOSTBYNAME2 - -#include "src/main.h" - -#include -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -#include - -#if defined IPV6 && !defined HAVE_GETHOSTBYNAME2 -struct hostent *gethostbyname2(const char *name, int af); -#endif -#endif /* _EGG_COMPAT_GETHOSTBYNAME2 */ diff --git a/src/md5/Makefile.in b/src/md5/Makefile.in index 4c9c670d3..7bf42c5c9 100644 --- a/src/md5/Makefile.in +++ b/src/md5/Makefile.in @@ -46,5 +46,5 @@ md5c.o: md5c.c md5.h ../../src/main.h ../../config.h ../../eggint.h \ ../../src/cmdt.h ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \ ../../src/users.h ../../src/compat/compat.h ../../src/compat/base64.h \ ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \ - ../../src/compat/gethostbyname2.h ../../src/compat/explicit_bzero.h \ + ../../src/compat/explicit_bzero.h \ ../../src/compat/strlcpy.h diff --git a/src/net.c b/src/net.c index 30e1f4cb8..bb71aad6d 100644 --- a/src/net.c +++ b/src/net.c @@ -133,12 +133,14 @@ int setsockname(sockname_t *addr, char *src, int port, int allowres) char *endptr, *src2 = src;; long val; IP ip; - struct hostent *hp; volatile int af = AF_UNSPEC; char ip2[EGG_INET_ADDRSTRLEN]; #ifdef IPV6 volatile int pref; + struct addrinfo *res0 = NULL, *res; + int error; #else + struct hostent *hp; int i, count; #endif @@ -176,18 +178,28 @@ int setsockname(sockname_t *addr, char *src, int port, int allowres) /* src is a hostname. Attempt to resolve it.. */ if (!sigsetjmp(alarmret, 1)) { alarm(resolve_timeout); - hp = gethostbyname2(src, pref_af ? AF_INET6 : AF_INET); - if (!hp) - hp = gethostbyname2(src, pref_af ? AF_INET : AF_INET6); - alarm(0); - } else - hp = NULL; - if (hp) { - if (hp->h_addrtype == AF_INET) - memcpy(&addr->addr.s4.sin_addr, hp->h_addr_list[0], hp->h_length); + error = getaddrinfo(src, NULL, NULL, &res0); + if (!error) { + for (res = res0; res; res = res->ai_next) { + if (res == res0 || res->ai_family == (pref_af ? AF_INET6 : AF_INET)) { + af = res->ai_family; + memcpy(&addr->addr.sa, res->ai_addr, res->ai_addrlen); + if (res->ai_family == (pref_af ? AF_INET6 : AF_INET)) { + break; + } + } + } + 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("net: setsockname(): getaddrinfo(): hostname %s not known", src); else - memcpy(&addr->addr.s6.sin6_addr, hp->h_addr_list[0], hp->h_length); - af = hp->h_addrtype; + debug1("net: setsockname(): getaddrinfo(): error = %s", gai_strerror(error)); + alarm(0); + } else { + debug1("net: setsockname(): getaddrinfo(): hostname %s resolve timeout", src); } } diff --git a/src/tcldcc.c b/src/tcldcc.c index 3fd96e0f0..3aba03757 100644 --- a/src/tcldcc.c +++ b/src/tcldcc.c @@ -22,6 +22,7 @@ */ #include "main.h" +#include #include "tandem.h" #include "modules.h" #include From 42916cee15222d20692569c161bc6ac3dec8ee19 Mon Sep 17 00:00:00 2001 From: Geo Date: Mon, 13 Feb 2023 19:22:17 -0500 Subject: [PATCH 22/35] Run autotools/makedepend --- config.h.in | 3 - configure | 24 +------- src/Makefile.in | 97 +++++++++++++++----------------- src/compat/Makefile.in | 8 +-- src/md5/Makefile.in | 3 +- src/mod/assoc.mod/Makefile | 1 - src/mod/blowfish.mod/Makefile | 1 - src/mod/channels.mod/Makefile | 1 - src/mod/compress.mod/Makefile.in | 1 - src/mod/compress.mod/configure | 2 +- src/mod/console.mod/Makefile | 1 - src/mod/ctcp.mod/Makefile | 7 +-- src/mod/dns.mod/Makefile.in | 4 +- src/mod/dns.mod/configure | 2 +- src/mod/filesys.mod/Makefile | 1 - src/mod/ident.mod/Makefile | 1 - src/mod/irc.mod/Makefile | 1 - src/mod/notes.mod/Makefile | 1 - src/mod/pbkdf2.mod/Makefile | 10 +++- src/mod/seen.mod/Makefile | 1 - src/mod/server.mod/Makefile | 1 - src/mod/share.mod/Makefile | 1 - src/mod/transfer.mod/Makefile | 1 - src/mod/twitch.mod/Makefile | 1 - src/mod/uptime.mod/Makefile | 7 +-- src/mod/woobie.mod/Makefile | 6 +- 26 files changed, 73 insertions(+), 114 deletions(-) diff --git a/config.h.in b/config.h.in index 4e56afd4a..1a412d315 100644 --- a/config.h.in +++ b/config.h.in @@ -111,9 +111,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H -/* Define to 1 if you have the `gethostbyname2' function. */ -#undef HAVE_GETHOSTBYNAME2 - /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE diff --git a/configure b/configure index 7372012d6..494e63381 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac 533f882a. +# From configure.ac de8c50be. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Eggdrop 1.9.4. # @@ -8933,14 +8933,14 @@ $as_echo "$TCL_INCLUDE_SPEC" >&6; } - if test "x$TCL_MAJOR_VERSION" = x || test "x$TCL_MINOR_VERSION" = x || test $TCL_MAJOR_VERSION -lt 8 || test $TCL_MAJOR_VERSION -eq 8 -a $TCL_MINOR_VERSION -lt 3; then + if test "x$TCL_MAJOR_VERSION" = x || test "x$TCL_MINOR_VERSION" = x || test $TCL_MAJOR_VERSION -lt 8 || test $TCL_MAJOR_VERSION -eq 8 -a $TCL_MINOR_VERSION -lt 5; then cat << EOF >&2 configure: error: Your Tcl version is much too old for Eggdrop to use. You should download and compile a more recent version. The most reliable current version is $tclrecommendver and can be downloaded from - ${tclrecommendsite}. We require at least Tcl 8.3. + ${tclrecommendsite}. We require at least Tcl 8.5. See doc/COMPILE-GUIDE's 'Tcl Detection and Installation' section for more information. @@ -8951,13 +8951,6 @@ EOF - if test $TCL_MAJOR_VERSION -gt 8 || test $TCL_MAJOR_VERSION -eq 8 -a $TCL_MINOR_VERSION -ge 4; then - -$as_echo "#define HAVE_TCL_NOTIFIER_INIT 1" >>confdefs.h - - fi - - if test "x$TCLINCFN" != x; then egg_tclinc="\\\"$TCLINC/$TCLINCFN\\\"" else @@ -9335,17 +9328,6 @@ $as_echo "#define IPV6 1" >>confdefs.h if test "$enable_ipv6" = "yes"; then - for ac_func in gethostbyname2 -do : - ac_fn_c_check_func "$LINENO" "gethostbyname2" "ac_cv_func_gethostbyname2" -if test "x$ac_cv_func_gethostbyname2" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETHOSTBYNAME2 1 -_ACEOF - -fi -done - ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" " #include #include diff --git a/src/Makefile.in b/src/Makefile.in index 5ecc97d54..6fbce846f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -86,155 +86,146 @@ eggdrop.h: bg.o: bg.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h \ - compat/explicit_bzero.h compat/strlcpy.h bg.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h \ + bg.h botcmd.o: botcmd.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - tandem.h modules.h mod/modvals.h + compat/explicit_bzero.h compat/strlcpy.h tandem.h modules.h \ + mod/modvals.h botmsg.o: botmsg.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - tandem.h + compat/explicit_bzero.h compat/strlcpy.h tandem.h botnet.o: botnet.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - tandem.h + compat/explicit_bzero.h compat/strlcpy.h tandem.h chanprog.o: chanprog.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - modules.h mod/modvals.h + compat/explicit_bzero.h compat/strlcpy.h modules.h mod/modvals.h cmds.o: cmds.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h compat/gethostbyname2.h \ - compat/explicit_bzero.h compat/strlcpy.h tandem.h modules.h \ - mod/modvals.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h \ + tandem.h modules.h mod/modvals.h dcc.o: dcc.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h compat/gethostbyname2.h \ - compat/explicit_bzero.h compat/strlcpy.h modules.h mod/modvals.h \ - tandem.h md5/md5.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h \ + modules.h mod/modvals.h tandem.h md5/md5.h dccutil.o: dccutil.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - modules.h mod/modvals.h tandem.h + compat/explicit_bzero.h compat/strlcpy.h modules.h mod/modvals.h \ + tandem.h dns.o: dns.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h compat/gethostbyname2.h \ - compat/explicit_bzero.h compat/strlcpy.h dns.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h \ + dns.h flags.o: flags.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h + compat/explicit_bzero.h compat/strlcpy.h language.o: language.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h + compat/explicit_bzero.h compat/strlcpy.h main.o: main.c ../config.h main.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h compat/gethostbyname2.h \ - compat/explicit_bzero.h compat/strlcpy.h version.h modules.h \ - mod/modvals.h tandem.h bg.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h \ + version.h modules.h mod/modvals.h tandem.h bg.h match.o: match.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h + compat/explicit_bzero.h compat/strlcpy.h mem.o: mem.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h compat/gethostbyname2.h \ - compat/explicit_bzero.h compat/strlcpy.h mod/modvals.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h \ + mod/modvals.h misc.o: misc.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h compat/gethostbyname2.h \ - compat/explicit_bzero.h compat/strlcpy.h tandem.h modules.h \ - mod/modvals.h stat.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h \ + tandem.h modules.h mod/modvals.h stat.h misc_file.o: misc_file.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h stat.h + compat/explicit_bzero.h compat/strlcpy.h stat.h modules.o: modules.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - modules.h mod/modvals.h tandem.h md5/md5.h + compat/explicit_bzero.h compat/strlcpy.h modules.h mod/modvals.h \ + tandem.h md5/md5.h net.o: net.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h compat/gethostbyname2.h \ - compat/explicit_bzero.h compat/strlcpy.h mod/server.mod/server.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h \ + mod/server.mod/server.h rfc1459.o: rfc1459.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h + compat/explicit_bzero.h compat/strlcpy.h tcl.o: tcl.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h compat/gethostbyname2.h \ - compat/explicit_bzero.h compat/strlcpy.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h tcldcc.o: tcldcc.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - tandem.h modules.h mod/modvals.h + compat/explicit_bzero.h compat/strlcpy.h tandem.h modules.h \ + mod/modvals.h tclhash.o: tclhash.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h + compat/explicit_bzero.h compat/strlcpy.h tclmisc.o: tclmisc.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - modules.h mod/modvals.h tandem.h md5/md5.h + compat/explicit_bzero.h compat/strlcpy.h modules.h mod/modvals.h \ + tandem.h md5/md5.h tcluser.o: tcluser.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - tandem.h modules.h mod/modvals.h + compat/explicit_bzero.h compat/strlcpy.h tandem.h modules.h \ + mod/modvals.h tls.o: tls.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \ compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \ chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \ - ../src/main.h compat/snprintf.h compat/gethostbyname2.h \ - compat/explicit_bzero.h compat/strlcpy.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h userent.o: userent.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h + compat/explicit_bzero.h compat/strlcpy.h userrec.o: userrec.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - modules.h mod/modvals.h tandem.h + compat/explicit_bzero.h compat/strlcpy.h modules.h mod/modvals.h \ + tandem.h users.o: users.c main.h ../config.h ../eggint.h ../lush.h lang.h \ eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \ tclhash.h chan.h users.h compat/compat.h compat/base64.h \ compat/inet_aton.h ../src/main.h compat/snprintf.h \ - compat/gethostbyname2.h compat/explicit_bzero.h compat/strlcpy.h \ - modules.h mod/modvals.h tandem.h + compat/explicit_bzero.h compat/strlcpy.h modules.h mod/modvals.h \ + tandem.h diff --git a/src/compat/Makefile.in b/src/compat/Makefile.in index 87012d46d..c431ee491 100644 --- a/src/compat/Makefile.in +++ b/src/compat/Makefile.in @@ -49,14 +49,14 @@ inet_aton.o: inet_aton.c ../../src/main.h ../../config.h ../../eggint.h \ ../../src/cmdt.h ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \ ../../src/users.h ../../src/compat/compat.h ../../src/compat/base64.h \ ../../src/compat/inet_aton.h ../../src/main.h \ - ../../src/compat/snprintf.h \ - ../../src/compat/explicit_bzero.h ../../src/compat/strlcpy.h inet_aton.h + ../../src/compat/snprintf.h ../../src/compat/explicit_bzero.h \ + ../../src/compat/strlcpy.h inet_aton.h snprintf.o: snprintf.c ../../src/main.h ../../config.h ../../eggint.h \ ../../lush.h ../../src/lang.h ../../src/eggdrop.h ../../src/compat/in6.h \ ../../src/flags.h ../../src/proto.h ../../src/misc_file.h \ ../../src/cmdt.h ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \ ../../src/users.h ../../src/compat/compat.h ../../src/compat/base64.h \ ../../src/compat/inet_aton.h ../../src/main.h \ - ../../src/compat/snprintf.h \ - ../../src/compat/explicit_bzero.h ../../src/compat/strlcpy.h snprintf.h + ../../src/compat/snprintf.h ../../src/compat/explicit_bzero.h \ + ../../src/compat/strlcpy.h snprintf.h strlcpy.o: strlcpy.c ../../config.h diff --git a/src/md5/Makefile.in b/src/md5/Makefile.in index 7bf42c5c9..81fb52a98 100644 --- a/src/md5/Makefile.in +++ b/src/md5/Makefile.in @@ -46,5 +46,4 @@ md5c.o: md5c.c md5.h ../../src/main.h ../../config.h ../../eggint.h \ ../../src/cmdt.h ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \ ../../src/users.h ../../src/compat/compat.h ../../src/compat/base64.h \ ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \ - ../../src/compat/explicit_bzero.h \ - ../../src/compat/strlcpy.h + ../../src/compat/explicit_bzero.h ../../src/compat/strlcpy.h diff --git a/src/mod/assoc.mod/Makefile b/src/mod/assoc.mod/Makefile index 756870353..5bc160183 100644 --- a/src/mod/assoc.mod/Makefile +++ b/src/mod/assoc.mod/Makefile @@ -35,6 +35,5 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h .././assoc.mod/assoc.h diff --git a/src/mod/blowfish.mod/Makefile b/src/mod/blowfish.mod/Makefile index 4a448b5b1..64b1e7344 100644 --- a/src/mod/blowfish.mod/Makefile +++ b/src/mod/blowfish.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h \ .././blowfish.mod/blowfish.h .././blowfish.mod/bf_tab.h diff --git a/src/mod/channels.mod/Makefile b/src/mod/channels.mod/Makefile index 2e75492be..b53d568cd 100644 --- a/src/mod/channels.mod/Makefile +++ b/src/mod/channels.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h \ .././channels.mod/channels.h .././channels.mod/cmdschan.c \ diff --git a/src/mod/compress.mod/Makefile.in b/src/mod/compress.mod/Makefile.in index 552f38f15..6f91a3342 100644 --- a/src/mod/compress.mod/Makefile.in +++ b/src/mod/compress.mod/Makefile.in @@ -39,7 +39,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h \ ../../../src/mod/share.mod/share.h .././compress.mod/compress.h \ diff --git a/src/mod/compress.mod/configure b/src/mod/compress.mod/configure index 3ea939674..88d9e0815 100755 --- a/src/mod/compress.mod/configure +++ b/src/mod/compress.mod/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac 533f882a. +# From configure.ac de8c50be. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Eggdrop Compress Module 1.9.4. # diff --git a/src/mod/console.mod/Makefile b/src/mod/console.mod/Makefile index e33c0b8e3..a678d1176 100644 --- a/src/mod/console.mod/Makefile +++ b/src/mod/console.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h \ .././console.mod/console.h diff --git a/src/mod/ctcp.mod/Makefile b/src/mod/ctcp.mod/Makefile index 8412533f0..dec8c9d97 100644 --- a/src/mod/ctcp.mod/Makefile +++ b/src/mod/ctcp.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/cmdt.h ../../../src/tclegg.h ../../../src/tclhash.h \ ../../../src/chan.h ../../../src/users.h ../../../src/compat/compat.h \ ../../../src/compat/base64.h ../../../src/compat/inet_aton.h \ - ../../../src/compat/snprintf.h ../../../src/compat/gethostbyname2.h \ - ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ - ../../../src/mod/modvals.h ../../../src/tandem.h \ - ../../../src/mod/server.mod/server.h + ../../../src/compat/snprintf.h ../../../src/compat/explicit_bzero.h \ + ../../../src/compat/strlcpy.h ../../../src/mod/modvals.h \ + ../../../src/tandem.h ../../../src/mod/server.mod/server.h diff --git a/src/mod/dns.mod/Makefile.in b/src/mod/dns.mod/Makefile.in index bba72091b..b2508d6a9 100644 --- a/src/mod/dns.mod/Makefile.in +++ b/src/mod/dns.mod/Makefile.in @@ -40,7 +40,5 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ - ../../../src/mod/modvals.h ../../../src/tandem.h .././dns.mod/dns.h \ - .././dns.mod/coredns.c + ../../../src/mod/modvals.h ../../../src/tandem.h diff --git a/src/mod/dns.mod/configure b/src/mod/dns.mod/configure index 84e203692..5f03ba0b7 100755 --- a/src/mod/dns.mod/configure +++ b/src/mod/dns.mod/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac 533f882a. +# From configure.ac de8c50be. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Eggdrop DNS Module 1.9.4. # diff --git a/src/mod/filesys.mod/Makefile b/src/mod/filesys.mod/Makefile index c5bb3ac99..f1a7e1309 100644 --- a/src/mod/filesys.mod/Makefile +++ b/src/mod/filesys.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h \ .././filesys.mod/filedb3.h .././filesys.mod/filesys.h \ diff --git a/src/mod/ident.mod/Makefile b/src/mod/ident.mod/Makefile index eb261e1cd..071e7ef01 100644 --- a/src/mod/ident.mod/Makefile +++ b/src/mod/ident.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h \ ../../../src/mod/server.mod/server.h diff --git a/src/mod/irc.mod/Makefile b/src/mod/irc.mod/Makefile index 4fb07ab95..8a17bf80c 100644 --- a/src/mod/irc.mod/Makefile +++ b/src/mod/irc.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h .././irc.mod/irc.h \ ../../../src/mod/server.mod/server.h \ diff --git a/src/mod/notes.mod/Makefile b/src/mod/notes.mod/Makefile index 7c001acfb..0c3ce51a5 100644 --- a/src/mod/notes.mod/Makefile +++ b/src/mod/notes.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h .././notes.mod/notes.h \ .././notes.mod/cmdsnote.c diff --git a/src/mod/pbkdf2.mod/Makefile b/src/mod/pbkdf2.mod/Makefile index b28559065..8266ce14f 100644 --- a/src/mod/pbkdf2.mod/Makefile +++ b/src/mod/pbkdf2.mod/Makefile @@ -28,4 +28,12 @@ clean: distclean: clean #safety hash -../pbkdf2.o: .././pbkdf2.mod/pbkdf2.c +../pbkdf2.o: .././pbkdf2.mod/pbkdf2.c ../../../src/mod/module.h \ + ../../../src/main.h ../../../config.h ../../../eggint.h ../../../lush.h \ + ../../../src/lang.h ../../../src/eggdrop.h ../../../src/compat/in6.h \ + ../../../src/flags.h ../../../src/cmdt.h ../../../src/tclegg.h \ + ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ + ../../../src/compat/compat.h ../../../src/compat/base64.h \ + ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ + ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ + ../../../src/mod/modvals.h ../../../src/tandem.h diff --git a/src/mod/seen.mod/Makefile b/src/mod/seen.mod/Makefile index c61d32b5c..bcf2454c0 100644 --- a/src/mod/seen.mod/Makefile +++ b/src/mod/seen.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h ../../../src/users.h \ ../../../src/chan.h ../../../src/mod/channels.mod/channels.h diff --git a/src/mod/server.mod/Makefile b/src/mod/server.mod/Makefile index aaa8ee887..1b26a1043 100644 --- a/src/mod/server.mod/Makefile +++ b/src/mod/server.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h \ .././server.mod/server.h .././server.mod/isupport.c \ diff --git a/src/mod/share.mod/Makefile b/src/mod/share.mod/Makefile index e6f804367..5543e3570 100644 --- a/src/mod/share.mod/Makefile +++ b/src/mod/share.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h ../../../src/chan.h \ ../../../src/users.h ../../../src/mod/transfer.mod/transfer.h \ diff --git a/src/mod/transfer.mod/Makefile b/src/mod/transfer.mod/Makefile index 9cfb660bc..21de50e84 100644 --- a/src/mod/transfer.mod/Makefile +++ b/src/mod/transfer.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h ../../../src/users.h \ .././transfer.mod/transfer.h .././transfer.mod/transferfstat.c \ diff --git a/src/mod/twitch.mod/Makefile b/src/mod/twitch.mod/Makefile index bb81afa35..3477b6281 100644 --- a/src/mod/twitch.mod/Makefile +++ b/src/mod/twitch.mod/Makefile @@ -35,7 +35,6 @@ distclean: clean ../../../src/tclhash.h ../../../src/chan.h ../../../src/users.h \ ../../../src/compat/compat.h ../../../src/compat/base64.h \ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \ - ../../../src/compat/gethostbyname2.h \ ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ ../../../src/mod/modvals.h ../../../src/tandem.h \ ../../../src/mod/twitch.mod/twitch.h \ diff --git a/src/mod/uptime.mod/Makefile b/src/mod/uptime.mod/Makefile index ec120df9b..ff49761a4 100644 --- a/src/mod/uptime.mod/Makefile +++ b/src/mod/uptime.mod/Makefile @@ -34,7 +34,6 @@ distclean: clean ../../../src/cmdt.h ../../../src/tclegg.h ../../../src/tclhash.h \ ../../../src/chan.h ../../../src/users.h ../../../src/compat/compat.h \ ../../../src/compat/base64.h ../../../src/compat/inet_aton.h \ - ../../../src/compat/snprintf.h ../../../src/compat/gethostbyname2.h \ - ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ - .././uptime.mod/../modvals.h ../../../src/tandem.h \ - .././uptime.mod/../server.mod/server.h + ../../../src/compat/snprintf.h ../../../src/compat/explicit_bzero.h \ + ../../../src/compat/strlcpy.h .././uptime.mod/../modvals.h \ + ../../../src/tandem.h .././uptime.mod/../server.mod/server.h diff --git a/src/mod/woobie.mod/Makefile b/src/mod/woobie.mod/Makefile index 8b1a3417e..9ce22150a 100644 --- a/src/mod/woobie.mod/Makefile +++ b/src/mod/woobie.mod/Makefile @@ -34,6 +34,6 @@ distclean: clean ../../../src/cmdt.h ../../../src/tclegg.h ../../../src/tclhash.h \ ../../../src/chan.h ../../../src/users.h ../../../src/compat/compat.h \ ../../../src/compat/base64.h ../../../src/compat/inet_aton.h \ - ../../../src/compat/snprintf.h ../../../src/compat/gethostbyname2.h \ - ../../../src/compat/explicit_bzero.h ../../../src/compat/strlcpy.h \ - ../../../src/mod/modvals.h ../../../src/tandem.h + ../../../src/compat/snprintf.h ../../../src/compat/explicit_bzero.h \ + ../../../src/compat/strlcpy.h ../../../src/mod/modvals.h \ + ../../../src/tandem.h From d9bda49c2d6f3b4e43252b8119999b271a931e9c Mon Sep 17 00:00:00 2001 From: Geo Date: Mon, 13 Feb 2023 19:23:15 -0500 Subject: [PATCH 23/35] bump patchlevel --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 5111478ae..36f59b15c 100644 --- a/src/version.h +++ b/src/version.h @@ -27,5 +27,5 @@ */ #define EGG_STRINGVER "1.9.4" -#define EGG_NUMVER 1090404 -#define EGG_PATCH "logupdates" +#define EGG_NUMVER 1090405 +#define EGG_PATCH "raisetcl" From 506f1405af21fa68652e0dae909d48a119cb3054 Mon Sep 17 00:00:00 2001 From: Geo Date: Mon, 13 Feb 2023 21:14:40 -0500 Subject: [PATCH 24/35] Update THANKS --- THANKS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/THANKS b/THANKS index 1f3f5ba6f..53fe4a189 100644 --- a/THANKS +++ b/THANKS @@ -236,6 +236,7 @@ eelcohuininga Eelco Huininga Ehrenberg ejm Emmanuel Marty +Empus Erick- Erick Velez erick@erick.org eryg-kai Evo|ver @@ -509,6 +510,7 @@ Robby robby@chatbelgie.be Roger Yerramsetti Rok Papez romulus +rsc Robert Scheck Rufus S Wilcox S7reaM From c27143997de77af5f66c6278f02f86de24bba15d Mon Sep 17 00:00:00 2001 From: Geo Date: Mon, 13 Feb 2023 21:15:52 -0500 Subject: [PATCH 25/35] Update NEWS --- NEWS | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/NEWS b/NEWS index 6af6b7bac..a884e737a 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,35 @@ Last revised: December 4, 2021 _________________________________________________________________ +Eggdrop v1.9.5: + + General changes: + - Implemented a workaround for a Tcl issue parsing emojis that can cause a + crash + - Fixed an improper change to the display of bind flags that caused issues + with Tcl scripts that parse bind flags + - Added SSL header information to .status to help diagnose ./configure + mismatches + - Lots of under-the-hood bug fixes + + Botnet changes: + - None + + Tcl API changes: + - Tcl minimum required version is now 8.5! This actually happened in version + version 1.9.0; we just forgot to tell people. Oops! :) + + Module changes: + - Updated woobie.mod with additional example code + + Eggdrop config changes: + - None + + Documentation changes: + - Added additional documentation to help write modules + - Updated botnet docs to include reference to TLS docs for secure links + - Updated Tcl repo from unmaintained FTP to HTTP repository + Eggdrop v1.9.4: General changes: From ffb8c1814095966386f9891e43d10a67ed9ceec3 Mon Sep 17 00:00:00 2001 From: Geo Date: Mon, 13 Feb 2023 21:22:26 -0500 Subject: [PATCH 26/35] Update copyright --- AUTHORS | 2 +- CONTENTS | 2 +- FEATURES | 2 +- INSTALL | 6 +- NEWS | 4 +- aclocal.m4 | 2 +- config.h.in | 2 +- configure | 4 +- configure.ac | 4 +- doc/ABOUT | 2 +- doc/BANS | 2 +- doc/BOTNET | 27 +- doc/COMPILE-GUIDE | 2 +- doc/CONTENTS | 2 +- doc/FIRST-SCRIPT | 2 +- doc/IPV6 | 2 +- doc/IRCv3 | 2 +- doc/MODULES | 2 +- doc/PARTYLINE | 2 +- doc/PATCH-HOWTO | 2 +- doc/PBKDF2 | 2 +- doc/TLS | 2 +- doc/TRICKS | 2 +- doc/USERS | 2 +- doc/core.settings | 6 +- doc/html/_static/basic.css | 331 ++- doc/html/_static/doctools.js | 377 +-- doc/html/_static/documentation_options.js | 6 +- doc/html/_static/language_data.js | 106 +- doc/html/_static/pygments.css | 7 +- doc/html/_static/searchtools.js | 793 ++--- doc/html/_static/sphinx_highlight.js | 144 + doc/html/about/about.html | 72 +- doc/html/about/legal.html | 52 +- doc/html/index.html | 121 +- doc/html/install/install.html | 121 +- doc/html/install/readme.html | 201 +- doc/html/install/upgrading.html | 108 +- doc/html/modules/assoc.html | 2 +- doc/html/modules/blowfish.html | 2 +- doc/html/modules/channels.html | 2 +- doc/html/modules/compress.html | 2 +- doc/html/modules/console.html | 2 +- doc/html/modules/ctcp.html | 2 +- doc/html/modules/dns.html | 2 +- doc/html/modules/filesys.html | 2 +- doc/html/modules/ident.html | 2 +- doc/html/modules/included.html | 154 +- doc/html/modules/index.html | 106 +- doc/html/modules/internals.html | 166 +- doc/html/modules/irc.html | 2 +- doc/html/modules/mod/assoc.html | 54 +- doc/html/modules/mod/blowfish.html | 54 +- doc/html/modules/mod/channels.html | 467 ++- doc/html/modules/mod/compress.html | 68 +- doc/html/modules/mod/console.html | 74 +- doc/html/modules/mod/ctcp.html | 83 +- doc/html/modules/mod/dns.html | 86 +- doc/html/modules/mod/filesys.html | 325 ++- doc/html/modules/mod/ident.html | 91 +- doc/html/modules/mod/irc.html | 197 +- doc/html/modules/mod/notes.html | 88 +- doc/html/modules/mod/pbkdf2.html | 70 +- doc/html/modules/mod/seen.html | 54 +- doc/html/modules/mod/server.html | 278 +- doc/html/modules/mod/share.html | 92 +- doc/html/modules/mod/transfer.html | 86 +- doc/html/modules/mod/twitch.html | 93 +- doc/html/modules/mod/uptime.html | 60 +- doc/html/modules/mod/woobie.html | 54 +- doc/html/modules/notes.html | 2 +- doc/html/modules/pbkdf2.html | 2 +- doc/html/modules/seen.html | 2 +- doc/html/modules/server.html | 2 +- doc/html/modules/share.html | 2 +- doc/html/modules/transfer.html | 2 +- doc/html/modules/twitch.html | 2 +- doc/html/modules/uptime.html | 2 +- doc/html/modules/woobie.html | 2 +- doc/html/modules/writing.html | 136 +- doc/html/objects.inv | Bin 1319 -> 1395 bytes doc/html/search.html | 75 +- doc/html/searchindex.js | 2 +- doc/html/tutorials/firstscript.html | 96 +- doc/html/tutorials/firststeps.html | 150 +- doc/html/tutorials/module.html | 106 +- doc/html/tutorials/setup.html | 269 +- doc/html/tutorials/tlssetup.html | 96 +- doc/html/using/accounts.html | 112 +- doc/html/using/bans.html | 108 +- doc/html/using/botnet.html | 326 +-- doc/html/using/core.html | 693 +++-- doc/html/using/features.html | 98 +- doc/html/using/ipv6.html | 99 +- doc/html/using/ircv3.html | 104 +- doc/html/using/partyline.html | 56 +- doc/html/using/patch.html | 85 +- doc/html/using/pbkdf2.html | 2 +- doc/html/using/pbkdf2info.html | 130 +- doc/html/using/tcl-commands.html | 2858 +++++++++---------- doc/html/using/text-sub.html | 153 +- doc/html/using/tls.html | 177 +- doc/html/using/tricks.html | 90 +- doc/html/using/twitch-tcl-commands.html | 162 +- doc/html/using/twitchinfo.html | 110 +- doc/html/using/users.html | 228 +- doc/man1/eggdrop.1 | 4 +- doc/modules/mod.assoc | 2 +- doc/modules/mod.blowfish | 2 +- doc/modules/mod.channels | 2 +- doc/modules/mod.compress | 2 +- doc/modules/mod.console | 2 +- doc/modules/mod.ctcp | 2 +- doc/modules/mod.dns | 2 +- doc/modules/mod.filesys | 2 +- doc/modules/mod.ident | 2 +- doc/modules/mod.irc | 2 +- doc/modules/mod.notes | 2 +- doc/modules/mod.pbkdf2 | 2 +- doc/modules/mod.seen | 2 +- doc/modules/mod.server | 2 +- doc/modules/mod.share | 2 +- doc/modules/mod.transfer | 2 +- doc/modules/mod.twitch | 2 +- doc/modules/mod.uptime | 2 +- doc/modules/mod.woobie | 2 +- doc/modules/writing-modules | 2 +- doc/settings/CONTENTS | 2 +- doc/settings/core.settings | 2 +- doc/settings/mod.assoc | 2 +- doc/settings/mod.blowfish | 2 +- doc/settings/mod.channels | 2 +- doc/settings/mod.compress | 2 +- doc/settings/mod.console | 2 +- doc/settings/mod.ctcp | 2 +- doc/settings/mod.dns | 2 +- doc/settings/mod.filesys | 2 +- doc/settings/mod.ident | 2 +- doc/settings/mod.irc | 2 +- doc/settings/mod.notes | 2 +- doc/settings/mod.seen | 2 +- doc/settings/mod.server | 2 +- doc/settings/mod.share | 2 +- doc/settings/mod.transfer | 2 +- doc/settings/mod.uptime | 2 +- doc/settings/mod.woobie | 2 +- doc/sphinx_source/about/about.rst | 2 +- doc/sphinx_source/conf.py | 2 +- doc/sphinx_source/install/install.rst | 2 +- doc/sphinx_source/install/readme.rst | 2 +- doc/sphinx_source/modules/index.rst | 2 +- doc/sphinx_source/modules/mod/assoc.rst | 2 +- doc/sphinx_source/modules/mod/blowfish.rst | 2 +- doc/sphinx_source/modules/mod/channels.rst | 2 +- doc/sphinx_source/modules/mod/compress.rst | 2 +- doc/sphinx_source/modules/mod/console.rst | 2 +- doc/sphinx_source/modules/mod/ctcp.rst | 2 +- doc/sphinx_source/modules/mod/dns.rst | 2 +- doc/sphinx_source/modules/mod/filesys.rst | 2 +- doc/sphinx_source/modules/mod/ident.rst | 2 +- doc/sphinx_source/modules/mod/irc.rst | 2 +- doc/sphinx_source/modules/mod/notes.rst | 2 +- doc/sphinx_source/modules/mod/pbkdf2.rst | 2 +- doc/sphinx_source/modules/mod/seen.rst | 2 +- doc/sphinx_source/modules/mod/server.rst | 2 +- doc/sphinx_source/modules/mod/share.rst | 2 +- doc/sphinx_source/modules/mod/transfer.rst | 2 +- doc/sphinx_source/modules/mod/twitch.rst | 2 +- doc/sphinx_source/modules/mod/uptime.rst | 2 +- doc/sphinx_source/modules/mod/woobie.rst | 2 +- doc/sphinx_source/tutorials/firstscript.rst | 2 +- doc/sphinx_source/using/bans.rst | 2 +- doc/sphinx_source/using/botnet.rst | 2 +- doc/sphinx_source/using/core.rst | 2 +- doc/sphinx_source/using/features.rst | 2 +- doc/sphinx_source/using/ipv6.rst | 2 +- doc/sphinx_source/using/ircv3.rst | 2 +- doc/sphinx_source/using/partyline.rst | 2 +- doc/sphinx_source/using/patch.rst | 2 +- doc/sphinx_source/using/pbkdf2info.rst | 2 +- doc/sphinx_source/using/tcl-commands.rst | 2 +- doc/sphinx_source/using/text-sub.rst | 2 +- doc/sphinx_source/using/tls.rst | 2 +- doc/sphinx_source/using/tricks.rst | 2 +- doc/sphinx_source/using/users.rst | 2 +- doc/tcl-commands.doc | 2 +- logs/CONTENTS | 2 +- m4/tcl.m4 | 2 +- misc/genchanges | 2 +- misc/generatedocs | 2 +- misc/getcommit | 2 +- misc/killwhitespace | 2 +- misc/makedepend | 2 +- misc/modconfig | 2 +- misc/newversion | 2 +- misc/releaseprep | 2 +- misc/runautotools | 2 +- misc/setpatch | 4 +- misc/updatecopyright | 2 +- scripts/CONTENTS | 2 +- scripts/action.fix.tcl | 2 +- scripts/autobotchk | 6 +- scripts/compat.tcl | 2 +- scripts/ques5.tcl | 2 +- src/bg.c | 2 +- src/bg.h | 2 +- src/botcmd.c | 2 +- src/botmsg.c | 2 +- src/botnet.c | 2 +- src/chan.h | 2 +- src/chanprog.c | 2 +- src/cmds.c | 2 +- src/cmdt.h | 2 +- src/compat/base64.c | 2 +- src/compat/base64.h | 2 +- src/compat/compat.h | 2 +- src/compat/explicit_bzero.c | 2 +- src/compat/explicit_bzero.h | 2 +- src/compat/in6.h | 2 +- src/compat/inet_aton.c | 2 +- src/compat/inet_aton.h | 2 +- src/compat/snprintf.c | 2 +- src/compat/snprintf.h | 2 +- src/compat/strlcpy.c | 2 +- src/compat/strlcpy.h | 2 +- src/dcc.c | 2 +- src/dccutil.c | 2 +- src/dns.c | 2 +- src/dns.h | 2 +- src/eggdrop.h | 2 +- src/flags.c | 2 +- src/flags.h | 2 +- src/lang.h | 2 +- src/language.c | 2 +- src/main.c | 6 +- src/main.h | 2 +- src/mem.c | 2 +- src/misc.c | 2 +- src/misc_file.c | 2 +- src/misc_file.h | 2 +- src/mod/assoc.mod/assoc.c | 2 +- src/mod/assoc.mod/assoc.h | 2 +- src/mod/blowfish.mod/bf_tab.h | 2 +- src/mod/blowfish.mod/blowfish.c | 2 +- src/mod/blowfish.mod/blowfish.h | 2 +- src/mod/channels.mod/channels.c | 2 +- src/mod/channels.mod/channels.h | 2 +- src/mod/channels.mod/cmdschan.c | 2 +- src/mod/channels.mod/tclchan.c | 2 +- src/mod/channels.mod/udefchan.c | 2 +- src/mod/channels.mod/userchan.c | 2 +- src/mod/compress.mod/compress.c | 2 +- src/mod/compress.mod/compress.h | 2 +- src/mod/compress.mod/configure | 4 +- src/mod/compress.mod/configure.ac | 2 +- src/mod/compress.mod/tclcompress.c | 2 +- src/mod/console.mod/console.c | 2 +- src/mod/console.mod/console.h | 2 +- src/mod/ctcp.mod/ctcp.c | 2 +- src/mod/ctcp.mod/ctcp.h | 2 +- src/mod/dns.mod/configure | 4 +- src/mod/dns.mod/configure.ac | 2 +- src/mod/dns.mod/coredns.c | 2 +- src/mod/dns.mod/dns.c | 2 +- src/mod/dns.mod/dns.h | 2 +- src/mod/filesys.mod/dbcompat.c | 2 +- src/mod/filesys.mod/dbcompat.h | 2 +- src/mod/filesys.mod/filedb3.c | 2 +- src/mod/filesys.mod/filedb3.h | 2 +- src/mod/filesys.mod/filelist.c | 2 +- src/mod/filesys.mod/filelist.h | 2 +- src/mod/filesys.mod/files.c | 2 +- src/mod/filesys.mod/files.h | 2 +- src/mod/filesys.mod/filesys.c | 2 +- src/mod/filesys.mod/filesys.h | 2 +- src/mod/filesys.mod/tclfiles.c | 2 +- src/mod/ident.mod/ident.c | 2 +- src/mod/irc.mod/chan.c | 2 +- src/mod/irc.mod/cmdsirc.c | 2 +- src/mod/irc.mod/irc.c | 2 +- src/mod/irc.mod/irc.h | 2 +- src/mod/irc.mod/mode.c | 2 +- src/mod/irc.mod/msgcmds.c | 2 +- src/mod/irc.mod/tclirc.c | 2 +- src/mod/module.h | 2 +- src/mod/modvals.h | 2 +- src/mod/notes.mod/cmdsnote.c | 2 +- src/mod/notes.mod/notes.c | 2 +- src/mod/notes.mod/notes.h | 2 +- src/mod/pbkdf2.mod/pbkdf2.c | 2 +- src/mod/seen.mod/seen.c | 2 +- src/mod/server.mod/cmdsserv.c | 2 +- src/mod/server.mod/isupport.c | 2 +- src/mod/server.mod/server.c | 2 +- src/mod/server.mod/server.h | 2 +- src/mod/server.mod/servmsg.c | 2 +- src/mod/server.mod/tclisupport.c | 2 +- src/mod/server.mod/tclserv.c | 2 +- src/mod/share.mod/share.c | 2 +- src/mod/share.mod/share.h | 2 +- src/mod/share.mod/uf_features.c | 2 +- src/mod/transfer.mod/tcltransfer.c | 2 +- src/mod/transfer.mod/transfer.c | 2 +- src/mod/transfer.mod/transfer.h | 2 +- src/mod/transfer.mod/transferfstat.c | 2 +- src/mod/transfer.mod/transferqueue.c | 2 +- src/mod/twitch.mod/twitch.c | 2 +- src/mod/twitch.mod/twitch.h | 2 +- src/mod/uptime.mod/uptime.c | 2 +- src/mod/uptime.mod/uptime.h | 2 +- src/mod/woobie.mod/woobie.c | 2 +- src/modules.c | 2 +- src/modules.h | 2 +- src/net.c | 2 +- src/proto.h | 2 +- src/rfc1459.c | 2 +- src/stat.h | 2 +- src/tandem.h | 2 +- src/tcl.c | 2 +- src/tcldcc.c | 2 +- src/tclegg.h | 2 +- src/tclhash.c | 2 +- src/tclhash.h | 2 +- src/tclmisc.c | 2 +- src/tcluser.c | 2 +- src/tls.c | 2 +- src/userent.c | 2 +- src/userrec.c | 2 +- src/users.c | 2 +- src/users.h | 2 +- src/version.h | 2 +- text/CONTENTS | 2 +- text/banner | 2 +- 333 files changed, 6148 insertions(+), 6209 deletions(-) create mode 100644 doc/html/_static/sphinx_highlight.js diff --git a/AUTHORS b/AUTHORS index 0a0d78221..dc4275d08 100644 --- a/AUTHORS +++ b/AUTHORS @@ -104,4 +104,4 @@ See also: THANKS, doc/Versions, doc/Changes ------------------------------------------------------------------------------ Copyright (C) 1997 Robey Pointer -Copyright (C) 1999 - 2021 Eggheads Development Team +Copyright (C) 1999 - 2023 Eggheads Development Team diff --git a/CONTENTS b/CONTENTS index ac9540049..6b5dbc606 100644 --- a/CONTENTS +++ b/CONTENTS @@ -82,4 +82,4 @@ Last revised: September 21, 2018 Contains information on upgrading from a 1.6 bot to a 1.8 bot. _____________________________________________________________________ - Copyright (C) 2003 - 2021 Eggheads Development Team + Copyright (C) 2003 - 2023 Eggheads Development Team diff --git a/FEATURES b/FEATURES index 5f8fafe56..4de630f7e 100644 --- a/FEATURES +++ b/FEATURES @@ -44,4 +44,4 @@ Eggdrop Features Copyright (C) 1997 Robey Pointer -Copyright (C) 2000 - 2022 Eggheads Development Team +Copyright (C) 2000 - 2023 Eggheads Development Team diff --git a/INSTALL b/INSTALL index 6304d2628..1b355fd85 100644 --- a/INSTALL +++ b/INSTALL @@ -19,8 +19,6 @@ Eggdrop uses the GNU autoconfigure scripts to make things easier. correctly compile Eggdrop. It will also try to find Tcl, which is required to compile. - For macOS tcl and openssl see doc/COMPILE-GUIDE. - 2. Type either 'make config' or 'make iconfig' to determine which @@ -160,5 +158,5 @@ the README file. If not, then READ IT!&@#%@! Have fun with Eggdrop! - Copyright (C) 1997 Robey Pointer - Copyright (C) 1999 - 2022 Eggheads Development Team + Copyright (C) 1997 Robey Pointer Copyright (C) 1999 - 2022 Eggheads + Development Team diff --git a/NEWS b/NEWS index a884e737a..fcb16e621 100644 --- a/NEWS +++ b/NEWS @@ -36,7 +36,7 @@ Eggdrop v1.9.5: Module changes: - Updated woobie.mod with additional example code - Eggdrop config changes: + Eggdrop config changes: - None Documentation changes: @@ -317,4 +317,4 @@ Eggdrop v1.9.0: ________________________________________________________________________ Copyright (C) 1997 Robey Pointer -Copyright (C) 1999 - 2021 Eggheads Development Team +Copyright (C) 1999 - 2023 Eggheads Development Team diff --git a/aclocal.m4 b/aclocal.m4 index 1d8827d64..f0df8ce91 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ dnl aclocal.m4: macros autoconf uses when building configure from configure.ac dnl -dnl Copyright (C) 1999 - 2022 Eggheads Development Team +dnl Copyright (C) 1999 - 2023 Eggheads Development Team dnl dnl This program is free software; you can redistribute it and/or dnl modify it under the terms of the GNU General Public License diff --git a/config.h.in b/config.h.in index 1a412d315..cec70a8a3 100644 --- a/config.h.in +++ b/config.h.in @@ -2,7 +2,7 @@ /* * Copyright (C) 1997 Robey Pointer - * Copyright (C) 1999 - 2022 Eggheads Development Team + * Copyright (C) 1999 - 2023 Eggheads Development Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/configure b/configure index 494e63381..a66f50b10 100755 --- a/configure +++ b/configure @@ -12,7 +12,7 @@ # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # -# Copyright (C) 1999 - 2022 Eggheads Development Team +# Copyright (C) 1999 - 2023 Eggheads Development Team ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## @@ -1518,7 +1518,7 @@ Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. -Copyright (C) 1999 - 2022 Eggheads Development Team +Copyright (C) 1999 - 2023 Eggheads Development Team _ACEOF exit fi diff --git a/configure.ac b/configure.ac index c90d97e56..3ae5947e2 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl configure.ac: this file is processed by autoconf to produce ./configure. AC_PREREQ(2.61) AC_INIT([Eggdrop],[1.9.4],[bugs@eggheads.org]) -AC_COPYRIGHT([Copyright (C) 1999 - 2022 Eggheads Development Team]) +AC_COPYRIGHT([Copyright (C) 1999 - 2023 Eggheads Development Team]) AC_LANG([C]) AC_REVISION([m4_esyscmd([misc/getcommit])]) AC_CONFIG_SRCDIR(src/eggdrop.h) @@ -14,7 +14,7 @@ AC_PRESERVE_HELP_ORDER dnl config.h stuff AH_TOP([/* * Copyright (C) 1997 Robey Pointer - * Copyright (C) 1999 - 2022 Eggheads Development Team + * Copyright (C) 1999 - 2023 Eggheads Development Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/doc/ABOUT b/doc/ABOUT index 30fb3e7ff..dd7301edd 100644 --- a/doc/ABOUT +++ b/doc/ABOUT @@ -55,4 +55,4 @@ About Eggdrop - Tcl -- Eggdrop cannot compile without Tcl installed on your shell. - Copyright (C) 1999 - 2022 Eggheads Development Team + Copyright (C) 1999 - 2023 Eggheads Development Team diff --git a/doc/BANS b/doc/BANS index 747f95ffa..0eb2ddfdb 100644 --- a/doc/BANS +++ b/doc/BANS @@ -75,4 +75,4 @@ Bans, Invites, and Exempts file) or until the channel goes -i again, whichever happens last. - Copyright (C) 1999 - 2022 Eggheads Development Team + Copyright (C) 1999 - 2023 Eggheads Development Team diff --git a/doc/BOTNET b/doc/BOTNET index d3e700766..cef4b16ee 100644 --- a/doc/BOTNET +++ b/doc/BOTNET @@ -1,4 +1,4 @@ -Botnet Sharing and Linking Last revised: Nov 09, 2017 +Botnet Sharing and Linking Botnet Sharing and Linking @@ -171,6 +171,16 @@ At this point, you can link the two bots by typing '.link BotA' on BotB passwords which are not stored encrypted in the userfile. Note that you can link as many bots as you wish to your botnet. +Secure (TLS) Links + +Since Eggdrop 1.8.0, the ability to encrypt bot links using TLS is +possible. On the hub bot you would prefix the port given in the listen +command with a +, and when you add the hub bot to the leaf, you would +prefix the port used in the .+bot command with a +. In other words, you +would set listen +5555 in the hub config and use .+bot hubbot 1.2.3.4 ++5555 on the leaf bot. These settings are explained more thoroughly in +the TLS botnet documentation. + USING BOTFLAGS Botflags are needed to assign special functions and tasks to your bots. @@ -338,4 +348,17 @@ MAKING BOTS SHARE USER RECORDS |-+beldin `-+Lameshare -Copyright (C) 1999 - 2022 Eggheads Development Team +USING CERTIFICATES TO AUTHENTICATE EGGDROPS + +Eggdrops can use certificates to authenticate when linking to each other +instead of a password. First, you must ensure you have set the +appropriate certificates in the ssl-privatekey and ssl-certificate +settings in the config file, and then enable the ssl-cert-auth setting. +Next, add the certificate on the partyline by using .fprint + to add the +fingerprint for the certificate currently in use, or .fprint to manually add a fingerprint. Once the config file +settings are set 0and fingerprints are added on the partyline, Eggdrops +will attempt to use their certificates intead of passwords for +authentication. + +Copyright (C) 1999 - 2023 Eggheads Development Team diff --git a/doc/COMPILE-GUIDE b/doc/COMPILE-GUIDE index 92ee2f4fb..7e4322866 100644 --- a/doc/COMPILE-GUIDE +++ b/doc/COMPILE-GUIDE @@ -581,4 +581,4 @@ Last revised: November 17, 2022 _____________________________________________________________________ Copyright (C) 1997 Robey Pointer - Copyright (C) 1999 - 2022 Eggheads Development Team + Copyright (C) 1999 - 2023 Eggheads Development Team diff --git a/doc/CONTENTS b/doc/CONTENTS index ba059a05e..a56d03cb4 100644 --- a/doc/CONTENTS +++ b/doc/CONTENTS @@ -72,4 +72,4 @@ Last revised: Nov 01, 2010 notes in reverse chronological order. _____________________________________________________________________ - Copyright (C) 2003 - 2021 Eggheads Development Team + Copyright (C) 2003 - 2023 Eggheads Development Team diff --git a/doc/FIRST-SCRIPT b/doc/FIRST-SCRIPT index c98d00674..919531af7 100644 --- a/doc/FIRST-SCRIPT +++ b/doc/FIRST-SCRIPT @@ -225,4 +225,4 @@ of salt!)
    -Copyright (C) 2003 - 2022 Eggheads Development Team +Copyright (C) 2003 - 2023 Eggheads Development Team diff --git a/doc/IPV6 b/doc/IPV6 index b088b8a8f..b181d3b14 100644 --- a/doc/IPV6 +++ b/doc/IPV6 @@ -77,4 +77,4 @@ Other affected variables: nat-ip works with IPv4 as it used to. It has no meaning for IPv6 and is not queried for IPv6 connections. -Copyright (C) 2010 - 2022 Eggheads Development Team +Copyright (C) 2010 - 2023 Eggheads Development Team diff --git a/doc/IRCv3 b/doc/IRCv3 index e72536ff9..2199771ee 100644 --- a/doc/IRCv3 +++ b/doc/IRCv3 @@ -54,4 +54,4 @@ The following capabilities are supported by Eggdrop: - setname - +typing -Copyright (C) 2010 - 2022 Eggheads Development Team +Copyright (C) 2010 - 2023 Eggheads Development Team diff --git a/doc/MODULES b/doc/MODULES index 9e6aeba41..b61a69b4b 100644 --- a/doc/MODULES +++ b/doc/MODULES @@ -418,4 +418,4 @@ WHAT TO DO WITH A MODULE? the modules directory on ftp.eggheads.org. Don't forget to mention in your text file which version Eggdrop the module is written for. -Copyright (C) 1999 - 2021 Eggheads Development Team +Copyright (C) 1999 - 2023 Eggheads Development Team diff --git a/doc/PARTYLINE b/doc/PARTYLINE index 4b4a030c1..3d490e611 100644 --- a/doc/PARTYLINE +++ b/doc/PARTYLINE @@ -34,4 +34,4 @@ prefixed with an apostrophe is sent to all users on the local bot only. You can change channels with the ".chat" command or even leave all channels with ".chat off". -Copyright (C) 2002 - 2022 Eggheads Development Team +Copyright (C) 2002 - 2023 Eggheads Development Team diff --git a/doc/PATCH-HOWTO b/doc/PATCH-HOWTO index abfa9c012..411ef0adc 100644 --- a/doc/PATCH-HOWTO +++ b/doc/PATCH-HOWTO @@ -34,4 +34,4 @@ To create a patch via github: 7. Pour yourself a cold one and bask in the warm feeling of contributing to the open source community! Karma++! -Copyright (C) 1999 - 2022 Eggheads Development Team +Copyright (C) 1999 - 2023 Eggheads Development Team diff --git a/doc/PBKDF2 b/doc/PBKDF2 index cbb4e5e81..7e60d55c7 100644 --- a/doc/PBKDF2 +++ b/doc/PBKDF2 @@ -138,4 +138,4 @@ where 'PBK method' is the method specified in the configuration file, 'salt' is the value used for the salt, and 'password hash' is the output of the hashing algorithm. -Copyright (C) 2000 - 2022 Eggheads Development Team +Copyright (C) 2000 - 2023 Eggheads Development Team diff --git a/doc/TLS b/doc/TLS index d4c9661d3..991217fd4 100644 --- a/doc/TLS +++ b/doc/TLS @@ -202,4 +202,4 @@ verification and authorization. Higher values enable specific exceptions like allowing self-signed or expired certificates. Details are documented in eggdrop.conf. -Copyright (C) 2010 - 2022 Eggheads Development Team +Copyright (C) 2010 - 2023 Eggheads Development Team diff --git a/doc/TRICKS b/doc/TRICKS index 157390db8..dfc5dbb6d 100644 --- a/doc/TRICKS +++ b/doc/TRICKS @@ -58,4 +58,4 @@ normal Tcl file. For example, you can set 'userfile' and 'chanfile' to set userfile "$myvar.user" set chanfile "$myvar.chan" -Copyright (C) 1999 - 2022 Eggheads Development Team +Copyright (C) 1999 - 2023 Eggheads Development Team diff --git a/doc/USERS b/doc/USERS index de72d3bf6..5e561135f 100644 --- a/doc/USERS +++ b/doc/USERS @@ -97,4 +97,4 @@ global flag applies to all channels. The standard global flags are: user-defined flags (Capital letters A through Z). These are used by scripts, and their uses vary depending on the script that uses them. -Copyright (C) 2002 - 2022 Eggheads Development Team +Copyright (C) 2002 - 2023 Eggheads Development Team diff --git a/doc/core.settings b/doc/core.settings index 236709f7f..28b090666 100644 --- a/doc/core.settings +++ b/doc/core.settings @@ -231,9 +231,7 @@ logfile "logs/logfile" set logfile-suffix ".%d%b%Y" If keep-all-logs is 1, this setting will define the suffix of the logfiles. The default will result in a suffix like "04May2000". "%Y%m%d" will produce the often used - yyyymmdd format. Read the strftime manpages for more options. NOTE: - On systems which don't support strftime, the default format will - always be used. + yyyymmdd format. Read the strftime manpages for more options. CONSOLE SETTINGS @@ -712,4 +710,4 @@ point. source scripts/alltools.tcl source scripts/action.fix.tcl -Copyright (C) 2000 - 2022 Eggheads Development Team +Copyright (C) 2000 - 2023 Eggheads Development Team diff --git a/doc/html/_static/basic.css b/doc/html/_static/basic.css index 9b49ca350..18255e5ae 100644 --- a/doc/html/_static/basic.css +++ b/doc/html/_static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -15,6 +15,12 @@ div.clearer { clear: both; } +div.section::after { + display: block; + content: ''; + clear: left; +} + /* -- relbar ---------------------------------------------------------------- */ div.related { @@ -124,7 +130,7 @@ ul.search li a { font-weight: bold; } -ul.search li div.context { +ul.search li p.context { color: #888; margin: 2px 0 0 30px; text-align: left; @@ -216,7 +222,7 @@ table.modindextable td { /* -- general body styles --------------------------------------------------- */ div.body { - min-width: 450px; + min-width: 360px; max-width: 800px; } @@ -261,19 +267,25 @@ p.rubric { font-weight: bold; } -img.align-left, .figure.align-left, object.align-left { +img.align-left, figure.align-left, .figure.align-left, object.align-left { clear: left; float: left; margin-right: 1em; } -img.align-right, .figure.align-right, object.align-right { +img.align-right, figure.align-right, .figure.align-right, object.align-right { clear: right; float: right; margin-left: 1em; } -img.align-center, .figure.align-center, object.align-center { +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { display: block; margin-left: auto; margin-right: auto; @@ -287,30 +299,45 @@ img.align-center, .figure.align-center, object.align-center { text-align: center; } +.align-default { + text-align: center; +} + .align-right { text-align: right; } /* -- sidebars -------------------------------------------------------------- */ -div.sidebar { +div.sidebar, +aside.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; - padding: 7px 7px 0 7px; + padding: 7px; background-color: #ffe; width: 40%; float: right; + clear: right; + overflow-x: auto; } p.sidebar-title { font-weight: bold; } +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + /* -- topics ---------------------------------------------------------------- */ +nav.contents, +aside.topic, div.topic { border: 1px solid #ccc; - padding: 7px 7px 0 7px; + padding: 7px; margin: 10px 0 10px 0; } @@ -332,10 +359,6 @@ div.admonition dt { font-weight: bold; } -div.admonition dl { - margin-bottom: 0; -} - p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; @@ -346,9 +369,34 @@ div.body p.centered { margin-top: 25px; } +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + /* -- tables ---------------------------------------------------------------- */ table.docutils { + margin-top: 10px; + margin-bottom: 10px; border: 0; border-collapse: collapse; } @@ -358,6 +406,11 @@ table.align-center { margin-right: auto; } +table.align-default { + margin-left: auto; + margin-right: auto; +} + table caption span.caption-number { font-style: italic; } @@ -373,10 +426,6 @@ table.docutils td, table.docutils th { border-bottom: 1px solid #aaa; } -table.footnote td, table.footnote th { - border: 0 !important; -} - th { text-align: left; padding-right: 5px; @@ -391,22 +440,34 @@ table.citation td { border-bottom: none; } +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + /* -- figures --------------------------------------------------------------- */ -div.figure { +div.figure, figure { margin: 0.5em; padding: 0.5em; } -div.figure p.caption { +div.figure p.caption, figcaption { padding: 0.3em; } -div.figure p.caption span.caption-number { +div.figure p.caption span.caption-number, +figcaption span.caption-number { font-style: italic; } -div.figure p.caption span.caption-text { +div.figure p.caption span.caption-text, +figcaption span.caption-text { } /* -- field list styles ----------------------------------------------------- */ @@ -433,10 +494,71 @@ table.field-list td, table.field-list th { /* -- hlist styles ---------------------------------------------------------- */ +table.hlist { + margin: 1em 0; +} + table.hlist td { vertical-align: top; } +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + /* -- other body styles ----------------------------------------------------- */ @@ -460,11 +582,81 @@ ol.upperroman { list-style: upper-roman; } +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + dl { margin-bottom: 15px; } -dd p { +dd > :first-child { margin-top: 0px; } @@ -478,6 +670,11 @@ dd { margin-left: 30px; } +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + dt:target, span.highlighted { background-color: #fbe54e; } @@ -491,14 +688,6 @@ dl.glossary dt { font-size: 1.1em; } -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - .versionmodified { font-style: italic; } @@ -537,6 +726,13 @@ dl.glossary dt { font-style: oblique; } +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + abbr, acronym { border-bottom: dotted 1px; cursor: help; @@ -549,29 +745,69 @@ pre { overflow-y: hidden; /* fixes display issues on Chrome browsers */ } +pre, div[class*="highlight-"] { + clear: both; +} + span.pre { -moz-hyphens: none; -ms-hyphens: none; -webkit-hyphens: none; hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; } td.linenos pre { - padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } table.highlighttable { - margin-left: 0.5em; + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; } table.highlighttable td { - padding: 0 0.5em 0 0.5em; + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; } div.code-block-caption { + margin-top: 1em; padding: 2px 5px; font-size: small; } @@ -580,8 +816,14 @@ div.code-block-caption code { background-color: transparent; } -div.code-block-caption + div > div.highlight > pre { - margin-top: 0; +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ } div.code-block-caption span.caption-number { @@ -593,21 +835,7 @@ div.code-block-caption span.caption-text { } div.literal-block-wrapper { - padding: 1em 1em 0; -} - -div.literal-block-wrapper div.highlight { - margin: 0; -} - -code.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -code.descclassname { - background-color: transparent; + margin: 1em 0; } code.xref, a code { @@ -648,8 +876,7 @@ span.eqno { } span.eqno a.headerlink { - position: relative; - left: 0px; + position: absolute; z-index: 1; } diff --git a/doc/html/_static/doctools.js b/doc/html/_static/doctools.js index 344db17dd..d06a71d75 100644 --- a/doc/html/_static/doctools.js +++ b/doc/html/_static/doctools.js @@ -2,314 +2,155 @@ * doctools.js * ~~~~~~~~~~~ * - * Sphinx JavaScript utilities for all documentation. + * Base JavaScript utilities for all Sphinx HTML documentation. * - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ - -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - -/** - * make the code below compatible with browsers without - * an installed firebug like debugger -if (!window.console || !console.firebug) { - var names = ["log", "debug", "info", "warn", "error", "assert", "dir", - "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", - "profile", "profileEnd"]; - window.console = {}; - for (var i = 0; i < names.length; ++i) - window.console[names[i]] = function() {}; -} - */ - -/** - * small helper function to urldecode strings - */ -jQuery.urldecode = function(x) { - return decodeURIComponent(x).replace(/\+/g, ' '); -}; - -/** - * small helper function to urlencode strings - */ -jQuery.urlencode = encodeURIComponent; - -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s === 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); } - return result; }; -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node, addItems) { - if (node.nodeType === 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 0 && - !jQuery(node.parentNode).hasClass(className) && - !jQuery(node.parentNode).hasClass("nohighlight")) { - var span; - var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.className = className; - } - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - if (isInSVG) { - var bbox = span.getBBox(); - var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute('class', className); - var parentOfText = node.parentNode.parentNode; - addItems.push({ - "parent": node.parentNode, - "target": rect}); - } - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this, addItems); - }); - } - } - var addItems = []; - var result = this.each(function() { - highlight(this, addItems); - }); - for (var i = 0; i < addItems.length; ++i) { - jQuery(addItems[i].parent).before(addItems[i].target); - } - return result; -}; - -/* - * backward compatibility for jQuery.browser - * This will be supported until firefox bug is fixed. - */ -if (!jQuery.browser) { - jQuery.uaMatch = function(ua) { - ua = ua.toLowerCase(); - - var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || - /(webkit)[ \/]([\w.]+)/.exec(ua) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || - /(msie) ([\w.]+)/.exec(ua) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || - []; - - return { - browser: match[ 1 ] || "", - version: match[ 2 ] || "0" - }; - }; - jQuery.browser = {}; - jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; -} - /** * Small JavaScript module for the documentation. */ -var Documentation = { - - init : function() { - this.fixFirefoxAnchorBug(); - this.highlightSearchWords(); - this.initIndexTable(); - if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { - this.initOnKeyListeners(); - } +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); }, /** * i18n support */ - TRANSLATIONS : {}, - PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, - LOCALE : 'unknown', + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) - gettext : function(string) { - var translated = Documentation.TRANSLATIONS[string]; - if (typeof translated === 'undefined') - return string; - return (typeof translated === 'string') ? translated : translated[0]; - }, - - ngettext : function(singular, plural, n) { - var translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated === 'undefined') - return (n == 1) ? singular : plural; - return translated[Documentation.PLURALEXPR(n)]; + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } }, - addTranslations : function(catalog) { - for (var key in catalog.messages) - this.TRANSLATIONS[key] = catalog.messages[key]; - this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); - this.LOCALE = catalog.locale; + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; }, - /** - * add context elements like header anchor links - */ - addContextElements : function() { - $('div[id] > :header:first').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this headline')). - appendTo(this); - }); - $('dt[id]').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this definition')). - appendTo(this); - }); + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; }, /** - * workaround a firefox stupidity - * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + * helper function to focus on search bar */ - fixFirefoxAnchorBug : function() { - if (document.location.hash && $.browser.mozilla) - window.setTimeout(function() { - document.location.href += ''; - }, 10); + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); }, /** - * highlight the search words provided in the url in the text + * Initialise the domain index toggle buttons */ - highlightSearchWords : function() { - var params = $.getQueryParameters(); - var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; - if (terms.length) { - var body = $('div.body'); - if (!body.length) { - body = $('body'); + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); } - window.setTimeout(function() { - $.each(terms, function() { - body.highlightText(this.toLowerCase(), 'highlighted'); - }); - }, 10); - $('') - .appendTo($('#searchbox')); - } - }, - - /** - * init the domain index toggle buttons - */ - initIndexTable : function() { - var togglers = $('img.toggler').click(function() { - var src = $(this).attr('src'); - var idnum = $(this).attr('id').substr(7); - $('tr.cg-' + idnum).toggle(); - if (src.substr(-9) === 'minus.png') - $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); - else - $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); - }).css('display', ''); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { - togglers.click(); - } - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords : function() { - $('#searchbox .highlight-link').fadeOut(300); - $('span.highlighted').removeClass('highlighted'); - }, - - /** - * make the url absolute - */ - makeURL : function(relativeURL) { - return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; - }, + }; - /** - * get the current relative url - */ - getCurrentURL : function() { - var path = document.location.pathname; - var parts = path.split(/\//); - $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { - if (this === '..') - parts.pop(); - }); - var url = parts.join('/'); - return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); }, - initOnKeyListeners: function() { - $(document).keyup(function(event) { - var activeElementType = document.activeElement.tagName; - // don't navigate when in search box or textarea - if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { - switch (event.keyCode) { - case 37: // left - var prevHref = $('link[rel="prev"]').prop('href'); - if (prevHref) { - window.location.href = prevHref; - return false; + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); } - case 39: // right - var nextHref = $('link[rel="next"]').prop('href'); - if (nextHref) { - window.location.href = nextHref; - return false; + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); } + break; } } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } }); - } + }, }; // quick alias for translations -_ = Documentation.gettext; +const _ = Documentation.gettext; -$(document).ready(function() { - Documentation.init(); -}); +_ready(Documentation.init); diff --git a/doc/html/_static/documentation_options.js b/doc/html/_static/documentation_options.js index c0721a95a..dbe4282de 100644 --- a/doc/html/_static/documentation_options.js +++ b/doc/html/_static/documentation_options.js @@ -1,10 +1,14 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), VERSION: '1.9.4', - LANGUAGE: 'None', + LANGUAGE: 'en', COLLAPSE_INDEX: false, + BUILDER: 'html', FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', HAS_SOURCE: true, SOURCELINK_SUFFIX: '.txt', NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, }; \ No newline at end of file diff --git a/doc/html/_static/language_data.js b/doc/html/_static/language_data.js index 5266fb19e..250f5665f 100644 --- a/doc/html/_static/language_data.js +++ b/doc/html/_static/language_data.js @@ -5,15 +5,16 @@ * This script contains the language-specific data used by searchtools.js, * namely the list of stopwords, stemmer, scorer and splitter. * - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ -var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"]; +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; -/* Non-minified version JS is _stemmer.js if file is provided */ +/* Non-minified version is copied as a separate JS file, is available */ + /** * Porter Stemmer */ @@ -196,102 +197,3 @@ var Stemmer = function() { } } - - - - -var splitChars = (function() { - var result = {}; - var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648, - 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702, - 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971, - 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345, - 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761, - 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823, - 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125, - 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695, - 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587, - 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141]; - var i, j, start, end; - for (i = 0; i < singles.length; i++) { - result[singles[i]] = true; - } - var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709], - [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161], - [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568], - [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807], - [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047], - [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383], - [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450], - [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547], - [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673], - [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820], - [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946], - [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023], - [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173], - [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332], - [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481], - [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718], - [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791], - [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095], - [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205], - [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687], - [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968], - [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869], - [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102], - [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271], - [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592], - [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822], - [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167], - [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959], - [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143], - [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318], - [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483], - [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101], - [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567], - [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292], - [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444], - [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783], - [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311], - [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511], - [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774], - [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071], - [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263], - [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519], - [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647], - [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967], - [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295], - [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274], - [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007], - [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381], - [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]]; - for (i = 0; i < ranges.length; i++) { - start = ranges[i][0]; - end = ranges[i][1]; - for (j = start; j <= end; j++) { - result[j] = true; - } - } - return result; -})(); - -function splitQuery(query) { - var result = []; - var start = -1; - for (var i = 0; i < query.length; i++) { - if (splitChars[query.charCodeAt(i)]) { - if (start !== -1) { - result.push(query.slice(start, i)); - start = -1; - } - } else if (start === -1) { - start = i; - } - } - if (start !== -1) { - result.push(query.slice(start)); - } - return result; -} - - diff --git a/doc/html/_static/pygments.css b/doc/html/_static/pygments.css index 20c4814dc..691aeb82d 100644 --- a/doc/html/_static/pygments.css +++ b/doc/html/_static/pygments.css @@ -1,5 +1,10 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } -.highlight { background: #eeffcc; } +.highlight { background: #eeffcc; } .highlight .c { color: #408090; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #007020; font-weight: bold } /* Keyword */ diff --git a/doc/html/_static/searchtools.js b/doc/html/_static/searchtools.js index 5ff318066..97d56a74d 100644 --- a/doc/html/_static/searchtools.js +++ b/doc/html/_static/searchtools.js @@ -4,22 +4,24 @@ * * Sphinx JavaScript utilities for the full-text search. * - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ +"use strict"; -if (!Scorer) { - /** - * Simple result scoring code. - */ +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { var Scorer = { // Implement the following function to further tweak the score for each result - // The function takes a result array [filename, title, anchor, descr, score] + // The function takes a result array [docname, title, anchor, descr, score, filename] // and returns the new score. /* - score: function(result) { - return result[4]; + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score }, */ @@ -28,423 +30,508 @@ if (!Scorer) { // or matches in the last dotted part of the object name objPartialMatch: 6, // Additive scores depending on the priority of the object - objPrio: {0: 15, // used to be importantResults - 1: 5, // used to be objectResults - 2: -5}, // used to be unimportantResults + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, // Used when the priority is not in the mapping. objPrioDefault: 0, // query found in title title: 15, + partialTitle: 7, // query found in terms - term: 5 + term: 5, + partialTerm: 2, }; } -if (!splitQuery) { - function splitQuery(query) { - return query.split(/\s+/); +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = docUrlRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = docUrlRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms) + ); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings } /** * Search Module */ -var Search = { - - _index : null, - _queued_query : null, - _pulse_status : -1, - - init : function() { - var params = $.getQueryParameters(); - if (params.q) { - var query = params.q[0]; - $('input[name="q"]')[0].value = query; - this.performSearch(query); - } +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; }, - loadIndex : function(url) { - $.ajax({type: "GET", url: url, data: null, - dataType: "script", cache: true, - complete: function(jqxhr, textstatus) { - if (textstatus != "success") { - document.getElementById("searchindexloader").src = url; - } - }}); + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); }, - setIndex : function(index) { - var q; - this._index = index; - if ((q = this._queued_query) !== null) { - this._queued_query = null; - Search.query(q); + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); } }, - hasIndex : function() { - return this._index !== null; - }, + hasIndex: () => Search._index !== null, - deferQuery : function(query) { - this._queued_query = query; - }, + deferQuery: (query) => (Search._queued_query = query), - stopPulse : function() { - this._pulse_status = 0; - }, + stopPulse: () => (Search._pulse_status = -1), - startPulse : function() { - if (this._pulse_status >= 0) - return; - function pulse() { - var i; + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { Search._pulse_status = (Search._pulse_status + 1) % 4; - var dotString = ''; - for (i = 0; i < Search._pulse_status; i++) - dotString += '.'; - Search.dots.text(dotString); - if (Search._pulse_status > -1) - window.setTimeout(pulse, 500); - } + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; pulse(); }, /** * perform a search for something (or wait until index is loaded) */ - performSearch : function(query) { + performSearch: (query) => { // create the required interface elements - this.out = $('#search-results'); - this.title = $('

    ' + _('Searching') + '

    ').appendTo(this.out); - this.dots = $('').appendTo(this.title); - this.status = $('

    ').appendTo(this.out); - this.output = $(' -

    Using Eggdrop

    +

    Using Eggdrop

    -

    Tutorials

    +

    Tutorials

    -

    Eggdrop Modules

    +

    Eggdrop Modules

    -

    About Eggdrop

    +

    About Eggdrop

    So this is how we register C callbacks for binds with the correct arguments:

    - -
    -

    Summary

    + +
    +

    Summary

    In summary, this is how the dcc bind is called:

      -
    • check_tcl_dcc() creates Tcl variables $_dcc1 $_dcc2 $_dcc3 and lets check_tcl_bind call the binds
    • -
    • Tcl binds are done at this point
    • -
    • C binds mean the Tcl command associated with the bind is *dcc:boot which calls builtin_dcc which gets cmd_boot as ClientData cd argument
    • -
    • buildin_dcc performs some sanity checking to avoid crashes and then calls cmd_boot() aka F() with the arguments it wants C callbacks to have
    • +
    • check_tcl_dcc() creates Tcl variables $_dcc1 $_dcc2 $_dcc3 and lets check_tcl_bind call the binds

    • +
    • Tcl binds are done at this point

    • +
    • C binds mean the Tcl command associated with the bind is *dcc:boot which calls builtin_dcc which gets cmd_boot as ClientData cd argument

    • +
    • gbuildin_dcc performs some sanity checking to avoid crashes and then calls cmd_boot() aka F() with the arguments it wants C callbacks to have

    -

    Example edited and annotated gdb backtrace in cmd_boot after doing .boot test on the partyline as user thommey with typical owner flags.

    +

    Example edited and annotated gdb backtrace in :code::cmd_boot after doing .boot test on the partyline as user thommey with typical owner flags.

    #0  cmd_boot (u=0x55e8bd8a49b0, idx=4, par=0x55e8be6a0010 "test") at cmds.c:614
         *u = {next = 0x55e8bd8aec90, handle = "thommey", flags = 8977024, flags_udef = 0, chanrec = 0x55e8bd8aeae0, entries = 0x55e8bd8a4a10}
     #1  builtin_dcc (cd=0x55e8bbf002d0 <cmd_boot>, irp=0x55e8bd59b1c0, argc=4, argv=0x55e8bd7e3e00) at tclhash.c:678
    @@ -355,10 +350,11 @@ 

    Summary

    @@ -371,7 +367,7 @@

    Summary
    - previous | next @@ -383,9 +379,9 @@

    Summary

    diff --git a/doc/html/modules/irc.html b/doc/html/modules/irc.html index f12063f7e..868377b61 100644 --- a/doc/html/modules/irc.html +++ b/doc/html/modules/irc.html @@ -255,7 +255,7 @@

    Search

    set this to 0.
    -

    Copyright (C) 2000 - 2022 Eggheads Development Team

    +

    Copyright (C) 2000 - 2023 Eggheads Development Team

    diff --git a/doc/html/modules/mod/assoc.html b/doc/html/modules/mod/assoc.html index 546553921..39f962f04 100644 --- a/doc/html/modules/mod/assoc.html +++ b/doc/html/modules/mod/assoc.html @@ -1,28 +1,23 @@ - + - + - - + + + Assoc Module — Eggdrop 1.9.4 documentation - - - - - - - + + + + +

    ---- - - - +
    +
    0turn off
    + + + - - + + - - + + - - + + - - + + - - + + - + - - + + - +

    0

    turn off

    1isoptest (allow serverop if registered op)

    1

    isoptest (allow serverop if registered op)

    2wasoptest (allow serverop if user had op before split)

    2

    wasoptest (allow serverop if user had op before split)

    3allow serverop if isop or wasop

    3

    allow serverop if isop or wasop

    4allow serverop if isop and wasop.

    4

    allow serverop if isop and wasop.

    5If the channel is -bitch, see stopnethack-mode 3

    5

    If the channel is -bitch, see stopnethack-mode 3

    If the channel is +bitch, see stopnethack-mode 1

    If the channel is +bitch, see stopnethack-mode 1

    6If the channel is -bitch, see stopnethack-mode 2

    6

    If the channel is -bitch, see stopnethack-mode 2

    If the channel is +bitch, see stopnethack-mode 4

    If the channel is +bitch, see stopnethack-mode 4

    -
    revenge-mode 0
    -

    This settings defines how the bot should punish bad users when +

    revenge-mode 0

    This settings defines how the bot should punish bad users when revenging. There are four possible settings:

    -
    -
    ---- - - - +
    +
    0Deop the user.
    + + + - - + + - - + + - - + +

    0

    Deop the user.

    1Deop the user and give them the +d flag for the channel.

    1

    Deop the user and give them the +d flag for the channel.

    2Deop the user, give them the +d flag for the channel, and kick them.

    2

    Deop the user, give them the +d flag for the channel, and kick them.

    3Deop the user, give them the +d flag for the channel, kick, and ban them.

    3

    Deop the user, give them the +d flag for the channel, kick, and ban them.

    -
    ban-type 3
    -

    This setting defines what type of bans should eggdrop place for +

    ban-type 3

    This setting defines what type of bans should eggdrop place for +k users or when revenge-mode is 3. Available types are:

    -
    ---- - - +
    0 *!user@host
    + + - + - + - + - + - + - + - + - + - +

    0 *!user@host

    1 *!*user@host

    1 *!*user@host

    2 *!*@host

    2 *!*@host

    3 *!*user@*.host

    3 *!*user@*.host

    4 *!*@*.host

    4 *!*@*.host

    5 nick!user@host

    5 nick!user@host

    6 nick!*user@host

    6 nick!*user@host

    7 nick!*@host

    7 nick!*@host

    8 nick!*user@*.host

    8 nick!*user@*.host

    9 nick!*@*.host

    9 nick!*@*.host

    -

    You can also specify types from 10 to 19 which correspond to types +

    You can also specify types from 10 to 19 which correspond to types 0 to 9, but instead of using a * wildcard to replace portions of the host, only numbers in hostnames are replaced with the ‘?’ wildcard. Same is valid for types 20-29, but instead of ‘?’, the ‘*’ wildcard will be used. Types 30-39 set the host to ‘*’.

    -
    ban-time 120
    -
    Set here how long temporary bans will last (in minutes). If you -set this setting to 0, the bot will never remove them.
    -
    exempt-time 60
    -
    Set here how long temporary exempts will last (in minutes). If you set +
    ban-time 120

    Set here how long temporary bans will last (in minutes). If you +set this setting to 0, the bot will never remove them.

    +
    +
    exempt-time 60

    Set here how long temporary exempts will last (in minutes). If you set this setting to 0, the bot will never remove them. The bot will check the exempts every X minutes, but will not remove the exempt if a ban is set on the channel that matches that exempt. Once the ban is removed, then the exempt will be removed the next time the bot checks. Please -note that this is an IRCnet feature.

    -
    invite-time 60
    -
    Set here how long temporary invites will last (in minutes). If you set +note that this is an IRCnet feature.

    +
    +
    invite-time 60

    Set here how long temporary invites will last (in minutes). If you set this setting to 0, the bot will never remove them. The bot will check the invites every X minutes, but will not remove the invite if a channel is set to +i. Once the channel is -i then the invite will be removed the next time the bot checks. Please note that this is an -IRCnet feature.

    -
    aop-delay (minimum:maximum)
    -
    +IRCnet feature.

    +
    +
    aop-delay (minimum:maximum)

    This is used for autoop, autohalfop, autovoice. If an op or voice joins a channel while another op or voice is pending, the bot will attempt to put both modes on one line.

    -
    ---- - - - +
    aop-delay 0No delay is used.
    + + + - - + + - - + +

    aop-delay 0

    No delay is used.

    aop-delay XAn X second delay is used.

    aop-delay X

    An X second delay is used.

    aop-delay X:YA random delay between X and Y is used.

    aop-delay X:Y

    A random delay between X and Y is used.

    -
    -
    need-op { putserv “PRIVMSG #lamest :op me cos i’m lame!” }
    -
    This setting will make the bot run the script enclosed in braces +
    +
    need-op { putserv “PRIVMSG #lamest :op me cos i’m lame!” }

    This setting will make the bot run the script enclosed in braces if it does not have ops. This must be shorter than 120 characters. If you use scripts like getops.tcl or botnetop.tcl, you don’t need -to set this setting.

    -
    need-invite { putserv “PRIVMSG #lamest :let me in!” }
    -
    This setting will make the bot run the script enclosed in braces +to set this setting.

    +
    +
    need-invite { putserv “PRIVMSG #lamest :let me in!” }

    This setting will make the bot run the script enclosed in braces if it needs an invite to the channel. This must be shorter than 120 characters. If you use scripts like getops.tcl or botnetop.tcl, you -don’t need to set this setting.

    -
    need-key { putserv “PRIVMSG #lamest :let me in!” }
    -
    This setting will make the bot run the script enclosed in braces +don’t need to set this setting.

    +
    +
    need-key { putserv “PRIVMSG #lamest :let me in!” }

    This setting will make the bot run the script enclosed in braces if it needs the key to the channel. This must be shorter than 120 characters. If you use scripts like getops.tcl or botnetop.tcl, you -don’t need to set this setting.

    -
    need-unban { putserv “PRIVMSG #lamest :let me in!” }
    -
    This setting will make the bot run the script enclosed in braces +don’t need to set this setting.

    +
    +
    need-unban { putserv “PRIVMSG #lamest :let me in!” }

    This setting will make the bot run the script enclosed in braces if it needs to be unbanned on the channel. This must be shorter than 120 characters. If you use scripts like getops.tcl or botnetop.tcl, -you don’t need to set this setting.

    -
    need-limit { putserv “PRIVMSG #lamest :let me in!” }
    -
    This setting will make the bot run the script enclosed in braces +you don’t need to set this setting.

    +
    +
    need-limit { putserv “PRIVMSG #lamest :let me in!” }

    This setting will make the bot run the script enclosed in braces if it needs the limit to be raised on the channel. This must be shorter than 120 characters. If you use scripts like getops.tcl or -botnetop.tcl, you don’t need to set this setting.

    -
    flood-chan 15:60
    -
    Set here how many channel messages in how many seconds from one +botnetop.tcl, you don’t need to set this setting.

    +
    +
    flood-chan 15:60

    Set here how many channel messages in how many seconds from one host constitutes a flood. Setting this to 0, 0:X or X:0 disables text -flood protection for the channel, where X is an integer >= 0.

    -
    flood-deop 3:10
    -
    Set here how many deops in how many seconds from one host constitutes +flood protection for the channel, where X is an integer >= 0.

    +
    +
    flood-deop 3:10

    Set here how many deops in how many seconds from one host constitutes a flood. Setting this to 0, 0:X or X:0 disables deop flood protection for -the channel, where X is an integer >= 0.

    -
    flood-kick 3:10
    -
    Set here how many kicks in how many seconds from one host constitutes +the channel, where X is an integer >= 0.

    +
    +
    flood-kick 3:10

    Set here how many kicks in how many seconds from one host constitutes a flood. Setting this to 0, 0:X or X:0 disables kick flood protection for -the channel, where X is an integer >= 0.

    -
    flood-join 5:60
    -
    Set here how many joins in how many seconds from one host constitutes +the channel, where X is an integer >= 0.

    +
    +
    flood-join 5:60

    Set here how many joins in how many seconds from one host constitutes a flood. Setting this to 0, 0:X or X:0 disables join flood protection for -the channel, where X is an integer >= 0.

    -
    flood-ctcp 3:60
    -
    Set here how many channel ctcps in how many seconds from one host +the channel, where X is an integer >= 0.

    +
    +
    flood-ctcp 3:60

    Set here how many channel ctcps in how many seconds from one host constitutes a flood. Setting this to 0, 0:X or X:0 disables ctcp flood -protection for the channel, where X is an integer >= 0.

    -
    flood-nick 5:60
    -
    Set here how many nick changes in how many seconds from one host +protection for the channel, where X is an integer >= 0.

    +
    +
    flood-nick 5:60

    Set here how many nick changes in how many seconds from one host constitutes a flood. Setting this to 0, 0:X or X:0 disables nick flood -protection for the channel, where X is an integer >= 0.

    +protection for the channel, where X is an integer >= 0.

    +
    -
    channel set <chan> +/-<setting>
    -

    There are many different options for channels which you can define. +

    channel set <chan> +/-<setting>

    There are many different options for channels which you can define. They can be enabled or disabled by a plus or minus in front of them.

    A complete list of all available channel settings:

    -
    -
    -
    enforcebans
    -
    When a ban is set, kick people who are on the channel and match -the ban?
    -
    dynamicbans
    -
    Only activate bans on the channel when necessary? This keeps the +
    +
    +
    enforcebans

    When a ban is set, kick people who are on the channel and match +the ban?

    +
    +
    dynamicbans

    Only activate bans on the channel when necessary? This keeps the channel’s ban list from getting excessively long. The bot still remembers every ban, but it only activates a ban on the channel -when it sees someone join who matches that ban.

    -
    userbans
    -
    Allow bans to be made by users directly? If turned off, the bot will -require all bans to be made through the bot’s console.
    -
    dynamicexempts
    -
    Only activate exempts on the channel when necessary? This keeps the +when it sees someone join who matches that ban.

    +
    +
    userbans

    Allow bans to be made by users directly? If turned off, the bot will +require all bans to be made through the bot’s console.

    +
    +
    dynamicexempts

    Only activate exempts on the channel when necessary? This keeps the channel’s exempt list from getting excessively long. The bot still remembers every exempt, but it only activates a exempt on the channel when it sees a ban set that matches the exempt. The exempt remains -active on the channel for as long as the ban is still active.

    -
    userexempts
    -
    Allow exempts to be made by users directly? If turned off, the bot will -require all exempts to be made through the bot’s console.
    -
    dynamicinvites
    -
    Only activate invites on the channel when necessary? This keeps the +active on the channel for as long as the ban is still active.

    +
    +
    userexempts

    Allow exempts to be made by users directly? If turned off, the bot will +require all exempts to be made through the bot’s console.

    +
    +
    dynamicinvites

    Only activate invites on the channel when necessary? This keeps the channel’s invite list from getting excessively long. The bot still remembers every invite, but the invites are only activated when the channel is set to invite only and a user joins after requesting an -invite. Once set, the invite remains until the channel goes to -i.

    -
    userinvites
    -
    Allow invites to be made by users directly? If turned off, the bot -will require all invites to be made through the bot’s console.
    -
    autoop
    -
    Op users with the +o flag as soon as they join the channel? -This is insecure and not recommended.
    -
    autohalfop
    -
    Halfop users with the +l flag as soon as they join the channel? -This is insecure and not recommended.
    -
    bitch
    -
    Only let users with the +o flag have op on the channel?
    -
    greet
    -
    Say a user’s info line when they join the channel?
    -
    protectops
    -
    Re-op a user with the +o flag if they get deopped?
    -
    protecthalfops
    -
    Re-halfop a user with the +l flag if they get dehalfopped?
    -
    protectfriends
    -
    Re-op a user with the +f flag if they get deopped?
    -
    statuslog
    -

    Log the channel status line every 5 minutes? This shows the bot’s +invite. Once set, the invite remains until the channel goes to -i.

    +
    +
    userinvites

    Allow invites to be made by users directly? If turned off, the bot +will require all invites to be made through the bot’s console.

    +
    +
    autoop

    Op users with the +o flag as soon as they join the channel? +This is insecure and not recommended.

    +
    +
    autohalfop

    Halfop users with the +l flag as soon as they join the channel? +This is insecure and not recommended.

    +
    +
    bitch

    Only let users with the +o flag have op on the channel?

    +
    +
    greet

    Say a user’s info line when they join the channel?

    +
    +
    protectops

    Re-op a user with the +o flag if they get deopped?

    +
    +
    protecthalfops

    Re-halfop a user with the +l flag if they get dehalfopped?

    +
    +
    protectfriends

    Re-op a user with the +f flag if they get deopped?

    +
    +
    statuslog

    Log the channel status line every 5 minutes? This shows the bot’s status on the channel (op, voice, etc.), the channel’s modes, and the total number of members, ops, voices, regular users, and +b, +e, and +I modes on the channel. A sample status line follows:

    -
    -
    [01:40] @#lamest (+istn) : [m/1 o/1 v/4 n/7 b/1 e/5 I/7]
    -
    -
    revenge
    -
    Remember people who deop/kick/ban the bot, valid ops, or friends -and punish them? Users with the +f flag are exempt from revenge.
    -
    revengebot
    -
    This is similar to to the ‘revenge’ option, but it only triggers -if a bot gets deopped, kicked or banned.
    -
    autovoice
    -
    Voice users with the +v flag when they join the channel?
    -
    secret
    -
    Prevent this channel from being listed on the botnet?
    -
    shared
    -
    Share channel-related user info for this channel?
    -
    cycle
    -
    Cycle the channel when it has no ops?
    -
    dontkickops
    -
    Do you want the bot not to be able to kick users who have the +o +
    +

    [01:40] @#lamest (+istn) : [m/1 o/1 v/4 n/7 b/1 e/5 I/7]

    +
    +
    +
    revenge

    Remember people who deop/kick/ban the bot, valid ops, or friends +and punish them? Users with the +f flag are exempt from revenge.

    +
    +
    revengebot

    This is similar to to the ‘revenge’ option, but it only triggers +if a bot gets deopped, kicked or banned.

    +
    +
    autovoice

    Voice users with the +v flag when they join the channel?

    +
    +
    secret

    Prevent this channel from being listed on the botnet?

    +
    +
    shared

    Share channel-related user info for this channel?

    +
    +
    cycle

    Cycle the channel when it has no ops?

    +
    +
    dontkickops

    Do you want the bot not to be able to kick users who have the +o flag, letting them kick-flood for instance to protect the channel -against clone attacks?

    -
    inactive
    -
    This prevents the bot from joining the channel (or makes it leave the +against clone attacks?

    +
    +
    inactive

    This prevents the bot from joining the channel (or makes it leave the channel if it is already there). It can be useful to make the bot leave a channel without losing its settings, channel-specific user flags, -channel bans, and without affecting sharing.

    -
    seen
    -
    Respond to seen requests in the channel? The seen module must be -loaded for this to work.
    -
    nodesynch
    -
    Allow non-ops to perform channel modes? This can stop the bot from +channel bans, and without affecting sharing.

    +
    +
    seen

    Respond to seen requests in the channel? The seen module must be +loaded for this to work.

    +
    +
    nodesynch

    Allow non-ops to perform channel modes? This can stop the bot from fighting with services such as ChanServ, or from kicking IRCops when -setting channel modes without having ops.

    -
    static
    -
    Allow only permanent owners to remove the channel?
    +setting channel modes without having ops.

    +
    +
    static

    Allow only permanent owners to remove the channel?

    +
    @@ -475,9 +450,8 @@

    Search

    set default-ban-time 120

    set default-exempt-time 60

    set default-invite-time 60

    -
    -
    set default-chanset {
    -
    +
    +
    set default-chanset {
    -autoop
    -autovoice
    -bitch
    @@ -510,11 +484,12 @@

    Search

    }

    -

    Copyright (C) 2000 - 2022 Eggheads Development Team

    +

    Copyright (C) 2000 - 2023 Eggheads Development Team

    - + +
    @@ -539,9 +514,9 @@

    Search

    diff --git a/doc/html/modules/mod/compress.html b/doc/html/modules/mod/compress.html index 55b0f5e18..c5b4b2d30 100644 --- a/doc/html/modules/mod/compress.html +++ b/doc/html/modules/mod/compress.html @@ -1,28 +1,23 @@ - + - + - - + + + Compress Module — Eggdrop 1.9.4 documentation - - - - - - - + + + + +
    - -
    -

    Partyline usage

    -
    -

    .files

    + +
    +

    Partyline usage

    +
    +

    .files

    -
    Moves you into the file transfer sub-system, if it has been enabled on this +

    Moves you into the file transfer sub-system, if it has been enabled on this bot. From there you can browse through the files online and use dcc file -transfers to download and upload.

    -
    -
    -

    .cancel <file> [file] …

    +transfers to download and upload.

    +
    + +
    +

    .cancel <file> [file] …

    -
    Tells the bot to stop sending a file that is pending (either -queued, waiting, or in the process of being transferred).
    -
    -
    -

    .cd <directory>

    +

    Tells the bot to stop sending a file that is pending (either +queued, waiting, or in the process of being transferred).

    +
    + +
    +

    .cd <directory>

    -
    Changes your current directory if possible. this works exactly -like the unix command.
    -
    -
    -

    .cp <source> <dst>

    +

    Changes your current directory if possible. this works exactly +like the unix command.

    +
    + +
    +

    .cp <source> <dst>

    -
    Copies a file or group of files from one place to another.
    -
    -
    -

    .desc <file> <description>

    +

    Copies a file or group of files from one place to another.

    +
    + +
    +

    .desc <file> <description>

    Changes the description for a file. if you are a master or file janitor, you can change the description for any file. @@ -198,20 +199,22 @@

    .desc <file> <description> -

    .filestats <user> [clear]

    +

    +
    +

    .filestats <user> [clear]

    -
    Reports on the users upload & download statistics. Optional argument -‘clear’ clears a users upload and download statistics.
    -
    -
    -

    .stats

    +

    Reports on the users upload & download statistics. Optional argument +‘clear’ clears a users upload and download statistics.

    +
    + +
    +

    .stats

    -
    Clears a users upload & download statistics.
    -
    -
    -

    .get <filename> [nickname]

    +

    Clears a users upload & download statistics.

    +
    + +
    +

    .get <filename> [nickname]

    Sends you the file(s) requested, over IRC. you should get a DCC SEND notice on IRC, and have your client accept it. if @@ -226,15 +229,16 @@

    .get <filename> [nickname] -

    .hide <file> [files] …

    +

    +
    +

    .hide <file> [files] …

    -
    Marks a file as hidden, so that normal users can’t see it. -Only a master or file janitor using %b’lsa’%b can see hidden files.
    -
    -
    -

    .ln <bot:filepath> <localfile>

    +

    Marks a file as hidden, so that normal users can’t see it. +Only a master or file janitor using %b’lsa’%b can see hidden files.

    +
    + +
    +

    .ln <bot:filepath> <localfile>

    Creates a link to a file on another bot. The filepath has to be complete, like ‘/gifs/uglyman.gif’. If the bot is not @@ -243,103 +247,116 @@

    .ln <bot:filepath> <localfile> -

    .ls [filemask]

    +

    +
    +

    .ls [filemask]

    -
    Displays the files in the current directory. Subdirectories +

    Displays the files in the current directory. Subdirectories are shown with “<DIR>” next to them, and other files will display their size (typically in kilobytes), who uploaded them (and when), and how many times each file has been downloaded. If a description of the file exists, it is displayed below the filename. You can -restrict the file listing by specifying a mask, just like in unix.

    -
    -
    -

    .mkdir <dir> [flags [channel]]

    +restrict the file listing by specifying a mask, just like in unix.

    +
    + +
    +

    .mkdir <dir> [flags [channel]]

    -
    Creates a subdirectory from this one, with the given name. If +

    Creates a subdirectory from this one, with the given name. If flags are specified, then those flags are required to enter or even see the directory. You can even specify a channel that the flags are matched against. You can use the %b’mkdir’%b command again -to alter or remove those flags.

    - -
    -

    .mv <source> <dest>

    +to alter or remove those flags.

    +
    +
    +
    +

    .mv <source> <dest>

    -
    Moves a file or group of files from one place to another (it -can also be used to rename files).
    - -
    -

    .pending

    +

    Moves a file or group of files from one place to another (it +can also be used to rename files).

    +
    +
    +
    +

    .pending

    -
    Gives you a listing of every file you’ve requested which is +

    Gives you a listing of every file you’ve requested which is still waiting, queued, or in the process of transferring. It shows you the nickname on IRC that the file is being sent to, and, if the transfer is in progress, tells you how far -along the transfer is.

    - -
    -

    .pwd

    +along the transfer is.

    +
    +
    +
    +

    .pwd

    -
    Tells you what your current directory is.
    - -
    -

    .quit

    +

    Tells you what your current directory is.

    +
    +
    +
    +

    .quit

    -
    Exits the file system.
    - -
    -

    rm <file> [files] …

    +

    Exits the file system.

    +
    +
    +
    +

    rm <file> [files] …

    -
    Erase a file for good.
    - -
    -

    .rmdir <dir>

    +

    Erase a file for good.

    +
    +
    +
    +

    .rmdir <dir>

    -
    Removes an existing directory, if there are no files in it.
    - -
    -

    .share <file> [files] …

    +

    Removes an existing directory, if there are no files in it.

    +
    +
    +
    +

    .share <file> [files] …

    -
    Marks a file as shared. This means that other bots can get +

    Marks a file as shared. This means that other bots can get the file remotely for users on their file systems. By default, -files are marked as unshared.

    - -
    -

    .optimize

    +files are marked as unshared.

    +
    +
    +
    +

    .optimize

    -
    Cleans up the current directory’s database. If you have a large +

    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 itself though.

    - -
    -

    .unhide

    +should clean up itself though.

    +
    +
    +
    +

    .unhide

    -
    Makes a file be not hidden any more.
    - -
    -

    .unshare <file> [file] …

    +

    Makes a file be not hidden any more.

    +
    +
    +
    +

    .unshare <file> [file] …

    -
    Removes the shared tag from a file.
    - -
    -

    .filesys module

    +

    Removes the shared tag from a file.

    +
    +
    +
    +

    .filesys module

    This module provides an area within the bot where users can store and manage files. With this module, the bot is usable as a file server.

    The following commands are provided by the filesys module:

    -
    -
    For filesystem users:
    -
    files
    +
    +
    For filesystem users:

    files

    +
    -

    Copyright (C) 2000 - 2022 Eggheads Development Team

    - - - +

    Copyright (C) 2000 - 2023 Eggheads Development Team

    +
    + + +
    @@ -364,9 +381,9 @@

    .filesys module
    diff --git a/doc/html/modules/mod/ident.html b/doc/html/modules/mod/ident.html index 0fb9cf6a6..59c0266a9 100644 --- a/doc/html/modules/mod/ident.html +++ b/doc/html/modules/mod/ident.html @@ -1,28 +1,23 @@ - + - + - - + + + Ident Module — Eggdrop 1.9.4 documentation - - - - - - - + + + + + diff --git a/doc/html/modules/twitch.html b/doc/html/modules/twitch.html index f8dfb3c13..bc21cddcf 100644 --- a/doc/html/modules/twitch.html +++ b/doc/html/modules/twitch.html @@ -163,7 +163,7 @@

    Partyline commandsSearch

    loadmodule uptime
     
    -

    Copyright (C) 2001 - 2022 Eggheads Development Team

    +

    Copyright (C) 2001 - 2023 Eggheads Development Team

    diff --git a/doc/html/modules/woobie.html b/doc/html/modules/woobie.html index 1076d3c2b..02f5b6c8b 100644 --- a/doc/html/modules/woobie.html +++ b/doc/html/modules/woobie.html @@ -125,7 +125,7 @@

    Search

    loadmodule woobie
     
    -

    Copyright (C) 2000 - 2022 Eggheads Development Team

    +

    Copyright (C) 2000 - 2023 Eggheads Development Team

    diff --git a/doc/html/modules/writing.html b/doc/html/modules/writing.html index 4cd607b43..8eb8cb6ad 100644 --- a/doc/html/modules/writing.html +++ b/doc/html/modules/writing.html @@ -1,34 +1,29 @@ - + - + - - - Writing an Eggdrop Module — Eggdrop 1.9.4 documentation - - - - - - - + + + + How to Write an Eggdrop Module — Eggdrop 1.9.4 documentation + + + + + - +
    @@ -417,7 +413,7 @@

    What to do with a module? previous | - next
    @@ -427,9 +423,9 @@

    What to do with a module?

    diff --git a/doc/html/objects.inv b/doc/html/objects.inv index 3eeec3c4f2f64ba7cdec65c523bdfc5395e4a612..7703dd2ccaddb86169d3a44b8031aed2182828a4 100644 GIT binary patch delta 1288 zcmV+j1^4==3iAq(e1A=E+c*%t`&ST1kM$bu0()2#1@ego+Y~{aqK9Hp&=hS8kx7B1 z;`rb1@SBuI&R!C0-n=K08a@u`Mh<30?O&oz^LHZ|S$-fihyU1{Lq{%M#_ev`DA_MO z-0>alrYslstShNnu_G~Y*lrh8Ye=@Fj&68oX$RR19oH-PzkhPDBVW8DmoE3g!HZ2N zkK0!7=eaQ>(yt;TD6l;hf_HjeA!bB{>&S=-^3W@;&nbkAq!1ZNL1@|Wa{?|Q^L>7# z8`huU0-A_V*N>6ah%+MwFmi6bts`aI0)9F}3ki{W7xDvr$3-g|{#x^6)ECFS{kdox zF3kLE92{SA?|*W`E3$s5zCt?G>3c#2kv$hg%Rw{je!qWYRK{ zuvw`ydlSI)C14@LcQ{Z3+r}7G69)~tE5o`aY>5LEO@AttO!x%btLgY>@@d=Ao&HRI zg$?-c0^WxdP=8uRz%Py;Lnx&<)>g1?Xn0dD?iefSnk2@tHT$#}nKP=i3aBbB4`?eD zOth7vkTF~d8vJJ>6~J2V3SI$X0b5L*5|gTJv^G)9F6T5VJDr#*W}9J- zrP5v}=6{O#=)6$2*|EuvEp=8S+HGaFBX6A}N82q;7xC9QdTGC7^PTwToJcm;+FD1O zewH5mpmKu(7t-+A2{_Qxzqvd_px-<<+mCY!9`zEBSO47HeZ(|0xAu=KSj_X+HVb8| z7p~^{7L5un6VupJHCu-c3<@p}5ip7hy`3LM#DBfaQ_RMcz~9*HhWBVt@tKIm(3|!! zJ0Fk6lgniy8b>KN?W~4Jy~aYlbp3Gi~`i#?@DmLnYeJqxt!yoC6FH-5FV@$;lBP`3m zD1Z4GUMhOWEXzKZI!;Z+Zkc7dS0#>et0D*bxXjI9;IaXSBv_-;Ml;p+mGPkop~ylx z6&12}@I=+{UY`@ScsiR7@bT_!n5=EQ5c3nmg*-MI7`dXlW#jtIB+bpx<9ZH?#bKP> zk3RJ{InQ+Zj7mg9dm`w@^^H$o*PzM<7=P!9NRef;(coV*TaEpemDv;qgK`Ut0d8$F zzU!on$w8RvOVvndjr8gl!}553V* zKpMdfBH`lkmh5uuhVWI`kgu(<0}3Kc)(1$A*4^T@%?lqn4q(fv85Bom5s_NsE`LM= zz3pHAno?~v9Q}_LANpP@6Df+l{E2XEIQ0uQqhj?`nG@6$GSLKuqiN5<-ymdHi6{E# zU@OAGP3_O}t`jnxRkzTuBkY95vS;el+opc?h3b9&K;<=ODl@qRrNw??-Y6^*rTD8^ z>S2S(1SG5iJlQ6YtcQ&@E$mbnR(}%duwldo+-}->@r`QPGe&XouvwZHDj3|6p4vXW z$8Fr@8`GaAjaI>Le{3-vf`6Qhl^shU4sc2#Lvi8IoVX0T*Y51yb8&3DhEdh%|9g#n ya1{ra888pHpMgSdYEa)Q+8UtOjZNrUeisMBM5F9%F2chy5Z-8X{sT1dCjoH?WO&d3 delta 1211 zcmV;s1VsDu3a1K?e1F@H+cpq=_g4r=ALANLfj$&LfW4xNW`jlSAP+?m&=hSGE0Y3A z+3UaW@G4RoI(^y8oH<7%HFG#3TRE5&u|FGa+CN)Ko8@l}8NEgM^XK6>-4jt1g_RWdB_7 zmI+gTjDzDto_}0!c*Lk5sxOlcb^5*`qLDoljh2I=taPl|{nBD{&WOxrpVxVn|Q6+KEpt~}(TS7}5iGOHQsf>h=&|YoFJ~bbA9og$o z%|D?5|6RcIkOJy2%Lw?x@oNaB6xYfH?S_`M`Qc8noUWV1ICFDIhcR*{l~w>n#f=Nv zNd+6_QY>cnhDnv)S2`c&aW##?17{A1d0kDZ@WPoBVxCu3$~|%Bh=}>sg+_0jI^)y_ zs~XWG3x9{47-Eeay)t)7#1w1v+%u<+IWxVQ$mocrA5J>8N)Jt3v~Y$CX;^gw4)pXd zE)Nmtx3BH)LruY>UgG8U@B7COn1*K7vvCEBdH&jFp=@5 zxI9F_C?fQ(zKn=_nN7^bl)#i|wc$M)RD33)F@N-iAFKQEXuNJ*CZchca?7h49`zdE zeda{tthkw6c@rqGLmu4SrK>K++C=ZCu{zezn};`c?2V2B(gUm`OJk~P!OTAH0v>1PG@&EFTCWqfE^=dPz>2cL`sdv5Dj$RpZ=Ir zZ8Ti7FBTvAUMdqQik^N)I5wQ_W}8v4dZNq)Y6{tCg2FX$U|>fOvZurneR7Fp;eT)) z+duP99A{_q9c$6nisEJ!}z~ zfP_N*@DZ`$eR_^-+~rTU zKTn#Rf^UE9FdTxvoDs{XgFqbMQZzx9;=*ANa2dAO9_`23;>^3264mPe` + - + - - + + Search — Eggdrop 1.9.4 documentation - - + + - - - - - - + + + + + - - - +
    @@ -260,9 +254,9 @@

    Writing an Eggdrop Script

    @@ -270,4 +264,4 @@

    Writing an Eggdrop Script + - + - - + + + Common First Steps — Eggdrop 1.9.4 documentation - - - - - - - + + + + + @@ -309,9 +303,9 @@

    Setting up SASL authentication
    diff --git a/doc/html/tutorials/module.html b/doc/html/tutorials/module.html index b750801ea..53d400935 100644 --- a/doc/html/tutorials/module.html +++ b/doc/html/tutorials/module.html @@ -1,28 +1,23 @@ - + - + - - - Writing an Eggdrop Module — Eggdrop 1.9.4 documentation - - - - - - - + + + + Writing a Basic Eggdrop Module — Eggdrop 1.9.4 documentation + + + + +