diff --git a/.gitignore b/.gitignore index 37ee0f2d9..ad58b54d0 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ eggdrop EGGMOD.stamp mod.xlibs __pycache__ +.clangd diff --git a/doc/sphinx_source/using/core.rst b/doc/sphinx_source/using/core.rst index f192c3cac..8c1e88e8f 100644 --- a/doc/sphinx_source/using/core.rst +++ b/doc/sphinx_source/using/core.rst @@ -589,7 +589,7 @@ Modules After the core settings, you should start loading modules. Modules are loaded by the command "loadmodule ". Eggdrop looks for modules -in the directory you specified by the module-path setting in the files +in the directory you specified by the mod-path setting in the files and directories section. Please note that for different configurations, different modules are needed. diff --git a/src/dns.c b/src/dns.c index 863d40c33..a47f53bcf 100644 --- a/src/dns.c +++ b/src/dns.c @@ -565,7 +565,8 @@ void *thread_dns_ipbyhost(void *arg) else if (error == EAI_NONAME) snprintf(dtn->strerror, sizeof dtn->strerror, "dns: thread_dns_ipbyhost(): getaddrinfo(): not known"); else if (error == EAI_SYSTEM) { - snprintf(dtn->strerror, sizeof dtn->strerror, "dns: thread_dns_ipbyhost(): getaddrinfo(): %s: %s", gai_strerror(error), strerror(errno)); + /* print raw errno, dont use strerror() in thread and dont use strerror_r() due to GNU / POSIX portability complexity */ + snprintf(dtn->strerror, sizeof dtn->strerror, "dns: thread_dns_ipbyhost(): getaddrinfo(): %s: errno %i", gai_strerror(error), errno); } else snprintf(dtn->strerror, sizeof dtn->strerror, "dns: thread_dns_ipbyhost(): getaddrinfo(): %s", gai_strerror(error)); close(dtn->fildes[1]); diff --git a/src/main.c b/src/main.c index 20ee14d9e..5e384dd7b 100644 --- a/src/main.c +++ b/src/main.c @@ -872,7 +872,7 @@ static void mainloop(int toplevel) if (strcmp(p->name, "eggdrop") && strcmp(p->name, "encryption") && strcmp(p->name, "encryption2") && strcmp(p->name, "uptime")) { f++; - debug1("stagnant module %s", p->name); + putlog(LOG_MISC, "*", "stagnant module %s", p->name); } } if (f != 0) { diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c index 2467b2d1b..7e57ffcfa 100644 --- a/src/mod/irc.mod/chan.c +++ b/src/mod/irc.mod/chan.c @@ -2240,7 +2240,7 @@ static int gotjoin(char *from, char *channame) */ static int gotpart(char *from, char *msg) { - char *nick, *chname, *key; + char *nick, *chname, uhost[UHOSTLEN], *key; struct chanset_t *chan; struct userrec *u; memberlist *m; @@ -2255,9 +2255,14 @@ static int gotpart(char *from, char *msg) return 0; } if (chan && !channel_pending(chan)) { + strlcpy(uhost, from, sizeof uhost); nick = splitnick(&from); m = ismember(chan, nick); - u = get_user_from_member(m); + // TODO: check account from rawt account-tags + if (m) + u = get_user_from_member(m); + else + u = get_user_by_host(uhost); if (!channel_active(chan)) { /* whoa! */ putlog(LOG_MISC, chan->dname, @@ -2276,7 +2281,8 @@ static int gotpart(char *from, char *msg) if (!chan) return 0; - killmember(chan, nick); + if (m) + killmember(chan, nick); if (msg[0]) putlog(LOG_JOIN, chan->dname, "%s (%s) left %s (%s).", nick, from, chan->dname, msg); diff --git a/src/mod/python.mod/Makefile.in b/src/mod/python.mod/Makefile.in index bf1c0b622..b7282f311 100644 --- a/src/mod/python.mod/Makefile.in +++ b/src/mod/python.mod/Makefile.in @@ -41,6 +41,5 @@ distclean: clean ../../../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 \ - ../../../src/mod/irc.mod/irc.h ../../../src/mod/server.mod/server.h \ - .././python.mod/python.h .././python.mod/pycmds.c \ - .././python.mod/tclpython.c + ../../../src/mod/server.mod/server.h .././python.mod/python.h \ + .././python.mod/pycmds.c .././python.mod/tclpython.c diff --git a/src/mod/python.mod/python.c b/src/mod/python.mod/python.c index 254a4b7d5..bb6d7cf3d 100644 --- a/src/mod/python.mod/python.c +++ b/src/mod/python.mod/python.c @@ -33,7 +33,6 @@ #undef days #include #include -#include "src/mod/irc.mod/irc.h" #include "src/mod/server.mod/server.h" #include "python.h" @@ -41,7 +40,7 @@ static PyObject *pirp, *pglobals; #undef global -static Function *global = NULL, *irc_funcs = NULL; +static Function *global = NULL; static PyThreadState *_pythreadsave; #include "pycmds.c" #include "tclpython.c" @@ -141,33 +140,27 @@ static Function python_table[] = { char *python_start(Function *global_funcs) { char *s; + /* Assign the core function table. After this point you use all normal * functions defined in src/mod/modules.h */ - global = global_funcs; - - /* Register the module. */ - module_register(MODULE_NAME, python_table, 0, 1); - - if (!module_depend(MODULE_NAME, "eggdrop", 109, 0)) { - module_undepend(MODULE_NAME); - return "This module requires Eggdrop 1.9.0 or later."; - } - // TODO: Is this dependency necessary? It auto-loads irc.mod, that might be undesired - if (!(irc_funcs = module_depend(MODULE_NAME, "irc", 1, 5))) { - module_undepend(MODULE_NAME); - return "This module requires irc module 1.5 or later."; + if (global_funcs) { + global = global_funcs; + + /* Register the module. */ + module_register(MODULE_NAME, python_table, 0, 1); + if (!module_depend(MODULE_NAME, "eggdrop", 109, 0)) { + module_undepend(MODULE_NAME); + return "This module requires Eggdrop 1.9.0 or later."; + } + if ((s = init_python())) + return s; } - // irc.mod depends on server.mod and channels.mod, so those were implicitly loaded - - if ((s = init_python())) - return s; /* Add command table to bind list */ add_builtins(H_dcc, mydcc); add_tcl_commands(my_tcl_cmds); add_hook(HOOK_PRE_SELECT, (Function)python_gil_unlock); add_hook(HOOK_POST_SELECT, (Function)python_gil_lock); - return NULL; } diff --git a/src/modules.c b/src/modules.c index 69664b0a6..1ae77d785 100644 --- a/src/modules.c +++ b/src/modules.c @@ -700,7 +700,6 @@ int module_register(char *name, Function *funcs, int major, int minor) const char *module_load(char *name) { - size_t len; module_entry *p; char *e; Function f; @@ -709,6 +708,7 @@ const char *module_load(char *name) #endif #ifndef STATIC + size_t len; char workbuf[PATH_MAX]; # ifdef MOD_USE_SHL shl_t hand; diff --git a/src/tcl.c b/src/tcl.c index 5bc135b35..949fc5842 100644 --- a/src/tcl.c +++ b/src/tcl.c @@ -615,10 +615,14 @@ int tclthreadmainloop(int zero) return (i == -5); } +struct threaddata *td_main = 0; + struct threaddata *threaddata() { static Tcl_ThreadDataKey tdkey; struct threaddata *td = Tcl_GetThreadData(&tdkey, sizeof(struct threaddata)); + if (!(td->mainloopfunc) && td_main) /* python thread */ + return td_main; return td; } @@ -638,6 +642,8 @@ void init_threaddata(int mainthread) td->blocktime.tv_usec = 0; td->MAXSOCKS = 0; increase_socks_max(); + if (mainthread) + td_main = td; } /* workaround for Tcl that does not support unicode outside BMP (3 byte utf-8 characters) */ diff --git a/src/tclhash.c b/src/tclhash.c index 08d5ee631..0fb2e6cfc 100644 --- a/src/tclhash.c +++ b/src/tclhash.c @@ -1240,13 +1240,19 @@ void check_tcl_die(char *reason) void check_tcl_log(int lv, char *chan, char *msg) { char mask[512]; + Tcl_Obj* prev_result; + /* We have to store the old result, as check_tcl_bind may override it */ + prev_result = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(prev_result); egg_snprintf(mask, sizeof mask, "%s %s", chan, msg); Tcl_SetVar(interp, "_log1", masktype(lv), TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "_log2", chan, TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "_log3", msg, TCL_GLOBAL_ONLY); check_tcl_bind(H_log, mask, 0, " $::_log1 $::_log2 $::_log3", MATCH_MASK | BIND_STACKABLE); + Tcl_SetObjResult(interp, prev_result); + Tcl_DecrRefCount(prev_result); } #ifdef TLS diff --git a/src/version.h b/src/version.h index 3898c7449..c446bfadf 100644 --- a/src/version.h +++ b/src/version.h @@ -27,4 +27,5 @@ */ #define EGG_STRINGVER "1.10.0" -#define EGG_NUMVER 1100003 +#define EGG_NUMVER 1100005 +#define EGG_PATCH "pythonfixes"