diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2016-06-05 14:16:21 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2016-06-12 22:29:23 +0100 |
commit | 4e3d5d30f673c7cc52a7aa2a50f7fda34bc1f4cc (patch) | |
tree | dcc032b92ea5a71785b95f540a7bed4516d244cb | |
parent | 09dbdc750e4612cb7a2db5331b6e9d6278d7f3c0 (diff) |
Revert "- Dropped contrib/"
This reverts commit 206336e601c61264d4dd7b6c031b5cc96b7e3f44.
Conflicts:
Makefile.in
configure
31 files changed, 4244 insertions, 3 deletions
diff --git a/Makefile.in b/Makefile.in index 6738493..436e968 100644 --- a/Makefile.in +++ b/Makefile.in @@ -80,7 +80,8 @@ host_triplet = @host@ subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ - $(srcdir)/config.h.in AUTHORS COPYING INSTALL NEWS README \ + $(srcdir)/config.h.in $(top_srcdir)/contrib/help/Makefile.in \ + AUTHORS COPYING INSTALL NEWS README \ compile config.guess config.sub depcomp install-sh missing \ ylwrap ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -102,7 +103,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = +CONFIG_CLEAN_FILES = contrib/help/Makefile CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -400,6 +401,8 @@ $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) distclean-hdr: -rm -f config.h stamp-h1 +contrib/help/Makefile: $(top_builddir)/config.status $(top_srcdir)/contrib/help/Makefile.in + cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo @@ -15513,7 +15513,7 @@ _ACEOF test "$exec_prefix_NONE" && exec_prefix=NONE -ac_config_files="$ac_config_files Makefile src/Makefile libltdl/Makefile modules/Makefile modules/core/Makefile doc/Makefile help/Makefile tools/Makefile" +ac_config_files="$ac_config_files Makefile contrib/Makefile contrib/help/Makefile src/Makefile libltdl/Makefile modules/Makefile modules/core/Makefile doc/Makefile help/Makefile tools/Makefile" cat >confcache <<\_ACEOF @@ -16556,6 +16556,8 @@ do "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "contrib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;; + "contrib/help/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/help/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "libltdl/Makefile") CONFIG_FILES="$CONFIG_FILES libltdl/Makefile" ;; "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; diff --git a/configure.ac b/configure.ac index 1afea6b..1fb6f61 100644 --- a/configure.ac +++ b/configure.ac @@ -97,6 +97,8 @@ AC_DEFINE_DIR([LOCALSTATEDIR],[localstatedir],[Set to localstatedir.]) AC_CONFIG_FILES( \ Makefile \ + contrib/Makefile \ + contrib/help/Makefile \ src/Makefile \ libltdl/Makefile \ modules/Makefile \ diff --git a/contrib/Makefile.am b/contrib/Makefile.am new file mode 100644 index 0000000..22015c9 --- /dev/null +++ b/contrib/Makefile.am @@ -0,0 +1,44 @@ +AUTOMAKE_OPTIONS = foreign +MODULE_FLAGS = -module -avoid-version + +AM_CPPFLAGS = -I$(top_srcdir)/include +modulesdir = $(pkglibdir)/modules/autoload + +modules_LTLIBRARIES = example_module.la \ + ip_cloaking.la \ + m_change.la \ + m_clearchan.la \ + m_ctrace.la \ + m_force.la \ + m_ltrace.la \ + m_ojoin.la \ + m_operspy.la \ + m_opme.la \ + m_webirc.la + +example_module_la_LDFLAGS = $(MODULE_FLAGS) +ip_cloaking_la_LDFLAGS = $(MODULE_FLAGS) +m_change_la_LDFLAGS = $(MODULE_FLAGS) +m_clearchan_la_LDFLAGS = $(MODULE_FLAGS) +m_ctrace_la_LDFLAGS = $(MODULE_FLAGS) +m_force_la_LDFLAGS = $(MODULE_FLAGS) +m_ltrace_la_LDFLAGS = $(MODULE_FLAGS) +m_ojoin_la_LDFLAGS = $(MODULE_FLAGS) +m_operspy_la_LDFLAGS = $(MODULE_FLAGS) +m_opme_la_LDFLAGS = $(MODULE_FLAGS) +m_webirc_la_LDFLAGS = $(MODULE_FLAGS) + + +example_module_la_SOURCES = example_module.c +ip_cloaking_la_SOURCES = ip_cloaking.c +m_change_la_SOURCES = m_change.c +m_clearchan_la_SOURCES = m_clearchan.c +m_ctrace_la_SOURCES = m_ctrace.c +m_force_la_SOURCES = m_force.c +m_ltrace_la_SOURCES = m_ltrace.c +m_ojoin_la_SOURCES = m_ojoin.c +m_operspy_la_SOURCES = m_operspy.c +m_opme_la_SOURCES = m_opme.c +m_webirc_la_SOURCES = m_webirc.c + +modules: $(modules_LTLIBRARIES) diff --git a/contrib/Makefile.in b/contrib/Makefile.in new file mode 100644 index 0000000..bd63c4b --- /dev/null +++ b/contrib/Makefile.in @@ -0,0 +1,733 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(modulesdir)" +LTLIBRARIES = $(modules_LTLIBRARIES) +example_module_la_LIBADD = +am_example_module_la_OBJECTS = example_module.lo +example_module_la_OBJECTS = $(am_example_module_la_OBJECTS) +example_module_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(example_module_la_LDFLAGS) $(LDFLAGS) -o $@ +ip_cloaking_la_LIBADD = +am_ip_cloaking_la_OBJECTS = ip_cloaking.lo +ip_cloaking_la_OBJECTS = $(am_ip_cloaking_la_OBJECTS) +ip_cloaking_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(ip_cloaking_la_LDFLAGS) $(LDFLAGS) -o $@ +m_change_la_LIBADD = +am_m_change_la_OBJECTS = m_change.lo +m_change_la_OBJECTS = $(am_m_change_la_OBJECTS) +m_change_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_change_la_LDFLAGS) $(LDFLAGS) -o $@ +m_clearchan_la_LIBADD = +am_m_clearchan_la_OBJECTS = m_clearchan.lo +m_clearchan_la_OBJECTS = $(am_m_clearchan_la_OBJECTS) +m_clearchan_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_clearchan_la_LDFLAGS) $(LDFLAGS) -o $@ +m_ctrace_la_LIBADD = +am_m_ctrace_la_OBJECTS = m_ctrace.lo +m_ctrace_la_OBJECTS = $(am_m_ctrace_la_OBJECTS) +m_ctrace_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_ctrace_la_LDFLAGS) $(LDFLAGS) -o $@ +m_force_la_LIBADD = +am_m_force_la_OBJECTS = m_force.lo +m_force_la_OBJECTS = $(am_m_force_la_OBJECTS) +m_force_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_force_la_LDFLAGS) $(LDFLAGS) -o $@ +m_ltrace_la_LIBADD = +am_m_ltrace_la_OBJECTS = m_ltrace.lo +m_ltrace_la_OBJECTS = $(am_m_ltrace_la_OBJECTS) +m_ltrace_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_ltrace_la_LDFLAGS) $(LDFLAGS) -o $@ +m_ojoin_la_LIBADD = +am_m_ojoin_la_OBJECTS = m_ojoin.lo +m_ojoin_la_OBJECTS = $(am_m_ojoin_la_OBJECTS) +m_ojoin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_ojoin_la_LDFLAGS) $(LDFLAGS) -o $@ +m_operspy_la_LIBADD = +am_m_operspy_la_OBJECTS = m_operspy.lo +m_operspy_la_OBJECTS = $(am_m_operspy_la_OBJECTS) +m_operspy_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_operspy_la_LDFLAGS) $(LDFLAGS) -o $@ +m_opme_la_LIBADD = +am_m_opme_la_OBJECTS = m_opme.lo +m_opme_la_OBJECTS = $(am_m_opme_la_OBJECTS) +m_opme_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_opme_la_LDFLAGS) $(LDFLAGS) -o $@ +m_webirc_la_LIBADD = +am_m_webirc_la_OBJECTS = m_webirc.lo +m_webirc_la_OBJECTS = $(am_m_webirc_la_OBJECTS) +m_webirc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_webirc_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(example_module_la_SOURCES) $(ip_cloaking_la_SOURCES) \ + $(m_change_la_SOURCES) $(m_clearchan_la_SOURCES) \ + $(m_ctrace_la_SOURCES) $(m_force_la_SOURCES) \ + $(m_ltrace_la_SOURCES) $(m_ojoin_la_SOURCES) \ + $(m_operspy_la_SOURCES) $(m_opme_la_SOURCES) \ + $(m_webirc_la_SOURCES) +DIST_SOURCES = $(example_module_la_SOURCES) $(ip_cloaking_la_SOURCES) \ + $(m_change_la_SOURCES) $(m_clearchan_la_SOURCES) \ + $(m_ctrace_la_SOURCES) $(m_force_la_SOURCES) \ + $(m_ltrace_la_SOURCES) $(m_ojoin_la_SOURCES) \ + $(m_operspy_la_SOURCES) $(m_opme_la_SOURCES) \ + $(m_webirc_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +MODULE_FLAGS = -module -avoid-version +AM_CPPFLAGS = -I$(top_srcdir)/include +modulesdir = $(pkglibdir)/modules/autoload +modules_LTLIBRARIES = example_module.la \ + ip_cloaking.la \ + m_change.la \ + m_clearchan.la \ + m_ctrace.la \ + m_force.la \ + m_ltrace.la \ + m_ojoin.la \ + m_operspy.la \ + m_opme.la \ + m_webirc.la + +example_module_la_LDFLAGS = $(MODULE_FLAGS) +ip_cloaking_la_LDFLAGS = $(MODULE_FLAGS) +m_change_la_LDFLAGS = $(MODULE_FLAGS) +m_clearchan_la_LDFLAGS = $(MODULE_FLAGS) +m_ctrace_la_LDFLAGS = $(MODULE_FLAGS) +m_force_la_LDFLAGS = $(MODULE_FLAGS) +m_ltrace_la_LDFLAGS = $(MODULE_FLAGS) +m_ojoin_la_LDFLAGS = $(MODULE_FLAGS) +m_operspy_la_LDFLAGS = $(MODULE_FLAGS) +m_opme_la_LDFLAGS = $(MODULE_FLAGS) +m_webirc_la_LDFLAGS = $(MODULE_FLAGS) +example_module_la_SOURCES = example_module.c +ip_cloaking_la_SOURCES = ip_cloaking.c +m_change_la_SOURCES = m_change.c +m_clearchan_la_SOURCES = m_clearchan.c +m_ctrace_la_SOURCES = m_ctrace.c +m_force_la_SOURCES = m_force.c +m_ltrace_la_SOURCES = m_ltrace.c +m_ojoin_la_SOURCES = m_ojoin.c +m_operspy_la_SOURCES = m_operspy.c +m_opme_la_SOURCES = m_opme.c +m_webirc_la_SOURCES = m_webirc.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign contrib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign contrib/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-modulesLTLIBRARIES: $(modules_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(modules_LTLIBRARIES)'; test -n "$(modulesdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(modulesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(modulesdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(modulesdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(modulesdir)"; \ + } + +uninstall-modulesLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(modules_LTLIBRARIES)'; test -n "$(modulesdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(modulesdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(modulesdir)/$$f"; \ + done + +clean-modulesLTLIBRARIES: + -test -z "$(modules_LTLIBRARIES)" || rm -f $(modules_LTLIBRARIES) + @list='$(modules_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +example_module.la: $(example_module_la_OBJECTS) $(example_module_la_DEPENDENCIES) $(EXTRA_example_module_la_DEPENDENCIES) + $(example_module_la_LINK) -rpath $(modulesdir) $(example_module_la_OBJECTS) $(example_module_la_LIBADD) $(LIBS) +ip_cloaking.la: $(ip_cloaking_la_OBJECTS) $(ip_cloaking_la_DEPENDENCIES) $(EXTRA_ip_cloaking_la_DEPENDENCIES) + $(ip_cloaking_la_LINK) -rpath $(modulesdir) $(ip_cloaking_la_OBJECTS) $(ip_cloaking_la_LIBADD) $(LIBS) +m_change.la: $(m_change_la_OBJECTS) $(m_change_la_DEPENDENCIES) $(EXTRA_m_change_la_DEPENDENCIES) + $(m_change_la_LINK) -rpath $(modulesdir) $(m_change_la_OBJECTS) $(m_change_la_LIBADD) $(LIBS) +m_clearchan.la: $(m_clearchan_la_OBJECTS) $(m_clearchan_la_DEPENDENCIES) $(EXTRA_m_clearchan_la_DEPENDENCIES) + $(m_clearchan_la_LINK) -rpath $(modulesdir) $(m_clearchan_la_OBJECTS) $(m_clearchan_la_LIBADD) $(LIBS) +m_ctrace.la: $(m_ctrace_la_OBJECTS) $(m_ctrace_la_DEPENDENCIES) $(EXTRA_m_ctrace_la_DEPENDENCIES) + $(m_ctrace_la_LINK) -rpath $(modulesdir) $(m_ctrace_la_OBJECTS) $(m_ctrace_la_LIBADD) $(LIBS) +m_force.la: $(m_force_la_OBJECTS) $(m_force_la_DEPENDENCIES) $(EXTRA_m_force_la_DEPENDENCIES) + $(m_force_la_LINK) -rpath $(modulesdir) $(m_force_la_OBJECTS) $(m_force_la_LIBADD) $(LIBS) +m_ltrace.la: $(m_ltrace_la_OBJECTS) $(m_ltrace_la_DEPENDENCIES) $(EXTRA_m_ltrace_la_DEPENDENCIES) + $(m_ltrace_la_LINK) -rpath $(modulesdir) $(m_ltrace_la_OBJECTS) $(m_ltrace_la_LIBADD) $(LIBS) +m_ojoin.la: $(m_ojoin_la_OBJECTS) $(m_ojoin_la_DEPENDENCIES) $(EXTRA_m_ojoin_la_DEPENDENCIES) + $(m_ojoin_la_LINK) -rpath $(modulesdir) $(m_ojoin_la_OBJECTS) $(m_ojoin_la_LIBADD) $(LIBS) +m_operspy.la: $(m_operspy_la_OBJECTS) $(m_operspy_la_DEPENDENCIES) $(EXTRA_m_operspy_la_DEPENDENCIES) + $(m_operspy_la_LINK) -rpath $(modulesdir) $(m_operspy_la_OBJECTS) $(m_operspy_la_LIBADD) $(LIBS) +m_opme.la: $(m_opme_la_OBJECTS) $(m_opme_la_DEPENDENCIES) $(EXTRA_m_opme_la_DEPENDENCIES) + $(m_opme_la_LINK) -rpath $(modulesdir) $(m_opme_la_OBJECTS) $(m_opme_la_LIBADD) $(LIBS) +m_webirc.la: $(m_webirc_la_OBJECTS) $(m_webirc_la_DEPENDENCIES) $(EXTRA_m_webirc_la_DEPENDENCIES) + $(m_webirc_la_LINK) -rpath $(modulesdir) $(m_webirc_la_OBJECTS) $(m_webirc_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example_module.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_cloaking.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_change.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_clearchan.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_ctrace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_force.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_ltrace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_ojoin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_operspy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_opme.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_webirc.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(modulesdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-modulesLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-modulesLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-modulesLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-modulesLTLIBRARIES cscopelist ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-modulesLTLIBRARIES \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-modulesLTLIBRARIES + + +modules: $(modules_LTLIBRARIES) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/README b/contrib/README new file mode 100644 index 0000000..32c107c --- /dev/null +++ b/contrib/README @@ -0,0 +1,122 @@ +$Id$ +----------------------------------------------- + +ircd-hybrid contributive add-ons :: + +This directory contains contributive modules, patches and other add-ons +that have been created by other people, or are not suitable to be included +into the main ircd-hybrid tree for various reasons. The coding team does +not officially support modules, patches and add-ons nor do they guarantee +that any of them will work to their intended capacity. + +It is to be noted WITH feeling, that not all of these modules, patches +or add-ons have been thoroughly tested, only that they've been tested +enough to see if they compile or work. This is one of the main driving +reasons why many of these are not in the main ircd-hybrid tree. At least +one or two of the modules in contrib have been known to core servers when +used. Heed this warning! + +To reiterate, ONE OR MORE OF THESE MAY AND PROBABLY WILL CORE YOUR SERVER. +USE AT YOUR OWN RISK. Reading this dicticates that you agree to the stated +fact. + +Modules :: +----------------------------------------------- +ip_cloaking.c -- This module enables IP/hostname cloaking support for + ircd-hybrid. It adds a CRC32 encrypted based cloaking + known to be used by other daemons such as Unreal IRCd + but with some modifications and different hashing + methods. Please read README.cloaking before you compile + and load this module, it contains VERY important + information. + + +m_change.c -- This module will allow IRC operators to alter the ident, + hostname or gecos (realname) fields of a given user. + + Syntax: CHGIDENT <nickname> <newident> + CHGHOST <nickname> <newhostname> + CHGNAME <nickname> <newname> + + Example: CHGIDENT lart llama + CHGHOST lart i.hate.packets + CHGNAME lart oorgle + + +m_clearchan.c -- Similar to the OperServ command CLEARCHAN, this module + will clear all users out of a channel, joins the person + who issued it, and locks the channel. It should be noted + that this command can be abused heavily. + + Syntax: CLEARCHAN <channel> + + Example: CLEARCHAN #warez + + +m_ctrace.c -- This module will perform a trace on a certain class. Valid + classes would be servers, users, operators or any custom + one you defined in class {} blocks. + + Syntax: CTRACE <class> + + Example: CTRACE users + + +m_force.c -- This module will force a user to either part or join a + channel with an optional status (@%+) + + Syntax: FORCEJOIN <nickname> [status]<channel> + FORCEPART <nickname> <channel> + + Example: FORCEJOIN nick @#chitchat + FORCEPART lamer #chitchat + + +m_ltrace.c -- This module will give a limited trace. This is similar to + TRACE except that it only reports current operators and servers. + + Syntax: LTRACE [nick|mask [server]] + + Example: LTRACE god + LTRACE node.server.com + + +m_ojoin.c -- This module will add the ability to join any channel no + matter what modes or limits are set with an optional + status (@%+) It should be noted that this command can be + abused heavily. + + Syntax: OJOIN [status]<channel> + + Example: OJOIN @#private + + +m_operspy.c -- This module will allow operators with access to spy on + users. It should be noted the notion of this module + practically invalidates any form of privacy. + + Syntax: OPERSPY <LIST/WHO/MODE/WHOIS/NAMES> <parameter> + + +m_opme.c -- This module will allow an IRC operator to op themselves in + an opless channel should the need arise. + + Syntax: OPME <channel> + Example: OPME #orphanchan + + +m_webirc.c -- Adds CGI:IRC/WebIRC support. A special auth{} block is + required in order to enable WebIRC support. For more + details check m_webirc.c + + +example_module.c -- This is an example module template to help users create + their own modules. + + +Help Files :: +----------------------------------------------- + +Each contrib module listed here has an accompanying help page or set of +help pages. They will be installed when you issue 'make install' inside +the contrib directory. To view them do /QUOTE HELP COMMAND. diff --git a/contrib/README.cloaking b/contrib/README.cloaking new file mode 100644 index 0000000..a89aa15 --- /dev/null +++ b/contrib/README.cloaking @@ -0,0 +1,87 @@ +ircd-hybrid IP/hostname cloaking README: +----------------------------------------------- +$Id$ + +Copyright (c) 2005 by Alan 'knight-' LeVee of ChatJunkies IRC Network +----------------------------------------------- + +This README file is designed to cover the aspects of the IP cloaking features +new to hybrid in the contrib module named ip_cloaking.c. The basis for the IP +cloaking is to add some level of privacy for local users to have by cloaking, or +rather masking a part of their hostname with a CRC32 polymorphism hash. + +This will make the necessary additions to the source code to allow IP cloaking +to work as well as adding in a new user mode known as +h. Normally on most IRC +daemons such as UnrealIRCd or ircu2, IP masking is assigned the user mode +x but +since we use +x for external operator messages we used +h as the next logical +step. + +Basically the IP cloaking is a proof of concept utilising a CRC32 based salt +encryption method that UnrealIRCd uses but with some changes and bit stuffing +and bit shifting. However, before you compile the contrib module, it is +*strongly* recommended that you modify the +ip_cloaking.c module and edit the following: + +#define KEY +#define KEY2 +#define KEY3 + +With different numbers than are present in the provided module. This insures +that no one can really decipher the secret keys because they'll go on the basis +that they are stock and not modified. To get proper or good entropy on random +numbers rather than trying to guess them it is a good idea to use an entropy +variable or device to grab them. If you have BASH available you can use the +randomization variable called ${RANDOM} to get your bits. You need at least 3 +secret keys in order for this to work, there is no preset requirement as to how +many numbers per key is required but it should have at least 4 to 6 numbers on +each block. If you want to do it easily and you have bash you can do the +following command in a BASH shell: + +$ echo -e "#define KEY ${RANDOM}\n#define KEY2 ${RANDOM}\n#define KEY3 +${RANDOM}" + +You'll get an output similar to this: + +#define KEY 935 +#define KEY2 23539 +#define KEY3 22522 + +Once you run that command you can copy and paste the output into ip_cloaking.c +and compile the module. However all servers *must* use the same secret keys in +order for this to work properly or you'll run into problems especially for +channel bans. + +Since you will also need the module m_change.so to go with IP cloaking it is +best just to cd into the contrib. directory and build all the modules like so: + +cd contrib; make install + +Then you'll need to edit etc/ircd.conf and add the following lines to the +modules {} block so you can load the module: + +module = "m_change.so"; +module = "ip_cloaking.so"; + +Please note that *all* servers *must* have these modules loaded or IP cloaking +will *not* work. Once this is done you can activate the IP cloaking by passing +the following user mode: + +/MODE nickname +h + +You should then recieve a message: + +--- ec6f50f-8f92678.ypwest01.mi.comcast.net :is your visible host + +This means that anyone who runs WHOIS on you will receive that as the host +response. However, if hide_spoof_ips is set to no yourself and IRC operators can +get your true IP from WHOIS but no one else. Once user mode +h is set however, +it cannot be unset (ala ircu2). Also as of right now, IP cloaking does not +support IPv6 users due to the rare use of IPv6 and the difficulty in coding +support for it. So if an IPv6 user tries to set +h they will get the following +message: + +--- *** Sorry, IP cloaking does not support IPv6 users! + +If you have any questions please direct them to knight- on irc.chatjunkies.org +in #cservice as this is not officially supported by the ircd-hybrid team. Thank +you, and enjoy! diff --git a/contrib/example_module.c b/contrib/example_module.c new file mode 100644 index 0000000..af62ee9 --- /dev/null +++ b/contrib/example_module.c @@ -0,0 +1,224 @@ +/************************************************************************ + * IRC - Internet Relay Chat, doc/example_module.c + * Copyright (C) 2001 Hybrid Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ + +/* List of ircd includes from ../include/ + * These ones are necessary to build THIS module... + */ + +#include "stdinc.h" /* includes setup.h */ + +#include "client.h" /* Required for IsClient, etc. */ + +#include "send.h" /* sendto_one, most useful function of all time */ + +#include "parse.h" + +#include "modules.h" /* includes msg.h; use for the msgtab */ + +/* OTHER USEFUL INCLUDES: + * + * #include "handlers.h" <-- include this file to be able to use default + * functions in place of your own 'Access Denied' kind of function + * + * #include "numeric.h" <-- include this file to be able to use form_str, + * standard message formats (see messages.tab and *.lang in messages/) + * Examples are strewn all across the ircd code, so just grep a bit to + * find one! + * + * #include "irc_string.h" <-- best to include this if you use *any* + * string comparison or parsing functions, although they may be available + * natively for your OS the prototypes in irc_string.h may be required for + * others. */ + +/* + * Declare the void's initially up here, as modules don't have an + * include file, we will normally have client_p, source_p, parc + * and parv[] where: + * + * client_p == client issuing command + * source_p == where the command came from + * parc == the number of parameters + * parv == an array of the parameters + */ + + +/* + * mr_test + * parv[0] = sender prefix + * parv[1] = parameter + */ + +/* + * Here we have the functions themselves that we declared above, + * and the fairly normal C coding + */ +static void +mr_test(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc == 1) + sendto_one(source_p, ":%s NOTICE %s :You are unregistered and sent no parameters", + me.name, source_p->name); + else + sendto_one(source_p, ":%s NOTICE %s :You are unregistered and sent parameter: %s", + me.name, source_p->name, parv[1]); +} + +/* + * m_test + * parv[0] = sender prefix + * parv[1] = parameter + */ +static void +m_test(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc == 1) + sendto_one(source_p, ":%s NOTICE %s :You are a normal user, and sent no parameters", + me.name, source_p->name); + else + sendto_one(source_p, ":%s NOTICE %s :You are a normal user, and send parameters: %s", + me.name, source_p->name, parv[1]); +} + +/* + * ms_test + * parv[0] = sender prefix + * parv[1] = parameter + */ +static void +ms_test(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc == 1) + { + if (IsServer(source_p)) + sendto_one(source_p, ":%s NOTICE %s :You are a server, and sent no parameters", + me.name, source_p->name); + else + sendto_one(source_p, ":%s NOTICE %s :You are a remote client, and sent no parameters", + me.name, source_p->name); + } + else + { + if (IsServer(source_p)) + sendto_one(source_p, ":%s NOTICE %s :You are a server, and sent parameters: %s", + me.name, source_p->name, parv[1]); + else + sendto_one(source_p, ":%s NOTICE %s :You are a remote client, and sent parameters: %s", + me.name, source_p->name, parv[1]); + } +} + +/* + * mo_test + * parv[0] = sender prefix + * parv[1] = parameter + */ +static void +mo_test(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc == 1) + sendto_one(source_p, ":%s NOTICE %s :You are an operator, and sent no parameters", + me.name, source_p->name); + else + sendto_one(source_p, ":%s NOTICE %s :You are an operator, and sent parameters: %s", + me.name, source_p->name, parv[1]); +} + +/* + * Show the commands this module can handle in a msgtab + * and give the msgtab a name, here its test_msgtab + */ +static struct Message test_msgtab = { + + /* Fields are in order: + *-> "COMMAND", 0, 0, parc_count, maxparc, MFLG_SLOW, 0, + * + * where: + * COMMAND == the /command you want + * parc_count == the number of parameters needed + * (the clients name is one param, parv[0]) + * maxparc == the maximum parameters we allow + * the 0's and MFLG_SLOW should not be changed.. + */ + + /* + * This would add the command "TEST" which requires no additional + * parameters + */ + "TEST", 0, 0, 1, MAXPARA, MFLG_SLOW, 0, + + /* Fields are in order: + *-> {unregged, regged, remote, encap, oper, dummy} + * + * where: + * unregged == function to call for unregistered clients + * regged == function to call for normal users + * remote == function to call for servers/remote users + * encap == function to call for encap'd server/remote commands + * oper == function to call for operators + * dummy == function called when client is quarantined + * + * There are also some pre-coded functions for use: + * m_unregistered: prevent the client using this if unregistered + * m_not_oper: tell the client it requires being an operator + * m_ignore: ignore the command when it comes from certain types + * rfc1459_command_send_error: give an error when the command comes from certain types + */ + { mr_test, m_test, ms_test, m_ignore, mo_test, m_ignore } + + /* It is normal for unregistered functions to be prefixed with mr_ + * " " normal users to be prefixed with m_ + * " " remote clients to be prefixed with ms_ + * " " operators to be prefixed with mo_ + */ +}; +/* That's the msgtab finished */ + +/* Here we tell it what to do when the module is loaded */ +static void +module_init(void) +{ + /* This will add the commands in test_msgtab (which is above) */ + mod_add_cmd(&test_msgtab); +} + +/* here we tell it what to do when the module is unloaded */ +static void +module_exit(void) +{ + /* This will remove the commands in test_msgtab (which is above) */ + mod_del_cmd(&test_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; + +/* END OF EXAMPLE MODULE */ diff --git a/contrib/help/Makefile.in b/contrib/help/Makefile.in new file mode 100644 index 0000000..4e83932 --- /dev/null +++ b/contrib/help/Makefile.in @@ -0,0 +1,53 @@ +# Makefile to install help files +# $Id$ + +INSTALL= @INSTALL@ +INSTALL_DATA= @INSTALL_DATA@ +RM= @RM@ + +prefix= @prefix@ +datarootdir = $(DESTDIR)@datarootdir@ +exec_prefix= @execprefix@ +datadir = ${DESTDIR}@datadir@ +helpdir = ${datadir}/help +uhelpdir = ${helpdir}/users +ohelpdir = ${helpdir}/opers + +SYMLINKS= topic accept cmode admin names links away whowas \ + version kick who invite quit join list nick oper part \ + time motd userhost users whois ison lusers user help \ + pass error challenge knock ping pong flags +all: +build: +clean: +depend: + +install: + @echo installing help files... + -@if test ! -d $(helpdir); then \ + echo "mkdir $(helpdir)"; \ + mkdir -p $(helpdir); \ + echo "mkdir $(uhelpdir)"; \ + mkdir $(uhelpdir); \ + echo "mkdir $(ohelpdir)"; \ + mkdir $(ohelpdir); \ + fi + @for help in opers/*; do \ + if [ -f $$help ]; then \ + ${INSTALL_DATA} $$help $(ohelpdir); \ + fi \ + done + @for help in users/*; do \ + if [ -f $$help ]; then \ + $(INSTALL_DATA) $$help $(uhelpdir); \ + fi \ + done + @for link in $(SYMLINKS); do \ + rm -f $(uhelpdir)/$$link; \ + ln -s $(ohelpdir)/$$link $(uhelpdir); \ + done + +distclean: + ${RM} -f Makefile + +depend: diff --git a/contrib/help/opers/chghost b/contrib/help/opers/chghost new file mode 100644 index 0000000..1018830 --- /dev/null +++ b/contrib/help/opers/chghost @@ -0,0 +1,7 @@ +# $Id$ +CHGHOST [nickname] <hostname> + +The CHGHOST command takes two arguments. The first argument is optional and +can be the nickname of a user you wish to change the host of. If no +argument for the nickname is supplied, then it will change your host instead. +The second argument is the hostname you wish to use. diff --git a/contrib/help/opers/chgident b/contrib/help/opers/chgident new file mode 100644 index 0000000..67cf164 --- /dev/null +++ b/contrib/help/opers/chgident @@ -0,0 +1,7 @@ +# $Id$ +CHGIDENT [nickname] <ident> + +The CHGIDENT command takes two arguments. The first argument is optional and +can be the nickname of a user you wish to alter the ident of. If no +argument for the nickname is supplied it will change your ident instead. +The second argument is the ident you wish to use. diff --git a/contrib/help/opers/chgname b/contrib/help/opers/chgname new file mode 100644 index 0000000..9a92100 --- /dev/null +++ b/contrib/help/opers/chgname @@ -0,0 +1,7 @@ +# $Id$ +CHGNAME [nickname] <realname> + +The CHGNAME command takes two arguments. The first argument is optional and +can be the nickname of a user you wish to alter the gecos of. If no +argument for the nickname is supplied it will change your gecos instead. +The second argument is the gecos you wish to use. diff --git a/contrib/help/opers/classlist b/contrib/help/opers/classlist new file mode 100644 index 0000000..3ff353b --- /dev/null +++ b/contrib/help/opers/classlist @@ -0,0 +1,8 @@ +# $Id$ +CLASSLIST <class> + +The CLASSLIST command will show complete totals of a class you wish to see. + +For example if you want to see the totals for the class users you would do: + +CLASSLIST users - Shows the totals in the users class. diff --git a/contrib/help/opers/clearchan b/contrib/help/opers/clearchan new file mode 100644 index 0000000..3fb2d6a --- /dev/null +++ b/contrib/help/opers/clearchan @@ -0,0 +1,8 @@ +# $Id$ +CLEARCHAN <channel> + +The CLEARCHAN command will essentially take over a channel by purging all +the modes and user's privileges (e.g. voice, half-op, chanop), then +kicking all the users out. + +This command requires that you PART the channel first. diff --git a/contrib/help/opers/ctrace b/contrib/help/opers/ctrace new file mode 100644 index 0000000..2939bf0 --- /dev/null +++ b/contrib/help/opers/ctrace @@ -0,0 +1,9 @@ +# $Id$ +CTRACE <class> + +The CTRACE command will do a trace of users depending on class. Similar +to TRACE but class specific. + +For example if you want to do a trace on the clients in the users class: + +CTRACE users - Shows the totals in the users class. diff --git a/contrib/help/opers/forcejoin b/contrib/help/opers/forcejoin new file mode 100644 index 0000000..455dc95 --- /dev/null +++ b/contrib/help/opers/forcejoin @@ -0,0 +1,9 @@ +# $Id$ +FORCEJOIN <nickname> <channel> + +The FORCEJOIN command requires two arguments to be given. The first +argument is the nickname of the user you wish to execute the command +on, and the second argument is the destination channel they are to join. + +The command can also be used to force join a user to a channel that does +not exist. diff --git a/contrib/help/opers/forcepart b/contrib/help/opers/forcepart new file mode 100644 index 0000000..3ab351c --- /dev/null +++ b/contrib/help/opers/forcepart @@ -0,0 +1,6 @@ +# $Id$ +FORCEPART <nickname> <channel> + +The FORCEPART command requires two arguments to be given. The first +argument is the nickname of the user you wish to execute the command +on, and the second argument is the destination channel they are to part. diff --git a/contrib/help/opers/index b/contrib/help/opers/index new file mode 100644 index 0000000..c4e55ca --- /dev/null +++ b/contrib/help/opers/index @@ -0,0 +1,34 @@ +# $Id$ +Help topics available to opers: + +CAPAB CAPTURE CBURST CHGHOST +CHGIDENT CHGNAME CLASSLIST CLEARCHAN +CLIENT CLOSE CONNECT CRYPTLINK +CTRACE DELSPOOF DIE DLINE +DROP EOB ETRACE FORCEJOIN +FORCEPART GLINE HASH JUPE +KILL KLINE KNOCKLL LLJOIN +LLNICK LOCOPS LTRACE MKPASSWD +MODLIST MODLOAD MODRESTART MODUNLOAD +NBURST NOTICE OJOIN OMOTD +OPERWALL OPME POST PRIVMSG +REHASH RESTART RESV RKLINE +RXLINE SERVER SET SJOIN +SPOOF SQUIT STATS SVINFO +SVSNICK TESTGECOS TESTLINE TESTMASK +TRACE UHELP UMODE UNCAPTURE +UNDLINE UNGLINE UNKLINE UNRESV +UNXLINE WALLOPS XLINE + +Help topics available to users: + +ACCEPT ADMIN AWAY CHALLENGE +CMODE ERROR FLAGS HELP +INFO INVITE ISON JOIN +KICK KNOCK LINKS LIST +LUSERS MAP MOTD NAMES +NICK NOTICE OPER PART +PASS PING PONG PRIVMSG +QUIT STATS TIME TOPIC +UMODE USER USERHOST USERS +VERSION WHO WHOIS WHOWAS diff --git a/contrib/help/opers/ltrace b/contrib/help/opers/ltrace new file mode 100644 index 0000000..6d9402c --- /dev/null +++ b/contrib/help/opers/ltrace @@ -0,0 +1,5 @@ +# $Id$ +LTRACE [nickname/server mask] + +This command is similar to TRACE, but it doesn't display plain users +or definitions of connection classes. diff --git a/contrib/help/opers/ojoin b/contrib/help/opers/ojoin new file mode 100644 index 0000000..f1c9525 --- /dev/null +++ b/contrib/help/opers/ojoin @@ -0,0 +1,12 @@ +# $Id$ +OJOIN [flags]<channel> + +The OJOIN command requires only one argument with optional status flags. +Valid mode flags are @ % and +. This allows operators to join any channel +with the given status. + +Examples: +OJOIN @#secretchan - Will join you to #secretchan with chan ops. +OJOIN +#secretchan - Will join you to #secretchan with voice. + +This also works on local channels as well. diff --git a/contrib/help/opers/opme b/contrib/help/opers/opme new file mode 100644 index 0000000..db474dd --- /dev/null +++ b/contrib/help/opers/opme @@ -0,0 +1,5 @@ +# $Id$ +OPME <channel> + +OPME will give chanop status to the operator in the given channel. +OPME will only work if the channel is opless. diff --git a/contrib/help/users/index b/contrib/help/users/index new file mode 100644 index 0000000..2cdeba9 --- /dev/null +++ b/contrib/help/users/index @@ -0,0 +1,13 @@ +# $Id$ +Help topics available to users: + +ACCEPT ADMIN AWAY CHALLENGE +CMODE ERROR FLAGS HELP +INFO INVITE ISON JOIN +KICK KNOCK LINKS LIST +LUSERS MAP MOTD NAMES +NICK NOTICE OPER PART +PASS PING PONG PRIVMSG +QUIT STATS TIME TOPIC +UMODE USER USERHOST USERS +VERSION WHO WHOIS WHOWAS diff --git a/contrib/ip_cloaking.c b/contrib/ip_cloaking.c new file mode 100644 index 0000000..2b2cf48 --- /dev/null +++ b/contrib/ip_cloaking.c @@ -0,0 +1,476 @@ +/* MODULE CONFIGURATION FOLLOWS -- please read!! */ + +/* Change these numbers to something else. Please + * make sure that they match on ALL servers + * to avoid problems! + */ +#define KEY 23857 +#define KEY2 38447 +#define KEY3 64709 + +/* END OF MODULE CONFIGURATION */ + +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon (ircd). + * ip_cloaking.c: Provides hostname (partial) cloaking for clients. + * + * Copyright (c) 2005 by the past and present ircd coders, and others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at you option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILILTY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have recieved a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + */ + +/* + * Originally re-written from AustNet's VirtualWorld Code. + * Virtual World written by Roger 'RogerY' Yerramesetti <rogery@austnet.org> + * + * Re-written using the crc32 encryption implementation by //ylo based on the original + * implementation by Gary S. Brown. + * + * HiddenHost implementation based on the code from Unreal IRCd by + * RaYmAn, NiQuiL, narf, Griever (great thinking) eternal, bball, JK.@ roxnet.org + * + * Additional ideas and code by ShadowMaster, [-Th3Dud3-] (RageIRCd), Solaris @ Demonkarma.net, + * Alan 'knight-' LeVee of the ChatJunkies IRC Network and doughk_ff7. + */ + +#include "stdinc.h" +#include "whowas.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "hook.h" +#include "irc_string.h" +#include "ircd.h" +#include "ircd_defs.h" +#include "numeric.h" +#include "s_serv.h" +#include "s_user.h" +#include "send.h" +#include "conf.h" +#include "modules.h" +#include "memory.h" +#include "log.h" +#include "sprintf_irc.h" +#include "userhost.h" + +static unsigned int umode_vhost = 0; +static int vhost_ipv6_err; +static dlink_node *prev_enter_umode; +static dlink_node *prev_umode; +static void *reset_ipv6err_flag(va_list); +static void *h_set_user_mode(va_list); + +/* + * The implementation originally comes from Gary S. Brown. The tables + * are a direct transplant of his original concept and have been + * changed for randomization purposes. Minor changes were also made + * to the crc32-function by //ylo. + * + * knight- + */ + +/* ============================================================= + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * First, the polynomial itself and its stable of feedback terms. The + * polynomial is: + * + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1. + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way, + * we and it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to high-bit; and the result is transmission bit + * by bit from highest-order to lowest-order term without requiring any + * bit shuffling on our part. Reception works similarly. + * + * The feedback term table consists of 256, 32-bit entries. Notes: + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback terms + * simply represent the results of eight shift/xor operations for + * all combinations of data and CRC register values. + * + * The values must be right shifted by eight bits by the "updcrc" + * logic; the shift must be unsigned (bring in zeroes). On some hardware + * you could probably optimize the shift in assembler by using byte-swap + * instructions. + * + * polynomial $edb88320 + * + * -------------------------------------------------------------------- + */ + +static unsigned long crc32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +static unsigned long +crc32(const char *s, unsigned int len) +{ + unsigned int i; + unsigned long crc32val = 0; + + for (i = 0; i < len; i++) + crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); + + return crc32val; +} + +/* + * str2arr() + * + * converts IPv4 address segments into arrays + * for encryption + * + * inputs - address parvs, strings and deliminator + * outputs - array + * side effects - not IPv6 friendly + */ +static int +str2arr(char **pparv, char *string, const char *delim) +{ + char *tok; + int pparc = 0; + + /* Diane had suggested to use this method rather than while() -- knight */ + for (tok = strtok(string, delim); tok != NULL; tok = strtok(NULL, delim)) + { + pparv[pparc++] = tok; + } + + return pparc; +} + +/* + * make_virthost() + * + * curr = current hostname/ip + * host = current host socket + * new = encrypted hostname/ip + */ +static void +make_virthost(char *curr, char *host, char *new) +{ + char mask[HOSTLEN + 1]; + char *parv[HOSTLEN + 1], *parv2[HOSTLEN + 1], s[HOSTLEN + 1], s2[HOSTLEN + 1]; + int parc = 0, parc2 = 0, len = 0; + unsigned long hash[8]; + + strlcpy(s2, curr, HOSTLEN + 1); + strlcpy(s, host, HOSTLEN + 1); + + parc = str2arr(parv, s, "."); + parc2 = str2arr(parv2, s2, "."); + + if (!parc2) + return; + + hash[0] = ((crc32 (parv[3], strlen (parv[3])) + KEY) ^ KEY2) ^ KEY3; + hash[1] = ((KEY2 ^ crc32 (parv[2], strlen (parv[2]))) + KEY3) ^ KEY; + hash[2] = ((crc32 (parv[1], strlen (parv[1])) + KEY3) ^ KEY) ^ KEY2; + hash[3] = ((KEY3 ^ crc32 (parv[0], strlen (parv[0]))) + KEY2) ^ KEY; + + hash[0] <<= 2; + hash[0] >>= 2; + hash[0] &= 0x3FFFFFFF; + hash[0] &= 0xFFFFFFFF; + hash[1] <<= 2; + hash[1] >>= 2; + hash[1] &= 0x7FFFFFFF; + hash[1] &= 0x3FFFFFFF; + hash[2] <<= 2; + hash[2] >>= 2; + hash[2] &= 0x7FFFFFFF; + hash[2] &= 0xFFFFFFFF; + hash[3] <<= 2; + hash[3] >>= 2; + hash[3] &= 0x3FFFFFFF; + hash[3] &= 0x7FFFFFFF; + + /* IPv4 */ + if (parc2 == 4 || parc2 < 2) + { + len = strlen (parv2[3]); + + if (strchr("0123456789", parv2[3][len - 1]) || parc2 < 2) + { + ircsprintf(mask, "%s.%s.%s.%lx", + parv2[parc2 - 4], parv2[parc2 - 3], + parv2[parc2 - 2], hash[3]); + } + else + { + /* isp.tld */ + ircsprintf(mask, "%lx-%lx.%s.%s", + hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]); + } + } + else + { + if (parc2 >= 4) + { + /* isp.sub.tld or district.isp.tld */ + ircsprintf(mask, "%lx-%lx.%s.%s.%s", + hash[3], hash[1], parv2[parc2 - 3], parv2[parc2 - 2], + parv2[parc2 - 1]); + } + else + { + /* isp.tld */ + ircsprintf(mask, "%lx-%lx.%s.%s", + hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]); + } + + if (parc2 >= 5) + { + /* zone.district.isp.tld or district.isp.sub.tld */ + ircsprintf(mask, "%lx-%lx.%s.%s.%s.%s", + hash[1], hash[0], parv2[parc2 - 4], parv2[parc2 - 3], + parv2[parc2 - 2], parv2[parc2 - 1]); + } + else + { + /* isp.tld */ + ircsprintf(mask, "%lx-%lx.%s.%s", + hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]); + } + } + + strlcpy(new, mask, HOSTLEN + 1); +} + +/* + * set_vhost() + * + * inputs - pointer to given client to set IP cloak. + * outputs - NONE + * side effects - NONE + */ +static void +set_vhost(struct Client *client_p, struct Client *source_p, + struct Client *target_p) +{ + target_p->umodes |= umode_vhost; + + if (IsUserHostIp(target_p)) + delete_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + + SetIPSpoof(target_p); + make_virthost(target_p->host, target_p->sockhost, target_p->host); + + add_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + SetUserHost(target_p); + + clear_ban_cache_client(target_p); + + if (IsClient(target_p)) + sendto_server(client_p, CAP_ENCAP, NOCAPS, + ":%s ENCAP * CHGHOST %s %s", + me.name, target_p->name, target_p->host); + + sendto_one(target_p, form_str(RPL_HOSTHIDDEN), + me.name, target_p->name, target_p->host); +} + +static void * +reset_ipv6err_flag(va_list args) +{ + struct Client *client_p = va_arg(args, struct Client *); + struct Client *source_p = va_arg(args, struct Client *); + + vhost_ipv6_err = 0; + + return pass_callback(prev_enter_umode, client_p, source_p); +} + +static void * +h_set_user_mode(va_list args) +{ + struct Client *client_p = va_arg(args, struct Client *); + struct Client *target_p = va_arg(args, struct Client *); + int what = va_arg(args, int); + unsigned int flag = va_arg(args, unsigned int); + + if (flag == umode_vhost) + { + if (what == MODE_ADD) + { + /* Automatically break if any of these conditions are met. -- knight- */ + if (!MyConnect(target_p)) + return NULL; + + if (IsIPSpoof(target_p)) + return NULL; + + /* + * IPv6 could potentially core the server if a user connected via IPv6 sets +h + * so we need to check and break before that happens. -- knight- + */ +#ifdef IPV6 + if (target_p->localClient->aftype == AF_INET6) + { + if (!vhost_ipv6_err) + { + sendto_one(target_p, ":%s NOTICE %s :*** Sorry, IP cloaking " + "does not support IPv6 users!", me.name, target_p->name); + vhost_ipv6_err = 1; + } + } + else +#endif + set_vhost(client_p, target_p, target_p); + } + + return NULL; + } + + return pass_callback(prev_umode, client_p, target_p, what, flag); +} + +static void +module_init(void) +{ + if (!user_modes['h']) + { + unsigned int all_umodes = 0, i; + + for (i = 0; i < 128; i++) + all_umodes |= user_modes[i]; + + for (umode_vhost = 1; umode_vhost && (all_umodes & umode_vhost); + umode_vhost <<= 1); + + if (!umode_vhost) + { + ilog(LOG_TYPE_IRCD, "You have more than 32 usermodes, " + "IP cloaking not installed"); + sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, + "You have more than " + "32 usermodes, IP cloaking not installed"); + return; + } + + user_modes['h'] = umode_vhost; + assemble_umode_buffer(); + } + else + { + ilog(LOG_TYPE_IRCD, "Usermode +h already in use, IP cloaking not installed"); + sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, + "Usermode +h already in use, " + "IP cloaking not installed"); + return; + } + + prev_enter_umode = install_hook(entering_umode_cb, reset_ipv6err_flag); + prev_umode = install_hook(umode_cb, h_set_user_mode); +} + +static void +module_exit(void) +{ + if (umode_vhost) + { + dlink_node *ptr; + + DLINK_FOREACH(ptr, local_client_list.head) + { + struct Client *cptr = ptr->data; + cptr->umodes &= ~umode_vhost; + } + + user_modes['h'] = 0; + assemble_umode_buffer(); + + uninstall_hook(entering_umode_cb, reset_ipv6err_flag); + uninstall_hook(umode_cb, h_set_user_mode); + } +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_change.c b/contrib/m_change.c new file mode 100644 index 0000000..b81b137 --- /dev/null +++ b/contrib/m_change.c @@ -0,0 +1,267 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_change.c: Allows changing user/host/real of connected clients. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "conf.h" +#include "log.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "s_user.h" +#include "hash.h" +#include "userhost.h" +#include "channel_mode.h" + + +static void +mo_chgident(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + if (MyClient(source_p) && !HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "CHGIDENT"); + return; + } + + if (EmptyString(parv[2])) + { + parv[2] = parv[1]; + target_p = source_p; + + if (!IsClient(target_p)) + return; + } + else { + target_p = hash_find_client(parv[1]); + + if (target_p == NULL || !IsClient(target_p)) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + } + + if (strlen(parv[2]) > USERLEN || !*parv[2] || !valid_username(parv[2])) + { + sendto_one(source_p, ":%s NOTICE %s :Invalid username", + me.name, source_p->name); + return; + } + + if (IsUserHostIp(target_p)) + delete_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + + strlcpy(target_p->username, parv[2], sizeof(target_p->username)); + + add_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + SetUserHost(target_p); + + if (MyClient(source_p)) + { + sendto_server(client_p, NOCAPS, NOCAPS, ":%s ENCAP * CHGIDENT %s %s", + source_p->name, target_p->name, parv[2]); + sendto_one(source_p, ":%s NOTICE %s :%s changed to %s@%s", + me.name, source_p->name, target_p->name, target_p->username, + target_p->host); + } + + if (MyClient(target_p)) + { + if (IsClient(source_p)) + sendto_one(target_p, ":%s NOTICE %s :You are now %s@%s", + me.name, target_p->name, target_p->username, target_p->host); + + clear_ban_cache_client(target_p); + } +} + +static void +mo_chghost(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + if (MyClient(source_p) && !HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "CHGHOST"); + return; + } + + if (EmptyString(parv[2])) + { + parv[2] = parv[1]; + target_p = source_p; + + if (!IsClient(target_p)) + return; + } + else { + target_p = hash_find_client(parv[1]); + + if (target_p == NULL || !IsClient(target_p)) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + } + + if (strlen(parv[2]) > HOSTLEN || !*parv[2] || !valid_hostname(parv[2])) + { + sendto_one(source_p, ":%s NOTICE %s :Invalid hostname", + me.name, source_p->name); + return; + } + + if (IsUserHostIp(target_p)) + delete_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + + strlcpy(target_p->host, parv[2], sizeof(target_p->host)); + SetIPSpoof(target_p); + + add_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + SetUserHost(target_p); + + if (MyClient(source_p)) + { + sendto_server(client_p, NOCAPS, NOCAPS, ":%s ENCAP * CHGHOST %s %s", + source_p->name, target_p->name, parv[2]); + sendto_one(source_p, ":%s NOTICE %s :%s changed to %s@%s", + me.name, source_p->name, target_p->name, target_p->username, + target_p->host); + } + + if (MyClient(target_p)) + { + if (IsClient(source_p)) + sendto_one(target_p, ":%s NOTICE %s :You are now %s@%s", + me.name, target_p->name, target_p->username, target_p->host); + clear_ban_cache_client(target_p); + } +} + +static void +mo_chgname(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + if (MyClient(source_p) && !HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "CHGNAME"); + return; + } + + if (EmptyString(parv[2])) + { + parv[2] = parv[1]; + target_p = source_p; + } + else if ((target_p = hash_find_client(parv[1])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + + if (strlen(parv[2]) > REALLEN || !*parv[2]) + { + sendto_one(source_p, ":%s NOTICE %s :Invalid realname", + me.name, source_p->name); + return; + } + + if (parc > 3 && MyClient(source_p)) + sendto_one(source_p, ":%s NOTICE %s :Warning -- too many parameters " + "for CHGNAME. You are probably missing a : before the new " + "IRC name.", me.name, source_p->name); + + strlcpy(target_p->info, parv[2], sizeof(target_p->info)); + + if (MyClient(source_p)) + { + sendto_server(client_p, NOCAPS, NOCAPS, ":%s ENCAP * CHGNAME %s :%s", + source_p->name, target_p->name, parv[2]); + sendto_one(source_p, ":%s NOTICE %s :%s realname changed to [%s]", + me.name, source_p->name, target_p->name, target_p->info); + } + + if (MyClient(target_p) && IsClient(source_p)) + sendto_one(target_p, ":%s NOTICE %s :Your realname is now [%s]", + me.name, target_p->name, target_p->info); +} + +static struct Message chgident_msgtab = { + "CHGIDENT", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, mo_chgident, mo_chgident, mo_chgident, m_ignore} +}; + +static struct Message chghost_msgtab = { + "CHGHOST", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, mo_chghost, mo_chghost, mo_chghost, m_ignore} +}; + +static struct Message chgname_msgtab = { + "CHGNAME", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, mo_chgname, mo_chgname, mo_chgname, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&chgident_msgtab); + mod_add_cmd(&chghost_msgtab); + mod_add_cmd(&chgname_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&chgname_msgtab); + mod_del_cmd(&chghost_msgtab); + mod_del_cmd(&chgident_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_clearchan.c b/contrib/m_clearchan.c new file mode 100644 index 0000000..e818fa3 --- /dev/null +++ b/contrib/m_clearchan.c @@ -0,0 +1,269 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_clearchan.c: Performs a channel takeover + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "log.h" +#include "s_serv.h" +#include "send.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "hash.h" +#include "parse.h" +#include "modules.h" +#include "conf.h" + + +static void kick_list(struct Client *, struct Channel *); +static void remove_our_modes(struct Channel *); +static void remove_a_mode(struct Channel *, int, char); + + +/* +** mo_clearchan +** parv[0] = sender prefix +** parv[1] = channel +*/ +static void +mo_clearchan(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + + /* admins only */ + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + if ((chptr = hash_find_channel(parv[1])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, parv[1]); + return; + } + + if (IsMember(source_p, chptr)) + { + sendto_one(source_p, ":%s NOTICE %s :*** Please part %s before using CLEARCHAN", + me.name, source_p->name, chptr->chname); + return; + } + + sendto_wallops_flags(UMODE_WALLOP, &me, "CLEARCHAN called for [%s] by %s!%s@%s", + chptr->chname, source_p->name, source_p->username, source_p->host); + sendto_server(NULL, NOCAPS, NOCAPS, + ":%s WALLOPS :CLEARCHAN called for [%s] by %s!%s@%s", + me.name, chptr->chname, source_p->name, source_p->username, + source_p->host); + ilog(LOG_TYPE_IRCD, "CLEARCHAN called for [%s] by %s!%s@%s", + chptr->chname, source_p->name, source_p->username, source_p->host); + + /* + * Kill all the modes we have about the channel.. + * making everyone a peon + */ + remove_our_modes(chptr); + + /* SJOIN the user to give them ops, and lock the channel */ + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s JOIN %lu %s +ntsi", + source_p->id, (unsigned long)(chptr->channelts - 1), + chptr->chname); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s +ntsi :@%s", + me.name, (unsigned long)(chptr->channelts - 1), + chptr->chname, source_p->name); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN %s", + source_p->name, source_p->username, + source_p->host, chptr->chname); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +o %s", + me.name, chptr->chname, source_p->name); + + + /* + * Take the TS down by 1, so we don't see the channel taken over + * again. + */ + if (chptr->channelts) + --chptr->channelts; + + chptr->mode.mode = MODE_SECRET | MODE_TOPICLIMIT | + MODE_INVITEONLY | MODE_NOPRIVMSGS; + + set_channel_topic(chptr, "", "", 0); + chptr->mode.key[0] = '\0'; + + /* Kick the users out and join the oper */ + kick_list(source_p, chptr); +} + +static void +kick_list(struct Client *source_p, struct Channel *chptr) +{ + dlink_node *ptr = NULL, *ptr_next = NULL; + struct Membership *ms = NULL; + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + + sendto_channel_local(ALL_MEMBERS, 0, chptr, + ":%s!%s@%s KICK %s %s CLEARCHAN", + source_p->name, source_p->username, + source_p->host, chptr->chname, ms->client_p->name); + sendto_server(NULL, NOCAPS, NOCAPS, + ":%s KICK %s %s :CLEARCHAN", source_p->name, + chptr->chname, ms->client_p->name); + } + + add_user_to_channel(chptr, source_p, CHFL_CHANOP, 0); + + DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head) + { + ms = ptr->data; + + if (ms->client_p != source_p) + remove_user_from_channel(ms); + } + + /* + * Join the user themselves to the channel down here, so they dont see a nicklist + * or people being kicked + */ + sendto_one(source_p, ":%s!%s@%s JOIN %s", + source_p->name, source_p->username, + source_p->host, chptr->chname); + channel_member_names(source_p, chptr, 1); +} + +/* remove_our_modes() + * + * inputs - hide from ops or not int flag + * - pointer to channel to remove modes from + * - client pointer + * output - NONE + * side effects - Go through the local members, remove all their + * chanop modes etc., this side lost the TS. + */ +static void +remove_our_modes(struct Channel *chptr) +{ + remove_a_mode(chptr, CHFL_CHANOP, 'o'); +#ifdef HALFOPS + remove_a_mode(chptr, CHFL_HALFOP, 'h'); +#endif + remove_a_mode(chptr, CHFL_VOICE, 'v'); + + /* Clear all +beI modes */ + free_channel_list(&chptr->banlist); + free_channel_list(&chptr->exceptlist); + free_channel_list(&chptr->invexlist); +} + +/* remove_a_mode() + * + * inputs - + * output - NONE + * side effects - remove ONE mode from a channel + */ +static void +remove_a_mode(struct Channel *chptr, int mask, char flag) +{ + const dlink_node *ptr = NULL; + char lmodebuf[MODEBUFLEN]; + const char *lpara[4] = { "", "", "", "" }; + char *mbuf = lmodebuf; + int count = 0; + + *mbuf++ = '-'; + + DLINK_FOREACH(ptr, chptr->members.head) + { + struct Membership *ms = ptr->data; + if ((ms->flags & mask) == 0) + continue; + + ms->flags &= ~mask; + + lpara[count++] = ms->client_p->name; + + *mbuf++ = flag; + + if (count == 4) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s %s %s %s %s %s", + me.name, chptr->chname, lmodebuf, lpara[0], + lpara[1], lpara[2], lpara[3]); + + mbuf = lmodebuf; + *mbuf++ = '-'; + count = 0; + lpara[0] = lpara[1] = lpara[2] = lpara[3] = ""; + } + } + + if (count != 0) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s %s %s %s %s %s", + me.name, chptr->chname, lmodebuf, lpara[0], + lpara[1], lpara[2], lpara[3]); + } +} + +static struct Message clearchan_msgtab = { + "CLEARCHAN", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_clearchan, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&clearchan_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&clearchan_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_ctrace.c b/contrib/m_ctrace.c new file mode 100644 index 0000000..7b4d658 --- /dev/null +++ b/contrib/m_ctrace.c @@ -0,0 +1,197 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_ctrace.c: Traces a given class + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "s_bsd.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + +static void do_ctrace(struct Client *, int, char *[]); +static void report_this_status(struct Client *, struct Client *); + + +/* +** mo_ctrace +** parv[0] = sender prefix +** parv[1] = classname +*/ +static void +mo_ctrace(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "CTRACE"); + return; + } + + do_ctrace(source_p, parc, parv); +} + +/* + * do_ctrace + */ +static void +do_ctrace(struct Client *source_p, int parc, char *parv[]) +{ + char *class_looking_for = parv[1]; + const char *class_name = NULL; + dlink_node *ptr; + + sendto_realops_flags(UMODE_SPY, L_ALL, SEND_NOTICE, + "CTRACE requested by %s (%s@%s) [%s]", + source_p->name, source_p->username, + source_p->host, source_p->servptr->name); + + /* report all direct connections */ + DLINK_FOREACH(ptr, local_client_list.head) + { + struct Client *target_p = ptr->data; + + class_name = get_client_class(&target_p->localClient->confs); + if ((class_name != NULL) && !match(class_looking_for, class_name)) + report_this_status(source_p, target_p); + } + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name, + source_p->name, class_looking_for); +} + +/* + * report_this_status + * + * inputs - pointer to client to report to + * - pointer to client to report about + * output - counter of number of hits + * side effects - NONE + */ +static void +report_this_status(struct Client *source_p, struct Client *target_p) +{ + const char *name = NULL; + const char *class_name = NULL; + + name = get_client_name(target_p, HIDE_IP); + class_name = get_client_class(&target_p->localClient->confs); + + switch(target_p->status) + { + case STAT_CLIENT: + + if ((HasUMode(source_p, UMODE_OPER) && + (MyClient(source_p) || !HasUMode(target_p, UMODE_INVISIBLE))) + || HasUMode(target_p, UMODE_OPER)) + { + if (HasUMode(target_p, UMODE_ADMIN) && !ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + HasUMode(source_p, UMODE_ADMIN) ? target_p->sockhost : "255.255.255.255", + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else if (HasUMode(target_p, UMODE_OPER)) + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost, + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + else + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEUSER), + me.name, source_p->name, class_name, name, + IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost, + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEUSER), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + } + break; + case STAT_SERVER: + if (!HasUMode(source_p, UMODE_ADMIN)) + name = get_client_name(target_p, MASK_IP); + + sendto_one(source_p, form_str(RPL_TRACESERVER), + me.name, source_p->name, class_name, 0, + 0, name, *(target_p->serv->by) ? + target_p->serv->by : "*", "*", + me.name, CurrentTime - target_p->localClient->lasttime); + break; + + default: /* ...we actually shouldn't come here... --msa */ + sendto_one(source_p, form_str(RPL_TRACENEWTYPE), me.name, + source_p->name, name); + break; + } +} + +static struct Message ctrace_msgtab = { + "CTRACE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_ctrace, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&ctrace_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&ctrace_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_force.c b/contrib/m_force.c new file mode 100644 index 0000000..9e8265b --- /dev/null +++ b/contrib/m_force.c @@ -0,0 +1,329 @@ +/* contrib/m_force.c + * Copyright (C) 2002, 2003, 2004, 2005 Hybrid Development Team + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1.Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2.Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3.The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "fdlist.h" +#include "hash.h" +#include "s_bsd.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "channel.h" +#include "channel_mode.h" + + +/* m_forcejoin() + * parv[0] = sender prefix + * parv[1] = user to force + * parv[2] = channel to force them into + */ +static void +mo_forcejoin(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + struct Channel *chptr = NULL; + unsigned int type = 0; + char mode = '\0'; + char sjmode = '\0'; + char *newch = NULL; + dlink_node *ptr = NULL; + + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + if ((target_p = hash_find_client(parv[1])) == NULL || !IsClient(target_p)) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + + if (!MyConnect(target_p)) + { + if (target_p->from != client_p) + { + if (IsCapable(target_p->from, CAP_ENCAP)) + sendto_one(target_p, ":%s ENCAP %s FORCEJOIN %s %s", + source_p->name, target_p->from->name, + target_p->name, parv[2]); + else + sendto_one(target_p, ":%s FORCEJOIN %s %s", + source_p->name, target_p->name, parv[2]); + } + + return; + } + + /* select our modes from parv[2] if they exist... (chanop)*/ + switch (*parv[2]) + { + case '@': + type = CHFL_CHANOP; + mode = 'o'; + sjmode = '@'; + parv[2]++; + break; +#ifdef HALFOPS + case '%': + type = CHFL_HALFOP; + mode = 'h'; + sjmode = '%'; + parv[2]++; + break; +#endif + case '+': + type = CHFL_VOICE; + mode = 'v'; + sjmode = '+'; + parv[2]++; + break; + default: + type = 0; + mode = sjmode = '\0'; /* make sure sjmode is 0. sjoin depends on it */ + break; + } + + if ((chptr = hash_find_channel(parv[2])) != NULL) + { + if (IsMember(target_p, chptr)) + { + sendto_one(source_p, ":%s NOTICE %s :*** Notice -- %s is already in %s", + me.name, source_p->name, target_p->name, chptr->chname); + return; + } + + add_user_to_channel(chptr, target_p, type, 0); + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN :%s", + target_p->name, target_p->username, + target_p->host, chptr->chname); + + if (sjmode) + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +%c %s", + me.name, chptr->chname, mode, target_p->name); + + if (chptr->chname[0] == '#') + { + if (sjmode) + { + DLINK_FOREACH (ptr, serv_list.head) + { + struct Client *serv_p = ptr->data; + if (serv_p == target_p->from || IsDead(serv_p)) + continue; + + sendto_one(serv_p, ":%s SJOIN %lu %s + :%c%s", + ID_or_name(&me, serv_p), (unsigned long)chptr->channelts, + chptr->chname, (sjmode == '%' && + !IsCapable(serv_p, CAP_HOPS)) ? '@' : sjmode, + ID_or_name(target_p, serv_p)); + } + } + else + { + sendto_server(target_p, CAP_TS6, NOCAPS, + ":%s SJOIN %lu %s + :%s", + me.id, (unsigned long)chptr->channelts, + chptr->chname, target_p->id); + sendto_server(target_p, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s + :%s", + me.name, (unsigned long)chptr->channelts, + chptr->chname, target_p->name); + } + } + + if (chptr->topic[0]) + { + sendto_one(target_p, form_str(RPL_TOPIC), + me.name, target_p->name, + chptr->chname, chptr->topic); + sendto_one(target_p, form_str(RPL_TOPICWHOTIME), + me.name, target_p->name, chptr->chname, + chptr->topic_info, chptr->topic_time); + } + + target_p->localClient->last_join_time = CurrentTime; + channel_member_names(target_p, chptr, 1); + } + else + { + newch = parv[2]; + + if (!check_channel_name(newch, 1)) + { + sendto_one(source_p, form_str(ERR_BADCHANNAME), + me.name, source_p->name, newch); + return; + } + + chptr = make_channel(newch); + add_user_to_channel(chptr, target_p, CHFL_CHANOP, 0); + + sendto_server(target_p, CAP_TS6, NOCAPS, + ":%s SJOIN %lu %s +nt :@%s", + me.id, (unsigned long)chptr->channelts, + chptr->chname, ID(target_p)); + sendto_server(target_p, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s +nt :@%s", + me.name, (unsigned long)chptr->channelts, + chptr->chname, target_p->name); + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN :%s", + target_p->name, target_p->username, + target_p->host, chptr->chname); + + chptr->mode.mode |= MODE_TOPICLIMIT | MODE_NOPRIVMSGS; + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +nt", + me.name, chptr->chname); + + target_p->localClient->last_join_time = CurrentTime; + channel_member_names(target_p, chptr, 1); + + /* we do this to let the oper know that a channel was created, this will be + * seen from the server handling the command instead of the server that + * the oper is on. + */ + sendto_one(source_p, ":%s NOTICE %s :*** Notice -- Creating channel %s", + me.name, source_p->name, chptr->chname); + } +} + +static void +mo_forcepart(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + struct Channel *chptr = NULL; + struct Membership *member = NULL; + + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + /* if target_p == NULL then let the oper know */ + if ((target_p = hash_find_client(parv[1])) == NULL || !IsClient(target_p)) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + + if (!MyConnect(target_p)) + { + if (target_p->from != client_p) + { + if (IsCapable(target_p->from, CAP_ENCAP)) + sendto_one(target_p, ":%s ENCAP %s FORCEPART %s %s", + source_p->name, target_p->from->name, + target_p->name, parv[2]); + else + sendto_one(target_p, ":%s FORCEPART %s %s", + source_p->name, target_p->name, parv[2]); + } + + return; + } + + if ((chptr = hash_find_channel(parv[2])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, parv[2]); + return; + } + + if ((member = find_channel_link(target_p, chptr)) == NULL) + { + sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), + me.name, source_p->name, chptr->chname, target_p->name); + return; + } + + sendto_server(target_p, CAP_TS6, NOCAPS, + ":%s PART %s :%s", ID(target_p), + chptr->chname, target_p->name); + sendto_server(target_p, NOCAPS, CAP_TS6, + ":%s PART %s :%s", target_p->name, + chptr->chname, target_p->name); + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s PART %s :%s", + target_p->name, target_p->username, + target_p->host, chptr->chname, + target_p->name); + remove_user_from_channel(member); +} + +static struct Message forcejoin_msgtab = { + "FORCEJOIN", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + { m_ignore, m_not_oper, mo_forcejoin, mo_forcejoin, mo_forcejoin, m_ignore } +}; + +static struct Message forcepart_msgtab = { + "FORCEPART", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + { m_ignore, m_not_oper, mo_forcepart, mo_forcepart, mo_forcepart, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&forcejoin_msgtab); + mod_add_cmd(&forcepart_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&forcejoin_msgtab); + mod_del_cmd(&forcepart_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_ltrace.c b/contrib/m_ltrace.c new file mode 100644 index 0000000..afdf2f5 --- /dev/null +++ b/contrib/m_ltrace.c @@ -0,0 +1,341 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_ltrace.c: Traces a path to a client/server. + * + * Copyright (C) 2002 Hybrid Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "s_serv.h" +#include "conf.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + +static void do_ltrace(struct Client *, int, char *[]); +static void report_this_status(struct Client *, struct Client *, int); + + +static void +trace_get_dependent(int *const server, + int *const client, const struct Client *target_p) +{ + const dlink_node *ptr = NULL; + + (*server)++; + (*client) += dlink_list_length(&target_p->serv->client_list); + + DLINK_FOREACH(ptr, target_p->serv->server_list.head) + trace_get_dependent(server, client, ptr->data); +} + +/* + * m_ltrace() + * + * parv[0] = sender prefix + * parv[1] = target client/server to trace + */ +static void +m_ltrace(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *tname = NULL; + + if (parc > 1) + tname = parv[1]; + else + tname = me.name; + sendto_one(source_p, form_str(RPL_ENDOFTRACE), + me.name, source_p->name, tname); +} + +/* + * do_ltrace + */ +static void +do_ltrace(struct Client *source_p, int parc, char *parv[]) +{ + struct Client *target_p = NULL; + int doall; + int wilds, dow; + dlink_node *ptr; + char *looking_for = parv[0]; + char *tname = parc > 1 ? parv[1] : me.name; + + switch (hunt_server(source_p->from, source_p, ":%s LTRACE :%s", 1,parc,parv)) + { + case HUNTED_PASS: /* note: gets here only if parv[1] exists */ + { + struct Client *ac2ptr = NULL; + + if ((ac2ptr = hash_find_client(tname)) == NULL) + DLINK_FOREACH(ptr, global_client_list.head) + { + ac2ptr = ptr->data; + + if (!match(tname, ac2ptr->name)) + break; + else + ac2ptr = NULL; + } + + if (ac2ptr != NULL) + sendto_one(source_p, form_str(RPL_TRACELINK), me.name, looking_for, + ircd_version, tname, ac2ptr->from->name); + else + sendto_one(source_p, form_str(RPL_TRACELINK), me.name, looking_for, + ircd_version, tname, "ac2ptr_is_NULL!!"); + return; + } + case HUNTED_ISME: + break; + default: + return; + } + + sendto_realops_flags(UMODE_SPY, L_ALL, SEND_NOTICE, + "LTRACE requested by %s (%s@%s) [%s]", + source_p->name, source_p->username, + source_p->host, source_p->servptr->name); + + doall = (parv[1] && (parc > 1)) ? !match(tname, me.name) : 1; + wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?'); + dow = wilds || doall; + + /* lusers cant issue ltrace.. */ + if (!dow) + { + const char* name; + const char* class_name; + + target_p = hash_find_client(tname); + + if (target_p && IsClient(target_p)) + { + name = get_client_name(target_p, HIDE_IP); + class_name = get_client_class(&target_p->localClient->confs); + + if (HasUMode(target_p, UMODE_OPER)) + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + } + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), + me.name, source_p->name, tname); + return; + } + + /* report all opers */ + DLINK_FOREACH(ptr, local_client_list.head) + { + target_p = ptr->data; + + if (!HasUMode(target_p, UMODE_OPER)) + continue; + + if (!doall && wilds && match(tname, target_p->name)) + continue; + + if (!dow && irccmp(tname, target_p->name)) + continue; + + report_this_status(source_p, target_p, dow); + } + + /* report all servers */ + DLINK_FOREACH(ptr, serv_list.head) + { + target_p = ptr->data; + + if (!doall && wilds && match(tname, target_p->name)) + continue; + if (!dow && irccmp(tname, target_p->name)) + continue; + + report_this_status(source_p, target_p, dow); + } + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name, parv[0], tname); +} + +/* + * mo_ltrace + * parv[0] = sender prefix + * parv[1] = servername + */ +static void +mo_ltrace(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (!HasUMode(source_p, UMODE_OPER)) + { + sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name, parv[0], + parc > 1 ? parv[1] : me.name); + return; + } + + if (parc > 2) + if (hunt_server(client_p, source_p, ":%s LTRACE %s :%s", 2, parc, parv)) + return; + + do_ltrace(source_p, parc, parv); +} + +/* + * report_this_status + * + * inputs - pointer to client to report to + * - pointer to client to report about + * output - counter of number of hits + * side effects - NONE + */ +static void +report_this_status(struct Client *source_p, struct Client *target_p, + int dow) +{ + const char *name = NULL; + const char *class_name = NULL; + + name = get_client_name(target_p, HIDE_IP); + class_name = get_client_class(&target_p->localClient->confs); + + switch (target_p->status) + { + case STAT_CONNECTING: + sendto_one(source_p, form_str(RPL_TRACECONNECTING), me.name, + source_p->name, class_name, + HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name); + break; + + case STAT_HANDSHAKE: + sendto_one(source_p, form_str(RPL_TRACEHANDSHAKE), me.name, + source_p->name, class_name, + HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name); + break; + + case STAT_CLIENT: + if (HasUMode(target_p, UMODE_ADMIN)) + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + HasUMode(source_p, UMODE_ADMIN) ? target_p->sockhost : + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + else if (HasUMode(target_p, UMODE_OPER)) + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + break; + + case STAT_SERVER: + { + int clients = 0; + int servers = 0; + + trace_get_dependent(&servers, &clients, target_p); + + if (!HasUMode(source_p, UMODE_ADMIN)) + name = get_client_name(target_p, MASK_IP); + + sendto_one(source_p, form_str(RPL_TRACESERVER), + me.name, source_p->name, class_name, servers, + clients, name, *(target_p->serv->by) ? + target_p->serv->by : "*", "*", + me.name, CurrentTime - target_p->localClient->lasttime); + break; + } + + case STAT_ME: + case STAT_UNKNOWN: + break; + + default: /* ...we actually shouldn't come here... --msa */ + sendto_one(source_p, form_str(RPL_TRACENEWTYPE), me.name, + source_p->name, name); + break; + } +} + +static struct Message ltrace_msgtab = { + "LTRACE", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_ltrace, mo_ltrace, m_ignore, mo_ltrace, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(<race_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(<race_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_ojoin.c b/contrib/m_ojoin.c new file mode 100644 index 0000000..e0ff868 --- /dev/null +++ b/contrib/m_ojoin.c @@ -0,0 +1,173 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_ojoin.c: Allows opers join channels with @%+ modes + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "irc_string.h" +#include "hash.h" +#include "s_serv.h" +#include "modules.h" +#include "channel_mode.h" +#include "parse.h" + + +/* mo_ojoin() + * parv[0] = sender prefix + * parv[1] = channels separated by commas + */ +static void +mo_ojoin(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + const char *prefix = ""; + char modeletter = '\0'; + char *name = parv[1]; + char *t = NULL; + unsigned int flags = 0; + dlink_node *ptr; + + /* admins only */ + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + for (name = strtoken(&t, name, ","); name; + name = strtoken(&t, NULL, ",")) + { + switch (*name) + { + case '@': + prefix = "@"; + flags = CHFL_CHANOP; + modeletter = 'o'; + ++name; + break; +#ifdef HALFOPS + case '%': + prefix = "%"; + flags = CHFL_HALFOP; + modeletter = 'h'; + ++name; + break; +#endif + case '+': + prefix = "+"; + flags = CHFL_VOICE; + modeletter = 'v'; + ++name; + break; + case '#': + prefix = ""; + flags = 0; + modeletter = '\0'; + break; + + default: + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, name); + continue; + } + + /* Error checking here */ + if ((chptr = hash_find_channel(name)) == NULL) + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, name); + else if (IsMember(source_p, chptr)) + sendto_one(source_p, ":%s NOTICE %s :Please part %s before using OJOIN", + me.name, source_p->name, name); + else + { + add_user_to_channel(chptr, source_p, flags, 0); + + DLINK_FOREACH(ptr, serv_list.head) + { + struct Client *serv_p = ptr->data; + + sendto_one(serv_p, ":%s SJOIN %lu %s + :%s%s", ID_or_name(&me, serv_p), + (unsigned long)chptr->channelts, chptr->chname, + (*prefix == '%' && !IsCapable(serv_p, CAP_HOPS)) ? + "@" : prefix, ID_or_name(source_p, serv_p)); + } + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN %s", + source_p->name, source_p->username, + source_p->host, + chptr->chname); + + if (modeletter != '\0') + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +%c %s", + me.name, chptr->chname, modeletter, source_p->name); + + /* send the topic... */ + if (chptr->topic[0]) + { + sendto_one(source_p, form_str(RPL_TOPIC), + me.name, source_p->name, chptr->chname, + chptr->topic); + sendto_one(source_p, form_str(RPL_TOPICWHOTIME), + me.name, source_p->name, chptr->chname, + chptr->topic_info, chptr->topic_time); + } + + source_p->localClient->last_join_time = CurrentTime; + channel_member_names(source_p, chptr, 1); + } + } +} + +static struct Message ojoin_msgtab = { + "OJOIN", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_ojoin, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&ojoin_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&ojoin_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_operspy.c b/contrib/m_operspy.c new file mode 100644 index 0000000..f893bb7 --- /dev/null +++ b/contrib/m_operspy.c @@ -0,0 +1,639 @@ +/************************************************************************ + * IRC - Internet Relay Chat, contrib/m_operspy.c + * Copyright (C) 2002 William Bierman III and the Hybrid Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ + +/*** PLEASE READ ME ***/ +/* + * This module gives an extraordinary amount of power to the opers + * who have the access to use it. It allows for users' privacy to + * be pretty much obliterated. The Hybrid Team assumes absolutely + * no responsibility for this file's (mis)use. + * + * - billy-jon + */ + +#include "stdinc.h" +#include "list.h" +#include "irc_string.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "ircd.h" +#include "sprintf_irc.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "conf.h" +#include "log.h" +#include "s_serv.h" +#include "s_misc.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "hash.h" + +/* enable logging of OPERSPY functions */ +#define OPERSPY_LOG + +/* enable this to log all local/remote operspy usage to a logfile */ +#define OPERSPY_LOGFILE + +/* enable this to send incoming operspy usage to connected +y (UMODE_SPY) opers */ +#define OPERSPY_NOTICE + +/* enable OPERSPY version of LIST */ +#define OPERSPY_LIST + +/* enable OPERSPY version of MODE */ +#define OPERSPY_MODE + +/* enable OPERSPY version of NAMES */ +#define OPERSPY_NAMES + +/* enable OPERSPY version of WHO */ +#define OPERSPY_WHO + +/* enable OPERSPY version of WHOIS */ +#define OPERSPY_WHOIS + +/* enable OPERSPY version of TOPIC */ +#define OPERSPY_TOPIC + +#define IsOperspy(x) (HasUMode(x, UMODE_OPER) && MyClient(x) && HasUMode(x, UMODE_ADMIN)) + +/* extensions for OPERSPY WHO */ +static void do_who(struct Client *, struct Client *, char *, const char *); +static void who_global(struct Client *, char *, int); +static void do_who_on_channel(struct Client *, struct Channel *, char *); + +static void operspy_list(struct Client *, int, char *[]); +static void operspy_mode(struct Client *, int, char *[]); +static void operspy_names(struct Client *, int, char *[]); +static void operspy_topic(struct Client *, int, char *[]); +static void operspy_who(struct Client *, int, char *[]); +static void operspy_whois(struct Client *, int, char *[]); +#ifdef OPERSPY_LOG +static void operspy_log(struct Client *, const char *, const char *); +#endif + + +static const struct operspy_s { + const char *const cmd; + void (*const func_p)(struct Client *, int, char *[]); +} operspy_table[] = { +#ifdef OPERSPY_LIST + { "LIST", operspy_list }, +#endif +#ifdef OPERSPY_MODE + { "MODE", operspy_mode }, +#endif +#ifdef OPERSPY_NAMES + { "NAMES", operspy_names }, +#endif +#ifdef OPERSPY_TOPIC + { "TOPIC", operspy_topic }, +#endif +#ifdef OPERSPY_WHO + { "WHO", operspy_who }, +#endif +#ifdef OPERSPY_WHOIS + { "WHOIS", operspy_whois }, +#endif + { NULL, NULL } +}; + +static void +ms_operspy(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ +#ifdef OPERSPY_LOG + operspy_log(source_p, parv[1], parv[2]); +#endif +} + +/* mo_operspy() + * parv[1] = operspy command + * parv[2] = command parameter + */ +static void +mo_operspy(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char cmdbuf[IRCD_BUFSIZE] = "<NONE>"; /* in case everything is undef'd */ + size_t bcnt = 0; + const struct operspy_s *optr = NULL; + + if (!IsOperspy(client_p)) + { + sendto_one(client_p, form_str(ERR_NOPRIVILEGES), + me.name, client_p->name); + return; + } + + assert(client_p == source_p); + + for (optr = operspy_table; optr->cmd; ++optr) + { + if (!irccmp(optr->cmd, parv[1])) + { + (*optr->func_p)(client_p, parc, parv); + return; + } + } + + for (optr = operspy_table; optr->cmd; ++optr) + { + /* str*cat is slow and sucks */ + bcnt += strlcpy(cmdbuf+bcnt, optr->cmd, sizeof(cmdbuf)-bcnt); + if ((optr + 1)->cmd != NULL && bcnt < (sizeof(cmdbuf)-2)) + { + cmdbuf[bcnt++] = ','; + cmdbuf[bcnt++] = ' '; + } + } + + sendto_one(client_p, ":%s NOTICE %s :%s is not a valid option. Choose from %s", + me.name, client_p->name, parv[1], cmdbuf); +} + +static void +operspy_list(struct Client *client_p, int parc, char *parv[]) +{ + const dlink_node *ptr = NULL; +#ifdef OPERSPY_LOG + operspy_log(client_p, "LIST", parv[2]); +#endif + + if (*parv[2] == '\0') + return; + + sendto_one(client_p, form_str(RPL_LISTSTART), + me.name, client_p->name); + + DLINK_FOREACH(ptr, global_channel_list.head) + { + const struct Channel *chptr_list = ptr->data; + + if (!match(parv[2], chptr_list->chname)) + sendto_one(client_p, form_str(RPL_LIST), me.name, client_p->name, + chptr_list->chname, dlink_list_length(&chptr_list->members), + chptr_list->topic); + } + + sendto_one(client_p, form_str(RPL_LISTEND), + me.name, client_p->name); +} + +static void +operspy_mode(struct Client *client_p, int parc, char *parv[]) +{ + /* needed to preserve actual client status */ + int c_status = 0; + char modebuf[MODEBUFLEN]; + char parabuf[MODEBUFLEN]; + struct Channel *chptr_mode = NULL; + + if ((chptr_mode = hash_find_channel(parv[2])) == NULL) + { + /* + * according to m_mode.c, the channel *could* exist on the uplink still, + * but I don't see how. Even if it does, we won't be able to spy without + * info. + */ + sendto_one(client_p, form_str(ERR_NOSUCHCHANNEL), + me.name, client_p->name, parv[2]); + return; + } + +#ifdef OPERSPY_LOG + operspy_log(client_p, "MODE", parv[2]); +#endif + + /* + * XXX - this is a dirty nasty kludge to trick channel_modes() + * into giving us the key + */ + c_status = client_p->status; + client_p->status = STAT_SERVER; + + channel_modes(chptr_mode, client_p, modebuf, parabuf); + client_p->status = c_status; + + sendto_one(client_p, form_str(RPL_CHANNELMODEIS), + me.name, client_p->name, parv[2], modebuf, parabuf); + sendto_one(client_p, form_str(RPL_CREATIONTIME), + me.name, client_p->name, parv[2], chptr_mode->channelts); +} + +static void +operspy_names(struct Client *client_p, int parc, char *parv[]) +{ + /* as with mode, must preserve channel modes */ + struct Channel *chptr_names = NULL; + + if ((chptr_names = hash_find_channel(parv[2])) == NULL) + { + sendto_one(client_p, form_str(ERR_NOSUCHCHANNEL), + me.name, client_p->name, parv[2]); + return; + } + +#ifdef OPERSPY_LOG + operspy_log(client_p, "NAMES", parv[2]); +#endif + + /* + * the way to go with this, rather than temporarily setting -sp, + * is to temporarily add our client to the member list. then + * we can also list +i users. an unfortunate side-effect of this + * is that your nickname shows up in the list. for now, there is + * no easy way around it. + */ + if (IsMember(client_p, chptr_names)) + channel_member_names(client_p, chptr_names, 1); + else + { + add_user_to_channel(chptr_names, client_p, CHFL_CHANOP, 0); + channel_member_names(client_p, chptr_names, 1); + remove_user_from_channel(find_channel_link(client_p, chptr_names)); + } +} + +static void +operspy_topic(struct Client *client_p, int parc, char *parv[]) +{ + const struct Channel *chptr_topic = NULL; + + if ((chptr_topic = hash_find_channel(parv[2])) == NULL) + { + sendto_one(client_p, form_str(ERR_NOSUCHCHANNEL), + me.name, client_p->name, parv[2]); + return; + } + +#ifdef OPERSPY_LOG + operspy_log(client_p, "TOPIC", parv[2]); +#endif + + if (chptr_topic->topic[0] == '\0') + sendto_one(client_p, form_str(RPL_NOTOPIC), + me.name, client_p->name, parv[2]); + else + { + sendto_one(client_p, form_str(RPL_TOPIC), me.name, client_p->name, + chptr_topic->chname, chptr_topic->topic); + sendto_one(client_p, form_str(RPL_TOPICWHOTIME), me.name, + client_p->name, chptr_topic->chname, chptr_topic->topic_info, + chptr_topic->topic_time); + } +} + +static void +operspy_who(struct Client *client_p, int parc, char *parv[]) +{ + char *mask = parc > 2 ? parv[2] : NULL; + int server_oper = parc > 3 ? (*parv[3] == 'o') : 0; + struct Channel *chptr_who = NULL; + struct Client *target_p_who = NULL; + + if (mask != NULL) + { + collapse(mask); + + if (*mask == '\0') + { + sendto_one(client_p, form_str(RPL_ENDOFWHO), + me.name, client_p->name, "*"); + return; + } + } + else + { +#ifdef OPERSPY_LOG + operspy_log(client_p, "WHO", "*"); +#endif + who_global(client_p, NULL, server_oper); + sendto_one(client_p, form_str(RPL_ENDOFWHO), + me.name, client_p->name, "*"); + return; + } + + /* /who #channel */ + if (IsChanPrefix(*mask)) + { + if ((chptr_who = hash_find_channel(mask)) != NULL) + { +#ifdef OPERSPY_LOG + operspy_log(client_p, "WHO", mask); +#endif + do_who_on_channel(client_p, chptr_who, chptr_who->chname); + } + + sendto_one(client_p, form_str(RPL_ENDOFWHO), + me.name, client_p->name, mask); + return; + } + + /* /who nick */ + if ((target_p_who = find_person(client_p, mask)) != NULL) + { +#ifdef OPERSPY_LOG + /* "nick!user@host server\0" */ + char nuh[NICKLEN + 1 + USERLEN + 1 + HOSTLEN + 1 + HOSTLEN + 1]; + + snprintf(nuh, sizeof(nuh), "%s!%s@%s %s", target_p_who->name, + target_p_who->username, target_p_who->host, + target_p_who->servptr->name); + operspy_log(client_p, "WHO", nuh); +#endif + + if (target_p_who->channel.head != NULL) + { + chptr_who = + ((struct Membership *)target_p_who->channel.head->data)->chptr; + + do_who(client_p, target_p_who, chptr_who->chname, + get_member_status(target_p_who->channel.head->data, 0)); + } + else + do_who(client_p, target_p_who, NULL, ""); + + sendto_one(client_p, form_str(RPL_ENDOFWHO), + me.name, client_p->name, mask); + return; + } + +#ifdef OPERSPY_LOG + operspy_log(client_p, "WHO", parv[2]); +#endif + + /* /who 0 */ + if (!strcmp(mask, "0")) + who_global(client_p, NULL, server_oper); + else + who_global(client_p, mask, server_oper); + + /* nothing else? end of /who. */ + sendto_one(client_p, form_str(RPL_ENDOFWHO), + me.name, client_p->name, mask); +} + +static void +operspy_whois(struct Client *client_p, int parc, char *parv[]) +{ + const dlink_node *lp; + struct Channel *chptr_whois = NULL; + struct Client *a2client_p; + struct Client *target_p = NULL; + char buf[IRCD_BUFSIZE]; +#ifdef OPERSPY_LOG + /* "nick!user@host server\0" */ + char nuh[NICKLEN + 1 + USERLEN + 1 + HOSTLEN + 1 + HOSTLEN + 1]; +#endif + char *t = NULL; + int mlen, tlen; + int cur_len = 0; + int reply_to_send = 0; + + if (has_wildcards(parv[2])) + { + sendto_one(client_p, ":%s NOTICE %s :Do not use wildcards with this.", + me.name, client_p->name); + return; + } + + if ((target_p = find_person(client_p, parv[2])) == NULL) + { + sendto_one(client_p, form_str(ERR_NOSUCHNICK), + me.name, client_p->name, parv[2]); + return; + } + +#ifdef OPERSPY_LOG + snprintf(nuh, sizeof(nuh), "%s!%s@%s %s", + target_p->name, target_p->username, target_p->host, + target_p->servptr->name); + operspy_log(client_p, "WHOIS", nuh); +#endif + + a2client_p = target_p->servptr; + + sendto_one(client_p, form_str(RPL_WHOISUSER), me.name, + client_p->name, target_p->name, target_p->username, + target_p->host, target_p->info); + mlen = ircsprintf(buf, form_str(RPL_WHOISCHANNELS), me.name, + client_p->name, target_p->name, ""); + cur_len = mlen; + t = buf + mlen; + + DLINK_FOREACH(lp, target_p->channel.head) + { + chptr_whois = ((struct Membership *)lp->data)->chptr; + + if ((cur_len + strlen(chptr_whois->chname) + 2) > (IRCD_BUFSIZE - 4)) + { + sendto_one(client_p, "%s", buf); + cur_len = mlen; + t = buf + mlen; + } + + tlen = ircsprintf(t, "%s%s%s ", + ShowChannel(client_p, chptr_whois) ? "" : "%", + get_member_status((struct Membership *)lp->data, 1), + chptr_whois->chname); + t += tlen; + cur_len += tlen; + reply_to_send = 1; + } + + if (reply_to_send == 1) + sendto_one(client_p, "%s", buf); + + sendto_one(client_p, form_str(RPL_WHOISSERVER), me.name, + client_p->name, target_p->name, a2client_p->name, + a2client_p->info); + + if (HasUMode(target_p, UMODE_OPER)) + sendto_one(client_p, form_str(HasUMode(target_p, UMODE_ADMIN) ? RPL_WHOISADMIN : + RPL_WHOISOPERATOR), me.name, client_p->name, target_p->name); + + if (MyConnect(target_p)) + sendto_one(client_p, form_str(RPL_WHOISIDLE), me.name, + client_p->name, target_p->name, + CurrentTime - target_p->localClient->last_privmsg, + target_p->localClient->firsttime); + sendto_one(client_p, form_str(RPL_ENDOFWHOIS), + me.name, client_p->name, parv[2]); +} + +/* extensions for OPERSPY WHO */ +static void +do_who(struct Client *source_p, struct Client *target_p, + char *chname, const char *op_flags) +{ + char status[8]; + + snprintf(status, sizeof(status), "%c%s%s", target_p->away[0] ? 'G' : 'H', + HasUMode(target_p, UMODE_OPER) ? "*" : "", op_flags); + sendto_one(source_p, form_str(RPL_WHOREPLY), me.name, source_p->name, + (chname) ? (chname) : "*", + target_p->username, + target_p->host, target_p->servptr->name, target_p->name, + status, target_p->hopcount, target_p->info); +} + +static void +who_global(struct Client *source_p, char *mask, int server_oper) +{ + struct Client *target_p; + dlink_node *lp; + int maxmatches = 500; + + /* list all matching visible clients */ + DLINK_FOREACH(lp, global_client_list.head) + { + target_p = lp->data; + + if (!IsClient(target_p)) + continue; + + if (server_oper && !HasUMode(target_p, UMODE_OPER)) + continue; + + if (!mask || + !match(mask, target_p->name) || !match(mask, target_p->username) || + !match(mask, target_p->host) || !match(mask, target_p->servptr->name) || + !match(mask, target_p->info) || + (MyClient(target_p) && !match(mask, target_p->sockhost))) + { + if (dlink_list_length(&target_p->channel)) + { + struct Channel *chptr; + static char fl[5]; + + chptr = ((struct Membership *)(target_p->channel.head->data))->chptr; + snprintf(fl, sizeof(fl), "%s", + get_member_status((struct Membership *)(target_p->channel.head->data), 0)); + + do_who(source_p, target_p, chptr->chname, fl); + } + else + do_who(source_p, target_p, NULL, ""); + + if (maxmatches > 0) + { + if (--maxmatches == 0) + return; + } + } + } +} + +static void +do_who_on_channel(struct Client *source_p, struct Channel *chptr, + char *chname) +{ + dlink_node *ptr; + struct Membership *ms; + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + do_who(source_p, ms->client_p, chname, get_member_status(ms, 0)); + } +} + +#ifdef OPERSPY_LOG +static void +operspy_log(struct Client *source_p, const char *command, const char *target) +{ + struct MaskItem *conf = NULL; +#ifdef OPERSPY_LOGFILE + FILE *operspy_fb; + dlink_node *cnode; + const char *opername = source_p->name; + char linebuf[IRCD_BUFSIZE], logfile[IRCD_BUFSIZE]; +#endif + + assert(source_p != NULL); + +#ifdef OPERSPY_LOGFILE + if (HasUMode(source_p, UMODE_OPER) && MyClient(source_p)) + { + DLINK_FOREACH(cnode, source_p->localClient->confs.head) + { + conf = cnode->data; + + if (conf->type == CONF_OPER) + opername = conf->name; + } + } + else if (!MyClient(source_p)) + opername = "remote"; + + snprintf(logfile, sizeof(logfile), "%s/operspy.%s.log", LOGPATH, opername); + if ((operspy_fb = fopen(logfile, "a")) == NULL) + return; + + snprintf(linebuf, sizeof(linebuf), "[%s] OPERSPY %s %s %s\n", + smalldate(CurrentTime), + get_oper_name(source_p), + command, target); + fputs(linebuf, operspy_fb); + fclose(operspy_fb); +#endif + +#ifdef OPERSPY_NOTICE + sendto_realops_flags(UMODE_SPY, L_ALL, SEND_NOTICE, "OPERSPY %s %s %s", + get_oper_name(source_p), command, target); +#endif + + if (MyClient(source_p)) + sendto_match_servs(source_p, "*", CAP_ENCAP, "ENCAP * OPERSPY %s :%s", + command, target); +} +#endif /* OPERSPY_LOG */ + +static struct Message operspy_msgtab = { + "OPERSPY", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + {m_ignore, m_not_oper, ms_operspy, ms_operspy, mo_operspy, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&operspy_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&operspy_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_opme.c b/contrib/m_opme.c new file mode 100644 index 0000000..4b5517a --- /dev/null +++ b/contrib/m_opme.c @@ -0,0 +1,150 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_opme.c: Regains ops on opless channels + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "log.h" +#include "s_serv.h" +#include "send.h" +#include "irc_string.h" +#include "hash.h" +#include "parse.h" +#include "modules.h" + + +static int +chan_is_opless(const struct Channel *const chptr) +{ + const dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, chptr->members.head) + if (((struct Membership *)ptr->data)->flags & CHFL_CHANOP) + return 0; + + return 1; +} + +/* + * mo_opme() + * parv[0] = sender prefix + * parv[1] = channel + */ +static void +mo_opme(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + struct Membership *member = NULL; + + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + if ((chptr = hash_find_channel(parv[1])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, parv[1]); + return; + } + + if ((member = find_channel_link(source_p, chptr)) == NULL) + { + sendto_one(source_p, form_str(ERR_NOTONCHANNEL), + me.name, source_p->name, chptr->chname); + return; + } + + if (!chan_is_opless(chptr)) + { + sendto_one(source_p, ":%s NOTICE %s :%s Channel is not opless", + me.name, source_p->name, chptr->chname); + return; + } + + AddMemberFlag(member, CHFL_CHANOP); + + sendto_wallops_flags(UMODE_WALLOP, &me, "OPME called for [%s] by %s!%s@%s", + chptr->chname, source_p->name, source_p->username, + source_p->host); + sendto_server(NULL, NOCAPS, NOCAPS, + ":%s WALLOPS :OPME called for [%s] by %s!%s@%s", + me.name, chptr->chname, source_p->name, source_p->username, + source_p->host); + + ilog(LOG_TYPE_IRCD, "OPME called for [%s] by %s!%s@%s", + chptr->chname, source_p->name, source_p->username, + source_p->host); + + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s PART %s", ID(source_p), chptr->chname); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s PART %s", source_p->name, chptr->chname); + + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s SJOIN %lu %s + :@%s", + me.id, (unsigned long)chptr->channelts, + chptr->chname, ID(source_p)); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s + :@%s", + me.name, (unsigned long)chptr->channelts, + chptr->chname, source_p->name); + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +o %s", + me.name, chptr->chname, source_p->name); +} + +static struct Message opme_msgtab = { + "OPME", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_opme, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&opme_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&opme_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; |