diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml deleted file mode 100644 index 485733521..000000000 --- a/.github/workflows/ccpp.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: C/C++ CI - -on: - pull_request: - branches: - - develop - -jobs: - build: - name: compile test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: install dependencies - run: sudo apt-get install tcl tcl-dev openssl libssl-dev - - name: configure - run: ./configure - - name: make config - run: make config - - name: make - run: make - - name: make install - run: make install diff --git a/.github/workflows/configure_flags.yml b/.github/workflows/configure_flags.yml deleted file mode 100644 index 60a8c07bb..000000000 --- a/.github/workflows/configure_flags.yml +++ /dev/null @@ -1,41 +0,0 @@ -on: - workflow_dispatch: - inputs: - name: - description: 'Test configure flags' - -jobs: - configure-nosslflag: - name: Configure, --disable-tls - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - run: sudo apt-get install tcl tcl-dev - - run: ./configure --disable-tls - - run: make config - - run: make - - run: make install - - - configure-noipv6: - name: Configure, --disable-ipv6 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - run: sudo apt-get install tcl tcl-dev - - run: ./configure --disable-ipv6 - - run: make config - - run: make - - run: make install - - - configure-notdns: - name: Configure, --disable-tdns - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - run: sudo apt-get install tcl tcl-dev - - run: ./configure --disable-tdns - - run: make config - - run: make - - run: make install diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml new file mode 100644 index 000000000..246f35043 --- /dev/null +++ b/.github/workflows/dependencies.yml @@ -0,0 +1,116 @@ +name: Tcl/SSL Versions + +on: + pull_request: + branches: [ develop ] + push: + branches: [ develop ] + +jobs: + tcl-versions: + name: Tcl Versions + strategy: + matrix: + tcl_version: [ '8.5.19', '8.6.14', '8.7a5', '9.0b2' ] + continue-on-error: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: install dependencies + run: sudo apt-get install openssl libssl-dev + - name: Build Tcl + run: | + wget http://prdownloads.sourceforge.net/tcl/tcl${{ matrix.tcl_version }}-src.tar.gz && \ + tar xzf tcl${{ matrix.tcl_version }}-src.tar.gz && \ + cd tcl${{ matrix.tcl_version }}/unix && \ + ./configure --prefix=$HOME/tcl && \ + make -j4 && make install + - name: Build + run: ./configure --with-tcl=$HOME/tcl/lib && LD_LIBRARY_PATH=$HOME/tcl/lib make config eggdrop + ssl-version-098: + name: OpenSSL 0.9.8 + continue-on-error: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + path: 'eggdrop' + - name: install dependencies + run: sudo apt-get install tcl tcl-dev + - name: Build OpenSSL + run: | + wget https://www.openssl.org/source/old/0.9.x/openssl-0.9.8zh.tar.gz && \ + sha256sum --status --check <(echo f1d9f3ed1b85a82ecf80d0e2d389e1fda3fca9a4dba0bf07adbf231e1a5e2fd6 openssl-0.9.8zh.tar.gz) && \ + tar xzf openssl-0.9.8zh.tar.gz && \ + cd openssl-0.9.8zh && ./config --prefix=$HOME/ssl -fPIC && make -j4 && make install_sw + - name: Build + run: cd $GITHUB_WORKSPACE/eggdrop && ./configure --with-sslinc=$HOME/ssl/include --with-ssllib=$HOME/ssl/lib && LD_LIBRARY_PATH=$HOME/ssl/lib make config eggdrop + ssl-version-10: + name: OpenSSL 1.0 + continue-on-error: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + path: 'eggdrop' + - name: install dependencies + run: sudo apt-get install tcl tcl-dev + - name: Build OpenSSL + run: | + wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2u.tar.gz && \ + sha256sum --status --check <(echo ecd0c6ffb493dd06707d38b14bb4d8c2288bb7033735606569d8f90f89669d16 openssl-1.0.2u.tar.gz) && \ + tar xzf openssl-1.0.2u.tar.gz && \ + cd openssl-1.0.2u && ./config --prefix=$HOME/ssl -fPIC && make -j4 && make install_sw + - name: Build + run: cd $GITHUB_WORKSPACE/eggdrop && ./configure --with-sslinc=$HOME/ssl/include --with-ssllib=$HOME/ssl/lib && LD_LIBRARY_PATH=$HOME/ssl/lib make config eggdrop + ssl-version-11: + name: OpenSSL 1.1 + continue-on-error: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + repository: openssl/openssl + ref: 'OpenSSL_1_1_1w' + path: 'openssl' + - name: Build OpenSSL + run: | + cd $GITHUB_WORKSPACE/openssl && ./config --prefix=$HOME/ssl && make -j4 && make install_sw + - name: install dependencies + run: sudo apt-get install tcl tcl-dev + - uses: actions/checkout@v4 + with: + path: 'eggdrop' + - name: Build + run: cd $GITHUB_WORKSPACE/eggdrop && ./configure --with-sslinc=$HOME/ssl/include --with-ssllib=$HOME/ssl/lib && LD_LIBRARY_PATH=$HOME/ssl/lib make config eggdrop + ssl-versions-3x: + name: OpenSSL 3.x + strategy: + matrix: + ssl_version: [ '3.0', '3.1', '3.2', '3.3' ] + continue-on-error: true + runs-on: ubuntu-latest + steps: + - uses: oprypin/find-latest-tag@v1 + with: + repository: openssl/openssl + releases-only: true + prefix: 'openssl-' + regex: "${{ matrix.ssl_version }}.[0-9]+" + sort-tags: true + id: openssl + - uses: actions/checkout@v4 + with: + repository: openssl/openssl + ref: ${{ steps.openssl.outputs.tag }} + path: 'openssl' + - name: Build OpenSSL + run: | + cd $GITHUB_WORKSPACE/openssl && ./config --prefix=$HOME/ssl && make -j4 && make install_sw + - uses: actions/checkout@v4 + with: + path: 'eggdrop' + - name: install dependencies + run: sudo apt-get install tcl tcl-dev + - name: Build + run: cd $GITHUB_WORKSPACE/eggdrop && ./configure --with-sslinc=$HOME/ssl/include --with-ssllib=$HOME/ssl/lib64 && LD_LIBRARY_PATH=$HOME/ssl/lib64 make config eggdrop diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml new file mode 100644 index 000000000..e1dc3be6b --- /dev/null +++ b/.github/workflows/make.yml @@ -0,0 +1,39 @@ +name: Eggdrop Compile + +on: + pull_request: + branches: [ develop ] + push: + branches: [ develop ] + +jobs: + default-build: + name: Compile Test + strategy: + matrix: + cc: [ 'gcc', 'clang' ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: install dependencies + run: sudo apt-get install clang tcl tcl-dev openssl libssl-dev + - name: Build + env: + CC: ${{ matrix.cc }} + run: ./configure && make config && make -j4 && make install + feature-test: + name: Features + continue-on-error: true + needs: default-build + strategy: + matrix: + conf_tls: [ '', '--disable-tls' ] + conf_ipv6: [ '', '--disable-ipv6' ] + conf_tdns: [ '', '--disable-tdns' ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: install dependencies + run: sudo apt-get install tcl tcl-dev openssl libssl-dev + - name: Build + run: ./configure ${{ matrix.conf_tls }} ${{ matrix.conf_ipv6 }} ${{ matrix.conf_tdns }} && make config && make -j4 diff --git a/.github/workflows/misc.yml b/.github/workflows/misc.yml new file mode 100644 index 000000000..b6a894b30 --- /dev/null +++ b/.github/workflows/misc.yml @@ -0,0 +1,45 @@ +name: Check autotools/makedepend + +on: + pull_request: + branches: [ develop ] + push: + branches: [ develop ] + +jobs: + autotools-check: + name: Check if misc/runautotools needs to be run + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: install dependencies + run: sudo apt-get install build-essential autoconf + - name: Stage configure with revision removed + run: | + for i in `find . -name configure`; do sed -i 's/From configure.ac .*//' $i; git add $i; done + - name: Run autotools + run: misc/runautotools + - name: Remove configure revision again + run: | + for i in `find . -name configure`; do sed -i 's/From configure.ac .*//' $i; done + - name: Check diff + run: | + git diff | tee .gitdiff + if [ -s .gitdiff ]; then + exit 1 + fi + makedepend-check: + name: Check if misc/makedepend needs to be run + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: install dependencies + run: sudo apt-get install build-essential autoconf tcl-dev tcl openssl libssl-dev + - name: Run makedepend + run: misc/makedepend + - name: Check diff + run: | + git diff | tee .gitdiff + if [ -s .gitdiff ]; then + exit 1 + fi diff --git a/INSTALL b/INSTALL index 81e2a5184..1db949afb 100644 --- a/INSTALL +++ b/INSTALL @@ -158,5 +158,5 @@ the README file. If not, then READ IT!&@#%@! Have fun with Eggdrop! - Copyright (C) 1997 Robey Pointer Copyright (C) 1999 - 2023 Eggheads + Copyright (C) 1997 Robey Pointer Copyright (C) 1999 - 2024 Eggheads Development Team diff --git a/README b/README index 2d74900ca..468549297 100644 --- a/README +++ b/README @@ -216,5 +216,5 @@ OBTAINING HELP - Don't ask to ask- just state your question, along with any relevant details and error messages -Copyright (C) 1997 Robey Pointer Copyright (C) 1999 - 2023 Eggheads +Copyright (C) 1997 Robey Pointer Copyright (C) 1999 - 2024 Eggheads Development Team diff --git a/aclocal.m4 b/aclocal.m4 index ff8a0c158..748fb2969 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1520,7 +1520,7 @@ AC_DEFUN([EGG_TLS_ENABLE], AC_MSG_CHECKING([whether to enable TLS support]) AC_ARG_ENABLE(tls, [ --disable-tls disable TLS support ], [tls_enabled="$enableval"], - [tls_enabled="$enableval"]) + [tls_enabled="yes"]) AC_MSG_RESULT([$tls_enabled]) ]) diff --git a/config.h.in b/config.h.in index 30cc2b7da..4ac55ced2 100644 --- a/config.h.in +++ b/config.h.in @@ -132,9 +132,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H -/* Define to 1 if you have the `isascii' function. */ -#undef HAVE_ISASCII - /* Define to 1 if you have the `crypto' library (-lcrypto). */ #undef HAVE_LIBCRYPTO @@ -287,6 +284,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + /* 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 b/configure index 2f2ee20a6..9c1c4eeb9 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac 1b958239. +# From configure.ac 4af46aa3. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for Eggdrop 1.9.5. # @@ -617,7 +617,7 @@ PACKAGE_TARNAME='eggdrop' PACKAGE_VERSION='1.9.5' PACKAGE_STRING='Eggdrop 1.9.5' PACKAGE_BUGREPORT='bugs@eggheads.org' -PACKAGE_URL='' +PACKAGE_URL='https://www.eggheads.org' ac_unique_file="src/eggdrop.h" ac_default_prefix=\${HOME}/eggdrop @@ -660,7 +660,6 @@ MOD_UPDIR DEST EGGVERSION egg_with_python_config -egg_enable_python SSL_LIBS SSL_INCLUDES DEBCFLGS @@ -803,7 +802,6 @@ enable_tls with_sslinc with_ssllib enable_tdns -enable_python with_python_config ' ac_precious_vars='build_alias @@ -1462,8 +1460,6 @@ Optional Features and Packages: --with-sslinc=PATH Path to OpenSSL headers --with-ssllib=PATH Path to OpenSSL libraries --disable-tdns disable threaded DNS core - --enable-python enable Python support (autodetect) - --disable-python disable Python support --with-python-config=PATH Path to python-config Some influential environment variables: @@ -1480,6 +1476,7 @@ Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . +Eggdrop home page: . _ACEOF ac_status=$? fi @@ -2792,7 +2789,6 @@ as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" as_fn_append ac_header_c_list " wchar.h wchar_h HAVE_WCHAR_H" as_fn_append ac_header_c_list " minix/config.h minix_config_h HAVE_MINIX_CONFIG_H" -as_fn_append ac_header_c_list " sys/time.h sys_time_h HAVE_SYS_TIME_H" as_fn_append ac_header_c_list " sys/select.h sys_select_h HAVE_SYS_SELECT_H" as_fn_append ac_header_c_list " sys/socket.h sys_socket_h HAVE_SYS_SOCKET_H" as_fn_append ac_header_c_list " sys/param.h sys_param_h HAVE_SYS_PARAM_H" @@ -6858,8 +6854,6 @@ fi fi - - ac_fn_c_check_header_compile "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default" if test "x$ac_cv_header_arpa_inet_h" = xyes then : @@ -6943,6 +6937,12 @@ if test "x$ac_cv_header_sys_time_h" = xyes then : printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h +fi +ac_fn_c_check_header_compile "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default" +if test "x$ac_cv_header_time_h" = xyes +then : + printf "%s\n" "#define HAVE_TIME_H 1" >>confdefs.h + fi ac_fn_c_check_header_compile "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_unistd_h" = xyes @@ -8218,12 +8218,6 @@ if test "x$ac_cv_func_inet_aton" = xyes then : printf "%s\n" "#define HAVE_INET_ATON 1" >>confdefs.h -fi -ac_fn_c_check_func "$LINENO" "isascii" "ac_cv_func_isascii" -if test "x$ac_cv_func_isascii" = xyes -then : - printf "%s\n" "#define HAVE_ISASCII 1" >>confdefs.h - fi ac_fn_c_check_func "$LINENO" "memset_s" "ac_cv_func_memset_s" if test "x$ac_cv_func_memset_s" = xyes @@ -8316,6 +8310,13 @@ rm -rf conftest* # Check for b64_ntop. If we have b64_ntop, we assume b64_pton as well. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for b64_ntop" >&5 printf %s "checking for b64_ntop... " >&6; } + if test "$cross_compiling" = yes +then : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -8331,15 +8332,17 @@ b64_ntop(NULL, 0, NULL, 0); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO" +if ac_fn_c_try_run "$LINENO" then : found_b64_ntop=yes else $as_nop found_b64_ntop=no fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + if test "x$found_b64_ntop" = xno; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } @@ -8348,7 +8351,14 @@ printf "%s\n" "no" >&6; } printf %s "checking for b64_ntop with -lresolv... " >&6; } OLD_LIBS="$LIBS" LIBS="$LIBS -lresolv" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test "$cross_compiling" = yes +then : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -8363,15 +8373,17 @@ b64_ntop(NULL, 0, NULL, 0); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO" +if ac_fn_c_try_run "$LINENO" then : found_b64_ntop=yes else $as_nop found_b64_ntop=no fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + if test "x$found_b64_ntop" = xno; then LIBS="$OLD_LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -8381,7 +8393,14 @@ printf "%s\n" "no" >&6; } printf %s "checking for b64_ntop with -lnetwork... " >&6; } OLD_LIBS="$LIBS" LIBS="-lnetwork" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test "$cross_compiling" = yes +then : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -8396,15 +8415,17 @@ b64_ntop(NULL, 0, NULL, 0); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO" +if ac_fn_c_try_run "$LINENO" then : found_b64_ntop=yes else $as_nop found_b64_ntop=no fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + if test "x$found_b64_ntop" = xno; then LIBS="$OLD_LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -10124,7 +10145,7 @@ if test ${enable_tls+y} then : enableval=$enable_tls; tls_enabled="$enableval" else $as_nop - tls_enabled="$enableval" + tls_enabled="yes" fi @@ -10612,38 +10633,17 @@ printf "%s\n" "#define EGG_TDNS 1" >>confdefs.h # Check for Python - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to compile the Python module" >&5 -$as_echo_n "checking whether to compile the Python module... " >&6; } - # Check whether --enable-python was given. -if test "${enable_python+set}" = set; then : - enableval=$enable_python; egg_enable_python="$enableval" -fi - - # Check whether --enable-python was given. -if test "${enable_python+set}" = set; then : - enableval=$enable_python; egg_enable_python="$enableval" -else - egg_enable_python="autodetect" -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $egg_enable_python" >&5 -$as_echo "$egg_enable_python" >&6; } - - - # Check whether --with-python-config was given. -if test "${with_python_config+set}" = set; then : +if test ${with_python_config+y} +then : withval=$with_python_config; - if test "x$enable_python" != "xno"; then - if test -d "$withval" || test -x "$withval"; then - egg_with_python_config="$withval" - else - egg_with_python_config="no" - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Invalid path to python-config. $withval is not a directory and not an executable." >&5 -$as_echo "$as_me: WARNING: Invalid path to python-config. $withval is not a directory and not an executable." >&2;} - fi + if test -d "$withval" || test -x "$withval"; then + egg_with_python_config="$withval" + else + egg_with_python_config="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Invalid path to python-config. $withval is not a directory and not an executable." >&5 +printf "%s\n" "$as_me: WARNING: Invalid path to python-config. $withval is not a directory and not an executable." >&2;} fi fi @@ -11262,7 +11262,8 @@ $config_headers Configuration commands: $config_commands -Report bugs to ." +Report bugs to . +Eggdrop home page: ." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` diff --git a/configure.ac b/configure.ac index 78a7e70d5..86756534d 100644 --- a/configure.ac +++ b/configure.ac @@ -91,9 +91,8 @@ EGG_CHECK_OS # Checks for header files. EGG_HEADER_STDC AC_HEADER_DIRENT -AC_CHECK_HEADERS_ONCE([sys/time.h]) -AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h locale.h netdb.h netinet/in.h stdio.h stdarg.h stddef.h sys/file.h sys/param.h sys/select.h sys/socket.h sys/time.h unistd.h wchar.h]) +AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h locale.h netdb.h netinet/in.h stdio.h stdarg.h stddef.h sys/file.h sys/param.h sys/select.h sys/socket.h sys/time.h time.h unistd.h wchar.h]) # Checks for typedefs, structures, and compiler characteristics. @@ -113,7 +112,7 @@ AX_TYPE_SOCKLEN_T AX_CREATE_STDINT_H([eggint.h]) # Checks for functions and their arguments. -AC_CHECK_FUNCS([dprintf explicit_bzero memset_explicit explicit_memset getrandom inet_aton isascii memset_s snprintf strlcpy vsnprintf]) +AC_CHECK_FUNCS([dprintf explicit_bzero memset_explicit explicit_memset getrandom inet_aton memset_s snprintf strlcpy vsnprintf]) AC_FUNC_SELECT_ARGTYPES EGG_FUNC_B64_NTOP AC_FUNC_MMAP @@ -165,7 +164,6 @@ EGG_TLS_DETECT EGG_TDNS_ENABLE # Check for Python -EGG_PYTHON_ENABLE EGG_PYTHON_WITHCONFIG diff --git a/doc/sphinx_source/modules/mod/python.rst b/doc/sphinx_source/modules/mod/python.rst index 55307eb6f..5e06a45b2 100644 --- a/doc/sphinx_source/modules/mod/python.rst +++ b/doc/sphinx_source/modules/mod/python.rst @@ -8,6 +8,11 @@ Python Module This module adds a Python interpreter to Eggdrop, allowing you to run Python scripts. +------------------- +System Requirements +------------------- +This module requires Python version 3.8 or higher in order to run. Similar to Tcl requirements, Eggdrop requires both python and python development libraries to be installed on the host machine. On Debian/Ubuntu machines, this means the packages ``python``, ``python-dev`` AND ``python-is-python3`` to be installed. The python-is-python3 updates symlinks on the host system that allow Eggdrop to find it. + -------------- Loading Python -------------- @@ -50,105 +55,3 @@ pysource ^^^^^^^^^^^^^^^^^^^^^^^ The ``pysource`` command is analogous to the Tcl ``source`` command, except that it loads a Python script into Eggdrop instead of a Tcl script. - ------------------------ -Eggdrop Python Commands ------------------------ - -The Python module is built to use the existing core Tcl commands integrated into Eggdrop via the ``eggdrop.tcl`` module. To call an existing Tcl command from Python, you can either load the entire catalog by running ``import eggdrop.tcl``, or be more specific by ``from eggdrop.tcl import putserv, putlog, chanlist``, etc. - -Arguments to the Tcl functions are automatically converted as follows: - -* ``None`` is converted to an empty Tcl object (the empty string, ``""``) -* ``List`` and ``Tuple`` is converted to a ``Tcl list`` -* ``Dict`` is converted to a ``Tcl dictionary`` -* Everything else is converted to a string using the str() method - -Return values from Tcl functions must be manually converted: - -* ``""`` the empty string is automatically converted to None -* everything else is returned as string -* ``Tcl list`` as string can be converted to a Python ``List`` using ``parse_tcl_list`` -* ``Tcl dictionary`` as string can be converted to a Python ``Dict`` using ``parse_tcl_list`` - -Additionally, a few extra python commands have been created for use without these conversions: - -^^^^^^^^^^^^^^^^ -bind -^^^^^^^^^^^^^^^^ - -The python version of the bind command is used to create a bind that triggers a python function. The python bind takes the same arguments as the Tcl binds, but here each argument is passed individually. For example, a bind that would look like ``bind pub * !foo myproc`` in Tcl is written as ``bind("pub", "*", "!foo", myproc)``. For more information on Eggsrop bind argument syntax please see :ref:`bind_types`. The eggdrop.tcl.bind command should not be used as it will attempt to call a Tcl proc. - -^^^^^^^^^^^^^^^^^^^^^^^ -parse_tcl_list -^^^^^^^^^^^^^^^^^^^^^^^ - -When a python script calls a Tcl command that returns a list via the eggdrop.tcl module, the return value will be a Tcl-formatted list- also simply known as a string. The ``parse_tcl_list`` command will convert the Tcl-formatted list into a Python list, which can then freely be used within the Python script. - -^^^^^^^^^^^^^^^^^^^^^^^ -parse_tcl_dict -^^^^^^^^^^^^^^^^^^^^^^^ - -When a python script calls a Tcl command that returns a dict via the eggdrop.tcl module, the return value will be a Tcl-formatted dict- also simply known as a string. The ``parse_tcl_dict`` command will c -onvert the Tcl-formatted dict into a Python list, which can then freely be used within the Python script. - ----------------- -Config variables ----------------- - -There are also some variables you can set in your config file: - - set allow-resync 0 - When two bots get disconnected, this setting allows them to create a - resync buffer which saves all changes done to the userfile during - the disconnect. When they reconnect, they will not have to transfer - the complete user file, but, instead, just send the resync buffer. - --------------------------------- -Writing an Eggdrop Python script --------------------------------- - -This is how to write a python script for Eggdrop. - -You can view examples of Python scripts in the exampleScripts folder included with this module. - -.. glossary:: - - bestfriend.py - This example script demonstrates how to use the parse_tcl_list() python command to convert a list returned by a Tcl command into a list that is usable by Python. - - greet.py - This is a very basic script that demonstrates how a Python script with binds can be run by Eggdrop. - - imdb.py - This script shows how to use an existing third-party module to extend a Python script, in this case retrieving information from imdb.com. - - listtls.py - This script demonstrates how to use parse-tcl_list() and parse_tcl_dict() to convert a list of dicts provided by Tcl into something that is usable by Python. - - urltitle.py - This script shows how to use an existing third-party module to extend a Python script, in this case using an http parser to collect title information from a provided web page. - - -^^^^^^^^^^^^^^ -Header section -^^^^^^^^^^^^^^ - -An Eggdrop python script requires you to import X Y and Z, in this format. - -^^^^^^^^^^^^ -Code Section -^^^^^^^^^^^^ - -Normal python code works here. To run a command from the Eggdrop Tcl library, use this format. - -Use this format all over. - -------------------------------------- -Writing a module for use with Eggdrop -------------------------------------- - -This is how you import a module for use with an egg python script. - - -Copyright (C) 2000 - 2024 Eggheads Development Team diff --git a/doc/sphinx_source/using/python.rst b/doc/sphinx_source/using/python.rst new file mode 100644 index 000000000..520aa1810 --- /dev/null +++ b/doc/sphinx_source/using/python.rst @@ -0,0 +1,113 @@ +======================= +Using the Python Module +======================= + +In Eggdrop 1.10.0, Eggdrop was shipped with a Python module that, similar to the existing core Tcl capability, allows Eggdrop to run python scripts. + +------------------- +System Requirements +------------------- +Similar to Tcl requirements, Eggdrop requires both python and python development libraries to be installed on the host machine. On Debian/Ubuntu machines, this requires the packages python-dev AND python-is-python3 to be installed. The python-is-python3 updates symlinks on the host system that allow Eggdrop to find it. + +-------------- +Loading Python +-------------- + +Put this line into your Eggdrop configuration file to load the python module:: + + loadmodule python + +To load a python script from your config file, place the .py file in the scripts/ folder and add the following line to your config:: + + pysource scripts/myscript.py + +----------------------- +Eggdrop Python Commands +----------------------- + +The Python module is built to use the existing core Tcl commands integrated into Eggdrop via the ``eggdrop.tcl`` module. To call an existing Tcl command from Python, you can either load the entire catalog by running ``import eggdrop.tcl``, or be more specific by ``from eggdrop.tcl import putserv, putlog, chanlist``, etc. + +Arguments to the Tcl functions are automatically converted as follows: + +* ``None`` is converted to an empty Tcl object (the empty string, ``""``) +* ``List`` and ``Tuple`` is converted to a ``Tcl list`` +* ``Dict`` is converted to a ``Tcl dictionary`` +* Everything else is converted to a string using the str() method + +Return values from Tcl functions must be manually converted: + +* ``""`` the empty string is automatically converted to None +* everything else is returned as string +* ``Tcl list`` as string can be converted to a Python ``List`` using ``parse_tcl_list`` +* ``Tcl dictionary`` as string can be converted to a Python ``Dict`` using ``parse_tcl_list`` + +^^^^^^^^^^^^^^^^ +bind +^^^^^^^^^^^^^^^^ + +An important difference to note is that Eggdrop Python has its own ``bind`` command implemented. You will generally want to create binds using the Python ``bind`` command and not import bind from eggdrop.tcl because a Python bind will call a Python function, whereas using the Tcl bind will call a Tcl function (not one from the script you are writing). + +The python version of the bind command is used to create a bind that triggers a python function. The python bind takes the same arguments as the Tcl binds, but here each argument is passed individually. For example, a bind that would look like ``bind pub * !foo myproc`` in Tcl is written as ``bind("pub", "*", "!foo", myproc)``. For more information on Eggsrop bind argument syntax please see :ref:`bind_types`. The eggdrop.tcl.bind command should not be used as it will attempt to call a Tcl proc. + +^^^^^^^^^^^^^^^^^^^^^^^ +parse_tcl_list +^^^^^^^^^^^^^^^^^^^^^^^ + +When a python script calls a Tcl command that returns a list via the eggdrop.tcl module, the return value will be a Tcl-formatted list- also simply known as a string. The ``parse_tcl_list`` command will convert the Tcl-formatted list into a Python list, which can then freely be used within the Python script. + +^^^^^^^^^^^^^^^^^^^^^^^ +parse_tcl_dict +^^^^^^^^^^^^^^^^^^^^^^^ + +When a python script calls a Tcl command that returns a dict via the eggdrop.tcl module, the return value will be a Tcl-formatted dict- also simply known as a string. The ``parse_tcl_dict`` command will convert the Tcl-formatted dict into a Python list, which can then freely be used within the Python script. + +-------------------------------- +Writing an Eggdrop Python script +-------------------------------- + +Some example scripts, complete with documentation, are included with the Python module that ships with Eggdrop (src/mod/python.mod/scripts). These scripts are included to help demonstrate script formatting and usage. The scripts are: + + +.. glossary:: + + bestfriend.py + This example script demonstrates how to use the parse_tcl_list() python command to convert a list returned by a Tcl command into a list that is usable by Python. + + greet.py + This is a very basic script that demonstrates how a Python script with binds can be run by Eggdrop. + + imdb.py + This script shows how to use an existing third-party module to extend a Python script, in this case retrieving information from imdb.com. + + listtls.py + This script demonstrates how to use parse-tcl_list() and parse_tcl_dict() to convert a list of dicts provided by Tcl into something that is usable by Python. + + urltitle.py + This script shows how to use an existing third-party module to extend a Python script, in this case using an http parser to collect title information from a provided web page. + + +^^^^^^^^^^^^^^ +Header section +^^^^^^^^^^^^^^ + +Python is able to call any Tcl command by importing the ``eggdrop`` module. For example, to use the ``putlog`` command in a python script, you would import it as:: + + from eggdrop.tcl import putlog + +and then call it using:: + + putlog("This is a logged message") + + +An important difference to note is that Eggdrop Python has its own ``bind`` command implemented. You will generally want to create binds using the Python ``bind`` command and not import bind from eggdrop.tcl because a Python bind will call a Python function, whereas using the Tcl bind will call a Tcl function (not one from the script you are writing). + +Where does python print go? + +------------------------------------- +Writing a module for use with Eggdrop +------------------------------------- + +This is how you import a module for use with an egg python script. + +Copyright (C) 2000 - 2024 Eggheads Development Team + diff --git a/doc/sphinx_source/using/tcl-commands.rst b/doc/sphinx_source/using/tcl-commands.rst index 7953dccbd..339c728c3 100644 --- a/doc/sphinx_source/using/tcl-commands.rst +++ b/doc/sphinx_source/using/tcl-commands.rst @@ -1136,7 +1136,7 @@ nick2hand [channel] Module: irc ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -account2nicks [channel] +account2nicks [channel] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Returns: a de-duplicated Tcl list of the nickname(s) on the specified channel (if one is specified) whose nickname matches the given account; "" is returned if no match is found. This command will only work if a server supports (and Eggdrop has enabled) the account-notify and extended-join capabilities, and the server understands WHOX requests (also known as raw 354 responses). If no channel is specified, all channels are checked. @@ -2200,6 +2200,26 @@ setflags [ [channel]] Module: filesys +PBKDF2 Module +------------- + +^^^^^^^^^^^^^^^ +encpass2 +^^^^^^^^^^^^^^^ + + + Returns: a hash in the format of "$pbkdf2-$rounds=$$" where digest is the digest set in the config variable pbkdf2-method, rounds is the number of rounds set in the config variable pbkdf2-rounds, salt is the base64 salt used to generate the hash, and hash is the generated base64 hash. + + Module: pbkdf2 + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +pbkdf2 [-bin] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Returns: a derived key from the provided "pass" string using "salt" and "rounds" count as specified in RFC 2898 as a hexadecimal string. Using the optional -bin flag will return the result as binary data. + + Module: pbkdf2 + Miscellaneous Commands ---------------------- diff --git a/eggdrop-basic.conf b/eggdrop-basic.conf index d14753d0e..849575610 100755 --- a/eggdrop-basic.conf +++ b/eggdrop-basic.conf @@ -300,9 +300,8 @@ set ssl-capath "/etc/ssl/" ## Eggdrop, things change. ## This path specifies the path were Eggdrop should look for its modules. -## If you run the bot from the compilation directory, you will want to set -## this to "". If you use 'make install' (like all good kiddies do ;), this -## is a fine default. Otherwise, use your head :) +## If you use 'make install' (like all good kiddies do ;), this is a fine +## default. Otherwise, use your head :) set mod-path "modules/" #### CHANNELS MODULE #### @@ -416,10 +415,7 @@ if {[file exists aclocal.m4]} { die {You are attempting to run Eggdrop from the if {[info exists net-type]} { switch -- ${net-type} { - "EFnet" { - # EFnet - source scripts/quotepong.tcl - } + "EFnet" - "0" { # EFnet source scripts/quotepong.tcl diff --git a/eggdrop.conf b/eggdrop.conf index 86ac99e64..852758286 100755 --- a/eggdrop.conf +++ b/eggdrop.conf @@ -605,9 +605,8 @@ die "Please make sure you edit your config file completely." # Eggdrop, things change. # This path specifies the path were Eggdrop should look for its modules. -# If you run the bot from the compilation directory, you will want to set -# this to "". If you use 'make install' (like all good kiddies do ;), this -# is a fine default. Otherwise, use your head :) +# If you use 'make install' (like all good kiddies do ;), this is a fine +# default. Otherwise, use your head :) set mod-path "modules/" @@ -656,6 +655,7 @@ loadmodule pbkdf2 # This setting is planned to be enabled by default in Eggdrop 2.0. #set remove-pass 0 + #### BLOWFISH MODULE #### # # This module is planned to be removed in Eggdrop 2.0 @@ -676,21 +676,14 @@ loadmodule blowfish set blowfish-use-mode cbc -#### DNS MODULE (Deprecated) #### - -## This module provided asynchronous dns support, but as of v1.9.2, this -## functionality was moved into the core code. If you are having issues with the -## new DNS functionality, or just want to continue using this module, compile -## Eggdrop with the --disable-tdns flag (./configure --disdable-tdns). +#### PYTHON MODULE ##### # -## You really probably don't want to uncomment this!!!! -# -#loadmodule dns -#set dns-servers "8.8.8.8 1.1.1.1 185.222.222.222" -#set dns-cache 86400 -#set dns-negcache 600 -#set dns-maxsends 4 -#set dns-retrydelay 3 +# This module gives Eggdrop the ability to run python scripts. if loaded, +# Python scripts can be loaded at the end of the config file using the pysouce +# command to tell Eggdrop where the file is loaded. The module requires Python +# version 3.8 or higher to run. To load the python module, uncomment it below. +#loadmodule python + #### CHANNELS MODULE #### @@ -1448,6 +1441,7 @@ set xfer-timeout 30 # be v1.9.0 or higher). #set sharefail-unlink 1 + #### SHARE MODULE #### # This module provides userfile sharing support between two directly @@ -1710,10 +1704,7 @@ loadhelp userinfo.help if {[info exists net-type]} { switch -- ${net-type} { - "EFnet" { - # EFnet - source scripts/quotepong.tcl - } + "EFnet" - "0" { # EFnet source scripts/quotepong.tcl diff --git a/language/core.portuguese.lang b/language/core.portuguese.lang index e1dd8958a..c1f9afbb6 100644 --- a/language/core.portuguese.lang +++ b/language/core.portuguese.lang @@ -431,4 +431,4 @@ Entre em ligação telnet com o bot e digite 'NEW' como o seu nick. 0xe34,Timeout em ligação de identificação 0xe35,Por favor, remova o #comentário na configuração de listen e tente novamente 0xe36,Esta porta é apenas para bots -0xe37,Esta porta é apenas para utilizadores (sem bots) +0xe37,Esta porta é apenas para utilizadores (não bots) diff --git a/misc/modconfig b/misc/modconfig index 0fd07b063..a22acd9dd 100755 --- a/misc/modconfig +++ b/misc/modconfig @@ -274,7 +274,7 @@ xdetect-modules) mc_new_mod_state=enabled fi fi - if test "${mc_new_mod_state}" = enabled; then + if test "${mc_new_mod_state}" = enabled && test -n "`find $mc_mod_bin_dir/${mc_mod}.mod -name \*.c`"; then ${mc_self_call} -q add ${mc_mod} else ${mc_self_call} -q del ${mc_mod} diff --git a/misc/updatecopyright b/misc/updatecopyright index a17b5edaf..a220e45d0 100755 --- a/misc/updatecopyright +++ b/misc/updatecopyright @@ -49,8 +49,8 @@ update_copyright() { mv ${i}_ $i fi # Cats and Dogs - sed -i '/Eggdrop v%s (C) 1997 Robey Pointer/c\ "Eggdrop v%s (C) 1997 Robey Pointer (C) 2010-'$YEAR' Eggheads",' src/main.c - sed -i '/Eggdrop v%s+%s (C) 1997 Robey Pointer/c\ "Eggdrop v%s+%s (C) 1997 Robey Pointer (C) 2010-'$YEAR' Eggheads",' src/main.c + sed -i '/Eggdrop v" EGG_STRINGVER " (C) 1997 Robey Pointer (C) 1999-/c\ "Eggdrop v" EGG_STRINGVER " (C) 1997 Robey Pointer (C) 1999-'$YEAR' Eggheads Development Team",' src/main.c + sed -i '/Eggdrop v" EGG_STRINGVER "+" EGG_PATCH " (C) 1997 Robey Pointer (C) 1999-/c\ "Eggdrop v" EGG_STRINGVER "+" EGG_PATCH " (C) 1997 Robey Pointer (C) 1999-'$YEAR' Eggheads Development Team",' src/main.c } diff --git a/src/Makefile.in b/src/Makefile.in index b6254d13c..21e359131 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -6,6 +6,7 @@ srcdir = @srcdir@ VPATH = @srcdir@ @SET_MAKE@ +EGGEXEC = @EGGEXEC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ @@ -18,6 +19,8 @@ CFLAGS = @CFLAGS@ -I.. -I$(top_srcdir) @SSL_INCLUDES@ @DEFS@ $(CFLGS) CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ +XLIBS = @SSL_LIBS@ @TCL_LIB_SPEC@ @LIBS@ + eggdrop_objs = bg.o botcmd.o botmsg.o botnet.o chanprog.o cmds.o dcc.o \ dccutil.o dns.o flags.o language.o match.o main.o mem.o misc.o misc_file.o \ modules.o net.o rfc1459.o tcl.o tcldcc.o tclhash.o tclmisc.o tcluser.o \ @@ -118,13 +121,12 @@ 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/explicit_bzero.h compat/strlcpy.h \ - modules.h mod/modvals.h tandem.h md5/md5.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/explicit_bzero.h compat/strlcpy.h modules.h mod/modvals.h \ - tandem.h + compat/explicit_bzero.h compat/strlcpy.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 \ @@ -144,7 +146,7 @@ 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/explicit_bzero.h compat/strlcpy.h \ - version.h modules.h mod/modvals.h tandem.h bg.h + version.h modules.h mod/modvals.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 \ @@ -174,7 +176,8 @@ modules.o: modules.c main.h ../config.h ../eggint.h ../lush.h lang.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/explicit_bzero.h compat/strlcpy.h + ../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h \ + modules.h mod/modvals.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 \ @@ -200,13 +203,12 @@ tclmisc.o: tclmisc.c main.h ../config.h ../eggint.h ../lush.h lang.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 modules.h mod/modvals.h \ - tandem.h md5/md5.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/explicit_bzero.h compat/strlcpy.h tandem.h modules.h \ - mod/modvals.h + compat/explicit_bzero.h compat/strlcpy.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 \ diff --git a/src/botcmd.c b/src/botcmd.c index f96c02608..5474f6d57 100644 --- a/src/botcmd.c +++ b/src/botcmd.c @@ -24,8 +24,6 @@ #include "main.h" #include "tandem.h" -#include "users.h" -#include "chan.h" #include "modules.h" extern char botnetnick[], ver[], admin[], network[], motdfile[]; diff --git a/src/botnet.c b/src/botnet.c index 88484235d..bb6b4aad3 100644 --- a/src/botnet.c +++ b/src/botnet.c @@ -174,10 +174,8 @@ int addparty(char *bot, char *nick, int chan, char flag, int sock, party = nrealloc(party, party_size * sizeof(party_t)); debug1("botnet: party size doubled to %i.", party_size); } - strncpy(party[parties].nick, nick, HANDLEN); - party[parties].nick[HANDLEN] = 0; - strncpy(party[parties].bot, bot, HANDLEN); - party[parties].bot[HANDLEN] = 0; + strlcpy(party[parties].nick, nick, HANDLEN + 1); + strlcpy(party[parties].bot, bot, HANDLEN + 1); party[parties].chan = chan; party[parties].sock = sock; party[parties].status = 0; diff --git a/src/chan.h b/src/chan.h index 19a56e5a1..31b639834 100644 --- a/src/chan.h +++ b/src/chan.h @@ -50,8 +50,8 @@ typedef struct memstruct { time_t split; /* in case they were just netsplit */ time_t last; /* for measuring idle time */ time_t delay; /* for delayed autoop */ - struct userrec *user; - int tried_getuser; + struct userrec *user; /* cached user lookup */ + int tried_getuser; /* negative user lookup cache */ struct memstruct *next; } memberlist; diff --git a/src/chanprog.c b/src/chanprog.c index c4b679c07..f589593fb 100644 --- a/src/chanprog.c +++ b/src/chanprog.c @@ -116,48 +116,13 @@ struct chanset_t *findchan_by_dname(const char *name) return NULL; } - -/* - * "caching" functions - */ - -/* Shortcut for get_user_by_host -- might have user record in one - * of the channel caches. - */ -struct userrec *check_chanlist(const char *host) -{ - char *nick, *uhost, buf[UHOSTLEN]; - memberlist *m; - struct chanset_t *chan; - - strlcpy(buf, host, sizeof buf); - uhost = buf; - nick = splitnick(&uhost); - for (chan = chanset; chan; chan = chan->next) - for (m = chan->channel.member; m && m->nick[0]; m = m->next) - if (!rfc_casecmp(nick, m->nick) && !strcasecmp(uhost, m->userhost)) - return m->user; - return NULL; -} - -/* Shortcut for get_user_by_handle -- might have user record in channels - */ -struct userrec *check_chanlist_hand(const char *hand) -{ - struct chanset_t *chan; - memberlist *m; - - for (chan = chanset; chan; chan = chan->next) - for (m = chan->channel.member; m && m->nick[0]; m = m->next) - if (m->user && !strcasecmp(m->user->handle, hand)) - return m->user; - return NULL; -} - /* Clear the user pointers in the chanlists. * - * Necessary when a hostmask is added/removed, a user is added or a new - * userfile is loaded. + * Necessary when: + * - a hostmask is added/removed + * - an account is added/removed + * - a user is added + * - new userfile is loaded */ void clear_chanlist(void) { @@ -173,8 +138,9 @@ void clear_chanlist(void) /* Clear the user pointer of a specific nick in the chanlists. * - * Necessary when a hostmask is added/removed, a nick changes, etc. - * Does not completely invalidate the channel cache like clear_chanlist(). + * Necessary when: + * - their hostmask changed (chghost) + * - their account changed */ void clear_chanlist_member(const char *nick) { @@ -190,23 +156,6 @@ void clear_chanlist_member(const char *nick) } } -/* If this user@host is in a channel, set it (it was null) - */ -void set_chanlist(const char *host, struct userrec *rec) -{ - char *nick, *uhost, buf[UHOSTLEN]; - memberlist *m; - struct chanset_t *chan; - - strlcpy(buf, host, sizeof buf); - uhost = buf; - nick = splitnick(&uhost); - for (chan = chanset; chan; chan = chan->next) - for (m = chan->channel.member; m && m->nick[0]; m = m->next) - if (!rfc_casecmp(nick, m->nick) && !strcasecmp(uhost, m->userhost)) - m->user = rec; -} - /* Calculate the memory we should be using */ int expmem_chanprog() @@ -407,7 +356,7 @@ void tell_settings(int idx) void reaffirm_owners() { - char *p, *q, s[121]; + char *p, *q, s[sizeof owner]; struct userrec *u; /* Please stop breaking this function. */ diff --git a/src/cmds.c b/src/cmds.c index 708f5fde2..507c69687 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -22,6 +22,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include "main.h" #include "tandem.h" #include "modules.h" @@ -1907,11 +1908,11 @@ static int add_to_handle(struct userrec *u, int idx, char *handle, char *host, i } } if ( !type && !glob_botmast(fr) && !chan_master(fr) && get_user_by_host(host)) { - dprintf(idx, "You cannot add %s matching another user!\n", - type ? "an account" : "a host"); + dprintf(idx, "You cannot add a host matching another user!\n"); return 1; } if (type) { + // host-variable contains account u2 = get_user_by_account(host); if (u2) { dprintf(idx, "That account already exists for user %s\n", u2->handle); @@ -1919,6 +1920,7 @@ static int add_to_handle(struct userrec *u, int idx, char *handle, char *host, i } addaccount_by_handle(handle, host); } else { + // host for (q = get_user(&USERENTRY_HOSTS, u); q; q = q->next) { if (!strcasecmp(q->extra, host)) { dprintf(idx, "That %s is already there.\n", @@ -2834,6 +2836,8 @@ static void cmd_page(struct userrec *u, int idx, char *par) */ static void cmd_tcl(struct userrec *u, int idx, char *msg) { + struct rusage ru1, ru2; + int r = 0; int code; char *result; Tcl_DString dstr; @@ -2842,8 +2846,15 @@ static void cmd_tcl(struct userrec *u, int idx, char *msg) dprintf(idx, "%s", MISC_NOSUCHCMD); return; } - debug1("tcl: evaluate (.tcl): %s", msg); + debug1("tcl: evaluating .tcl %s", msg); + r = getrusage(RUSAGE_SELF, &ru1); code = Tcl_GlobalEval(interp, msg); + if (!r && !getrusage(RUSAGE_SELF, &ru2)) + debug3("tcl: evaluated .tcl %s, user %.3fms sys %.3fms", msg, + (double) (ru2.ru_utime.tv_usec - ru1.ru_utime.tv_usec) / 1000 + + (double) (ru2.ru_utime.tv_sec - ru1.ru_utime.tv_sec ) * 1000, + (double) (ru2.ru_stime.tv_usec - ru1.ru_stime.tv_usec) / 1000 + + (double) (ru2.ru_stime.tv_sec - ru1.ru_stime.tv_sec ) * 1000); /* properly convert string to system encoding. */ Tcl_DStringInit(&dstr); diff --git a/src/dcc.c b/src/dcc.c index 9030f1a02..3ce979ee5 100644 --- a/src/dcc.c +++ b/src/dcc.c @@ -25,7 +25,6 @@ #include "main.h" #include -#include "modules.h" #include "tandem.h" /* Includes for botnet md5 challenge/response code */ @@ -355,10 +354,25 @@ static void dcc_bot_digest(int idx, char *challenge, char *password) dcc[idx].nick); } +static char *get_bot_pass(struct userrec *u) { + char *pass2 = get_user(&USERENTRY_PASS2, u); + char *pass = get_user(&USERENTRY_PASS, u); + if (pass2) { + if (!pass) { + pass = pass2; + if (encrypt_pass) + set_user(&USERENTRY_PASS, u, pass); + } else if (strcmp(pass2, pass) && encrypt_pass2) + pass = pass2; + } else if (pass && encrypt_pass2) + set_user(&USERENTRY_PASS2, u, pass); + return pass; +} + static void dcc_bot_new(int idx, char *buf, int x) { struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick); - char *code, *pass2 = NULL, *pass = NULL; + char *code, *pass; if (raw_log) { if (!strncmp(buf, "s ", 2)) @@ -376,17 +390,7 @@ static void dcc_bot_new(int idx, char *buf, int x) /* We entered the wrong password */ putlog(LOG_BOTS, "*", DCC_BADPASS, dcc[idx].nick); else if (!strcasecmp(code, "passreq")) { - pass2 = get_user(&USERENTRY_PASS2, u); - pass = get_user(&USERENTRY_PASS, u); - if (pass2) { - if (!pass) { - pass = pass2; - if (encrypt_pass) - set_user(&USERENTRY_PASS, u, pass); - } else if (strcmp(pass2, pass) && encrypt_pass2) - pass = pass2; - } else if (pass && encrypt_pass2) - set_user(&USERENTRY_PASS2, u, pass); + pass = get_bot_pass(u); if (!pass || !strcmp(pass, "-")) { putlog(LOG_BOTS, "*", DCC_PASSREQ, dcc[idx].nick); dprintf(idx, "-\n"); @@ -596,7 +600,7 @@ static int dcc_bot_check_digest(int idx, char *remote_digest) char digest_string[33]; /* 32 for digest in hex + null */ unsigned char digest[16]; int i, ret; - char *password = get_user(&USERENTRY_PASS, dcc[idx].user); + char *password = get_bot_pass(dcc[idx].user); if (!password) return 1; diff --git a/src/dccutil.c b/src/dccutil.c index 17b5054e9..24cb43cfd 100644 --- a/src/dccutil.c +++ b/src/dccutil.c @@ -27,9 +27,6 @@ #include #include "main.h" -#include -#include "chan.h" -#include "modules.h" #include "tandem.h" extern struct dcc_t *dcc; diff --git a/src/dns.c b/src/dns.c index 2e5035b88..69b3a03e5 100644 --- a/src/dns.c +++ b/src/dns.c @@ -492,6 +492,8 @@ void call_ipbyhost(char *hostn, sockname_t *ip, int ok) * is closed and the thread is ended by return. The other end will make * eggdrops mainloop select() return, read the result from the dns_thread_node * and call call_hostbyip() or call_ipbyhost(). No signal or tcl thread problem. + * + * defer debug() / putlog() from dns threads to main thread via dtn.strerror */ void *thread_dns_hostbyip(void *arg) @@ -502,8 +504,10 @@ void *thread_dns_hostbyip(void *arg) i = getnameinfo((const struct sockaddr *) &addr->addr.sa, addr->addrlen, dtn->host, sizeof dtn->host, NULL, 0, 0); - if (i) { - debug1("dns: thread_dns_hostbyip(): getnameinfo(): error = %s", gai_strerror(i)); + if (!i) + *dtn->strerror = 0; + else { + snprintf(dtn->strerror, sizeof dtn->strerror, "dns: thread_dns_hostbyip(): getnameinfo(): %s", gai_strerror(i)); #ifdef IPV6 if (addr->family == AF_INET6) inet_ntop(AF_INET6, &addr->addr.s6.sin6_addr, dtn->host, sizeof dtn->host); @@ -512,7 +516,6 @@ void *thread_dns_hostbyip(void *arg) inet_ntop(AF_INET, &addr->addr.s4.sin_addr.s_addr, dtn->host, sizeof dtn->host); } pthread_mutex_lock(&dtn->mutex); - dtn->ok = !i; close(dtn->fildes[1]); pthread_mutex_unlock(&dtn->mutex); return NULL; @@ -528,6 +531,7 @@ void *thread_dns_ipbyhost(void *arg) error = getaddrinfo(dtn->host, NULL, NULL, &res0); memset(addr, 0, sizeof *addr); if (!error) { + *dtn->strerror = 0; #ifdef IPV6 for (res = res0; res; res = res->ai_next) { if (res == res0 || res->ai_family == (pref_af ? AF_INET6 : AF_INET)) { @@ -545,21 +549,25 @@ void *thread_dns_ipbyhost(void *arg) addr->family = res->ai_family; addr->addrlen = res->ai_addrlen; memcpy(&addr->addr.sa, res->ai_addr, res->ai_addrlen); - error = 0; + error = 0; + *dtn->strerror = 0; break; } } + if (error) + snprintf(dtn->strerror, sizeof dtn->strerror, "dns: thread_dns_ipbyhost(): no ipv4"); #endif if (res0) /* The behavior of freeadrinfo(NULL) is left unspecified by RFCs * 2553 and 3493. Avoid to be compatible with all OSes. */ freeaddrinfo(res0); } else if (error == EAI_NONAME) - debug1("dns: thread_dns_ipbyhost(): getaddrinfo(): hostname %s not known", dtn->host); + 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)); else - debug1("dns: thread_dns_ipbyhost(): getaddrinfo(): error = %s", gai_strerror(error)); + snprintf(dtn->strerror, sizeof dtn->strerror, "dns: thread_dns_ipbyhost(): getaddrinfo(): %s", gai_strerror(error)); pthread_mutex_lock(&dtn->mutex); - dtn->ok = !error; close(dtn->fildes[1]); pthread_mutex_unlock(&dtn->mutex); return NULL; @@ -726,7 +734,7 @@ static int tcl_dnslookup STDVAR tcl_dnshostbyip(&addr, argv[2], Tcl_DStringValue(¶s)); else { if (strlen(argv[1]) > 255) { - Tcl_AppendResult(irp, "hostname too long. max 255 chars.", NULL); + Tcl_SetResult(irp, "hostname too long. max 255 chars.", TCL_STATIC); return TCL_ERROR; } tcl_dnsipbyhost(argv[1], argv[2], Tcl_DStringValue(¶s)); diff --git a/src/eggdrop.h b/src/eggdrop.h index 076a16252..c91ae91e2 100644 --- a/src/eggdrop.h +++ b/src/eggdrop.h @@ -89,13 +89,6 @@ #define PASSWORDMAX 30 /* highest value compatible to older eggdrop */ #define PASSWORDLEN PASSWORDMAX + 1 - -/* We have to generate compiler errors in a weird way since not all compilers - * support the #error preprocessor directive. */ -#ifndef STDC_HEADERS -# include "Error: Your system must have standard ANSI C headers." -#endif - #ifdef HAVE_UNISTD_H # include #endif @@ -190,12 +183,8 @@ #endif /* Almost every module needs some sort of time thingy, so... */ -#ifdef HAVE_SYS_TIME_H -# include -#else -# include -#endif - +#include /* gettimeofday() POSIX 2001 */ +#include /* POSIX 2001 */ /* Yikes...who would have thought finding a usable random() would be so much * trouble? @@ -757,7 +746,7 @@ struct dns_thread_node { int type; sockname_t addr; char host[256]; - int ok; + char strerror[3 * 64]; /* msg + gai_strerror() + strerror() */ struct dns_thread_node *next; }; diff --git a/src/flags.c b/src/flags.c index aea4ec9b2..b7bb0bd86 100644 --- a/src/flags.c +++ b/src/flags.c @@ -1419,7 +1419,7 @@ static int botfl_tcl_get(Tcl_Interp *interp, struct userrec *u, fr.bot = e->u.ulong; build_flags(x, &fr, NULL); - Tcl_AppendResult(interp, x, NULL); + Tcl_SetResult(interp, x, TCL_STATIC); return TCL_OK; } diff --git a/src/language.c b/src/language.c index 7056311a2..534aace7b 100644 --- a/src/language.c +++ b/src/language.c @@ -649,7 +649,7 @@ static int tcl_language STDVAR strcpy(buf, argv[1]); if (!split_lang(buf, &lang, §ion)) { - Tcl_AppendResult(irp, "Invalid parameter", NULL); + Tcl_SetResult(irp, "Invalid parameter", TCL_STATIC); nfree(buf); return TCL_ERROR; } @@ -677,7 +677,7 @@ static int tcl_mnslang STDVAR BADARGS(2, 2, " language"); if (!del_lang(argv[1])) { - Tcl_AppendResult(irp, "Language not found.", NULL); + Tcl_SetResult(irp, "Language not found.", TCL_STATIC); return TCL_ERROR; } recheck_lang_sections(); @@ -698,7 +698,7 @@ static int tcl_dellangsection STDVAR BADARGS(2, 2, " section"); if (!del_lang_section(argv[1])) { - Tcl_AppendResult(irp, "Section not found", NULL); + Tcl_SetResult(irp, "Section not found", TCL_STATIC); return TCL_ERROR; } return TCL_OK; diff --git a/src/main.c b/src/main.c index f698606a0..0b321d025 100644 --- a/src/main.c +++ b/src/main.c @@ -53,12 +53,6 @@ #include #include -#ifdef HAVE_SYS_TIME_H -# include -#else -# include -#endif - #ifdef STOP_UAC /* OSF/1 complains a lot */ # include # define UAC_NOPRINT 0x00000001 /* Don't report unaligned fixups */ @@ -67,7 +61,6 @@ #include "version.h" #include "chan.h" #include "modules.h" -#include "tandem.h" #include "bg.h" #ifdef DEBUG /* For debug compile */ @@ -130,7 +123,7 @@ int make_userfile = 0; /* Using bot in userfile-creation mode? */ int save_users_at = 0; /* Minutes past the hour to save the userfile? */ int notify_users_at = 0; /* Minutes past the hour to notify users of notes? */ -char version[81]; /* Version info (long form) */ +char version[128]; /* Version info (long form) */ char ver[41]; /* Version info (short form) */ volatile sig_atomic_t do_restart = 0; /* .restart has been called, restart ASAP */ @@ -303,10 +296,10 @@ static void write_debug() tcl_resultstring() : "*unknown*"); /* info tclversion/patchlevel */ - dprintf(-x, "Tcl version: %s (header version %s)\n", + dprintf(-x, "Tcl version: %s (header version " TCL_PATCH_LEVEL ")\n", ((interp) && (Tcl_Eval(interp, "info patchlevel") == TCL_OK)) ? tcl_resultstring() : (Tcl_Eval(interp, "info tclversion") == TCL_OK) ? - tcl_resultstring() : "*unknown*", TCL_PATCH_LEVEL); + tcl_resultstring() : "*unknown*"); if (tcl_threaded()) dprintf(-x, "Tcl is threaded\n"); @@ -565,6 +558,7 @@ static void core_secondly() int miltime; time_t nowmins; int i; + uint64_t drift_mins; do_check_timers(&utimer); /* Secondly timers */ cnt++; @@ -595,14 +589,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 (%" PRId64 " seconds)", (int64_t) (nowmins - lastmin)); + drift_mins = nowmins - lastmin; + debug2("timer: drift (%" PRId64 " minute%s)", drift_mins, drift_mins == 1 ? "" : "s"); i++; ++lastmin; call_hook(HOOK_MINUTELY); } - if (i > 1) - putlog(LOG_MISC, "*", "(!) timer drift -- spun %" PRId64 " minutes", - ((int64_t) (nowmins - lastmin)) / 60); + if (i) + putlog(LOG_MISC, "*", "(!) timer drift -- spun %i minute%s", i, i == 1 ? "" : "s"); miltime = (nowtm.tm_hour * 100) + (nowtm.tm_min); if (((int) (nowtm.tm_min / 5) * 5) == (nowtm.tm_min)) { /* 5 min */ call_hook(HOOK_5MINUTELY); @@ -722,7 +716,8 @@ int init_userent(); int init_misc(); int init_bots(); int init_modules(); -void init_tcl(int, char **); +void init_tcl0(int, char **); +void init_tcl1(int, char **); void init_language(int); #ifdef TLS int ssl_init(); @@ -893,14 +888,17 @@ static void mainloop(int toplevel) } kill_tcl(); - init_tcl(argc, argv); + init_tcl1(argc, argv); init_language(0); /* this resets our modules which we didn't unload (encryption and uptime) */ for (p = module_list; p; p = p->next) { if (p->funcs) { startfunc = p->funcs[MODCALL_START]; - startfunc(NULL); + if (startfunc) + startfunc(NULL); + else + debug2("module: %s: %s", p->name, MOD_NOSTARTDEF); } } @@ -978,15 +976,15 @@ int main(int arg_c, char **arg_v) #ifdef EGG_PATCH egg_snprintf(egg_version, sizeof egg_version, "%s+%s %u", EGG_STRINGVER, EGG_PATCH, egg_numver); egg_snprintf(ver, sizeof ver, "eggdrop v%s+%s", EGG_STRINGVER, EGG_PATCH); - egg_snprintf(version, sizeof version, - "Eggdrop v%s+%s (C) 1997 Robey Pointer (C) 2010-2024 Eggheads", - EGG_STRINGVER, EGG_PATCH); + strlcpy(version, + "Eggdrop v" EGG_STRINGVER "+" EGG_PATCH " (C) 1997 Robey Pointer (C) 1999-2024 Eggheads Development Team", + sizeof version); #else egg_snprintf(egg_version, sizeof egg_version, "%s %u", EGG_STRINGVER, egg_numver); egg_snprintf(ver, sizeof ver, "eggdrop v%s", EGG_STRINGVER); - egg_snprintf(version, sizeof version, - "Eggdrop v%s (C) 1997 Robey Pointer (C) 2010-2024 Eggheads", - EGG_STRINGVER); + strlcpy(version, + "Eggdrop v" EGG_STRINGVER " (C) 1997 Robey Pointer (C) 1999-2024 Eggheads Development Team", + sizeof version); #endif /* For OSF/1 */ @@ -1025,6 +1023,10 @@ int main(int arg_c, char **arg_v) sigaction(SIGILL, &sv, NULL); sv.sa_handler = got_alarm; sigaction(SIGALRM, &sv, NULL); + // Added for python.mod because the _signal handler otherwise overwrites it + // see https://discuss.python.org/t/asyncio-skipping-signal-handling-setup-during-import-for-python-embedded-context/37054/6 + sv.sa_handler = got_term; + sigaction(SIGINT, &sv, NULL); /* Initialize variables and stuff */ now = time(NULL); @@ -1034,6 +1036,7 @@ int main(int arg_c, char **arg_v) init_mem(); if (argc > 1) do_arg(); + init_tcl0(argc, argv); init_language(1); printf("\n%s\n", version); @@ -1053,7 +1056,7 @@ int main(int arg_c, char **arg_v) init_modules(); if (backgrd) bg_prepare_split(); - init_tcl(argc, argv); + init_tcl1(argc, argv); init_language(0); #ifdef STATIC link_statics(); diff --git a/src/main.h b/src/main.h index d9c3cc50d..79d388492 100644 --- a/src/main.h +++ b/src/main.h @@ -41,15 +41,18 @@ #include "eggint.h" #include "lush.h" +#ifndef TCL_SIZE_MAX + typedef int Tcl_Size; +# define Tcl_GetSizeIntFromObj Tcl_GetIntFromObj +# define TCL_SIZE_MAX INT_MAX +# define TCL_SIZE_MODIFIER "" +#endif + #ifndef TCL_PATCH_LEVEL # define TCL_PATCH_LEVEL "*unknown*" #endif -#ifdef CONST -# define EGG_CONST CONST -#else -# define EGG_CONST -#endif +#define EGG_CONST const #ifdef CONST86 # define TCL_CONST86 CONST86 @@ -57,12 +60,7 @@ # define TCL_CONST86 #endif -#ifdef HAVE_STDARG_H -# include -#else -# error "Must have stdarg.h" -#endif - +#include #include #include #include diff --git a/src/misc.c b/src/misc.c index ee7ffc3d6..1c521475e 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1422,6 +1422,7 @@ void make_rand_str(char *s, const int len) /* Convert an octal string into a decimal integer value. If the string * is empty or contains non-octal characters, -1 is returned. + * Deprecated, use strtol() instead. */ int oatoi(const char *octal) { diff --git a/src/mod/channels.mod/channels.c b/src/mod/channels.mod/channels.c index 95fed762b..d5d849879 100644 --- a/src/mod/channels.mod/channels.c +++ b/src/mod/channels.mod/channels.c @@ -737,7 +737,7 @@ static char *traced_globchanset(ClientData cdata, Tcl_Interp *irp, EGG_CONST char *name1, EGG_CONST char *name2, int flags) { - int i, items; + Tcl_Size i, items; char *t, *s; EGG_CONST char **item, *s2; diff --git a/src/mod/channels.mod/cmdschan.c b/src/mod/channels.mod/cmdschan.c index 4d96630a7..d613f43a9 100644 --- a/src/mod/channels.mod/cmdschan.c +++ b/src/mod/channels.mod/cmdschan.c @@ -1191,7 +1191,7 @@ static void cmd_mns_chrec(struct userrec *u, int idx, char *par) static void cmd_pls_chan(struct userrec *u, int idx, char *par) { - int i, argc; + Tcl_Size i, argc; EGG_CONST char **argv; char *chname; struct chanset_t *chan; diff --git a/src/mod/channels.mod/tclchan.c b/src/mod/channels.mod/tclchan.c index 512702703..f40f9f8d2 100644 --- a/src/mod/channels.mod/tclchan.c +++ b/src/mod/channels.mod/tclchan.c @@ -1013,7 +1013,7 @@ static int tcl_channel_getlist(Tcl_Interp *irp, struct chanset_t *chan) { char s[121], *str; EGG_CONST char **argv = NULL; - int argc = 0; + Tcl_Size argc = 0; struct udef_struct *ul; /* String values first */ @@ -1133,7 +1133,7 @@ static int tcl_channel_get(Tcl_Interp *irp, struct chanset_t *chan, { char s[121], *str = NULL; EGG_CONST char **argv = NULL; - int argc = 0; + Tcl_Size argc = 0; struct udef_struct *ul; if (!strcmp(setting, "chanmode")) @@ -1998,17 +1998,17 @@ static void init_masklist(masklist *m) static void init_channel(struct chanset_t *chan, int reset) { int flags = reset ? reset : CHAN_RESETALL; + memberlist *m, *m1; if (flags & CHAN_RESETWHO) { - if (chan->channel.member) { - nfree(chan->channel.member); + for (m = chan->channel.member; m; m = m1) { + m1 = m->next; + nfree(m); } chan->channel.members = 0; chan->channel.member = nmalloc(sizeof *chan->channel.member); /* Since we don't have channel_malloc, manually bzero */ egg_bzero(chan->channel.member, sizeof *chan->channel.member); - chan->channel.member->nick[0] = 0; - chan->channel.member->next = NULL; } if (flags & CHAN_RESETMODES) { @@ -2089,7 +2089,7 @@ static void clear_channel(struct chanset_t *chan, int reset) */ static int tcl_channel_add(Tcl_Interp *irp, char *newname, char *options) { - int items; + Tcl_Size items; int ret = TCL_OK; int join = 0; char buf[2048], buf2[256]; diff --git a/src/mod/channels.mod/userchan.c b/src/mod/channels.mod/userchan.c index 12d5c3202..2bac2ac3a 100644 --- a/src/mod/channels.mod/userchan.c +++ b/src/mod/channels.mod/userchan.c @@ -1270,12 +1270,7 @@ static int expired_mask(struct chanset_t *chan, char *who) * present in the channel and has op. */ - if (m->user) - u = m->user; - else { - simple_sprintf(buf, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(buf); - } + u = get_user_from_member(m); /* Do not expire masks set by bots. */ if (u && u->flags & USER_BOT) return 0; diff --git a/src/mod/compress.mod/compress.c b/src/mod/compress.mod/compress.c index e94124fed..c4a86fb76 100644 --- a/src/mod/compress.mod/compress.c +++ b/src/mod/compress.mod/compress.c @@ -396,7 +396,7 @@ static int compress_report(int idx, int details) if (details) { int size = compress_expmem(); - dprintf(idx, " zlib version %s\n", ZLIB_VERSION); + dprintf(idx, " zlib version: %s (header version " ZLIB_VERSION ")\n", zlibVersion()); dprintf(idx, " %u file%s compressed\n", compressed_files, (compressed_files != 1) ? "s" : ""); dprintf(idx, " %u file%s uncompressed\n", uncompressed_files, diff --git a/src/mod/compress.mod/configure b/src/mod/compress.mod/configure index e95014b1d..21927d124 100755 --- a/src/mod/compress.mod/configure +++ b/src/mod/compress.mod/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac 1b958239. +# From configure.ac 4af46aa3. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for Eggdrop Compress Module 1.9.5. # diff --git a/src/mod/console.mod/console.c b/src/mod/console.mod/console.c index d54f93751..c91d11e59 100644 --- a/src/mod/console.mod/console.c +++ b/src/mod/console.mod/console.c @@ -25,7 +25,6 @@ #define MAKING_CONSOLE #include "src/mod/module.h" -#include #include "console.h" static Function *global = NULL; @@ -134,13 +133,12 @@ static int console_set(struct userrec *u, struct user_entry *e, void *buf) return 1; } -static int console_tcl_format(char *work, struct console_info *i) +static void console_tcl_format(char *work, struct console_info *i) { simple_sprintf(work, "%s %s %s %d %d %d", i->channel, masktype(i->conflags), stripmasktype(i->stripflags), i->echoflags, i->page, i->conchan); - return 0; } static int console_tcl_get(Tcl_Interp *irp, struct userrec *u, @@ -149,7 +147,7 @@ static int console_tcl_get(Tcl_Interp *irp, struct userrec *u, char work[1024]; console_tcl_format(work, e->u.extra); - Tcl_AppendResult(irp, work, NULL); + Tcl_SetResult(irp, work, TCL_STATIC); return TCL_OK; } diff --git a/src/mod/dns.mod/configure b/src/mod/dns.mod/configure index 894006d91..54e38bf94 100755 --- a/src/mod/dns.mod/configure +++ b/src/mod/dns.mod/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac 1b958239. +# From configure.ac 4af46aa3. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for Eggdrop DNS Module 1.9.5. # diff --git a/src/mod/filesys.mod/files.c b/src/mod/filesys.mod/files.c index f6c26edfc..edc491e3d 100644 --- a/src/mod/filesys.mod/files.c +++ b/src/mod/filesys.mod/files.c @@ -425,6 +425,12 @@ static void cmd_reget_get(int idx, char *par, int resend) long where = 0; int nicklen = NICKLEN; + if (!par[0]) { + dprintf(idx, "%s: %sget [nickname]\n", MISC_USAGE, + resend ? "re" : ""); + return; + } + what = newsplit(&par); /* Get the nick length if necessary. */ if (NICKLEN > 9) { module_entry *me = module_find("server", 1, 1); @@ -432,12 +438,6 @@ static void cmd_reget_get(int idx, char *par, int resend) if (me && me->funcs) nicklen = (*(int *)me->funcs[SERVER_NICKLEN]); } - if (!par[0]) { - dprintf(idx, "%s: %sget [nickname]\n", MISC_USAGE, - resend ? "re" : ""); - return; - } - what = newsplit(&par); if (strlen(par) > nicklen) { dprintf(idx, "%s", FILES_BADNICK); return; diff --git a/src/mod/filesys.mod/filesys.c b/src/mod/filesys.mod/filesys.c index 2db7aec92..dcaafef76 100644 --- a/src/mod/filesys.mod/filesys.c +++ b/src/mod/filesys.mod/filesys.c @@ -48,12 +48,6 @@ # endif #endif -#ifdef HAVE_SYS_TIME_H -# include -#else -# include -#endif - #include "filedb3.h" #include "filesys.h" #include "src/tandem.h" @@ -212,11 +206,14 @@ static void dcc_files_pass(int idx, char *buf, int x) */ static int got_files_cmd(int idx, char *msg) { + const char *filt; char *code; - strcpy(msg, check_tcl_filt(idx, msg)); - if (!msg[0]) + filt = check_tcl_filt(idx, msg); + if (!filt[0]) return 1; + if (filt != msg) + strcpy(msg, filt); if (msg[0] == '.') msg++; code = newsplit(&msg); @@ -225,13 +222,17 @@ static int got_files_cmd(int idx, char *msg) static void dcc_files(int idx, char *buf, int i) { + const char*filt; + if (buf[0] && detect_dcc_flood(&dcc[idx].timeval, dcc[idx].u.file->chat, idx)) return; dcc[idx].timeval = now; - strcpy(buf, check_tcl_filt(idx, buf)); - if (!buf[0]) + filt = check_tcl_filt(idx, buf); + if (!filt[0]) return; + if (filt != buf) + strcpy(buf, filt); touch_laston(dcc[idx].user, "filearea", now); if (buf[0] == ',') { for (i = 0; i < dcc_total; i++) { diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c index 0a80927e9..9124d428c 100644 --- a/src/mod/irc.mod/chan.c +++ b/src/mod/irc.mod/chan.c @@ -110,12 +110,14 @@ static void setaccount(char *nick, char *account) } else { putlog(LOG_MODES, chan->dname, "%s!%s logged in to their account %s", nick, m->userhost, account); } - check_tcl_account(m->nick, m->userhost, m->user, chan->dname, account); + check_tcl_account(m->nick, m->userhost, get_user_from_member(m), chan->dname, account); } strlcpy(m->account, account, sizeof m->account); } } } + /* Username for nick could be different after account change, invalidate cache */ + clear_chanlist_member(nick); } /* Returns the current channel mode. @@ -207,9 +209,11 @@ static void do_mask(struct chanset_t *chan, masklist *m, char *mask, char mode) /* This is a clone of detect_flood, but works for channel specificity now * and handles kick & deop as well. + * + * victim for flood-deop, account for flood-join */ static int detect_chan_flood(char *floodnick, char *floodhost, char *from, - struct chanset_t *chan, int which, char *victim) + struct chanset_t *chan, int which, char *victim_or_account) { char h[NICKMAX+UHOSTLEN+1], ftype[12], *p; struct userrec *u; @@ -236,7 +240,8 @@ static int detect_chan_flood(char *floodnick, char *floodhost, char *from, if (!m && (which != FLOOD_JOIN)) return 0; - get_user_flagrec(get_user_by_host(from), &fr, chan->dname); + u = lookup_user_record(m, victim_or_account, from); + get_user_flagrec(u, &fr, chan->dname); if (glob_bot(fr) || ((which == FLOOD_DEOP) && (glob_master(fr) || chan_master(fr)) && (glob_friend(fr) || chan_friend(fr))) || ((which == FLOOD_KICK) && (glob_master(fr) || chan_master(fr)) && @@ -307,10 +312,10 @@ static int detect_chan_flood(char *floodnick, char *floodhost, char *from, } /* Deop'n the same person, sillyness ;) - so just ignore it */ if (which == FLOOD_DEOP) { - if (!rfc_casecmp(chan->deopd, victim)) + if (!rfc_casecmp(chan->deopd, victim_or_account)) return 0; else - strlcpy(chan->deopd, victim, sizeof chan->deopd); + strlcpy(chan->deopd, victim_or_account, sizeof chan->deopd); } chan->floodnum[which]++; if (chan->floodnum[which] >= thr) { /* FLOOD */ @@ -320,7 +325,6 @@ static int detect_chan_flood(char *floodnick, char *floodhost, char *from, chan->floodwho[which][0] = 0; if (which == FLOOD_DEOP) chan->deopd[0] = 0; - u = get_user_by_host(from); if (check_tcl_flud(floodnick, floodhost, u, ftype, chan->dname)) return 0; switch (which) { @@ -425,8 +429,7 @@ static void kick_all(struct chanset_t *chan, char *hostmask, char *comment, flushed = 0; kicknick[0] = 0; for (m = chan->channel.member; m && m->nick[0]; m = m->next) { - sprintf(s, "%s!%s", m->nick, m->userhost); - get_user_flagrec(m->user ? m->user : get_user_by_host(s), &fr, chan->dname); + get_user_flagrec(get_user_from_member(m), &fr, chan->dname); if ((me_op(chan) || (me_halfop(chan) && !chan_hasop(m))) && match_addr(hostmask, s) && !chan_sentkick(m) && !match_my_nick(m->nick) && !chan_issplit(m) && @@ -474,10 +477,7 @@ static void refresh_ban_kick(struct chanset_t *chan, char *user, char *nick) if (match_addr(b->mask, user)) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; char c[512]; /* The ban comment. */ - char s[NICKMAX+UHOSTLEN+1]; - - sprintf(s, "%s!%s", m->nick, m->userhost); - get_user_flagrec(m->user ? m->user : get_user_by_host(s), &fr, + get_user_flagrec(get_user_from_member(m), &fr, chan->dname); if (!glob_friend(fr) && !chan_friend(fr)) { add_mode(chan, '-', 'o', nick); /* Guess it can't hurt. */ @@ -869,7 +869,7 @@ static void check_this_member(struct chanset_t *chan, char *nick, (me_op(chan) || (me_halfop(chan) && !chan_hasop(m)))) { check_exemptlist(chan, s); quickban(chan, m->userhost); - p = get_user(&USERENTRY_COMMENT, m->user); + p = get_user(&USERENTRY_COMMENT, get_user_from_member(m)); dprintf(DP_SERVER, "KICK %s %s :%s\n", chan->name, m->nick, p ? p : IRC_POLITEKICK); m->flags |= SENTKICK; @@ -888,8 +888,7 @@ static void check_this_user(char *hand, int delete, char *host) for (chan = chanset; chan; chan = chan->next) for (m = chan->channel.member; m && m->nick[0]; m = m->next) { - sprintf(s, "%s!%s", m->nick, m->userhost); - u = m->user ? m->user : get_user_by_host(s); + u = get_user_from_member(m); if ((u && !strcasecmp(u->handle, hand) && delete < 2) || (!u && delete == 2 && match_addr(host, s))) { u = delete ? NULL : u; @@ -904,8 +903,8 @@ static void check_this_user(char *hand, int delete, char *host) static void recheck_channel(struct chanset_t *chan, int dobans) { memberlist *m; - char s[NICKMAX+UHOSTLEN+1]; struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; + struct userrec *u; static int stacking = 0; int stop_reset = 0; @@ -915,12 +914,8 @@ static void recheck_channel(struct chanset_t *chan, int dobans) stacking++; /* Okay, sort through who needs to be deopped. */ for (m = chan->channel.member; m && m->nick[0]; m = m->next) { - sprintf(s, "%s!%s", m->nick, m->userhost); - if (!m->user && !m->tried_getuser) { - m->tried_getuser = 1; - m->user = get_user_by_host(s); - } - get_user_flagrec(m->user, &fr, chan->dname); + u = get_user_from_member(m); + get_user_flagrec(u, &fr, chan->dname); if (glob_bot(fr) && chan_hasop(m) && !match_my_nick(m->nick)) stop_reset = 1; /* Perhaps we were halfop and tried to halfop/kick the user earlier but @@ -1084,7 +1079,6 @@ static int got352or4(struct chanset_t *chan, char *user, char *host, simple_sprintf(m->userhost, "%s@%s", user, host); simple_sprintf(userhost, "%s!%s", nick, m->userhost); /* Combine n!u@h */ - m->user = NULL; /* No handle match (yet) */ if (match_my_nick(nick)) /* Is it me? */ strcpy(botuserhost, m->userhost); /* Yes, save my own userhost */ m->flags |= WHO_SYNCED; @@ -1115,7 +1109,6 @@ static int got352or4(struct chanset_t *chan, char *user, char *host, if (chan->need_op[0]) do_tcl("need-op", chan->need_op); } - m->user = get_user_by_host(userhost); /* Update accountname in channel records, 0 means logged out */ /* A 0 is not a change from "" */ @@ -1214,13 +1207,13 @@ static int got354(char *from, char *msg) } return 0; } - + /* React to IRCv3 CHGHOST command. CHGHOST changes the hostname and/or * ident of the user. Format: * :geo!awesome@eggdrop.com CHGHOST tehgeo foo.io * changes user hostmask to tehgeo@foo.io */ -static int gotchghost(char *from, char *msg){ +static int gotchghost(char *from, char *msg) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; struct userrec *u; struct chanset_t *chan; @@ -1234,20 +1227,21 @@ static int gotchghost(char *from, char *msg){ if (match_my_nick(nick)) { snprintf(botuserhost, UHOSTMAX, "%s@%s", ident, msg); } - u = get_user_by_host(from); /* Run the bind for each channel the user is on */ for (chan = chanset; chan; chan = chan->next) { chname = chan->dname; m = ismember(chan, nick); if (m) { + u = get_user_from_member(m); snprintf(m->userhost, sizeof m->userhost, "%s@%s", ident, msg); snprintf(mask, sizeof mask, "%s %s!%s@%s", chname, nick, ident, msg); check_tcl_chghost(nick, from, mask, u, chname, ident, msg); - get_user_flagrec(m->user ? m->user : get_user_by_host(s1), &fr, - chan->dname); + get_user_flagrec(u, &fr, chan->dname); check_this_member(chan, m->nick, &fr); } } + /* Username for nick could be different after host change, invalidate cache */ + clear_chanlist_member(nick); return 0; } @@ -1309,7 +1303,7 @@ static int got353(char *from, char *msg) } return 0; } - + /* React to 396 numeric (HOSTHIDDEN), sent when user mode +x (hostmasking) was * successfully set. Format: * :barjavel.freenode.net 396 BeerBot unaffiliated/geo/bot/beerbot :is now your hidden host (set by services.) @@ -1400,12 +1394,12 @@ static int gotaway(char *from, char *msg) strlcpy(s1, from, sizeof buf); nick = splitnick(&s1); - u = get_user_by_host(from); /* Run the bind for each channel the user is on */ for (chan = chanset; chan; chan = chan->next) { chname = chan->dname; m = ismember(chan, nick); if (m) { + u = get_user_from_member(m); snprintf(mask, sizeof mask, "%s %s", chname, from); check_tcl_ircaway(nick, from, mask, u, chname, msg); if (strlen(msg)) { @@ -1831,7 +1825,6 @@ static int gottopic(char *from, char *msg) chname = newsplit(&msg); fixcolon(msg); - u = get_user_by_host(from); nick = splitnick(&from); chan = findchan(chname); if (chan) { @@ -1841,6 +1834,7 @@ static int gottopic(char *from, char *msg) if (m != NULL) m->last = now; set_topic(chan, msg); + u = lookup_user_record(m, NULL, from); // TODO: get account from msgtags check_tcl_topc(nick, from, u, chan->dname, msg); } return 0; @@ -1942,28 +1936,27 @@ static void set_delay(struct chanset_t *chan, char *nick) */ static int gotjoin(char *from, char *channame) { - char *nick, *p, buf[UHOSTLEN], *uhost = buf, *chname; + char *nick, *p, buf[UHOSTLEN], *uhost = buf, *chname, *account = NULL; char *ch_dname = NULL; - int extjoin = 0; struct chanset_t *chan; memberlist *m; masklist *b; - struct capability *current; + int extjoin = 0; + struct capability *captmp; struct userrec *u; struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; - /* Check if extended-join CAP is enabled */ - current = cap; - while (current != NULL) { - if (!strcasecmp("extended-join", current->name)) { - extjoin = current->enabled ? 1 : 0; - } - current = current->next; - } + captmp = find_capability("extended-join"); + extjoin = captmp && captmp->enabled; + strlcpy(uhost, from, sizeof buf); nick = splitnick(&uhost); chname = newsplit(&channame); - if (!extjoin) { + if (extjoin) { + // :nick!user@host JOIN #chan account :realname + account = newsplit(&channame); + } else { + // :nick!user@host JOIN :#chan fixcolon(chname); } chan = findchan_by_dname(chname); @@ -2014,7 +2007,8 @@ static int gotjoin(char *from, char *channame) } } else if (!channel_pending(chan)) { chan->status &= ~CHAN_STOP_CYCLE; - detect_chan_flood(nick, uhost, from, chan, FLOOD_JOIN, NULL); + + detect_chan_flood(nick, uhost, from, chan, FLOOD_JOIN, extjoin ? account : NULL); chan = findchan(chname); if (!chan) { @@ -2027,9 +2021,6 @@ static int gotjoin(char *from, char *channame) /* The channel doesn't exist anymore, so get out of here. */ goto exit; - /* Grab last time joined before we update it */ - u = get_user_by_host(from); - get_user_flagrec(u, &fr, chan->dname); /* Lam: fix to work with !channels */ if (!channel_active(chan) && !match_my_nick(nick)) { /* uh, what?! i'm on the channel?! */ putlog(LOG_MISC, chan->dname, @@ -2041,6 +2032,8 @@ static int gotjoin(char *from, char *channame) } else { m = ismember(chan, nick); if (m && m->split && !strcasecmp(m->userhost, uhost)) { + u = get_user_from_member(m); + get_user_flagrec(u, &fr, chan->dname); check_tcl_rejn(nick, uhost, u, chan->dname); chan = findchan(chname); @@ -2055,12 +2048,11 @@ static int gotjoin(char *from, char *channame) goto exit; /* The tcl binding might have deleted the current user. Recheck. */ - u = get_user_by_host(from); + u = get_user_from_member(m); m->split = 0; m->last = now; m->delay = 0L; m->flags = (chan_hasop(m) ? WASOP : 0) | (chan_hashalfop(m) ? WASHALFOP : 0); - m->user = u; set_handle_laston(chan->dname, u, now); m->flags |= STOPWHO; putlog(LOG_JOIN, chan->dname, "%s (%s) returned to %s.", nick, uhost, @@ -2076,19 +2068,20 @@ static int gotjoin(char *from, char *channame) m->delay = 0L; strlcpy(m->nick, nick, sizeof m->nick); strlcpy(m->userhost, uhost, sizeof m->userhost); - m->user = u; m->flags |= STOPWHO; if (extjoin) { + u = lookup_user_record(m, account, from); /* calls check_tcl_account which can delete the channel */ - setaccount(nick, newsplit(&channame)); - + setaccount(nick, account); + if (!(chan = findchan(chname)) && !(chan = findchan_by_dname(ch_dname ? ch_dname : chname))) { /* The channel doesn't exist anymore, so get out of here. */ goto exit; } + } else { + u = lookup_user_record(find_member_from_nick(nick), NULL, from); // TODO: get account from msgtags } - check_tcl_join(nick, uhost, u, chan->dname); if (!(chan = findchan(chname)) && !(chan = findchan_by_dname(ch_dname ? ch_dname : chname))) { @@ -2098,7 +2091,6 @@ static int gotjoin(char *from, char *channame) /* The record saved in the channel record always gets updated, * so we can use that. */ - u = m->user; if (match_my_nick(nick)) { /* It was me joining! Need to update the channel record with the @@ -2129,9 +2121,9 @@ static int gotjoin(char *from, char *channame) if (u) { struct laston_info *li = 0; - cr = get_chanrec(m->user, chan->dname); + cr = get_chanrec(u, chan->dname); if (!cr && no_chanrec_info) - li = get_user(&USERENTRY_LASTON, m->user); + li = get_user(&USERENTRY_LASTON, u); if (channel_greet(chan) && use_info && ((cr && now - cr->laston > wait_info) || (no_chanrec_info && (!li || now - li->laston > wait_info)))) { @@ -2189,7 +2181,7 @@ static int gotjoin(char *from, char *channame) (me_op(chan) || (me_halfop(chan) && !chan_hasop(m)))) { check_exemptlist(chan, from); quickban(chan, from); - p = get_user(&USERENTRY_COMMENT, m->user); + p = get_user(&USERENTRY_COMMENT, get_user_from_member(m)); dprintf(DP_MODE, "KICK %s %s :%s\n", chname, nick, (p && (p[0] != '@')) ? p : IRC_COMMENTKICK); m->flags |= SENTKICK; @@ -2249,6 +2241,7 @@ static int gotpart(char *from, char *msg) char *nick, *chname, *key; struct chanset_t *chan; struct userrec *u; + memberlist *m; chname = newsplit(&msg); fixcolon(chname); @@ -2260,8 +2253,9 @@ static int gotpart(char *from, char *msg) return 0; } if (chan && !channel_pending(chan)) { - u = get_user_by_host(from); nick = splitnick(&from); + m = ismember(chan, nick); + u = get_user_from_member(m); if (!channel_active(chan)) { /* whoa! */ putlog(LOG_MISC, chan->dname, @@ -2341,7 +2335,6 @@ static int gotkick(char *from, char *origmsg) } if (channel_active(chan)) { fixcolon(msg); - u = get_user_by_host(from); strlcpy(buf, from, sizeof buf); uhost = buf; whodid = splitnick(&uhost); @@ -2352,6 +2345,7 @@ static int gotkick(char *from, char *origmsg) return 0; m = ismember(chan, whodid); + u = lookup_user_record(m, NULL, from); // TODO: get account from msgtags if (m) m->last = now; /* This _needs_ to use chan->dname */ @@ -2368,7 +2362,7 @@ static int gotkick(char *from, char *origmsg) struct userrec *u2; simple_sprintf(s1, "%s!%s", m->nick, m->userhost); - u2 = get_user_by_host(s1); + u2 = get_user_from_member(m); set_handle_laston(chan->dname, u2, now); maybe_revenge(chan, from, s1, REVENGE_KICK); } @@ -2451,12 +2445,11 @@ static int gotnick(char *from, char *msg) m->flags &= ~(SENTKICK | SENTDEOP | SENTOP | SENTDEHALFOP | SENTHALFOP | SENTVOICE | SENTDEVOICE); /* nick-ban or nick is +k or something? */ - get_user_flagrec(m->user ? m->user : get_user_by_host(s1), &fr, - chan->dname); + u = get_user_from_member(m); + get_user_flagrec(u, &fr, chan->dname); check_this_member(chan, m->nick, &fr); /* Make sure this is in the loop, someone could have changed the record * in an earlier iteration of the loop. */ - u = get_user_by_host(from); found = 1; check_tcl_nick(nick, uhost, u, chan->dname, msg); @@ -2467,10 +2460,9 @@ static int gotnick(char *from, char *msg) } } if (!found) { - u = get_user_by_host(from); s1[0] = '*'; s1[1] = 0; - check_tcl_nick(nick, uhost, u, s1, msg); + check_tcl_nick(nick, uhost, NULL, s1, msg); } return 0; } @@ -2514,7 +2506,7 @@ static int gotquit(char *from, char *msg) chname = chan->dname; m = ismember(chan, nick); if (m) { - u = get_user_by_host(from2); + u = get_user_from_member(m); if (u) /* If you remove this, the bot will crash when the user record in * question is removed/modified during the tcl binds below, and the @@ -2612,7 +2604,7 @@ static int gotmsg(char *from, char *msg) ctcp_count++; if (ctcp[0] != ' ') { code = newsplit(&ctcp); - u = get_user_by_host(from); + u = lookup_user_record(find_member_from_nick(nick), NULL, from); // TODO: get account from msgtags if (!ignoring || trigger_on_ignore) { if (!check_tcl_ctcp(nick, uhost, u, to, code, ctcp)) { chan = findchan(realto); @@ -2704,8 +2696,7 @@ static int gotnotice(char *from, char *msg) fixcolon(msg); strlcpy(uhost, from, sizeof buf); nick = splitnick(&uhost); - u = get_user_by_host(from); - + u = lookup_user_record(find_member_from_nick(nick), NULL, from); // TODO: get account from msgtags /* Check for CTCP: */ p = strchr(msg, 1); while (p && *p) { diff --git a/src/mod/irc.mod/cmdsirc.c b/src/mod/irc.mod/cmdsirc.c index 2491b6731..c9bf58ab1 100644 --- a/src/mod/irc.mod/cmdsirc.c +++ b/src/mod/irc.mod/cmdsirc.c @@ -68,13 +68,11 @@ static int has_oporhalfop(int idx, struct chanset_t *chan) */ static char *getnick(char *handle, struct chanset_t *chan) { - char s[UHOSTLEN]; struct userrec *u; memberlist *m; for (m = chan->channel.member; m && m->nick[0]; m = m->next) { - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - if ((u = get_user_by_host(s)) && !strcasecmp(u->handle, handle)) + if ((u = get_user_from_member(m)) && !strcasecmp(u->handle, handle)) return m->nick; } return NULL; @@ -163,8 +161,8 @@ static void cmd_kickban(struct userrec *u, int idx, char *par) struct chanset_t *chan; char *chname, *nick, *s1; memberlist *m; - char s[UHOSTLEN]; char bantype = 0; + char s[UHOSTLEN]; if (!par[0]) { dprintf(idx, "Usage: kickban [channel] [-|@] [reason]\n"); @@ -208,7 +206,7 @@ static void cmd_kickban(struct userrec *u, int idx, char *par) return; } egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s); + u = get_user_from_member(m); get_user_flagrec(u, &victim, chan->dname); if ((chan_op(victim) || (glob_op(victim) && !chan_deop(victim))) && !(chan_master(user) || glob_master(user))) { @@ -265,7 +263,6 @@ static void cmd_op(struct userrec *u, int idx, char *par) struct chanset_t *chan; char *nick; memberlist *m; - char s[UHOSTLEN]; nick = newsplit(&par); chan = get_channel(idx, par); @@ -294,8 +291,7 @@ static void cmd_op(struct userrec *u, int idx, char *par) dprintf(idx, "%s is not on %s.\n", nick, chan->dname); return; } - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s); + u = get_user_from_member(m); get_user_flagrec(u, &victim, chan->dname); if (chan_deop(victim) || (glob_deop(victim) && !glob_op(victim))) { dprintf(idx, "%s is currently being auto-deopped.\n", m->nick); @@ -315,7 +311,6 @@ static void cmd_deop(struct userrec *u, int idx, char *par) struct chanset_t *chan; char *nick; memberlist *m; - char s[UHOSTLEN]; nick = newsplit(&par); chan = get_channel(idx, par); @@ -348,8 +343,7 @@ static void cmd_deop(struct userrec *u, int idx, char *par) dprintf(idx, "I'm not going to deop myself.\n"); return; } - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s); + u = get_user_from_member(m); get_user_flagrec(u, &victim, chan->dname); if ((chan_master(victim) || glob_master(victim)) && !(chan_owner(user) || glob_owner(user))) { @@ -371,7 +365,6 @@ static void cmd_halfop(struct userrec *u, int idx, char *par) struct userrec *u2; char *nick; memberlist *m; - char s[UHOSTLEN]; nick = newsplit(&par); chan = get_channel(idx, par); @@ -386,10 +379,9 @@ static void cmd_halfop(struct userrec *u, int idx, char *par) get_user_flagrec(dcc[idx].user, &user, chan->dname); m = ismember(chan, nick); if (m && !chan_op(user) && (!glob_op(user) || chan_deop(user))) { - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u2 = m->user ? m->user : get_user_by_host(s); + u2 = get_user_from_member(m); - if (!u2 || strcmp(u2->handle, dcc[idx].nick) || (!chan_halfop(user) && + if (!u2 || strcasecmp(u2->handle, dcc[idx].nick) || (!chan_halfop(user) && (!glob_halfop(user) || chan_dehalfop(user)))) { dprintf(idx, "You are not a channel op on %s.\n", chan->dname); return; @@ -414,8 +406,7 @@ static void cmd_halfop(struct userrec *u, int idx, char *par) dprintf(idx, "%s is not on %s.\n", nick, chan->dname); return; } - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s); + u = get_user_from_member(m); get_user_flagrec(u, &victim, chan->dname); if (chan_dehalfop(victim) || (glob_dehalfop(victim) && !glob_halfop(victim))) { dprintf(idx, "%s is currently being auto-dehalfopped.\n", m->nick); @@ -437,7 +428,6 @@ static void cmd_dehalfop(struct userrec *u, int idx, char *par) struct userrec *u2; char *nick; memberlist *m; - char s[UHOSTLEN]; nick = newsplit(&par); chan = get_channel(idx, par); @@ -452,10 +442,8 @@ static void cmd_dehalfop(struct userrec *u, int idx, char *par) get_user_flagrec(dcc[idx].user, &user, chan->dname); m = ismember(chan, nick); if (m && !chan_op(user) && (!glob_op(user) || chan_deop(user))) { - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u2 = m->user ? m->user : get_user_by_host(s); - - if (!u2 || strcmp(u2->handle, dcc[idx].nick) || (!chan_halfop(user) && + u2 = get_user_from_member(m); + if (!u2 || strcasecmp(u2->handle, dcc[idx].nick) || (!chan_halfop(user) && (!glob_halfop(user) || chan_dehalfop(user)))) { dprintf(idx, "You are not a channel op on %s.\n", chan->dname); return; @@ -484,8 +472,7 @@ static void cmd_dehalfop(struct userrec *u, int idx, char *par) dprintf(idx, "I'm not going to dehalfop myself.\n"); return; } - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s); + u = get_user_from_member(m); get_user_flagrec(u, &victim, chan->dname); if ((chan_master(victim) || glob_master(victim)) && !(chan_owner(user) || glob_owner(user))) { @@ -512,7 +499,6 @@ static void cmd_voice(struct userrec *u, int idx, char *par) struct userrec *u2; char *nick; memberlist *m; - char s[UHOSTLEN]; nick = newsplit(&par); chan = get_channel(idx, par); @@ -533,10 +519,9 @@ static void cmd_voice(struct userrec *u, int idx, char *par) * - stdarg */ if (m && !(chan_op(user) || chan_halfop(user) || (glob_op(user) && !chan_deop(user)) || (glob_halfop(user) && !chan_dehalfop(user)))) { - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u2 = m->user ? m->user : get_user_by_host(s); + u2 = get_user_from_member(m); - if (!u2 || strcmp(u2->handle, dcc[idx].nick) || (!chan_voice(user) && + if (!u2 || strcasecmp(u2->handle, dcc[idx].nick) || (!chan_voice(user) && (!glob_voice(user) || chan_quiet(user)))) { dprintf(idx, "You are not a channel op or halfop on %s.\n", chan->dname); return; @@ -570,7 +555,6 @@ static void cmd_devoice(struct userrec *u, int idx, char *par) struct userrec *u2; char *nick; memberlist *m; - char s[UHOSTLEN]; nick = newsplit(&par); chan = get_channel(idx, par); @@ -586,10 +570,9 @@ static void cmd_devoice(struct userrec *u, int idx, char *par) m = ismember(chan, nick); if (m && !(chan_op(user) || chan_halfop(user) || (glob_op(user) && !chan_deop(user)) || (glob_halfop(user) && !chan_dehalfop(user)))) { - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u2 = m->user ? m->user : get_user_by_host(s); + u2 = get_user_from_member(m); - if (!u2 || strcmp(u2->handle, dcc[idx].nick) || (!chan_voice(user) && + if (!u2 || strcasecmp(u2->handle, dcc[idx].nick) || (!chan_voice(user) && (!glob_voice(user) || chan_quiet(user)))) { dprintf(idx, "You are not a channel op or halfop on %s.\n", chan->dname); return; @@ -623,7 +606,6 @@ static void cmd_kick(struct userrec *u, int idx, char *par) struct chanset_t *chan; char *chname, *nick; memberlist *m; - char s[UHOSTLEN]; if (!par[0]) { dprintf(idx, "Usage: kick [channel] [reason]\n"); @@ -663,8 +645,7 @@ static void cmd_kick(struct userrec *u, int idx, char *par) chan->dname); return; } - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s); + u = get_user_from_member(m); get_user_flagrec(u, &victim, chan->dname); if ((chan_op(victim) || (glob_op(victim) && !chan_deop(victim))) && !(chan_master(user) || glob_master(user))) { @@ -748,8 +729,9 @@ static void cmd_channel(struct userrec *u, int idx, char *par) for (m = chan->channel.member; m && m->nick[0]; m = m->next) { if (strlen(m->nick) > maxnicklen) maxnicklen = strlen(m->nick); - if ((m->user) && (strlen(m->user->handle) > maxhandlen)) - maxhandlen = strlen(m->user->handle); + u = get_user_from_member(m); + if (u && (strlen(u->handle) > maxhandlen)) + maxhandlen = strlen(u->handle); } if (maxnicklen < 9) maxnicklen = 9; @@ -768,15 +750,13 @@ static void cmd_channel(struct userrec *u, int idx, char *par) strftime(s, 6, "%H:%M", localtime(&(m->joined))); } else strlcpy(s, " --- ", sizeof s); - if (m->user == NULL) { - egg_snprintf(s1, sizeof s1, "%s!%s", m->nick, m->userhost); - m->user = get_user_by_host(s1); - } - if (m->user == NULL) + egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); + u = get_user_from_member(m); + if (u == NULL) strlcpy(handle, "*", sizeof handle); else - strlcpy(handle, m->user->handle, sizeof handle); - get_user_flagrec(m->user, &user, chan->dname); + strlcpy(handle, u->handle, sizeof handle); + get_user_flagrec(u, &user, chan->dname); /* Determine status char to use */ if (glob_bot(user) && (glob_op(user) || chan_op(user))) atrflag = 'B'; @@ -1022,7 +1002,7 @@ static void cmd_adduser(struct userrec *u, int idx, char *par) if (strlen(hand) > HANDLEN) hand[HANDLEN] = 0; egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s); + u = get_user_from_member(m); if (u) { dprintf(idx, "%s is already known as %s.\n", nick, u->handle); return; @@ -1059,7 +1039,7 @@ static void cmd_adduser(struct userrec *u, int idx, char *par) static void cmd_deluser(struct userrec *u, int idx, char *par) { - char *nick, s[UHOSTLEN]; + char *nick; struct chanset_t *chan; memberlist *m = NULL; struct flag_record victim = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 }; @@ -1080,8 +1060,7 @@ static void cmd_deluser(struct userrec *u, int idx, char *par) return; } get_user_flagrec(u, &user, chan->dname); - egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s); + u = get_user_from_member(m); if (!u) { dprintf(idx, "%s is not a valid user.\n", nick); return; diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c index 8cce81776..bc3f578e4 100644 --- a/src/mod/irc.mod/irc.c +++ b/src/mod/irc.mod/irc.c @@ -142,7 +142,6 @@ static void punish_badguy(struct chanset_t *chan, char *whobad, /* Set the offender +d */ if ((chan->revenge_mode > 0) && !(chan_deop(fr) || glob_deop(fr))) { char s[UHOSTLEN], s1[UHOSTLEN]; - memberlist *mx = NULL; /* Removing op */ if (chan_op(fr) || (glob_op(fr) && !chan_deop(fr))) { @@ -186,8 +185,6 @@ static void punish_badguy(struct chanset_t *chan, char *whobad, fr.chan = USER_DEOP; fr.udef_chan = 0; u = get_user_by_handle(userlist, s1); - if ((mx = ismember(chan, badnick))) - mx->user = u; set_user_flagrec(u, &fr, chan->dname); simple_sprintf(s, "(%s) %s (%s)", ct, reason, whobad); set_user(&USERENTRY_COMMENT, u, (void *) s); @@ -227,20 +224,25 @@ static void punish_badguy(struct chanset_t *chan, char *whobad, static void maybe_revenge(struct chanset_t *chan, char *whobad, char *whovictim, int type) { - char *badnick, *victim; + char *badnick, *victim, buf[NICKLEN + UHOSTLEN]; int mevictim; struct userrec *u, *u2; + memberlist *m; if (!chan || (type < 0)) return; /* Get info about offender */ - u = get_user_by_host(whobad); + strlcpy(buf, whobad, sizeof buf); badnick = splitnick(&whobad); + m = ismember(chan, badnick); + u = lookup_user_record(m, NULL, buf); // TODO: get account from msgtags /* Get info about victim */ - u2 = get_user_by_host(whovictim); + strlcpy(buf, whovictim, sizeof buf); victim = splitnick(&whovictim); + m = ismember(chan, victim); + u2 = lookup_user_record(m, NULL, buf); // TODO: get account from msgtags mevictim = match_my_nick(victim); /* Do we want to revenge? */ @@ -264,12 +266,10 @@ static void set_key(struct chanset_t *chan, char *k) static int hand_on_chan(struct chanset_t *chan, struct userrec *u) { - char s[NICKMAX+UHOSTLEN+1]; memberlist *m; for (m = chan->channel.member; m && m->nick[0]; m = m->next) { - sprintf(s, "%s!%s", m->nick, m->userhost); - if (u == get_user_by_host(s)) + if (u == get_user_from_member(m)) return 1; } return 0; @@ -531,7 +531,6 @@ static void status_log() static void check_lonely_channel(struct chanset_t *chan) { memberlist *m; - char s[NICKMAX+UHOSTLEN+1]; int i = 0; if (channel_pending(chan) || !channel_active(chan) || me_op(chan) || @@ -576,8 +575,7 @@ static void check_lonely_channel(struct chanset_t *chan) chan->status |= CHAN_WHINED; } for (m = chan->channel.member; m && m->nick[0]; m = m->next) { - sprintf(s, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s); + u = get_user_from_member(m); if (!match_my_nick(m->nick) && (!u || !(u->flags & USER_BOT))) { ok = 0; break; @@ -601,7 +599,7 @@ static void check_expired_chanstuff() { masklist *b, *e; memberlist *m, *n; - char *key, s[NICKMAX+UHOSTLEN+1]; + char *key; struct chanset_t *chan; struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; @@ -670,9 +668,7 @@ static void check_expired_chanstuff() for (m = chan->channel.member; m && m->nick[0]; m = m->next) if (now - m->last >= chan->idle_kick * 60 && !match_my_nick(m->nick) && !chan_issplit(m)) { - sprintf(s, "%s!%s", m->nick, m->userhost); - get_user_flagrec(m->user ? m->user : get_user_by_host(s), - &fr, chan->dname); + get_user_flagrec(get_user_from_member(m), &fr, chan->dname); if ((!(glob_bot(fr) || glob_friend(fr) || (glob_op(fr) && !chan_deop(fr)) || chan_friend(fr) || chan_op(fr))) && (me_op(chan) || (me_halfop(chan) && !chan_hasop(m)))) { @@ -685,9 +681,7 @@ static void check_expired_chanstuff() for (m = chan->channel.member; m && m->nick[0]; m = n) { n = m->next; if (m->split && now - m->split > wait_split) { - sprintf(s, "%s!%s", m->nick, m->userhost); - check_tcl_sign(m->nick, m->userhost, - m->user ? m->user : get_user_by_host(s), + check_tcl_sign(m->nick, m->userhost, get_user_from_member(m), chan->dname, "lost in the netsplit"); putlog(LOG_JOIN, chan->dname, "%s (%s) got lost in the net-split.", m->nick, m->userhost); @@ -915,12 +909,16 @@ static int check_tcl_pub(char *nick, char *from, char *chname, char *msg) struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; int x; char buf[512], *args = buf, *cmd, host[161], *hand; - struct userrec *u; + struct chanset_t *chan; + struct userrec *u = NULL; + memberlist *m; strlcpy(buf, msg, sizeof buf); cmd = newsplit(&args); simple_sprintf(host, "%s!%s", nick, from); - u = get_user_by_host(host); + chan = findchan(chname); + m = ismember(chan, nick); + u = lookup_user_record(m ? m : find_member_from_nick(nick), NULL, from); // TODO: get account from msgtags hand = u ? u->handle : "*"; get_user_flagrec(u, &fr, chname); Tcl_SetVar(interp, "_pub1", nick, 0); @@ -943,10 +941,14 @@ static int check_tcl_pubm(char *nick, char *from, char *chname, char *msg) int x; char buf[1024], host[161]; struct userrec *u; + struct chanset_t *chan; + memberlist *m; simple_sprintf(buf, "%s %s", chname, msg); simple_sprintf(host, "%s!%s", nick, from); - u = get_user_by_host(host); + chan = findchan(chname); + m = ismember(chan, nick); + u = lookup_user_record(m ? m : find_member_from_nick(nick), NULL, from); // TODO: get account from msgtags get_user_flagrec(u, &fr, chname); Tcl_SetVar(interp, "_pubm1", nick, 0); Tcl_SetVar(interp, "_pubm2", from, 0); diff --git a/src/mod/irc.mod/mode.c b/src/mod/irc.mod/mode.c index 327844c3b..5350fafd7 100644 --- a/src/mod/irc.mod/mode.c +++ b/src/mod/irc.mod/mode.c @@ -52,11 +52,11 @@ static struct chanset_t *modebind_refresh(char *chname, if (!chname || !(chan = findchan(chname))) return NULL; if (usrhost) { - u = get_user_by_host(usrhost); + u = lookup_user_record(NULL, NULL, usrhost); // TODO: get account from somewhere get_user_flagrec(u, usr, chan->dname); } if (vcrhost) { - u = get_user_by_host(vcrhost); + u = lookup_user_record(NULL, NULL, vcrhost); // TODO: get account from somewhere get_user_flagrec(u, vcr, chan->dname); } return chan; @@ -421,11 +421,7 @@ static void got_op(struct chanset_t *chan, char *nick, char *from, check_chan = 1; strcpy(ch, chan->name); - simple_sprintf(s, "%s!%s", m->nick, m->userhost); - if (!m->user) - u = get_user_by_host(s); - else - u = m->user; + u = get_user_from_member(m); get_user_flagrec(u, &victim, chan->dname); /* Flags need to be set correctly right from the beginning now, so that @@ -519,11 +515,7 @@ static void got_halfop(struct chanset_t *chan, char *nick, char *from, check_chan = 1; strcpy(ch, chan->name); - simple_sprintf(s, "%s!%s", m->nick, m->userhost); - if (!m->user) - u = get_user_by_host(s); - else - u = m->user; + u = get_user_from_member(m); get_user_flagrec(u, &victim, chan->dname); /* Flags need to be set correctly right from the beginning now, so that @@ -612,7 +604,7 @@ static void got_deop(struct chanset_t *chan, char *nick, char *from, strcpy(ch, chan->name); simple_sprintf(s, "%s!%s", m->nick, m->userhost); simple_sprintf(s1, "%s!%s", nick, from); - u = get_user_by_host(s); + u = get_user_from_member(m); get_user_flagrec(u, &victim, chan->dname); had_halfop = chan_hasop(m); @@ -703,9 +695,8 @@ static void got_dehalfop(struct chanset_t *chan, char *nick, char *from, } strcpy(ch, chan->name); - simple_sprintf(s, "%s!%s", m->nick, m->userhost); simple_sprintf(s1, "%s!%s", nick, from); - u = get_user_by_host(s); + u = get_user_from_member(m); get_user_flagrec(u, &victim, chan->dname); had_halfop = chan_hasop(m); @@ -784,7 +775,7 @@ static void got_ban(struct chanset_t *chan, char *nick, char *from, char *who, for (m = chan->channel.member; m && m->nick[0]; m = m->next) { egg_snprintf(s1, sizeof s1, "%s!%s", m->nick, m->userhost); if (match_addr(who, s1)) { - targ = get_user_by_host(s1); + targ = get_user_from_member(m); if (targ) { get_user_flagrec(targ, &victim, chan->dname); if ((glob_friend(victim) || (glob_op(victim) && !chan_deop(victim)) || @@ -1025,12 +1016,15 @@ static int gotmode(char *from, char *origmsg) msg[z] = 0; putlog(LOG_MODES, chan->dname, "%s: mode change '%s %s' by %s", ch, chg, msg, from); - u = get_user_by_host(from); - get_user_flagrec(u, &user, ch); nick = splitnick(&from); m = ismember(chan, nick); - if (m) + if (m) { + u = get_user_from_member(m); + get_user_flagrec(u, &user, ch); m->last = now; + } else { + u = NULL; + } if (m && channel_active(chan) && (me_op(chan) || (me_halfop(chan) && !chan_hasop(m))) && !(glob_friend(user) || chan_friend(user) || (channel_dontkickops(chan) && (chan_op(user) || (glob_op(user) && @@ -1249,8 +1243,7 @@ static int gotmode(char *from, char *origmsg) refresh_who_chan(chan->name); } else { simple_sprintf(s, "%s!%s", m->nick, m->userhost); - get_user_flagrec(m->user ? m->user : get_user_by_host(s), - &victim, chan->dname); + get_user_flagrec(get_user_from_member(m), &victim, chan->dname); if (ms2[0] == '+') { m->flags &= ~SENTVOICE; m->flags |= CHANVOICE; diff --git a/src/mod/irc.mod/msgcmds.c b/src/mod/irc.mod/msgcmds.c index e8baa831e..1c8a45f6b 100644 --- a/src/mod/irc.mod/msgcmds.c +++ b/src/mod/irc.mod/msgcmds.c @@ -226,7 +226,7 @@ static int msg_addhost(char *nick, char *host, struct userrec *u, char *par) if (!par[0]) { if (!quiet_reject) dprintf(DP_HELP, "NOTICE %s :You must supply a hostmask\n", nick); - } else if (rfc_casecmp(u->handle, origbotname)) { + } else if (strcasecmp(u->handle, origbotname)) { /* This could be used as detection... */ if (u_pass_match(u, "-")) { if (!quiet_reject) @@ -383,7 +383,8 @@ static int msg_who(char *nick, char *host, struct userrec *u, char *par) struct userrec *u; egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s); + /* Don't use s for host here, b/c if we don't have m, we won't have s */ + u = get_user_from_member(m); info = get_user(&USERENTRY_INFO, u); if (u && (u->flags & USER_BOT)) info = 0; @@ -431,7 +432,7 @@ static int msg_who(char *nick, char *host, struct userrec *u, char *par) static int msg_whois(char *nick, char *host, struct userrec *u, char *par) { - char s[UHOSTLEN + 1], s1[143], *s2, stime[14]; + char s1[143], *s2, stime[14], uhost[NICKLEN + UHOSTLEN]; int ok; struct chanset_t *chan; memberlist *m; @@ -454,7 +455,8 @@ static int msg_whois(char *nick, char *host, struct userrec *u, char *par) } if (strlen(par) > NICKMAX) par[NICKMAX] = 0; - putlog(LOG_CMDS, "*", "(%s!%s) !%s! WHOIS %s", nick, host, u->handle, par); + egg_snprintf(uhost, sizeof uhost, "%s!%s", nick, host); + putlog(LOG_CMDS, "*", "(%s) !%s! WHOIS %s", uhost, u->handle, par); u2 = get_user_by_handle(userlist, par); if (!u2) { /* No such handle -- maybe it's a nickname of someone on a chan? */ @@ -462,8 +464,7 @@ static int msg_whois(char *nick, char *host, struct userrec *u, char *par) for (chan = chanset; chan && !ok; chan = chan->next) { m = ismember(chan, par); if (m) { - egg_snprintf(s, sizeof s, "%s!%s", par, m->userhost); - u2 = get_user_by_host(s); + u2 = get_user_from_member(m); if (u2) { ok = 1; dprintf(DP_HELP, "NOTICE %s :[%s] AKA '%s':\n", nick, diff --git a/src/mod/irc.mod/tclirc.c b/src/mod/irc.mod/tclirc.c index 52826b8e5..2e27744a8 100644 --- a/src/mod/irc.mod/tclirc.c +++ b/src/mod/irc.mod/tclirc.c @@ -24,10 +24,10 @@ */ static int tcl_chanlist STDVAR { - char nuh[1024]; int f; memberlist *m; struct chanset_t *chan; + struct userrec *u; struct flag_record plus = { FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0 }, minus = { FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0}, user = { FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0 }; @@ -55,11 +55,8 @@ static int tcl_chanlist STDVAR minus.match = plus.match ^ (FR_AND | FR_OR); for (m = chan->channel.member; m && m->nick[0]; m = m->next) { - if (!m->user) { - egg_snprintf(nuh, sizeof nuh, "%s!%s", m->nick, m->userhost); - m->user = get_user_by_host(nuh); - } - get_user_flagrec(m->user, &user, argv[1]); + u = get_user_from_member(m); + get_user_flagrec(u, &user, argv[1]); user.match = plus.match; if (flagrec_eq(&plus, &user)) { if (!f || !flagrec_eq(&minus, &user)) @@ -347,8 +344,8 @@ static int tcl_onchan STDVAR static int tcl_handonchan STDVAR { - char nuh[1024]; struct chanset_t *chan, *thechan = NULL; + struct userrec *u; memberlist *m; BADARGS(2, 3, " handle ?channel?"); @@ -365,11 +362,8 @@ static int tcl_handonchan STDVAR while (chan && (thechan == NULL || thechan == chan)) { for (m = chan->channel.member; m && m->nick[0]; m = m->next) { - if (!m->user) { - egg_snprintf(nuh, sizeof nuh, "%s!%s", m->nick, m->userhost); - m->user = get_user_by_host(nuh); - } - if (m->user && !rfc_casecmp(m->user->handle, argv[1])) { + u = get_user_from_member(m); + if (u && !strcasecmp(u->handle, argv[1])) { Tcl_AppendResult(irp, "1", NULL); return TCL_OK; } @@ -511,7 +505,7 @@ static int tcl_accounttracking STDVAR if (current->enabled) { acctnotify = 1; } - Tcl_SetResult(irp, use_354 && extjoin && acctnotify ? "1" : "0", NULL); + Tcl_SetResult(irp, use_354 && extjoin && acctnotify ? "1" : "0", TCL_STATIC); return TCL_OK; } @@ -986,7 +980,8 @@ static int tcl_account2nicks STDVAR struct chanset_t *chan, *thechan = NULL; Tcl_Obj *nicks; Tcl_Obj **nicksv = NULL; - int nicksc = 0, i, found; + Tcl_Size nicksc = 0, i; + int found; BADARGS(2, 3, " account ?channel?"); @@ -1027,12 +1022,13 @@ static int tcl_account2nicks STDVAR static int tcl_hand2nicks STDVAR { - char nuh[1024]; memberlist *m; struct chanset_t *chan, *thechan = NULL; + struct userrec *u; Tcl_Obj *nicks; Tcl_Obj **nicksv = NULL; - int nicksc = 0, i, found; + Tcl_Size nicksc = 0, i; + int found; BADARGS(2, 3, " handle ?channel?"); @@ -1050,13 +1046,8 @@ static int tcl_hand2nicks STDVAR while (chan && (thechan == NULL || thechan == chan)) { for (m = chan->channel.member; m && m->nick[0]; m = m->next) { found = 0; - /* Does this user have the account we're looking for? */ - if (!m->user && !m->tried_getuser) { - egg_snprintf(nuh, sizeof nuh, "%s!%s", m->nick, m->userhost); - m->tried_getuser = 1; - m->user = get_user_by_host(nuh); - } - if (m->user && !rfc_casecmp(m->user->handle, argv[1])) { + u = get_user_from_member(m); + if (u && !strcasecmp(u->handle, argv[1])) { /* Is the nick of the user already in the list? */ Tcl_ListObjGetElements(irp, nicks, &nicksc, &nicksv); for (i = 0; i < nicksc; i++) { @@ -1078,9 +1069,9 @@ static int tcl_hand2nicks STDVAR static int tcl_hand2nick STDVAR { - char nuh[1024]; memberlist *m; struct chanset_t *chan, *thechan = NULL; + struct userrec *u; BADARGS(2, 3, " handle ?channel?"); @@ -1096,12 +1087,8 @@ static int tcl_hand2nick STDVAR while (chan && (thechan == NULL || thechan == chan)) { for (m = chan->channel.member; m && m->nick[0]; m = m->next) { - if (!m->user && !m->tried_getuser) { - egg_snprintf(nuh, sizeof nuh, "%s!%s", m->nick, m->userhost); - m->tried_getuser = 1; - m->user = get_user_by_host(nuh); - } - if (m->user && !rfc_casecmp(m->user->handle, argv[1])) { + u = get_user_from_member(m); + if (u && !strcasecmp(u->handle, argv[1])) { Tcl_AppendResult(irp, m->nick, NULL); return TCL_OK; } @@ -1113,9 +1100,9 @@ static int tcl_hand2nick STDVAR static int tcl_nick2hand STDVAR { - char nuh[1024]; memberlist *m; struct chanset_t *chan, *thechan = NULL; + struct userrec *u; BADARGS(2, 3, " nick ?channel?"); @@ -1132,11 +1119,8 @@ static int tcl_nick2hand STDVAR while (chan && (thechan == NULL || thechan == chan)) { m = ismember(chan, argv[1]); if (m) { - if (!m->user) { - egg_snprintf(nuh, sizeof nuh, "%s!%s", m->nick, m->userhost); - m->user = get_user_by_host(nuh); - } - Tcl_AppendResult(irp, m->user ? m->user->handle : "*", NULL); + u = get_user_from_member(m); + Tcl_AppendResult(irp, u ? u->handle : "*", NULL); return TCL_OK; } chan = chan->next; diff --git a/src/mod/module.h b/src/mod/module.h index 951241adb..efab4174f 100644 --- a/src/mod/module.h +++ b/src/mod/module.h @@ -202,7 +202,7 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr #define open_telnet ((int (*) (int, char *, int))global[87]) /* 88 - 91 */ #define check_tcl_event ((void (*) (const char *))global[88]) -/* was my_memcpy -- use memcpy() instead */ +/* was my_memcpy() -- use memcpy() instead */ #define my_atoul ((IP(*)(char *))global[90]) #define my_strcpy ((int (*)(char *, const char *))global[91]) /* 92 - 95 */ @@ -426,10 +426,10 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr /* 252 - 255 */ #define egg_snprintf (global[252]) #define egg_vsnprintf ((int (*)(char *, size_t, const char *, va_list))global[253]) -/* was egg_memset -- use memset() instead */ -/* was egg_strcasecmp -- use strcasecmp instead */ +/* was egg_memset() -- use memset() instead */ +/* was egg_strcasecmp() -- use strcasecmp() instead */ /* 256 - 259 */ -/* was egg_strncasecmp -- use strncasecmp instead */ +/* was egg_strncasecmp() -- use strncasecmp() instead */ #define is_file ((int (*)(const char *))global[257]) #define must_be_owner (*(int *)(global[258])) #define tandbot (*(tand_t **)(global[259])) @@ -497,7 +497,7 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr # define strlcpy ((size_t (*) (char *, const char *, size_t))global[303]) #endif /* 304 - 307 */ -#define strncpyz ((size_t (*) (char *, const char *, size_t))global[304]) +#define strncpyz strlcpy /* strncpyz() is deprecated, use strlcpy() instead */ #ifndef HAVE_BASE64 # define b64_ntop ((int (*) (uint8_t const *, size_t, char *, size_t))global[305]) # define b64_pton ((int (*) (const char *, uint8_t *, size_t))global[306]) @@ -524,7 +524,10 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr #define bind_bind_entry ((int(*)(tcl_bind_list_t *, const char *, const char *, const char *))global[320]) #define unbind_bind_entry ((int(*)(tcl_bind_list_t *, const char *, const char *, const char *))global[321]) #define argv0 ((char *)global[322]) - +#define lookup_user_record ((struct userrec * (*)(memberlist *, char *, char *))global[323]) +/* 324 - 327 */ +#define find_member_from_nick ((memberlist * (*) (char *))global[324]) +#define get_user_from_member ((struct userrec * (*) (memberlist *))global[325]) /* hostmasking */ diff --git a/src/mod/modvals.h b/src/mod/modvals.h index 9ec2a9e18..a840e09cf 100644 --- a/src/mod/modvals.h +++ b/src/mod/modvals.h @@ -39,7 +39,11 @@ #define HOOK_LOADED 13 #define HOOK_BACKUP 14 #define HOOK_DIE 15 -#define REAL_HOOKS 16 +#define HOOK_PRE_SELECT 16 +#define HOOK_POST_SELECT 17 + +#define REAL_HOOKS 18 + #define HOOK_SHAREOUT 105 #define HOOK_SHAREIN 106 #define HOOK_ENCRYPT_PASS 107 @@ -72,7 +76,7 @@ /* Server */ #define SERVER_BOTNAME 4 #define SERVER_BOTUSERHOST 5 -#define SERVER_NICKLEN 38 +#define SERVER_NICKLEN 37 /* IRC */ #define IRC_RECHECK_CHANNEL 15 #define IRC_RECHECK_CHANNEL_MODES 17 diff --git a/src/mod/notes.mod/notes.c b/src/mod/notes.mod/notes.c index 5c5d47aa8..ee9a9b3e5 100644 --- a/src/mod/notes.mod/notes.c +++ b/src/mod/notes.mod/notes.c @@ -834,13 +834,11 @@ static void notes_hourly() memberlist *m; int k; int l; - char s1[NICKMAX+UHOSTLEN+1]; struct userrec *u; for (chan = chanset; chan; chan = chan->next) { for (m = chan->channel.member; m && m->nick[0]; m = m->next) { - sprintf(s1, "%s!%s", m->nick, m->userhost); - u = get_user_by_host(s1); + u = get_user_from_member(m); if (u) { k = num_notes(u->handle); for (l = 0; l < dcc_total; l++) diff --git a/src/mod/pbkdf2.mod/Makefile b/src/mod/pbkdf2.mod/Makefile index 6cf40c584..38e70d0fe 100644 --- a/src/mod/pbkdf2.mod/Makefile +++ b/src/mod/pbkdf2.mod/Makefile @@ -36,4 +36,5 @@ distclean: clean ../../../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 + ../../../src/mod/modvals.h ../../../src/tandem.h \ + .././pbkdf2.mod/tclpbkdf2.c diff --git a/src/mod/pbkdf2.mod/pbkdf2.c b/src/mod/pbkdf2.mod/pbkdf2.c index 169d92bc8..faf7313d2 100644 --- a/src/mod/pbkdf2.mod/pbkdf2.c +++ b/src/mod/pbkdf2.mod/pbkdf2.c @@ -10,6 +10,8 @@ #include "src/mod/module.h" #if OPENSSL_VERSION_NUMBER >= 0x1000000fL /* 1.0.0 */ +#include "tclpbkdf2.c" + #define MODULE_NAME "encryption2" #include /* base64 encode b64_ntop() and base64 decode b64_pton() */ @@ -108,7 +110,7 @@ static char *pbkdf2_hash(const char *pass, const char *digest_name, digestlen, buf)) { explicit_bzero(buf, digestlen); explicit_bzero(out, outlen); - putlog(LOG_MISC, "*", "PBKDF2 error: PKCS5_PBKDF2_HMAC(): %s.", + putlog(LOG_MISC, "*", "PBKDF2 key derivation error: %s.", ERR_error_string(ERR_get_error(), NULL)); nfree(buf); return NULL; @@ -223,21 +225,6 @@ static char *pbkdf2_verify(const char *pass, const char *encrypted) return (char *) encrypted; } -static int tcl_encpass2 STDVAR -{ - BADARGS(2, 2, " string"); - if (strlen(argv[1]) > 0) - Tcl_AppendResult(irp, pbkdf2_encrypt(argv[1]), NULL); - else - Tcl_AppendResult(irp, "", NULL); - return TCL_OK; -} - -static tcl_cmds my_tcl_cmds[] = { - {"encpass2", tcl_encpass2}, - {NULL, NULL} -}; - static tcl_ints my_tcl_ints[] = { {"pbkdf2-re-encode", &pbkdf2_re_encode, 0}, {"pbkdf2-rounds", &pbkdf2_rounds, 0}, diff --git a/src/mod/pbkdf2.mod/tclpbkdf2.c b/src/mod/pbkdf2.mod/tclpbkdf2.c new file mode 100644 index 000000000..8fa7bf8dd --- /dev/null +++ b/src/mod/pbkdf2.mod/tclpbkdf2.c @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * tclpbkdf2.c -- tcl functions for pbkdf2.mod + * + * Written by thommey and Michael Ortmann + * + * Copyright (C) 2017 - 2024 Eggheads Development Team + */ + +#include +#include + +static char *pbkdf2_encrypt(const char *); + +static int tcl_encpass2 STDVAR +{ + BADARGS(2, 2, " string"); + Tcl_SetResult(irp, pbkdf2_encrypt(argv[1]), TCL_STATIC); + return TCL_OK; +} + +static int tcl_pbkdf2 STDVAR +{ + int hex, digestlen, i; + unsigned int rounds; + const EVP_MD *digest; + unsigned char buf[256]; + char buf_hex[256]; + Tcl_Obj *result = 0; + + BADARGS(5, 6, " ?-bin? pass salt rounds digest"); + if (argc == 6) { + if (!strcmp(argv[1], "-bin")) + hex = 0; + else { + Tcl_AppendResult(irp, "bad option ", argv[1], ": must be -bin", NULL); + return TCL_ERROR; + } + } + else + hex = 1; + rounds = atoi(argv[3 + !hex]); + digest = EVP_get_digestbyname(argv[4 + !hex]); + if (!digest) { + Tcl_AppendResult(irp, "PBKDF2 error: Unknown message digest '", argv[4 + !hex], "'.", NULL); + return TCL_ERROR; + } + digestlen = EVP_MD_size(digest); + if (!PKCS5_PBKDF2_HMAC(argv[1 + !hex], strlen(argv[1 + !hex]), (const unsigned char *) argv[2+ !hex], strlen(argv[2 + !hex]), rounds, digest, digestlen, buf)) { + Tcl_AppendResult(irp, "PBKDF2 key derivation error: ", ERR_error_string(ERR_get_error(), NULL), ".", NULL); + return TCL_ERROR; + } + if (hex) { + for (i = 0; i < digestlen; i++) + sprintf(buf_hex + (i * 2), "%.2X", buf[i]); + result = Tcl_NewByteArrayObj((unsigned char *) buf_hex, digestlen * 2); + explicit_bzero(buf_hex, digestlen * 2); + } + else + result = Tcl_NewByteArrayObj(buf, digestlen); + explicit_bzero(buf, digestlen); + Tcl_SetObjResult(irp, result); + return TCL_OK; +} + +static tcl_cmds my_tcl_cmds[] = { + {"encpass2", tcl_encpass2}, + {"pbkdf2", tcl_pbkdf2}, + {NULL, NULL} +}; diff --git a/src/mod/python.mod/Makefile.in b/src/mod/python.mod/Makefile.in index e5b251ee9..be58760c3 100644 --- a/src/mod/python.mod/Makefile.in +++ b/src/mod/python.mod/Makefile.in @@ -43,5 +43,5 @@ distclean: clean ../../../src/mod/modvals.h ../../../src/tandem.h \ ../../../src/mod/irc.mod/irc.h ../../../src/mod/server.mod/server.h \ ../../../src/mod/python.mod/python.h \ - ../../../src/mod/python.mod/tclpython.c \ - ../../../src/mod/python.mod/pycmds.c + ../../../src/mod/python.mod/pycmds.c \ + ../../../src/mod/python.mod/tclpython.c diff --git a/src/mod/python.mod/configure b/src/mod/python.mod/configure index 532be77df..def84c793 100755 --- a/src/mod/python.mod/configure +++ b/src/mod/python.mod/configure @@ -1,12 +1,13 @@ #! /bin/sh -# From configure.ac 9fdf80a3. +# From configure.ac 4af46aa3. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Eggdrop Python Module 1.9.3. +# Generated by GNU Autoconf 2.71 for Eggdrop Python Module 1.10.0. # # Report bugs to . # # -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Inc. # # # This configure script is free software; the Free Software Foundation @@ -19,14 +20,16 @@ # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else +else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( @@ -36,46 +39,46 @@ esac fi + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then +if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || @@ -84,13 +87,6 @@ if test "${PATH_SEPARATOR+set}" != set; then fi -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( @@ -99,8 +95,12 @@ case $0 in #(( for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS @@ -112,30 +112,10 @@ if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. @@ -157,20 +137,22 @@ esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + as_bourne_compatible="as_nop=: +if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST -else +else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( @@ -190,42 +172,53 @@ as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : -else +else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : + if (eval "$as_required") 2>/dev/null +then : as_have_required=yes -else +else $as_nop as_have_required=no fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : -else +else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base + as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : break 2 fi fi @@ -233,14 +226,21 @@ fi esac as_found=false done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi +fi - if test "x$CONFIG_SHELL" != x; then : + if test "x$CONFIG_SHELL" != x +then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also @@ -258,18 +258,19 @@ esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org and bugs@eggheads.org + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and bugs@eggheads.org $0: about your system, including any error possibly output $0: before this message. Then install a modern shell, or $0: manually run the script under such a shell if you do @@ -297,6 +298,7 @@ as_fn_unset () } as_unset=as_fn_unset + # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -314,6 +316,14 @@ as_fn_exit () as_fn_set_status $1 exit $1 } # as_fn_exit +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop # as_fn_mkdir_p # ------------- @@ -328,7 +338,7 @@ as_fn_mkdir_p () as_dirs= while :; do case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" @@ -337,7 +347,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | +printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -376,12 +386,13 @@ as_fn_executable_p () # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : eval 'as_fn_append () { eval $1+=\$2 }' -else +else $as_nop as_fn_append () { eval $1=\$$1\$2 @@ -393,18 +404,27 @@ fi # as_fn_append # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : eval 'as_fn_arith () { as_val=$(( $* )) }' -else +else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- @@ -416,9 +436,9 @@ as_fn_error () as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $2" >&2 + printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -445,7 +465,7 @@ as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | +printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q @@ -489,7 +509,7 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall @@ -503,6 +523,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits exit } + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) @@ -516,6 +540,13 @@ case `echo -n x` in #((((( ECHO_N='-n';; esac +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + + rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file @@ -583,20 +614,21 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Eggdrop Python Module' PACKAGE_TARNAME='eggdrop-python-module' -PACKAGE_VERSION='1.9.3' -PACKAGE_STRING='Eggdrop Python Module 1.9.3' +PACKAGE_VERSION='1.10.0' +PACKAGE_STRING='Eggdrop Python Module 1.10.0' PACKAGE_BUGREPORT='bugs@eggheads.org' PACKAGE_URL='' ac_unique_file="python.c" ac_subst_vars='LTLIBOBJS LIBOBJS +AWK +PYTHON_VERSION PYTHON_LDFLAGS PYTHON_CFLAGS PYTHON_CONFIG_ARGS python_config_bin egg_with_python_config -egg_enable_python FGREP GREP target_alias @@ -641,12 +673,12 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking -enable_python with_python_config ' ac_precious_vars='build_alias host_alias -target_alias' +target_alias +PYTHON_VERSION' # Initialize some variables set by options. @@ -715,8 +747,6 @@ do *) ac_optarg=yes ;; esac - # Accept the important Cygnus configure options, so we can diagnose typos. - case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; @@ -757,9 +787,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" @@ -783,9 +813,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" @@ -996,9 +1026,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" @@ -1012,9 +1042,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" @@ -1058,9 +1088,9 @@ Try \`$0 --help' for more information" *) # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; @@ -1076,7 +1106,7 @@ if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1140,7 +1170,7 @@ $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | +printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -1197,7 +1227,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Eggdrop Python Module 1.9.3 to adapt to many kinds of systems. +\`configure' configures Eggdrop Python Module 1.10.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1260,22 +1290,24 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Eggdrop Python Module 1.9.3:";; + short | recursive ) echo "Configuration of Eggdrop Python Module 1.10.0:";; esac cat <<\_ACEOF -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-python enable Python support (autodetect) - --disable-python disable Python support - Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-python-config=PATH Path to python-config +Some influential environment variables: + PYTHON_VERSION + The installed Python version to use, for example '2.3'. This + string will be appended to the Python interpreter canonical + name. + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + Report bugs to . _ACEOF ac_status=$? @@ -1292,9 +1324,9 @@ if test "$ac_init_help" = "recursive"; then case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; @@ -1322,7 +1354,8 @@ esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive @@ -1330,7 +1363,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix echo && $SHELL "$ac_srcdir/configure" --help=recursive else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done @@ -1339,10 +1372,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Eggdrop Python Module configure 1.9.3 -generated by GNU Autoconf 2.69 +Eggdrop Python Module configure 1.10.0 +generated by GNU Autoconf 2.71 -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. @@ -1354,14 +1387,34 @@ fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Eggdrop Python Module $as_me 1.9.3, which was -generated by GNU Autoconf 2.69. Invocation command line was +It was created by Eggdrop Python Module $as_me 1.10.0, which was +generated by GNU Autoconf 2.71. Invocation command line was - $ $0 $@ + $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log @@ -1394,8 +1447,12 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS @@ -1430,7 +1487,7 @@ do | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; @@ -1465,11 +1522,13 @@ done # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo - $as_echo "## ---------------- ## + printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo @@ -1480,8 +1539,8 @@ trap 'exit_status=$? case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( @@ -1505,7 +1564,7 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ) echo - $as_echo "## ----------------- ## + printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo @@ -1513,14 +1572,14 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; do eval ac_val=\$$ac_var case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac - $as_echo "$ac_var='\''$ac_val'\''" + printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## + printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo @@ -1528,15 +1587,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; do eval ac_val=\$$ac_var case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac - $as_echo "$ac_var='\''$ac_val'\''" + printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then - $as_echo "## ----------- ## + printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo @@ -1544,8 +1603,8 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; echo fi test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && @@ -1559,63 +1618,48 @@ ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h -$as_echo "/* confdefs.h */" > confdefs.h +printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac + ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" + +for ac_site_file in $ac_site_files do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi @@ -1625,16 +1669,16 @@ if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi @@ -1648,12 +1692,12 @@ for ac_var in $ac_precious_vars; do eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) @@ -1662,24 +1706,24 @@ $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in @@ -1689,11 +1733,12 @@ $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi done if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' + and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -1708,44 +1753,17 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -ac_aux_dir= -for ac_dir in ../../../misc "$srcdir"/../../../misc; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../../../misc \"$srcdir\"/../../../misc" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +printf %s "checking for grep that handles long lines and -e... " >&6; } +if test ${ac_cv_path_GREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST @@ -1753,10 +1771,15 @@ else for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in grep ggrep + do for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP @@ -1765,13 +1788,13 @@ case `"$ac_path_GREP" --version 2>&1` in ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 - $as_echo_n 0123456789 >"conftest.in" + printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" + printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val @@ -1799,16 +1822,17 @@ else fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 -$as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +printf %s "checking for fgrep... " >&6; } +if test ${ac_cv_path_FGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else @@ -1819,10 +1843,15 @@ else for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in fgrep; do + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in fgrep + do for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP @@ -1831,13 +1860,13 @@ case `"$ac_path_FGREP" --version 2>&1` in ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 - $as_echo_n 0123456789 >"conftest.in" + printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - $as_echo 'FGREP' >> "conftest.nl" + printf "%s\n" 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val @@ -1866,44 +1895,23 @@ fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 -$as_echo "$ac_cv_path_FGREP" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +printf "%s\n" "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to compile the Python module" >&5 -$as_echo_n "checking whether to compile the Python module... " >&6; } - # Check whether --enable-python was given. -if test "${enable_python+set}" = set; then : - enableval=$enable_python; egg_enable_python="$enableval" -fi - - # Check whether --enable-python was given. -if test "${enable_python+set}" = set; then : - enableval=$enable_python; egg_enable_python="$enableval" -else - egg_enable_python="autodetect" -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $egg_enable_python" >&5 -$as_echo "$egg_enable_python" >&6; } - - - # Check whether --with-python-config was given. -if test "${with_python_config+set}" = set; then : +if test ${with_python_config+y} +then : withval=$with_python_config; - if test "x$enable_python" != "xno"; then - if test -d "$withval" || test -x "$withval"; then - egg_with_python_config="$withval" - else - egg_with_python_config="no" - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Invalid path to python-config. $withval is not a directory and not an executable." >&5 -$as_echo "$as_me: WARNING: Invalid path to python-config. $withval is not a directory and not an executable." >&2;} - fi + if test -d "$withval" || test -x "$withval"; then + egg_with_python_config="$withval" + else + egg_with_python_config="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Invalid path to python-config. $withval is not a directory and not an executable." >&5 +printf "%s\n" "$as_me: WARNING: Invalid path to python-config. $withval is not a directory and not an executable." >&2;} fi fi @@ -1915,15 +1923,17 @@ python_avail="false" if test "x$egg_enable_python" != "xno"; then if test "x$egg_with_python_config" = "x"; then - for ac_prog in python3-config python-config + # based on serial 20 https://www.gnu.org/software/autoconf-archive/ax_python.html + for ac_prog in python3-config python3.12-config python3.11-config python3.10-config python3.9-config python3.8-config python-config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_python_config_bin+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_python_config_bin+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $python_config_bin in [\\/]* | ?:[\\/]*) ac_cv_path_python_config_bin="$python_config_bin" # Let the user override the test with a path. @@ -1933,11 +1943,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_python_config_bin="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_python_config_bin="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -1949,11 +1963,11 @@ esac fi python_config_bin=$ac_cv_path_python_config_bin if test -n "$python_config_bin"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $python_config_bin" >&5 -$as_echo "$python_config_bin" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $python_config_bin" >&5 +printf "%s\n" "$python_config_bin" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -1962,17 +1976,18 @@ done else if test -d "$egg_with_python_config"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Checking for python-config binaries in $egg_with_python_config" >&5 -$as_echo "$as_me: Checking for python-config binaries in $egg_with_python_config" >&6;} - for ac_prog in python3-config python-config + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Checking for python-config binaries in $egg_with_python_config" >&5 +printf "%s\n" "$as_me: Checking for python-config binaries in $egg_with_python_config" >&6;} + for ac_prog in python3-config python3.12-config python3.11-config python3.10-config python3.9-config python3.8-config python-config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_python_config_bin+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_python_config_bin+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $python_config_bin in [\\/]* | ?:[\\/]*) ac_cv_path_python_config_bin="$python_config_bin" # Let the user override the test with a path. @@ -1982,11 +1997,15 @@ else for as_dir in $egg_with_python_config do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_python_config_bin="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_python_config_bin="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -1998,11 +2017,11 @@ esac fi python_config_bin=$ac_cv_path_python_config_bin if test -n "$python_config_bin"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $python_config_bin" >&5 -$as_echo "$python_config_bin" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $python_config_bin" >&5 +printf "%s\n" "$python_config_bin" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -2012,60 +2031,160 @@ done else if test -x "$egg_with_python_config"; then python_config_bin="$egg_with_python_config" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Specified --with-python-config=$egg_with_python_config does not exist." >&5 -$as_echo "$as_me: WARNING: Specified --with-python-config=$egg_with_python_config does not exist." >&2;} fi fi fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: Python module disabled." >&5 -$as_echo "$as_me: Python module disabled." >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Python module disabled." >&5 +printf "%s\n" "$as_me: Python module disabled." >&6;} fi if test "x$python_config_bin" != "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether python-config supports --embed" >&5 -$as_echo_n "checking whether python-config supports --embed... " >&6; } - if $python_config_bin --help | $FGREP -q -- --embed; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether python-config supports --embed" >&5 +printf %s "checking whether python-config supports --embed... " >&6; } + if $python_config_bin --help | $FGREP -q -- --embed +then : PYTHON_CONFIG_ARGS="--embed" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } -else +else $as_nop PYTHON_CONFIG_ARGS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for python C flags" >&5 -$as_echo_n "checking for python C flags... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python C flags" >&5 +printf %s "checking for python C flags... " >&6; } PYTHON_CFLAGS=`$python_config_bin $PYTHON_CONFIG_ARGS --cflags` - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CFLAGS" >&5 -$as_echo "$PYTHON_CFLAGS" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CFLAGS" >&5 +printf "%s\n" "$PYTHON_CFLAGS" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for python LD flags" >&5 -$as_echo_n "checking for python LD flags... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python LD flags" >&5 +printf %s "checking for python LD flags... " >&6; } PYTHON_LDFLAGS=`$python_config_bin $PYTHON_CONFIG_ARGS --ldflags` - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LDFLAGS" >&5 -$as_echo "$PYTHON_LDFLAGS" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LDFLAGS" >&5 +printf "%s\n" "$PYTHON_LDFLAGS" >&6; } python_avail="true" fi +# Check python path + + +PYTHON_VERSION=`echo $PYTHON_LDFLAGS | sed 's/.*-lpython\(.*[0-9]\).*/\1/'` + +# Check for python version +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AWK+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +printf "%s\n" "$AWK" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AWK" && break +done + + + + + # Used to indicate true or false condition + ax_compare_version=false + + # Convert the two version strings to be compared into a format that + # allows a simple string comparison. The end result is that a version + # string of the form 1.12.5-r617 will be converted to the form + # 0001001200050617. In other words, each number is zero padded to four + # digits, and non digits are removed. + + ax_compare_version_A=`echo "$PYTHON_VERSION" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/[^0-9]//g'` + + + ax_compare_version_B=`echo "3.8.0" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/[^0-9]//g'` + + + ax_compare_version=`echo "x$ax_compare_version_A +x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` + + + + if test "$ax_compare_version" = "true" ; then + ax_check_ver="yes" + else ax_check_ver="no" + fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking python version is >= 3.8.0" >&5 +printf %s "checking python version is >= 3.8.0... " >&6; } +if test "x$ax_check_ver" = x"no"; then + python_avail="false" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no ($PYTHON_VERSION)" >&5 +printf "%s\n" "no ($PYTHON_VERSION)" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Eggdrop requires python version 3.8.0 or higher" >&5 +printf "%s\n" "$as_me: WARNING: Eggdrop requires python version 3.8.0 or higher" >&2;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes ($PYTHON_VERSION)" >&5 +printf "%s\n" "yes ($PYTHON_VERSION)" >&6; } +fi + # Disable the module if test "x$python_avail" = "xfalse"; then if test "x$egg_enable_python" != "xno"; then cat >&2 <&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( @@ -2134,15 +2253,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; /^ac_cv_env_/b end t clear :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else @@ -2156,8 +2275,8 @@ $as_echo "$as_me: updating cache $cache_file" >&6;} fi fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache @@ -2210,7 +2329,7 @@ U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" @@ -2226,8 +2345,8 @@ LTLIBOBJS=$ac_ltlibobjs ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL @@ -2250,14 +2369,16 @@ cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else +else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( @@ -2267,46 +2388,46 @@ esac fi + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then +if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || @@ -2315,13 +2436,6 @@ if test "${PATH_SEPARATOR+set}" != set; then fi -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( @@ -2330,8 +2444,12 @@ case $0 in #(( for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS @@ -2343,30 +2461,10 @@ if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] @@ -2379,13 +2477,14 @@ as_fn_error () as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $2" >&2 + printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error + # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -2412,18 +2511,20 @@ as_fn_unset () { eval $1=; unset $1;} } as_unset=as_fn_unset + # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : eval 'as_fn_append () { eval $1+=\$2 }' -else +else $as_nop as_fn_append () { eval $1=\$$1\$2 @@ -2435,12 +2536,13 @@ fi # as_fn_append # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : eval 'as_fn_arith () { as_val=$(( $* )) }' -else +else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` @@ -2471,7 +2573,7 @@ as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | +printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q @@ -2493,6 +2595,10 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) @@ -2506,6 +2612,12 @@ case `echo -n x` in #((((( ECHO_N='-n';; esac +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file @@ -2547,7 +2659,7 @@ as_fn_mkdir_p () as_dirs= while :; do case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" @@ -2556,7 +2668,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | +printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -2618,8 +2730,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Eggdrop Python Module $as_me 1.9.3, which was -generated by GNU Autoconf 2.69. Invocation command line was +This file was extended by Eggdrop Python Module $as_me 1.10.0, which was +generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -2668,19 +2780,22 @@ $config_files Report bugs to ." _ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -Eggdrop Python Module config.status 1.9.3 -configured by $0, generated by GNU Autoconf 2.69, +Eggdrop Python Module config.status 1.10.0 +configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' +AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF @@ -2712,21 +2827,21 @@ do -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; + printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; + printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; + printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; @@ -2754,7 +2869,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" @@ -2768,7 +2883,7 @@ exec 5>>config.log sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX - $as_echo "$ac_log" + printf "%s\n" "$ac_log" } >&5 _ACEOF @@ -2793,7 +2908,7 @@ done # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree @@ -3021,7 +3136,7 @@ do esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done @@ -3029,17 +3144,17 @@ do # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | + ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac @@ -3056,7 +3171,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | +printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -3080,9 +3195,9 @@ $as_echo X"$ac_file" | case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; @@ -3135,8 +3250,8 @@ ac_sed_dataroot=' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' @@ -3178,9 +3293,9 @@ test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" @@ -3227,6 +3342,8 @@ if test "$no_create" != yes; then $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi + + diff --git a/src/mod/python.mod/configure.ac b/src/mod/python.mod/configure.ac index dba914235..ddb3f28d2 100644 --- a/src/mod/python.mod/configure.ac +++ b/src/mod/python.mod/configure.ac @@ -21,16 +21,15 @@ python_avail="false" if test "x$egg_enable_python" != "xno"; then if test "x$egg_with_python_config" = "x"; then - AC_PATH_PROGS([python_config_bin], [python3-config python-config]) + # based on serial 20 https://www.gnu.org/software/autoconf-archive/ax_python.html + AC_PATH_PROGS([python_config_bin], [python3-config python3.12-config python3.11-config python3.10-config python3.9-config python3.8-config python-config]) else if test -d "$egg_with_python_config"; then AC_MSG_NOTICE([Checking for python-config binaries in $egg_with_python_config]) - AC_PATH_PROGS([python_config_bin], [python3-config python-config], [], [$egg_with_python_config]) + AC_PATH_PROGS([python_config_bin], [python3-config python3.12-config python3.11-config python3.10-config python3.9-config python3.8-config python-config], [], [$egg_with_python_config]) else if test -x "$egg_with_python_config"; then python_config_bin="$egg_with_python_config" - else - AC_MSG_WARN([Specified --with-python-config=$egg_with_python_config does not exist.]) fi fi fi @@ -66,28 +65,18 @@ version to use, for example '2.3'. This string will be appended to the Python interpreter canonical name.]) -AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) - if test -z "$PYTHON"; then - AC_MSG_WARN([Cannot find python$PYTHON_VERSION in your system path]) - if ! $ax_python_devel_optional; then - AC_MSG_ERROR([Giving up, python development not available]) - fi - ax_python_devel_found=no - PYTHON_VERSION="" -fi +PYTHON_VERSION=`echo $PYTHON_LDFLAGS | sed 's/.*-lpython\(.*[[0-9]]\).*/\1/'` # Check for python version - python_ver=`$PYTHON -c "import sys; \ - print(sys.version.split ()[[0]])"` - AX_COMPARE_VERSION([$python_ver],[ge],[3.8.0], [ax_check_ver="yes"], [ax_check_ver="no"]) - AC_MSG_CHECKING([$PYTHON version is >= 3.8.0]) - if test "x$ax_check_ver" = x"no"; then - python_avail="false" - AC_MSG_RESULT([no ($python_ver)]) - AC_MSG_WARN([Eggdrop requires python version 3.8.0 or higher]) - else - AC_MSG_RESULT([yes ($python_ver)]) - fi +AX_COMPARE_VERSION([$PYTHON_VERSION],[ge],[3.8.0], [ax_check_ver="yes"], [ax_check_ver="no"]) +AC_MSG_CHECKING([python version is >= 3.8.0]) +if test "x$ax_check_ver" = x"no"; then + python_avail="false" + AC_MSG_RESULT([no ($PYTHON_VERSION)]) + AC_MSG_WARN([Eggdrop requires python version 3.8.0 or higher]) +else + AC_MSG_RESULT([yes ($PYTHON_VERSION)]) +fi # Disable the module if test "x$python_avail" = "xfalse"; then diff --git a/src/mod/python.mod/pycmds.c b/src/mod/python.mod/pycmds.c index 051bf7844..1e55088c4 100644 --- a/src/mod/python.mod/pycmds.c +++ b/src/mod/python.mod/pycmds.c @@ -149,7 +149,7 @@ static int tcl_call_python(ClientData cd, Tcl_Interp *irp, int objc, Tcl_Obj *co } if (!PyObject_Call(bindinfo->callback, args, NULL)) { PyErr_Print(); - Tcl_SetResult(irp, "Error calling python code", NULL); + Tcl_SetResult(irp, "Error calling python code", TCL_STATIC); return TCL_ERROR; } return TCL_OK; diff --git a/src/mod/python.mod/python.c b/src/mod/python.mod/python.c index 60b3a052f..c4221efac 100644 --- a/src/mod/python.mod/python.c +++ b/src/mod/python.mod/python.c @@ -31,7 +31,6 @@ #undef interp #define tclinterp (*(Tcl_Interp **)(global[128])) #undef days -#include #include #include #include "src/mod/irc.mod/irc.h" @@ -43,6 +42,7 @@ static PyObject *pirp, *pglobals; #undef global static Function *global = NULL, *irc_funcs = NULL; +static PyThreadState *_pythreadsave; #include "src/mod/python.mod/pycmds.c" #include "src/mod/python.mod/tclpython.c" @@ -53,42 +53,43 @@ static int python_expmem() return 0; // TODO } -// TODO: Do we really have to exit eggdrop on module load failure? -static void init_python() { +static int python_gil_unlock() { + _pythreadsave = PyEval_SaveThread(); + return 0; +} + +static int python_gil_lock() { + PyEval_RestoreThread(_pythreadsave); + return 0; +} + +static char *init_python() { PyObject *pmodule; PyStatus status; PyConfig config; - if (PY_VERSION_HEX < 0x0308) { - putlog(LOG_MISC, "*", "Python: Python version %d is lower than 3.8, not loading Python module", PY_VERSION_HEX); - return; - } PyConfig_InitPythonConfig(&config); config.install_signal_handlers = 0; config.parse_argv = 0; status = PyConfig_SetBytesString(&config, &config.program_name, argv0); if (PyStatus_Exception(status)) { PyConfig_Clear(&config); - putlog(LOG_MISC, "*", "Python: Fatal error: Could not set program base path"); - Py_ExitStatusException(status); + return "Python: Fatal error: Could not set program base path"; } if (PyImport_AppendInittab("eggdrop", &PyInit_eggdrop) == -1) { - putlog(LOG_MISC, "*", "Python: Error: could not extend in-built modules table"); - exit(1); + PyConfig_Clear(&config); + return "Python: Error: could not extend in-built modules table"; } status = Py_InitializeFromConfig(&config); if (PyStatus_Exception(status)) { PyConfig_Clear(&config); - putlog(LOG_MISC, "*", "Python: Fatal error: Could not initialize config"); - fatal(1); + return "Python: Fatal error: Could not initialize config"; } PyConfig_Clear(&config); PyDateTime_IMPORT; pmodule = PyImport_ImportModule("eggdrop"); if (!pmodule) { - PyErr_Print(); - putlog(LOG_MISC, "*", "Error: could not import module 'eggdrop'"); - fatal(1); + return "Error: could not import module 'eggdrop'"; } pirp = PyImport_AddModule("__main__"); @@ -100,7 +101,7 @@ static void init_python() { PyRun_SimpleString("import eggdrop"); PyRun_SimpleString("sys.displayhook = eggdrop.__displayhook__"); - return; + return NULL; } static void kill_python() { @@ -112,12 +113,14 @@ static void kill_python() { static void python_report(int idx, int details) { - // TODO + if (details) + dprintf(idx, " python version: %s (header version " PY_VERSION ")\n", Py_GetVersion()); } static char *python_close() { - Context; + del_hook(HOOK_PRE_SELECT, (Function)python_gil_unlock); + del_hook(HOOK_POST_SELECT, (Function)python_gil_lock); kill_python(); rem_builtins(H_dcc, mydcc); rem_tcl_commands(my_tcl_cmds); @@ -134,12 +137,12 @@ 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; - Context; /* Register the module. */ module_register(MODULE_NAME, python_table, 0, 1); @@ -154,10 +157,14 @@ char *python_start(Function *global_funcs) } // irc.mod depends on server.mod and channels.mod, so those were implicitely loaded - init_python(); + 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/mod/python.mod/scripts/urlTitle.py b/src/mod/python.mod/scripts/urlTitle.py index 60dc6ae00..b2d35899a 100644 --- a/src/mod/python.mod/scripts/urlTitle.py +++ b/src/mod/python.mod/scripts/urlTitle.py @@ -17,6 +17,7 @@ def pubGetTitle(nick, host, handle, channel, text, **kwargs): try: reqs = requests.get(text) soup = BeautifulSoup(reqs.text, 'html.parser') + putlog("Found title for "+text) putmsg(channel, "The title of the webpage is: "+soup.find_all('title')[0].get_text()) except Exception as e: putmsg(channel, "Error: " + str(e)) @@ -24,4 +25,4 @@ def pubGetTitle(nick, host, handle, channel, text, **kwargs): # Call binds at the end of the script, not the top- the functions must be defined! bind("pub", "*", "!title", pubGetTitle) -print('Loaded example.py') +print('Loaded urlTitle.py') diff --git a/src/mod/seen.mod/seen.c b/src/mod/seen.mod/seen.c index 41cea68d2..63ddd0593 100644 --- a/src/mod/seen.mod/seen.c +++ b/src/mod/seen.mod/seen.c @@ -73,12 +73,6 @@ #include "src/mod/module.h" -#ifdef HAVE_SYS_TIME_H -# include -#else -# include -#endif - #include "src/users.h" #include "src/chan.h" #include "channels.mod/channels.h" @@ -148,7 +142,7 @@ static int dcc_seen(struct userrec *u, int idx, char *par) static void do_seen(int idx, char *prefix, char *nick, char *hand, char *channel, char *text) { - char stuff[512], word1[512], word2[512], whotarget[128], object[128], + char word1[512], word2[512], whotarget[128], object[128], whoredirect[512], *oix, *lastonplace = 0; struct userrec *urec; struct chanset_t *chan; @@ -194,8 +188,7 @@ static void do_seen(int idx, char *prefix, char *nick, char *hand, m = ismember(chan, object); if (m) { onchan = 1; - snprintf(stuff, sizeof stuff, "%s!%s", object, m->userhost); - urec = get_user_by_host(stuff); + urec = get_user_from_member(m); if (!urec || !strcasecmp(object, urec->handle)) break; strcat(whoredirect, object); @@ -342,7 +335,7 @@ static void do_seen(int idx, char *prefix, char *nick, char *hand, if (m) { onchan = 1; snprintf(word1, sizeof word1, "%s!%s", whotarget, m->userhost); - urec = get_user_by_host(word1); + urec = get_user_from_member(m); if (!urec || !strcasecmp(whotarget, urec->handle)) break; strcat(whoredirect, whotarget); @@ -359,8 +352,7 @@ static void do_seen(int idx, char *prefix, char *nick, char *hand, while (chan) { m = chan->channel.member; while (m && m->nick[0]) { - snprintf(word2, sizeof word2, "%s!%s", m->nick, m->userhost); - urec = get_user_by_host(word2); + urec = get_user_from_member(m); if (urec && !strcasecmp(urec->handle, whotarget)) { strcat(whoredirect, whotarget); strcat(whoredirect, " is "); diff --git a/src/mod/server.mod/cmdsserv.c b/src/mod/server.mod/cmdsserv.c index ab580d208..ceb79e436 100644 --- a/src/mod/server.mod/cmdsserv.c +++ b/src/mod/server.mod/cmdsserv.c @@ -20,7 +20,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include static void cmd_servers(struct userrec *u, int idx, char *par) { diff --git a/src/mod/server.mod/server.c b/src/mod/server.mod/server.c index 80d0ad5f1..6aff0e488 100644 --- a/src/mod/server.mod/server.c +++ b/src/mod/server.mod/server.c @@ -1413,7 +1413,7 @@ static int server_raw STDVAR static int server_rawt STDVAR { - int unused; + Tcl_Size unused; Tcl_Obj *tagdict; Function F = (Function) cd; @@ -1809,7 +1809,8 @@ static char *tcl_eggserver(ClientData cdata, Tcl_Interp *irp, EGG_CONST char *name1, EGG_CONST char *name2, int flags) { - int lc, code, i; + Tcl_Size lc, i; + int code; char x[1024]; EGG_CONST char **list, *slist; struct server_list *q; diff --git a/src/mod/server.mod/servmsg.c b/src/mod/server.mod/servmsg.c index 85baed7cf..91a50e2e9 100644 --- a/src/mod/server.mod/servmsg.c +++ b/src/mod/server.mod/servmsg.c @@ -493,7 +493,7 @@ static int detect_flood(char *floodnick, char *floodhost, char *from, int which) if (!strcasecmp(floodhost, botuserhost)) return 0; - u = get_user_by_host(from); + u = lookup_user_record(NULL, NULL, from); // TODO: get account somehow atr = u ? u->flags : 0; if (atr & (USER_BOT | USER_FRIEND)) return 0; @@ -539,7 +539,7 @@ static int detect_flood(char *floodnick, char *floodhost, char *from, int which) lastmsgs[which] = 0; lastmsgtime[which] = 0; lastmsghost[which][0] = 0; - u = get_user_by_host(from); + u = lookup_user_record(NULL, NULL, from); // TODO: get account somehow if (check_tcl_flud(floodnick, floodhost, u, ftype, "*")) return 0; /* Private msg */ @@ -607,7 +607,7 @@ static int gotmsg(char *from, char *msg) putlog(LOG_PUBLIC, to, "CTCP %s: %s from %s (%s) to %s", code, ctcp, nick, uhost, to); } else { - u = get_user_by_host(from); + u = lookup_user_record(find_member_from_nick(nick), NULL, from); // TODO: get account from msgtags if (!ignoring || trigger_on_ignore) { if (!check_tcl_ctcp(nick, uhost, u, to, code, ctcp) && !ignoring) { if ((lowercase_ctcp && !strcasecmp(code, "DCC")) || @@ -670,7 +670,7 @@ static int gotmsg(char *from, char *msg) } detect_flood(nick, uhost, from, FLOOD_PRIVMSG); - u = get_user_by_host(from); + u = lookup_user_record(find_member_from_nick(nick), NULL, from); // TODO: get account from msgtags code = newsplit(&msg); rmspace(msg); @@ -730,7 +730,7 @@ static int gotnotice(char *from, char *msg) "CTCP reply %s: %s from %s (%s) to %s", code, ctcp, nick, uhost, to); } else { - u = get_user_by_host(from); + u = lookup_user_record(find_member_from_nick(nick), NULL, from); // TODO: get account from msgtags if (!ignoring || trigger_on_ignore) { check_tcl_ctcr(nick, uhost, u, to, code, ctcp); if (!ignoring) @@ -766,7 +766,7 @@ static int gotnotice(char *from, char *msg) } detect_flood(nick, uhost, from, FLOOD_NOTICE); - u = get_user_by_host(from); + u = lookup_user_record(find_member_from_nick(nick), NULL, from); // TODO: get account from msgtags if (!ignoring || trigger_on_ignore) if (check_tcl_notc(nick, uhost, u, botname, msg) == 2) @@ -2001,6 +2001,54 @@ static int got730or1(char *from, char *msg, int code) return 0; } +/* Got IRCv3 standard-reply + * [...] + */ +static int gotstdreply(char *from, char *msgtype, char *msg) +{ + char *cmd, *code, *text; + char context[MSGMAX] = ""; + int len; + + cmd = newsplit(&msg); + code = newsplit(&msg); +/* TODO: Once this feature is better implemented, consider how to handle + * one-word descriptions that aren't technically required to have a : + */ + text = strstr(msg, " :"); + if (text) { + text++; + if (text != msg) { + len = text - msg; + snprintf(context, sizeof context, "%.*s", len, msg); + } + fixcolon(text); + } + putlog(LOG_SERV, "*", "%s: %s: Received a %s message from %s: %s", cmd, code, msgtype, from, text); + return 0; +} + +/* Got IRCv3 FAIL standard-reply */ +static int gotstdfail(char *from, char *msg) +{ + gotstdreply(from, "FAIL", msg); + return 0; +} + +/* Got IRCv3 NOTE standard-reply */ +static int gotstdnote(char *from, char *msg) +{ + gotstdreply(from, "NOTE", msg); + return 0; +} + +/* Got IRCv3 WARN standard-reply */ +static int gotstdwarn(char *from, char *msg) +{ + gotstdreply(from, "WARN", msg); + return 0; +} + /* Got 730/RPL_MONONLINE * : 730 :target[!user@host][,target[!user@host]]* */ @@ -2097,6 +2145,9 @@ static cmd_t my_raw_binds[] = { {"PING", "", (IntFunc) gotping, NULL}, {"PONG", "", (IntFunc) gotpong, NULL}, {"WALLOPS", "", (IntFunc) gotwall, NULL}, + {"FAIL", "", (IntFunc) gotstdfail, NULL}, + {"NOTE", "", (IntFunc) gotstdnote, NULL}, + {"WARN", "", (IntFunc) gotstdwarn, NULL}, {"001", "", (IntFunc) got001, NULL}, {"005", "", (IntFunc) got005, NULL}, {"303", "", (IntFunc) got303, NULL}, diff --git a/src/mod/server.mod/tclisupport.c b/src/mod/server.mod/tclisupport.c index 9dff94a65..66fa72aae 100644 --- a/src/mod/server.mod/tclisupport.c +++ b/src/mod/server.mod/tclisupport.c @@ -67,7 +67,7 @@ int tcl_isupport STDOBJVAR static int tcl_isupport_get STDOBJVAR { - int keylen; + Tcl_Size keylen; const char *key, *value; Tcl_Obj *tclres; @@ -95,13 +95,13 @@ static int tcl_isupport_get STDOBJVAR static int tcl_isupport_isset STDOBJVAR { - int keylen; + Tcl_Size keylen; const char *key, *value; BADOBJARGS(3, 3, 2, "setting"); key = Tcl_GetStringFromObj(objv[2], &keylen); value = isupport_get(key, keylen); - Tcl_SetResult(interp, value ? "1" : "0", NULL); + Tcl_SetResult(interp, value ? "1" : "0", TCL_STATIC); return TCL_OK; } @@ -109,7 +109,7 @@ static int tcl_isupport_isset STDOBJVAR /* not exposed for now */ static int tcl_isupport_set STDOBJVAR { - int keylen, valuelen; + Tcl_Size keylen, valuelen; const char *key, *value; /* First one to check for type validity only */ @@ -126,7 +126,7 @@ static int tcl_isupport_set STDOBJVAR static int tcl_isupport_unset STDOBJVAR { struct isupport *data; - int keylen; + Tcl_Size keylen; const char *key; BADOBJARGS(3, 3, 2, "setting"); @@ -138,7 +138,7 @@ static int tcl_isupport_unset STDOBJVAR TCL_ERR_NOTSET(irp, objv[2]); } if (!data->value) { - Tcl_SetResult(interp, "no server value set, cannot unset default values, change 'set isupport-default' instead", NULL); + Tcl_SetResult(interp, "no server value set, cannot unset default values, change 'set isupport-default' instead", TCL_STATIC); return TCL_ERROR; } isupport_unset(key, keylen); @@ -170,7 +170,7 @@ char *traced_isupport(ClientData cdata, Tcl_Interp *irp, } /* remove trailing space */ if (Tcl_DStringLength(&ds)) - Tcl_DStringTrunc(&ds, Tcl_DStringLength(&ds) - 1); + Tcl_DStringSetLength(&ds, Tcl_DStringLength(&ds) - 1); Tcl_SetVar2(interp, name1, name2, Tcl_DStringValue(&ds), TCL_GLOBAL_ONLY); Tcl_DStringFree(&ds); diff --git a/src/modules.c b/src/modules.c index afb614221..0fd005760 100644 --- a/src/modules.c +++ b/src/modules.c @@ -23,6 +23,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include #include "main.h" #include "modules.h" @@ -60,16 +61,10 @@ # ifndef RTLD_NOW # define RTLD_NOW 1 # endif -# ifdef RTLD_LAZY -# define DLFLAGS RTLD_LAZY|RTLD_GLOBAL -# else -# define DLFLAGS RTLD_NOW|RTLD_GLOBAL -# endif +# define DLFLAGS RTLD_NOW|RTLD_GLOBAL # endif /* MOD_USE_DL */ #endif /* !STATIC */ -#define strncpyz strlcpy - extern struct dcc_t *dcc; extern struct userrec *userlist, *lastuser; extern struct chanset_t *chanset; @@ -301,7 +296,7 @@ Function global_table[] = { (Function) open_telnet, /* 88 - 91 */ (Function) check_tcl_event, - (Function) 0, /* was egg_memcpy -- use memcpy() instead */ + (Function) memcpy, /* was egg_memcpy -- use memcpy() instead */ (Function) my_atoul, (Function) my_strcpy, /* 92 - 95 */ @@ -524,10 +519,10 @@ Function global_table[] = { /* 252 - 255 */ (Function) egg_snprintf, (Function) egg_vsnprintf, - (Function) 0, /* was egg_memset -- use memset() or egg_bzero() instead */ - (Function) 0, /* was egg_strcasecmp -- use strcasecmp() instead */ + (Function) memset, /* was egg_memset -- use memset() or egg_bzero() instead */ + (Function) strcasecmp, /* was egg_strcasecmp -- use strcasecmp() instead */ /* 256 - 259 */ - (Function) 0, /* was egg_strncasecmp -- use strncasecmp() instead */ + (Function) strncasecmp, /* was egg_strncasecmp -- use strncasecmp() instead */ (Function) is_file, (Function) & must_be_owner, /* int */ (Function) & tandbot, /* tand_t * */ @@ -595,7 +590,7 @@ Function global_table[] = { (Function) 0, #endif /* 304 - 307 */ - (Function) strncpyz, + (Function) strlcpy, /* was strncpyz() -- use strlcpy() instead */ #ifndef HAVE_BASE64 (Function) b64_ntop, (Function) b64_pton, @@ -626,7 +621,11 @@ Function global_table[] = { /* 320 - 323 */ (Function) bind_bind_entry, (Function) unbind_bind_entry, - (Function) & argv0 + (Function) & argv0, + (Function) lookup_user_record, +/* 324 - 327 */ + (Function) find_member_from_nick, + (Function) get_user_from_member, }; void init_modules(void) @@ -696,6 +695,7 @@ 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; @@ -704,7 +704,7 @@ const char *module_load(char *name) #endif #ifndef STATIC - char workbuf[1024]; + char workbuf[PATH_MAX]; # ifdef MOD_USE_SHL shl_t hand; # endif @@ -730,11 +730,14 @@ const char *module_load(char *name) #ifndef STATIC if (moddir[0] != '/') { - if (getcwd(workbuf, 1024) == NULL) + if (getcwd(workbuf, sizeof workbuf) == NULL) { + debug1("modules: getcwd(): %s\n", strerror(errno)); return MOD_BADCWD; - sprintf(&(workbuf[strlen(workbuf)]), "/%s%s." EGG_MOD_EXT, moddir, name); + } + len = strlen(workbuf); + snprintf(workbuf + len, (sizeof workbuf) - len, "/%s%s." EGG_MOD_EXT, moddir, name); } else { - sprintf(workbuf, "%s%s." EGG_MOD_EXT, moddir, name); + snprintf(workbuf, sizeof workbuf, "%s%s." EGG_MOD_EXT, moddir, name); } # ifdef MOD_USE_SHL diff --git a/src/net.c b/src/net.c index c8aa62cd5..5a63d5808 100644 --- a/src/net.c +++ b/src/net.c @@ -27,6 +27,7 @@ #include #include "main.h" +#include "modules.h" #include #include #include @@ -924,11 +925,13 @@ int sockread(char *s, int *len, sock_list *slist, int slistmax, int tclonly) t.tv_sec = td->blocktime.tv_sec; t.tv_usec = td->blocktime.tv_usec; + call_hook(HOOK_PRE_SELECT); x = select((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 (maxfd_r >= 0 ? &fdr : NULL), SELECT_TYPE_ARG234 (maxfd_w >= 0 ? &fdw : NULL), SELECT_TYPE_ARG234 (maxfd_e >= 0 ? &fde : NULL), SELECT_TYPE_ARG5 &t); + call_hook(HOOK_POST_SELECT); if (x == -1) return -2; /* socket error */ if (x == 0) @@ -973,7 +976,12 @@ int sockread(char *s, int *len, sock_list *slist, int slistmax, int tclonly) { if (slist[i].ssl) { x = SSL_read(slist[i].ssl, s, grab); - if (x < 0) { + if (!x && (SSL_get_shutdown(slist[i].ssl) == SSL_RECEIVED_SHUTDOWN)) { + *len = slist[i].sock; + slist[i].flags &= ~SOCK_CONNECT; + debug1("net: SSL_read(): received shutdown sock %i", slist[i].sock); + return -1; + } else if (x < 0) { int err = SSL_get_error(slist[i].ssl, x); if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) errno = EAGAIN; @@ -1053,16 +1061,18 @@ int sockread(char *s, int *len, sock_list *slist, int slistmax, int tclonly) #ifdef EGG_TDNS dtn_prev = dns_thread_head; for (dtn = dtn_prev->next; dtn; dtn = dtn->next) { + if (*dtn->strerror) + debug2("%s: hostname %s", dtn->strerror, dtn->host); fd = dtn->fildes[0]; if (FD_ISSET(fd, &fdr)) { if (dtn->type == DTN_TYPE_HOSTBYIP) { pthread_mutex_lock(&dtn->mutex); - call_hostbyip(&dtn->addr, dtn->host, dtn->ok); + call_hostbyip(&dtn->addr, dtn->host, !*dtn->strerror); pthread_mutex_unlock(&dtn->mutex); } else { pthread_mutex_lock(&dtn->mutex); - call_ipbyhost(dtn->host, &dtn->addr, dtn->ok); + call_ipbyhost(dtn->host, &dtn->addr, !*dtn->strerror); pthread_mutex_unlock(&dtn->mutex); } close(dtn->fildes[0]); @@ -1214,9 +1224,10 @@ int sockgets(char *s, int *len) /* Might be necessary to prepend stored-up data! */ if (socklist[ret].handler.sock.inbuf != NULL) { p = socklist[ret].handler.sock.inbuf; - socklist[ret].handler.sock.inbuf = nmalloc(strlen(p) + strlen(xx) + 1); - strcpy(socklist[ret].handler.sock.inbuf, p); - strcat(socklist[ret].handler.sock.inbuf, xx); + len2 = strlen(p); + socklist[ret].handler.sock.inbuf = nmalloc(len2 + strlen(xx) + 1); + memcpy(socklist[ret].handler.sock.inbuf, p, len2); + strcpy(socklist[ret].handler.sock.inbuf + len2, xx); nfree(p); if (strlen(socklist[ret].handler.sock.inbuf) < READMAX + 2) { strcpy(xx, socklist[ret].handler.sock.inbuf); @@ -1267,10 +1278,11 @@ int sockgets(char *s, int *len) /* Prepend old data back */ if (socklist[ret].handler.sock.inbuf != NULL) { p = socklist[ret].handler.sock.inbuf; - socklist[ret].handler.sock.inbuflen = strlen(p) + strlen(xx); + len2 = strlen(xx); + socklist[ret].handler.sock.inbuflen = len2 + strlen(p); socklist[ret].handler.sock.inbuf = nmalloc(socklist[ret].handler.sock.inbuflen + 1); - strcpy(socklist[ret].handler.sock.inbuf, xx); - strcat(socklist[ret].handler.sock.inbuf, p); + memcpy(socklist[ret].handler.sock.inbuf, xx, len2); + strcpy(socklist[ret].handler.sock.inbuf + len2, p); nfree(p); } else { socklist[ret].handler.sock.inbuflen = strlen(xx); @@ -1708,8 +1720,9 @@ char *traced_myiphostname(ClientData cd, Tcl_Interp *irp, EGG_CONST char *name1, { const char *value; - if (flags & TCL_INTERP_DESTROYED) + if (Tcl_InterpDeleted(irp)) return NULL; + /* 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_myiphostname, cd); diff --git a/src/proto.h b/src/proto.h index 463a087d6..0d95ae488 100644 --- a/src/proto.h +++ b/src/proto.h @@ -338,7 +338,6 @@ void correct_handle(char *); int write_user(struct userrec *, FILE *, int); int write_ignores(FILE *f, int); void write_userfile(int); -struct userrec *check_dcclist_hand(char *); void touch_laston(struct userrec *, char *, time_t); void user_del_chan(char *); int check_conflags(struct flag_record *fr, int md); diff --git a/src/tcl.c b/src/tcl.c index fe9b7eedf..64409ee25 100644 --- a/src/tcl.c +++ b/src/tcl.c @@ -183,9 +183,10 @@ static char *tcl_eggint(ClientData cdata, Tcl_Interp *irp, EGG_CONST char *name1, EGG_CONST char *name2, int flags) { - char *s, s1[40]; + char *s, s1[40], *endptr; long l; intinfo *ii = (intinfo *) cdata; + int p; if (flags & (TCL_TRACE_READS | TCL_TRACE_UNSETS)) { /* Special cases */ @@ -223,10 +224,9 @@ static char *tcl_eggint(ClientData cdata, Tcl_Interp *irp, default_uflags = fr.udef_global; } else if ((int *) ii->var == &userfile_perm) { - int p = oatoi(s); - - if (p <= 0) - return "Invalid userfile permissions"; + p = strtol(s, &endptr, 8); + if ((p < 01) || (p > 0777) || (*endptr)) + return "Invalid userfile permissions, must be octal between 01 and 0777"; userfile_perm = p; } else if ((ii->ro == 2) || ((ii->ro == 1) && protect_readonly)) return "Read-only variable"; @@ -767,6 +767,7 @@ Tcl_Obj *egg_string_unicodesup_desurrogate(const char *oldstr, int len) { int stridx = 0, bufidx = 0; char *buf = nmalloc(len); + Tcl_Obj *o; while (stridx < len) { uint32_t low, high; @@ -787,7 +788,10 @@ Tcl_Obj *egg_string_unicodesup_desurrogate(const char *oldstr, int len) } } } - return Tcl_NewStringObj(buf, bufidx); + + o = Tcl_NewStringObj(buf, bufidx); + nfree(buf); + return o; } /* C function called for ::egg_tcl_tolower/toupper/totitle @@ -901,17 +905,10 @@ void init_unicodesup(void) } #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 - */ -void init_tcl(int argc, char **argv) +void init_tcl0(int argc, char **argv) { Tcl_NotifierProcs notifierprocs; - - const char *encoding; - int i, j; - char *langEnv, pver[1024] = ""; - + egg_bzero(¬ifierprocs, sizeof(notifierprocs)); notifierprocs.initNotifierProc = tickle_InitNotifier; notifierprocs.createFileHandlerProc = tickle_CreateFileHandler; @@ -923,8 +920,8 @@ void init_tcl(int argc, char **argv) notifierprocs.serviceModeHookProc = tickle_ServiceModeHook; Tcl_SetNotifier(¬ifierprocs); - -/* This must be done *BEFORE* Tcl_SetSystemEncoding(), + + /* This must be done *BEFORE* Tcl_SetSystemEncoding(), * or Tcl_SetSystemEncoding() will cause a segfault. */ /* This is used for 'info nameofexecutable'. @@ -932,6 +929,19 @@ void init_tcl(int argc, char **argv) * the environment variable PATH for it to register anything. */ Tcl_FindExecutable(argv[0]); +#if TCL_MAJOR_VERSION >= 9 + Tcl_InitSubsystems(); +#endif +} + +/* Not going through Tcl's crazy main() system (what on earth was he + * smoking?!) so we gotta initialize the Tcl interpreter + */ +void init_tcl1(int argc, char **argv) +{ + const char *encoding; + int i, j; + char *langEnv, pver[1024] = ""; /* Initialize the interpreter */ interp = Tcl_CreateInterp(); @@ -1242,17 +1252,17 @@ time_t get_expire_time(Tcl_Interp * irp, const char *s) { long expire_foo = strtol(s, &endptr, 10); if (*endptr) { - Tcl_AppendResult(irp, "bogus expire time", NULL); + Tcl_SetResult(irp, "bogus expire time", TCL_STATIC); return -1; } if (expire_foo < 0) { - Tcl_AppendResult(irp, "expire time must be 0 (perm) or greater than 0 days", NULL); + Tcl_SetResult(irp, "expire time must be 0 (perm) or greater than 0 days", TCL_STATIC); return -1; } if (expire_foo == 0) return 0; if (expire_foo > (60 * 24 * 2000)) { - Tcl_AppendResult(irp, "expire time must be equal to or less than 2000 days", NULL); + Tcl_SetResult(irp, "expire time must be equal to or less than 2000 days", TCL_STATIC); return -1; } return now + 60 * expire_foo; diff --git a/src/tclhash.c b/src/tclhash.c index 5128821ba..76d170af8 100644 --- a/src/tclhash.c +++ b/src/tclhash.c @@ -744,15 +744,12 @@ static int trigger_bind(const char *proc, const char *param, char *mask) r = getrusage(RUSAGE_SELF, &ru1); } x = Tcl_VarEval(interp, proc, param, NULL); - if (proc && proc[0] != '*' && !r) { - if (!getrusage(RUSAGE_SELF, &ru2)) { - debug3("triggered bind %s, user %.3fms sys %.3fms", proc, - (double) (ru2.ru_utime.tv_usec - ru1.ru_utime.tv_usec) / 1000 + - (double) (ru2.ru_utime.tv_sec - ru1.ru_utime.tv_sec ) * 1000, - (double) (ru2.ru_stime.tv_usec - ru1.ru_stime.tv_usec) / 1000 + - (double) (ru2.ru_stime.tv_sec - ru1.ru_stime.tv_sec ) * 1000); - } - } + if (proc && proc[0] != '*' && !r && !getrusage(RUSAGE_SELF, &ru2)) + debug3("triggered bind %s, user %.3fms sys %.3fms", proc, + (double) (ru2.ru_utime.tv_usec - ru1.ru_utime.tv_usec) / 1000 + + (double) (ru2.ru_utime.tv_sec - ru1.ru_utime.tv_sec ) * 1000, + (double) (ru2.ru_stime.tv_usec - ru1.ru_stime.tv_usec) / 1000 + + (double) (ru2.ru_stime.tv_sec - ru1.ru_stime.tv_sec ) * 1000); if (x == TCL_ERROR) { /* FIXME: we really should be able to log longer errors */ diff --git a/src/tclmisc.c b/src/tclmisc.c index ad9406809..bbfdb5299 100644 --- a/src/tclmisc.c +++ b/src/tclmisc.c @@ -24,15 +24,7 @@ #include #include "main.h" #include "modules.h" -#include "tandem.h" #include "md5/md5.h" - -#ifdef HAVE_SYS_TIME_H -# include -#else -# include -#endif - #include #include diff --git a/src/tcluser.c b/src/tcluser.c index d8e51a48b..383de67f7 100644 --- a/src/tcluser.c +++ b/src/tcluser.c @@ -22,9 +22,6 @@ */ #include "main.h" -#include "users.h" -#include "chan.h" -#include "tandem.h" #include "modules.h" #include "string.h" diff --git a/src/tls.c b/src/tls.c index 180af6b37..d3af0c6ea 100644 --- a/src/tls.c +++ b/src/tls.c @@ -531,6 +531,12 @@ static char *ssl_printname(X509_NAME *name) /* X509_NAME_oneline() is easier and shorter, but is deprecated and the manual discourages it's usage, so let's not be lazy ;) */ + if (!bio) { + debug0("TLS: ssl_printname(): BIO_new(): error"); + buf = nmalloc(1); + *buf = 0; + return buf; + } if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_ONELINE & ~XN_FLAG_SPC_EQ)) { len = BIO_get_mem_data(bio, &data); if (len > 0) { @@ -564,6 +570,12 @@ static char *ssl_printtime(ASN1_UTCTIME *t) char *data, *buf; BIO *bio = BIO_new(BIO_s_mem()); + if (!bio) { + debug0("TLS: ssl_printtime(): BIO_new(): error"); + buf = nmalloc(1); + *buf = 0; + return buf; + } ASN1_UTCTIME_print(bio, t); len = BIO_get_mem_data(bio, &data); if (len > 0) { @@ -591,6 +603,12 @@ static char *ssl_printnum(ASN1_INTEGER *i) char *data, *buf; BIO *bio = BIO_new(BIO_s_mem()); + if (!bio) { + debug0("TLS: ssl_printnum(): BIO_new(): error"); + buf = nmalloc(1); + *buf = 0; + return buf; + } i2a_ASN1_INTEGER(bio, i); len = BIO_get_mem_data(bio, &data); if (len > 0) { @@ -712,7 +730,7 @@ int ssl_verify(int ok, X509_STORE_CTX *ctx) !(data->verify & TLS_VERIFYFROM)) || ((err == X509_V_ERR_CERT_HAS_EXPIRED) && !(data->verify & TLS_VERIFYTO))) { - debug1("TLS: peer certificate warning: %s", + putlog(data->loglevel, "*", "TLS: peer certificate warning: %s", X509_verify_cert_error_string(err)); ok = 1; } @@ -799,7 +817,7 @@ static void ssl_info(const SSL *ssl, int where, int ret) SSL_alert_desc_string_long(ret)); } else { /* Ignore close notify warnings */ - debug1("Received close notify warning during %s", + debug1("TLS: Received close notify during %s", (where & SSL_CB_READ) ? "read" : "write"); } } else if (where & SSL_CB_EXIT) { @@ -819,10 +837,16 @@ static void ssl_info(const SSL *ssl, int where, int ret) SSL_state_string_long(ssl)); } } - } else { - /* Display the state of the engine for debugging purposes */ - debug1("TLS: state change: %s", SSL_state_string_long(ssl)); } + /* Display the state of the engine for debugging purposes */ + else if (where == SSL_CB_HANDSHAKE_START) + debug1("TLS: handshake start: %s", SSL_state_string_long(ssl)); + else if (where == SSL_CB_CONNECT_LOOP) + debug1("TLS: connect loop: %s", SSL_state_string_long(ssl)); + else if (where == SSL_CB_ACCEPT_LOOP) + debug1("TLS: accept loop: %s", SSL_state_string_long(ssl)); + else + debug1("TLS: state change: %s", SSL_state_string_long(ssl)); } /* Switch a socket to SSL communication @@ -902,9 +926,9 @@ int ssl_handshake(int sock, int flags, int verify, int loglevel, char *host, SSL_set_mode(td->socklist[i].ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); if (data->flags & TLS_CONNECT) { - struct timespec req = { 0, 1000000L }; SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify); /* Introduce 1ms lag so an unpatched hub has time to setup the ssl handshake */ + const struct timespec req = { 0, 1000000L }; nanosleep(&req, NULL); #ifdef SSL_set_tlsext_host_name if (*data->host) diff --git a/src/userent.c b/src/userent.c index 3fde1f20a..a070995fd 100644 --- a/src/userent.c +++ b/src/userent.c @@ -1036,7 +1036,8 @@ static int xtra_pack(struct userrec *u, struct user_entry *e) static void xtra_display(int idx, struct user_entry *e) { - int code, lc, j; + int code; + Tcl_Size lc, j; EGG_CONST char **list; struct xtra_key *xk; diff --git a/src/userrec.c b/src/userrec.c index 487fd79a8..66bb8f16c 100644 --- a/src/userrec.c +++ b/src/userrec.c @@ -25,8 +25,6 @@ #include #include "main.h" -#include "users.h" -#include "chan.h" #include "modules.h" #include "tandem.h" @@ -161,7 +159,9 @@ int count_users(struct userrec *bu) return tot; } -struct userrec *check_dcclist_hand(char *handle) +/* Shortcut for get_user_by_handle -- might have user record in dccs + */ +static struct userrec *check_dcclist_hand(char *handle) { int i; @@ -171,6 +171,23 @@ struct userrec *check_dcclist_hand(char *handle) return NULL; } +/* Search every channel record for the provided nickname. Used in cases where + * we are searching for a user record but don't have a memberlist to start from + */ +memberlist *find_member_from_nick(char *nick) { + struct chanset_t *chan; + memberlist *m = NULL; + + for (chan = chanset; chan; chan = chan->next) { + for (m = chan->channel.member; m && m->nick[0]; m = m->next) { + if (!rfc_casecmp(m->nick, nick)) { + return m; + } + } + } + return m; +} + /* Search userlist for a provided account name * Returns: userrecord for user containing the account */ @@ -179,12 +196,11 @@ struct userrec *get_user_by_account(char *acct) struct userrec *u; struct list_type *q; - if (acct == NULL) + if (!acct || !acct[0] || !strcmp(acct, "*")) return NULL; for (u = userlist; u; u = u->next) { - q = get_user(&USERENTRY_ACCOUNT, u); - for (; q; q = q->next) { - if(q && !strcasecmp(q->extra, acct)) { + for (q = get_user(&USERENTRY_ACCOUNT, u); q; q = q->next) { + if (!rfc_casecmp(q->extra, acct)) { return u; } } @@ -192,7 +208,6 @@ struct userrec *get_user_by_account(char *acct) return NULL; } - struct userrec *get_user_by_handle(struct userrec *bu, char *handle) { struct userrec *u, *ret; @@ -213,11 +228,6 @@ struct userrec *get_user_by_handle(struct userrec *bu, char *handle) cache_hit++; return ret; } - ret = check_chanlist_hand(handle); - if (ret) { - cache_hit++; - return ret; - } cache_miss++; } for (u = bu; u; u = u->next) @@ -229,6 +239,76 @@ struct userrec *get_user_by_handle(struct userrec *bu, char *handle) return NULL; } +struct userrec *get_user_from_member(memberlist *m) +{ + struct userrec *ret = NULL; + + /* Check positive/negative cache first */ + if (m->user || m->tried_getuser) { + return m->user; + } + + /* Check if there is a user with a matching account if one is provided */ + if (m->account[0] != '*') { + ret = get_user_by_account(m->account); + if (ret) { + goto getuser_done; + } + } + + /* Check if there is a user with a matching hostmask if one is provided */ + if ((m->userhost[0] != '\0') && (m->nick[0] != '\0')) { + char s[NICKMAX+UHOSTLEN+1]; + sprintf(s, "%s!%s", m->nick, m->userhost); + ret = get_user_by_host(s); + if (ret) { + goto getuser_done; + } + } + +getuser_done: + m->user = ret; + m->tried_getuser = 1; + return NULL; +} + +/* Wrapper function to find an Eggdrop user record based on either a provided + * channel memberlist record, host, or account. This function will first check + * a provided memberlist and return the result. If no user record is found (or + * the memberlist itself was NULL), this function will try again based on a + * provided account, and then again on a provided host. + * + * When calling this function it is best to provide all available independent + * variables- ie, if you provide 'm' for the memberlist, don't provide + * 'm->account' for the account, use the independent source variable 'account' + * if available. This allows redundant checking in case of unexpected NULLs + */ +struct userrec *lookup_user_record(memberlist *m, char *host, char *account) +{ + struct userrec *u = NULL; + +/* First check for a user record tied to a memberlist */ + if (m) { + u = get_user_from_member(m); + if (u) { + return u; + } + } +/* Next check for a user record tied to an account */ + if (account && account[0]) { + u = get_user_by_account(account); + if (u) { + return u; + } + } +/* Last check for a user record tied to a hostmask */ + if (host && host[0]) { + u = get_user_by_host(host); + return u; + } + return NULL; +} + /* Fix capitalization, etc */ void correct_handle(char *handle) @@ -252,8 +332,6 @@ void clear_masks(maskrec *m) temp = m->next; if (m->mask) nfree(m->mask); - if (m->user) - nfree(m->user); if (m->desc) nfree(m->desc); nfree(m); @@ -298,12 +376,10 @@ void clear_userlist(struct userrec *bu) /* Find CLOSEST host match * (if "*!*@*" and "*!*@*clemson.edu" both match, use the latter!) - * - * Checks the chanlist first, to possibly avoid needless search. */ struct userrec *get_user_by_host(char *host) { - struct userrec *u, *ret; + struct userrec *u, *ret = NULL; struct list_type *q; int cnt, i; char host2[UHOSTLEN]; @@ -313,12 +389,7 @@ struct userrec *get_user_by_host(char *host) rmspace(host); if (!host[0]) return NULL; - ret = check_chanlist(host); cnt = 0; - if (ret != NULL) { - cache_hit++; - return ret; - } cache_miss++; strlcpy(host2, host, sizeof host2); for (u = userlist; u; u = u->next) { @@ -333,7 +404,6 @@ struct userrec *get_user_by_host(char *host) } if (ret != NULL) { lastuser = ret; - set_chanlist(host2, ret); } return ret; } diff --git a/src/users.c b/src/users.c index 703e344b1..928f85ae9 100644 --- a/src/users.c +++ b/src/users.c @@ -30,8 +30,6 @@ */ #include "main.h" -#include "users.h" -#include "chan.h" #include "modules.h" #include "tandem.h" @@ -525,8 +523,6 @@ void tell_user_ident(int idx, char *id) struct userrec *u; u = get_user_by_handle(userlist, id); - if (u == NULL) - u = get_user_by_host(id); if (u == NULL) { dprintf(idx, "%s.\n", USERF_NOMATCH); return; @@ -1033,7 +1029,7 @@ void autolink_cycle(char *start) } /* new run through the user list */ while (u && !autc) { while (u && !autc) { - if (u->flags & USER_BOT && strcmp(u->handle, botnetnick)) { /* ignore our own user record */ + if (u->flags & USER_BOT && strcasecmp(u->handle, botnetnick)) { /* ignore our own user record */ bfl = bot_flags(u); if (bfl & (BOT_HUB | BOT_ALT)) { linked = 0; diff --git a/src/users.h b/src/users.h index 49f20853b..6bc27c1ce 100644 --- a/src/users.h +++ b/src/users.h @@ -184,8 +184,10 @@ struct userrec *get_user_by_handle(struct userrec *, char *); struct userrec *get_user_by_host(char *); struct userrec *get_user_by_account(char *); struct userrec *get_user_by_nick(char *); +struct userrec *get_user_from_member(memberlist *); +struct userrec *lookup_user_record(memberlist *, char *, char *); struct userrec *check_chanlist(const char *); -struct userrec *check_chanlist_hand(const char *); +memberlist *find_member_from_nick(char *); /* All the default userentry stuff, for code re-use */ diff --git a/src/version.h b/src/version.h index 63e9d3316..64e4e4698 100644 --- a/src/version.h +++ b/src/version.h @@ -27,5 +27,5 @@ */ #define EGG_STRINGVER "1.9.5" -#define EGG_NUMVER 1090505 -#define EGG_PATCH "python" +#define EGG_NUMVER 1090506 +#define EGG_PATCH "accounttracking"