diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 20:18:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 20:18:39 +0000 |
commit | fff5217f02d91268ce90c8c05665602c059faaef (patch) | |
tree | 2ba24d32dc96eafe7ed0a85269548e76796d849d /src/fe-common/irc | |
parent | Initial commit. (diff) | |
download | irssi-fff5217f02d91268ce90c8c05665602c059faaef.tar.xz irssi-fff5217f02d91268ce90c8c05665602c059faaef.zip |
Adding upstream version 1.4.5.upstream/1.4.5upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/fe-common/irc')
46 files changed, 9582 insertions, 0 deletions
diff --git a/src/fe-common/irc/Makefile.am b/src/fe-common/irc/Makefile.am new file mode 100644 index 0000000..8a04bee --- /dev/null +++ b/src/fe-common/irc/Makefile.am @@ -0,0 +1,42 @@ +SUBDIRS = dcc notifylist + +noinst_LIBRARIES = libfe_common_irc.a + +AM_CPPFLAGS = \ + -I$(top_builddir) \ + $(GLIB_CFLAGS) \ + -DHELPDIR=\""$(datadir)/irssi/help"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" + +real_sources = \ + fe-irc-channels.c \ + fe-irc-commands.c \ + fe-irc-messages.c \ + fe-irc-queries.c \ + fe-irc-server.c \ + fe-ircnet.c \ + fe-ctcp.c \ + fe-events.c \ + fe-events-numeric.c \ + fe-modes.c \ + fe-netjoin.c \ + fe-netsplit.c \ + fe-common-irc.c \ + fe-whois.c \ + fe-sasl.c \ + fe-cap.c \ + irc-completion.c \ + module-formats.c + +libfe_common_irc_a_SOURCES = \ + $(real_sources) \ + irc-modules.c + +pkginc_fe_common_ircdir=$(pkgincludedir)/src/fe-common/irc +pkginc_fe_common_irc_HEADERS = \ + fe-irc-server.h \ + fe-irc-channels.h \ + module.h \ + module-formats.h + +EXTRA_DIST = meson.build diff --git a/src/fe-common/irc/Makefile.in b/src/fe-common/irc/Makefile.in new file mode 100644 index 0000000..202076b --- /dev/null +++ b/src/fe-common/irc/Makefile.in @@ -0,0 +1,929 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 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__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +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 = src/fe-common/irc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/glib-2.0.m4 \ + $(top_srcdir)/m4/glibtests.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/libotr.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(pkginc_fe_common_irc_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/irssi-config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libfe_common_irc_a_AR = $(AR) $(ARFLAGS) +libfe_common_irc_a_LIBADD = +am__objects_1 = fe-irc-channels.$(OBJEXT) fe-irc-commands.$(OBJEXT) \ + fe-irc-messages.$(OBJEXT) fe-irc-queries.$(OBJEXT) \ + fe-irc-server.$(OBJEXT) fe-ircnet.$(OBJEXT) fe-ctcp.$(OBJEXT) \ + fe-events.$(OBJEXT) fe-events-numeric.$(OBJEXT) \ + fe-modes.$(OBJEXT) fe-netjoin.$(OBJEXT) fe-netsplit.$(OBJEXT) \ + fe-common-irc.$(OBJEXT) fe-whois.$(OBJEXT) fe-sasl.$(OBJEXT) \ + fe-cap.$(OBJEXT) irc-completion.$(OBJEXT) \ + module-formats.$(OBJEXT) +am_libfe_common_irc_a_OBJECTS = $(am__objects_1) irc-modules.$(OBJEXT) +libfe_common_irc_a_OBJECTS = $(am_libfe_common_irc_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/fe-cap.Po \ + ./$(DEPDIR)/fe-common-irc.Po ./$(DEPDIR)/fe-ctcp.Po \ + ./$(DEPDIR)/fe-events-numeric.Po ./$(DEPDIR)/fe-events.Po \ + ./$(DEPDIR)/fe-irc-channels.Po ./$(DEPDIR)/fe-irc-commands.Po \ + ./$(DEPDIR)/fe-irc-messages.Po ./$(DEPDIR)/fe-irc-queries.Po \ + ./$(DEPDIR)/fe-irc-server.Po ./$(DEPDIR)/fe-ircnet.Po \ + ./$(DEPDIR)/fe-modes.Po ./$(DEPDIR)/fe-netjoin.Po \ + ./$(DEPDIR)/fe-netsplit.Po ./$(DEPDIR)/fe-sasl.Po \ + ./$(DEPDIR)/fe-whois.Po ./$(DEPDIR)/irc-completion.Po \ + ./$(DEPDIR)/irc-modules.Po ./$(DEPDIR)/module-formats.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libfe_common_irc_a_SOURCES) +DIST_SOURCES = $(libfe_common_irc_a_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +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)$(pkginc_fe_common_ircdir)" +HEADERS = $(pkginc_fe_common_irc_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHAT_MODULES = @CHAT_MODULES@ +COMMON_LIBS = @COMMON_LIBS@ +COMMON_NOUI_LIBS = @COMMON_NOUI_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +FUZZER_LIBS = @FUZZER_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBOTR_CFLAGS = @LIBOTR_CFLAGS@ +LIBOTR_LIBS = @LIBOTR_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +OTR_CFLAGS = @OTR_CFLAGS@ +OTR_LDFLAGS = @OTR_LDFLAGS@ +OTR_LINK_FLAGS = @OTR_LINK_FLAGS@ +OTR_LINK_LIBS = @OTR_LINK_LIBS@ +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@ +PERL_CFLAGS = @PERL_CFLAGS@ +PERL_EXTRA_OPTS = @PERL_EXTRA_OPTS@ +PERL_FE_LINK_LIBS = @PERL_FE_LINK_LIBS@ +PERL_LDFLAGS = @PERL_LDFLAGS@ +PERL_LINK_FLAGS = @PERL_LINK_FLAGS@ +PERL_LINK_LIBS = @PERL_LINK_LIBS@ +PERL_MM_OPT = @PERL_MM_OPT@ +PERL_MM_PARAMS = @PERL_MM_PARAMS@ +PERL_STATIC_LIBS = @PERL_STATIC_LIBS@ +PERL_USE_LIB = @PERL_USE_LIB@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROG_LIBS = @PROG_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TEXTUI_LIBS = @TEXTUI_LIBS@ +VERSION = @VERSION@ +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@ +installed_test_metadir = @installed_test_metadir@ +installed_testdir = @installed_testdir@ +irc_MODULES = @irc_MODULES@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +otr_module_lib = @otr_module_lib@ +otr_static_lib = @otr_static_lib@ +pdfdir = @pdfdir@ +perl_module_fe_lib = @perl_module_fe_lib@ +perl_module_lib = @perl_module_lib@ +perl_static_fe_lib = @perl_static_fe_lib@ +perl_static_lib = @perl_static_lib@ +perlpath = @perlpath@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sedpath = @sedpath@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = dcc notifylist +noinst_LIBRARIES = libfe_common_irc.a +AM_CPPFLAGS = \ + -I$(top_builddir) \ + $(GLIB_CFLAGS) \ + -DHELPDIR=\""$(datadir)/irssi/help"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" + +real_sources = \ + fe-irc-channels.c \ + fe-irc-commands.c \ + fe-irc-messages.c \ + fe-irc-queries.c \ + fe-irc-server.c \ + fe-ircnet.c \ + fe-ctcp.c \ + fe-events.c \ + fe-events-numeric.c \ + fe-modes.c \ + fe-netjoin.c \ + fe-netsplit.c \ + fe-common-irc.c \ + fe-whois.c \ + fe-sasl.c \ + fe-cap.c \ + irc-completion.c \ + module-formats.c + +libfe_common_irc_a_SOURCES = \ + $(real_sources) \ + irc-modules.c + +pkginc_fe_common_ircdir = $(pkgincludedir)/src/fe-common/irc +pkginc_fe_common_irc_HEADERS = \ + fe-irc-server.h \ + fe-irc-channels.h \ + module.h \ + module-formats.h + +EXTRA_DIST = meson.build +all: all-recursive + +.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 src/fe-common/irc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/fe-common/irc/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__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + 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): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libfe_common_irc.a: $(libfe_common_irc_a_OBJECTS) $(libfe_common_irc_a_DEPENDENCIES) $(EXTRA_libfe_common_irc_a_DEPENDENCIES) + $(AM_V_at)-rm -f libfe_common_irc.a + $(AM_V_AR)$(libfe_common_irc_a_AR) libfe_common_irc.a $(libfe_common_irc_a_OBJECTS) $(libfe_common_irc_a_LIBADD) + $(AM_V_at)$(RANLIB) libfe_common_irc.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-cap.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-common-irc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-ctcp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-events-numeric.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-events.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-irc-channels.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-irc-commands.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-irc-messages.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-irc-queries.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-irc-server.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-ircnet.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-modes.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-netjoin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-netsplit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-sasl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-whois.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-completion.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-modules.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/module-formats.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-pkginc_fe_common_ircHEADERS: $(pkginc_fe_common_irc_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginc_fe_common_irc_HEADERS)'; test -n "$(pkginc_fe_common_ircdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_fe_common_ircdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkginc_fe_common_ircdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkginc_fe_common_ircdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_fe_common_ircdir)" || exit $$?; \ + done + +uninstall-pkginc_fe_common_ircHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginc_fe_common_irc_HEADERS)'; test -n "$(pkginc_fe_common_ircdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkginc_fe_common_ircdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + 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-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + 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: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + 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: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(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 + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LIBRARIES) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkginc_fe_common_ircdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +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-recursive + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/fe-cap.Po + -rm -f ./$(DEPDIR)/fe-common-irc.Po + -rm -f ./$(DEPDIR)/fe-ctcp.Po + -rm -f ./$(DEPDIR)/fe-events-numeric.Po + -rm -f ./$(DEPDIR)/fe-events.Po + -rm -f ./$(DEPDIR)/fe-irc-channels.Po + -rm -f ./$(DEPDIR)/fe-irc-commands.Po + -rm -f ./$(DEPDIR)/fe-irc-messages.Po + -rm -f ./$(DEPDIR)/fe-irc-queries.Po + -rm -f ./$(DEPDIR)/fe-irc-server.Po + -rm -f ./$(DEPDIR)/fe-ircnet.Po + -rm -f ./$(DEPDIR)/fe-modes.Po + -rm -f ./$(DEPDIR)/fe-netjoin.Po + -rm -f ./$(DEPDIR)/fe-netsplit.Po + -rm -f ./$(DEPDIR)/fe-sasl.Po + -rm -f ./$(DEPDIR)/fe-whois.Po + -rm -f ./$(DEPDIR)/irc-completion.Po + -rm -f ./$(DEPDIR)/irc-modules.Po + -rm -f ./$(DEPDIR)/module-formats.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkginc_fe_common_ircHEADERS + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/fe-cap.Po + -rm -f ./$(DEPDIR)/fe-common-irc.Po + -rm -f ./$(DEPDIR)/fe-ctcp.Po + -rm -f ./$(DEPDIR)/fe-events-numeric.Po + -rm -f ./$(DEPDIR)/fe-events.Po + -rm -f ./$(DEPDIR)/fe-irc-channels.Po + -rm -f ./$(DEPDIR)/fe-irc-commands.Po + -rm -f ./$(DEPDIR)/fe-irc-messages.Po + -rm -f ./$(DEPDIR)/fe-irc-queries.Po + -rm -f ./$(DEPDIR)/fe-irc-server.Po + -rm -f ./$(DEPDIR)/fe-ircnet.Po + -rm -f ./$(DEPDIR)/fe-modes.Po + -rm -f ./$(DEPDIR)/fe-netjoin.Po + -rm -f ./$(DEPDIR)/fe-netsplit.Po + -rm -f ./$(DEPDIR)/fe-sasl.Po + -rm -f ./$(DEPDIR)/fe-whois.Po + -rm -f ./$(DEPDIR)/irc-completion.Po + -rm -f ./$(DEPDIR)/irc-modules.Po + -rm -f ./$(DEPDIR)/module-formats.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkginc_fe_common_ircHEADERS + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic clean-libtool \ + clean-noinstLIBRARIES cscopelist-am ctags ctags-am 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-pdf install-pdf-am install-pkginc_fe_common_ircHEADERS \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am \ + uninstall-pkginc_fe_common_ircHEADERS + +.PRECIOUS: Makefile + + +# 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/src/fe-common/irc/dcc/Makefile.am b/src/fe-common/irc/dcc/Makefile.am new file mode 100644 index 0000000..feee349 --- /dev/null +++ b/src/fe-common/irc/dcc/Makefile.am @@ -0,0 +1,24 @@ +noinst_LIBRARIES = libfe_irc_dcc.a + +AM_CPPFLAGS = \ + -I$(top_builddir) \ + $(GLIB_CFLAGS) \ + -DHELPDIR=\""$(datadir)/irssi/help"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" + +libfe_irc_dcc_a_SOURCES = \ + fe-dcc.c \ + fe-dcc-chat.c \ + fe-dcc-chat-messages.c \ + fe-dcc-get.c \ + fe-dcc-send.c \ + module-formats.c \ + fe-dcc-server.c + +pkginc_fe_common_irc_dccdir=$(pkgincludedir)/src/fe-common/irc/dcc +pkginc_fe_common_irc_dcc_HEADERS = \ + module.h \ + module-formats.h \ + fe-dcc.h + +EXTRA_DIST = meson.build diff --git a/src/fe-common/irc/dcc/Makefile.in b/src/fe-common/irc/dcc/Makefile.in new file mode 100644 index 0000000..f73bf3b --- /dev/null +++ b/src/fe-common/irc/dcc/Makefile.in @@ -0,0 +1,750 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 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__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +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 = src/fe-common/irc/dcc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/glib-2.0.m4 \ + $(top_srcdir)/m4/glibtests.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/libotr.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am \ + $(pkginc_fe_common_irc_dcc_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/irssi-config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libfe_irc_dcc_a_AR = $(AR) $(ARFLAGS) +libfe_irc_dcc_a_LIBADD = +am_libfe_irc_dcc_a_OBJECTS = fe-dcc.$(OBJEXT) fe-dcc-chat.$(OBJEXT) \ + fe-dcc-chat-messages.$(OBJEXT) fe-dcc-get.$(OBJEXT) \ + fe-dcc-send.$(OBJEXT) module-formats.$(OBJEXT) \ + fe-dcc-server.$(OBJEXT) +libfe_irc_dcc_a_OBJECTS = $(am_libfe_irc_dcc_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/fe-dcc-chat-messages.Po \ + ./$(DEPDIR)/fe-dcc-chat.Po ./$(DEPDIR)/fe-dcc-get.Po \ + ./$(DEPDIR)/fe-dcc-send.Po ./$(DEPDIR)/fe-dcc-server.Po \ + ./$(DEPDIR)/fe-dcc.Po ./$(DEPDIR)/module-formats.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libfe_irc_dcc_a_SOURCES) +DIST_SOURCES = $(libfe_irc_dcc_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +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)$(pkginc_fe_common_irc_dccdir)" +HEADERS = $(pkginc_fe_common_irc_dcc_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHAT_MODULES = @CHAT_MODULES@ +COMMON_LIBS = @COMMON_LIBS@ +COMMON_NOUI_LIBS = @COMMON_NOUI_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +FUZZER_LIBS = @FUZZER_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBOTR_CFLAGS = @LIBOTR_CFLAGS@ +LIBOTR_LIBS = @LIBOTR_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +OTR_CFLAGS = @OTR_CFLAGS@ +OTR_LDFLAGS = @OTR_LDFLAGS@ +OTR_LINK_FLAGS = @OTR_LINK_FLAGS@ +OTR_LINK_LIBS = @OTR_LINK_LIBS@ +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@ +PERL_CFLAGS = @PERL_CFLAGS@ +PERL_EXTRA_OPTS = @PERL_EXTRA_OPTS@ +PERL_FE_LINK_LIBS = @PERL_FE_LINK_LIBS@ +PERL_LDFLAGS = @PERL_LDFLAGS@ +PERL_LINK_FLAGS = @PERL_LINK_FLAGS@ +PERL_LINK_LIBS = @PERL_LINK_LIBS@ +PERL_MM_OPT = @PERL_MM_OPT@ +PERL_MM_PARAMS = @PERL_MM_PARAMS@ +PERL_STATIC_LIBS = @PERL_STATIC_LIBS@ +PERL_USE_LIB = @PERL_USE_LIB@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROG_LIBS = @PROG_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TEXTUI_LIBS = @TEXTUI_LIBS@ +VERSION = @VERSION@ +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@ +installed_test_metadir = @installed_test_metadir@ +installed_testdir = @installed_testdir@ +irc_MODULES = @irc_MODULES@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +otr_module_lib = @otr_module_lib@ +otr_static_lib = @otr_static_lib@ +pdfdir = @pdfdir@ +perl_module_fe_lib = @perl_module_fe_lib@ +perl_module_lib = @perl_module_lib@ +perl_static_fe_lib = @perl_static_fe_lib@ +perl_static_lib = @perl_static_lib@ +perlpath = @perlpath@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sedpath = @sedpath@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libfe_irc_dcc.a +AM_CPPFLAGS = \ + -I$(top_builddir) \ + $(GLIB_CFLAGS) \ + -DHELPDIR=\""$(datadir)/irssi/help"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" + +libfe_irc_dcc_a_SOURCES = \ + fe-dcc.c \ + fe-dcc-chat.c \ + fe-dcc-chat-messages.c \ + fe-dcc-get.c \ + fe-dcc-send.c \ + module-formats.c \ + fe-dcc-server.c + +pkginc_fe_common_irc_dccdir = $(pkgincludedir)/src/fe-common/irc/dcc +pkginc_fe_common_irc_dcc_HEADERS = \ + module.h \ + module-formats.h \ + fe-dcc.h + +EXTRA_DIST = meson.build +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 src/fe-common/irc/dcc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/fe-common/irc/dcc/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__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + 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): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libfe_irc_dcc.a: $(libfe_irc_dcc_a_OBJECTS) $(libfe_irc_dcc_a_DEPENDENCIES) $(EXTRA_libfe_irc_dcc_a_DEPENDENCIES) + $(AM_V_at)-rm -f libfe_irc_dcc.a + $(AM_V_AR)$(libfe_irc_dcc_a_AR) libfe_irc_dcc.a $(libfe_irc_dcc_a_OBJECTS) $(libfe_irc_dcc_a_LIBADD) + $(AM_V_at)$(RANLIB) libfe_irc_dcc.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-dcc-chat-messages.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-dcc-chat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-dcc-get.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-dcc-send.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-dcc-server.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-dcc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/module-formats.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-pkginc_fe_common_irc_dccHEADERS: $(pkginc_fe_common_irc_dcc_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginc_fe_common_irc_dcc_HEADERS)'; test -n "$(pkginc_fe_common_irc_dccdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_fe_common_irc_dccdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkginc_fe_common_irc_dccdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkginc_fe_common_irc_dccdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_fe_common_irc_dccdir)" || exit $$?; \ + done + +uninstall-pkginc_fe_common_irc_dccHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginc_fe_common_irc_dcc_HEADERS)'; test -n "$(pkginc_fe_common_irc_dccdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkginc_fe_common_irc_dccdir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + 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-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + 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: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + 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: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(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 $(LIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(pkginc_fe_common_irc_dccdir)"; 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-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/fe-dcc-chat-messages.Po + -rm -f ./$(DEPDIR)/fe-dcc-chat.Po + -rm -f ./$(DEPDIR)/fe-dcc-get.Po + -rm -f ./$(DEPDIR)/fe-dcc-send.Po + -rm -f ./$(DEPDIR)/fe-dcc-server.Po + -rm -f ./$(DEPDIR)/fe-dcc.Po + -rm -f ./$(DEPDIR)/module-formats.Po + -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-pkginc_fe_common_irc_dccHEADERS + +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 -f ./$(DEPDIR)/fe-dcc-chat-messages.Po + -rm -f ./$(DEPDIR)/fe-dcc-chat.Po + -rm -f ./$(DEPDIR)/fe-dcc-get.Po + -rm -f ./$(DEPDIR)/fe-dcc-send.Po + -rm -f ./$(DEPDIR)/fe-dcc-server.Po + -rm -f ./$(DEPDIR)/fe-dcc.Po + -rm -f ./$(DEPDIR)/module-formats.Po + -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-pkginc_fe_common_irc_dccHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLIBRARIES \ + cscopelist-am ctags ctags-am 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-pdf \ + install-pdf-am install-pkginc_fe_common_irc_dccHEADERS \ + 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 tags-am uninstall uninstall-am \ + uninstall-pkginc_fe_common_irc_dccHEADERS + +.PRECIOUS: Makefile + + +# 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/src/fe-common/irc/dcc/fe-dcc-chat-messages.c b/src/fe-common/irc/dcc/fe-dcc-chat-messages.c new file mode 100644 index 0000000..8dd67f7 --- /dev/null +++ b/src/fe-common/irc/dcc/fe-dcc-chat-messages.c @@ -0,0 +1,164 @@ +/* + fe-dcc-chat-messages.c : irssi + + Copyright (C) 2002 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> + +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-queries.h> +#include <irssi/src/irc/dcc/dcc-chat.h> +#include <irssi/src/core/ignore.h> + +#include <irssi/src/fe-common/irc/dcc/module-formats.h> +#include <irssi/src/fe-common/core/printtext.h> + +static void sig_message_dcc_own(CHAT_DCC_REC *dcc, const char *msg) +{ + TEXT_DEST_REC dest; + QUERY_REC *query; + char *tag; + + tag = g_strconcat("=", dcc->id, NULL); + query = query_find(NULL, tag); + + format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, + MSGLEVEL_DCCMSGS | MSGLEVEL_NOHILIGHT | + MSGLEVEL_NO_ACT, NULL); + + printformat_dest(&dest, query != NULL ? IRCTXT_OWN_DCC_QUERY : + IRCTXT_OWN_DCC, dcc->mynick, dcc->id, msg); + g_free(tag); +} + +static void sig_message_dcc_own_action(CHAT_DCC_REC *dcc, const char *msg) +{ + TEXT_DEST_REC dest; + QUERY_REC *query; + char *tag; + + tag = g_strconcat("=", dcc->id, NULL); + query = query_find(NULL, tag); + + format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, + MSGLEVEL_DCCMSGS | MSGLEVEL_ACTIONS | + MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, NULL); + + printformat_dest(&dest, query != NULL ? IRCTXT_OWN_DCC_ACTION_QUERY : + IRCTXT_OWN_DCC_ACTION, dcc->mynick, dcc->id, msg); + g_free(tag); +} + +static void sig_message_dcc_own_ctcp(CHAT_DCC_REC *dcc, const char *cmd, + const char *data) +{ + TEXT_DEST_REC dest; + char *tag; + + tag = g_strconcat("=", dcc->id, NULL); + + format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, + MSGLEVEL_DCC | MSGLEVEL_CTCPS | + MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, NULL); + + printformat_dest(&dest, IRCTXT_OWN_DCC_CTCP, dcc->id, cmd, data); + g_free(tag); +} + +static void sig_message_dcc(CHAT_DCC_REC *dcc, const char *msg) +{ + TEXT_DEST_REC dest; + QUERY_REC *query; + char *tag; + int level = MSGLEVEL_DCCMSGS; + + tag = g_strconcat("=", dcc->id, NULL); + query = query_find(NULL, tag); + + ignore_check_plus(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, + &level, FALSE); + + format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, + level, NULL); + + printformat_dest(&dest, query != NULL ? IRCTXT_DCC_MSG_QUERY : + IRCTXT_DCC_MSG, dcc->id, msg); + g_free(tag); +} + +static void sig_message_dcc_action(CHAT_DCC_REC *dcc, const char *msg) +{ + TEXT_DEST_REC dest; + QUERY_REC *query; + char *tag; + int level = MSGLEVEL_DCCMSGS | MSGLEVEL_ACTIONS; + + tag = g_strconcat("=", dcc->id, NULL); + query = query_find(NULL, tag); + + ignore_check_plus(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, + &level, FALSE); + + format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, + level, NULL); + + printformat_dest(&dest, query != NULL ? IRCTXT_ACTION_DCC_QUERY : + IRCTXT_ACTION_DCC, dcc->id, msg); + g_free(tag); +} + +static void sig_message_dcc_ctcp(CHAT_DCC_REC *dcc, const char *cmd, + const char *data) +{ + TEXT_DEST_REC dest; + char *tag; + int level = MSGLEVEL_DCCMSGS | MSGLEVEL_CTCPS; + + tag = g_strconcat("=", dcc->id, NULL); + + ignore_check_plus(SERVER(dcc->server), tag, dcc->addrstr, NULL, cmd, + &level, FALSE); + + format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, + level, NULL); + + printformat_dest(&dest, IRCTXT_DCC_CTCP, dcc->id, cmd, data); + g_free(tag); +} + +void fe_dcc_chat_messages_init(void) +{ + signal_add("message dcc own", (SIGNAL_FUNC) sig_message_dcc_own); + signal_add("message dcc own_action", (SIGNAL_FUNC) sig_message_dcc_own_action); + signal_add("message dcc own_ctcp", (SIGNAL_FUNC) sig_message_dcc_own_ctcp); + signal_add("message dcc", (SIGNAL_FUNC) sig_message_dcc); + signal_add("message dcc action", (SIGNAL_FUNC) sig_message_dcc_action); + signal_add("message dcc ctcp", (SIGNAL_FUNC) sig_message_dcc_ctcp); +} + +void fe_dcc_chat_messages_deinit(void) +{ + signal_remove("message dcc own", (SIGNAL_FUNC) sig_message_dcc_own); + signal_remove("message dcc own_action", (SIGNAL_FUNC) sig_message_dcc_own_action); + signal_remove("message dcc own_ctcp", (SIGNAL_FUNC) sig_message_dcc_own_ctcp); + signal_remove("message dcc", (SIGNAL_FUNC) sig_message_dcc); + signal_remove("message dcc action", (SIGNAL_FUNC) sig_message_dcc_action); + signal_remove("message dcc ctcp", (SIGNAL_FUNC) sig_message_dcc_ctcp); +} diff --git a/src/fe-common/irc/dcc/fe-dcc-chat.c b/src/fe-common/irc/dcc/fe-dcc-chat.c new file mode 100644 index 0000000..4099e2f --- /dev/null +++ b/src/fe-common/irc/dcc/fe-dcc-chat.c @@ -0,0 +1,385 @@ +/* + fe-dcc-chat.c : irssi + + Copyright (C) 1999-2002 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/signals.h> +#include <irssi/src/core/commands.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/settings.h> +#include <irssi/src/core/misc.h> + +#include <irssi/src/irc/core/irc.h> +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-queries.h> +#include <irssi/src/irc/dcc/dcc-chat.h> + +#include <irssi/src/fe-common/irc/dcc/module-formats.h> +#include <irssi/src/fe-common/core/printtext.h> +#include <irssi/src/fe-common/core/fe-messages.h> + +#include <irssi/src/fe-common/core/chat-completion.h> + +void fe_dcc_chat_messages_init(void); +void fe_dcc_chat_messages_deinit(void); + +static void dcc_request(CHAT_DCC_REC *dcc) +{ + if (!IS_DCC_CHAT(dcc)) return; + + printformat(dcc->server, NULL, MSGLEVEL_DCC, + server_ischannel(SERVER(dcc->server), dcc->target) ? IRCTXT_DCC_CHAT_CHANNEL : + IRCTXT_DCC_CHAT, dcc->id, dcc->addrstr, + dcc->port, dcc->target); +} + +static void dcc_connected(CHAT_DCC_REC *dcc) +{ + char *sender; + + if (!IS_DCC_CHAT(dcc)) return; + + sender = g_strconcat("=", dcc->id, NULL); + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_CHAT_CONNECTED, + dcc->id, dcc->addrstr, dcc->port); + + if (query_find(NULL, sender) == NULL) { + int level = settings_get_level("autocreate_query_level"); + int autocreate_dccquery = (level & MSGLEVEL_DCCMSGS) != 0; + + if (!autocreate_dccquery) + completion_last_message_add(sender); + else + irc_query_create(dcc->servertag, sender, TRUE); + } + g_free(sender); +} + +static void dcc_closed(CHAT_DCC_REC *dcc) +{ + char *sender; + + if (!IS_DCC_CHAT(dcc)) return; + + sender = g_strconcat("=", dcc->id, NULL); + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_CHAT_DISCONNECTED, dcc->id); + g_free(sender); +} + +static void dcc_chat_msg(CHAT_DCC_REC *dcc, const char *msg) +{ + QUERY_REC *query; + char *sender, *freemsg; + + g_return_if_fail(IS_DCC_CHAT(dcc)); + g_return_if_fail(msg != NULL); + + sender = g_strconcat("=", dcc->id, NULL); + query = query_find(NULL, sender); + + if (settings_get_bool("emphasis")) + msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg); + else + freemsg = NULL; + + if (query == NULL) + completion_last_message_add(sender); + signal_emit("message dcc", 2, dcc, msg); + + g_free_not_null(freemsg); + g_free(sender); +} + +static void dcc_chat_action(CHAT_DCC_REC *dcc, const char *msg) +{ + char *sender; + + g_return_if_fail(IS_DCC_CHAT(dcc)); + g_return_if_fail(msg != NULL); + + sender = g_strconcat("=", dcc->id, NULL); + if (query_find(NULL, sender) == NULL) + completion_last_message_add(sender); + + signal_emit("message dcc action", 2, dcc, msg); + g_free(sender); +} + +static void dcc_chat_ctcp(CHAT_DCC_REC *dcc, const char *cmd, const char *data) +{ + g_return_if_fail(IS_DCC_CHAT(dcc)); + + signal_emit("message dcc ctcp", 3, dcc, cmd, data); +} + +static void dcc_error_ctcp(const char *type, const char *data, + const char *nick, const char *addr, + const char *target) +{ + printformat(NULL, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_INVALID_CTCP, type, nick, addr, target); +} + +static void dcc_unknown_ctcp(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr, + const char *target, CHAT_DCC_REC *chat) +{ + char *type, *args; + void *free_arg; + + g_return_if_fail(data != NULL); + + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, + &type, &args)) + return; + + printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_CTCP, + type, nick, args); + cmd_params_free(free_arg); +} + +static void dcc_unknown_reply(IRC_SERVER_REC *server, const char *data, + const char *nick) +{ + char *type, *args; + void *free_arg; + + g_return_if_fail(data != NULL); + + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, + &type, &args)) + return; + + printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_REPLY, + type, nick, args); + cmd_params_free(free_arg); +} + +static void sig_dcc_destroyed(CHAT_DCC_REC *dcc) +{ + QUERY_REC *query; + char *nick; + + if (!IS_DCC_CHAT(dcc)) return; + + nick = g_strconcat("=", dcc->id, NULL); + query = query_find(NULL, nick); + if (query != NULL) { + /* DCC chat closed, close the query with it. */ + if (dcc->connection_lost) query->unwanted = TRUE; + query_destroy(query); + } else { + /* remove nick from msg completion + since it won't work anymore */ + completion_last_message_remove(nick); + } + + g_free(nick); +} + +static void sig_query_destroyed(QUERY_REC *query) +{ + CHAT_DCC_REC *dcc; + + if (*query->name != '=') + return; + + dcc = dcc_chat_find_id(query->name+1); + if (dcc != NULL && !dcc->destroyed) { + /* DCC query window closed, close the dcc chat too. */ + dcc_close(DCC(dcc)); + } +} + +static void dcc_error_close_not_found(const char *type, const char *nick, + const char *fname) +{ + g_return_if_fail(type != NULL); + g_return_if_fail(nick != NULL); + if (g_ascii_strcasecmp(type, "CHAT") != 0) return; + + printformat(NULL, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_CHAT_NOT_FOUND, nick); +} + +static void sig_dcc_list_print(CHAT_DCC_REC *dcc) +{ + if (!IS_DCC_CHAT(dcc)) return; + + printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_LIST_LINE_CHAT, + dcc->id, "CHAT"); +} + +static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + CHAT_DCC_REC *dcc; + GHashTable *optlist; + char *text, *target; + void *free_arg; + + g_return_if_fail(data != NULL); + + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_UNKNOWN_OPTIONS | + PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, "msg", + &optlist, &target, &text)) + return; + + /* handle only DCC messages */ + if (g_strcmp0(target, "*") == 0) + dcc = item_get_dcc(item); + else if (*target == '=') + dcc = dcc_chat_find_id(target+1); + else + dcc = NULL; + + if (dcc == NULL && *target == '=') { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + IRCTXT_DCC_CHAT_NOT_FOUND, target+1); + } else if (dcc != NULL) { + if (query_find(NULL, target) == NULL) + completion_last_message_add(target); + + signal_emit("message dcc own", 2, dcc, text); + } + + cmd_params_free(free_arg); +} + +static void cmd_me(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + CHAT_DCC_REC *dcc; + + dcc = item_get_dcc(item); + if (dcc != NULL) + signal_emit("message dcc own_action", 2, dcc, data); +} + +static void cmd_action(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + CHAT_DCC_REC *dcc; + char *target, *text; + void *free_arg; + + g_return_if_fail(data != NULL); + + if (*data != '=') { + /* handle only DCC actions */ + return; + } + + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, + &target, &text)) + return; + if (*target == '\0' || *text == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + dcc = dcc_chat_find_id(target+1); + if (dcc == NULL || dcc->sendbuf == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + IRCTXT_DCC_CHAT_NOT_FOUND, target+1); + } else { + if (query_find(NULL, target) == NULL) + completion_last_message_add(target); + + signal_emit("message dcc own_action", 2, dcc, text); + } + cmd_params_free(free_arg); +} + +static void cmd_ctcp(const char *data, SERVER_REC *server) +{ + CHAT_DCC_REC *dcc; + char *target, *ctcpcmd, *ctcpdata; + void *free_arg; + + g_return_if_fail(data != NULL); + if (server == NULL || !server->connected) + cmd_return_error(CMDERR_NOT_CONNECTED); + + if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, + &target, &ctcpcmd, &ctcpdata)) + return; + if (*target == '\0' || *ctcpcmd == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + if (*target != '=') { + /* handle only DCC CTCPs */ + cmd_params_free(free_arg); + return; + } + + dcc = dcc_chat_find_id(target+1); + if (dcc == NULL || dcc->sendbuf == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + IRCTXT_DCC_CHAT_NOT_FOUND, target+1); + } else { + ascii_strup(ctcpcmd); + signal_emit("message dcc own_ctcp", 3, dcc, ctcpcmd, ctcpdata); + } + + cmd_params_free(free_arg); +} + +void fe_dcc_chat_init(void) +{ + fe_dcc_chat_messages_init(); + + signal_add("dcc request", (SIGNAL_FUNC) dcc_request); + signal_add("dcc connected", (SIGNAL_FUNC) dcc_connected); + signal_add("dcc closed", (SIGNAL_FUNC) dcc_closed); + signal_add("dcc chat message", (SIGNAL_FUNC) dcc_chat_msg); + signal_add("dcc ctcp action", (SIGNAL_FUNC) dcc_chat_action); + signal_add("default dcc ctcp", (SIGNAL_FUNC) dcc_chat_ctcp); + signal_add("dcc error ctcp", (SIGNAL_FUNC) dcc_error_ctcp); + signal_add("default ctcp msg dcc", (SIGNAL_FUNC) dcc_unknown_ctcp); + signal_add("default ctcp reply dcc", (SIGNAL_FUNC) dcc_unknown_reply); + signal_add("dcc destroyed", (SIGNAL_FUNC) sig_dcc_destroyed); + signal_add("query destroyed", (SIGNAL_FUNC) sig_query_destroyed); + signal_add("dcc list print", (SIGNAL_FUNC) sig_dcc_list_print); + command_bind("msg", NULL, (SIGNAL_FUNC) cmd_msg); + command_bind("me", NULL, (SIGNAL_FUNC) cmd_me); + command_bind("action", NULL, (SIGNAL_FUNC) cmd_action); + command_bind("ctcp", NULL, (SIGNAL_FUNC) cmd_ctcp); + signal_add("dcc error close not found", (SIGNAL_FUNC) dcc_error_close_not_found); +} + +void fe_dcc_chat_deinit(void) +{ + fe_dcc_chat_messages_deinit(); + + signal_remove("dcc request", (SIGNAL_FUNC) dcc_request); + signal_remove("dcc connected", (SIGNAL_FUNC) dcc_connected); + signal_remove("dcc closed", (SIGNAL_FUNC) dcc_closed); + signal_remove("dcc chat message", (SIGNAL_FUNC) dcc_chat_msg); + signal_remove("dcc ctcp action", (SIGNAL_FUNC) dcc_chat_action); + signal_remove("default dcc ctcp", (SIGNAL_FUNC) dcc_chat_ctcp); + signal_remove("dcc error ctcp", (SIGNAL_FUNC) dcc_error_ctcp); + signal_remove("default ctcp msg dcc", (SIGNAL_FUNC) dcc_unknown_ctcp); + signal_remove("default ctcp reply dcc", (SIGNAL_FUNC) dcc_unknown_reply); + signal_remove("dcc destroyed", (SIGNAL_FUNC) sig_dcc_destroyed); + signal_remove("query destroyed", (SIGNAL_FUNC) sig_query_destroyed); + signal_remove("dcc list print", (SIGNAL_FUNC) sig_dcc_list_print); + command_unbind("msg", (SIGNAL_FUNC) cmd_msg); + command_unbind("me", (SIGNAL_FUNC) cmd_me); + command_unbind("action", (SIGNAL_FUNC) cmd_action); + command_unbind("ctcp", (SIGNAL_FUNC) cmd_ctcp); + signal_remove("dcc error close not found", (SIGNAL_FUNC) dcc_error_close_not_found); +} diff --git a/src/fe-common/irc/dcc/fe-dcc-get.c b/src/fe-common/irc/dcc/fe-dcc-get.c new file mode 100644 index 0000000..e75640b --- /dev/null +++ b/src/fe-common/irc/dcc/fe-dcc-get.c @@ -0,0 +1,150 @@ +/* + fe-dcc-get.c : irssi + + Copyright (C) 1999-2001 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/servers.h> + +#include <irssi/src/irc/core/irc.h> +#include <irssi/src/irc/dcc/dcc-file.h> +#include <irssi/src/irc/dcc/dcc-get.h> + +#include <irssi/src/fe-common/irc/dcc/module-formats.h> +#include <irssi/src/fe-common/core/printtext.h> + +#include <irssi/src/fe-common/irc/dcc/fe-dcc.h> + +static void dcc_request(GET_DCC_REC *dcc) +{ + char *sizestr; + + if (!IS_DCC_GET(dcc)) return; + + sizestr = dcc_get_size_str(dcc->size); + + printformat(dcc->server, NULL, MSGLEVEL_DCC, + server_ischannel(SERVER(dcc->server), dcc->target) ? IRCTXT_DCC_SEND_CHANNEL : + IRCTXT_DCC_SEND, dcc->nick, dcc->addrstr, + dcc->port, dcc->arg, sizestr, dcc->target); + + g_free(sizestr); +} + +static void dcc_connected(GET_DCC_REC *dcc) +{ + if (!IS_DCC_GET(dcc)) return; + + printformat(dcc->server, NULL, MSGLEVEL_DCC, IRCTXT_DCC_GET_CONNECTED, + dcc->arg, dcc->nick, dcc->addrstr, dcc->port); +} + +static void dcc_closed(GET_DCC_REC *dcc) +{ + char *sizestr, timestr[20]; + double kbs; + time_t secs; + + if (!IS_DCC_GET(dcc)) return; + + secs = dcc->starttime == 0 ? -1 : time(NULL)-dcc->starttime; + kbs = (double) (dcc->transfd-dcc->skipped) / + (secs == 0 ? 1 : secs) / 1024.0; + + sizestr = dcc_get_size_str(dcc->transfd); + g_snprintf(timestr, sizeof(timestr), "%02d:%02d:%02d", + (int)(secs/3600), (int)((secs/60)%60), (int)(secs%60)); + + if (secs == -1) { + /* aborted */ + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_GET_ABORTED, dcc->arg, dcc->nick); + } else { + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_GET_COMPLETE, dcc->arg, sizestr, + dcc->nick, timestr, kbs); + } + + g_free(sizestr); +} + +static void dcc_error_file_create(GET_DCC_REC *dcc, const char *fname, + const char *error) +{ + printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_CANT_CREATE, + fname, error); +} + + +static void dcc_error_get_not_found(const char *nick) +{ + g_return_if_fail(nick != NULL); + + printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_GET_NOT_FOUND, nick); +} + +static void dcc_error_close_not_found(const char *type, const char *nick, + const char *fname) +{ + g_return_if_fail(type != NULL); + g_return_if_fail(nick != NULL); + g_return_if_fail(fname != NULL); + if (g_ascii_strcasecmp(type, "GET") != 0) return; + + if (fname == NULL || *fname == '\0') fname = "(ANY)"; + printformat(NULL, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_GET_NOT_FOUND, nick, fname); +} + +static void dcc_error_write(GET_DCC_REC *dcc, const char *error) +{ + printformat(NULL, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_GET_WRITE_ERROR, dcc->file, error); +} + +static void sig_dcc_list_print(GET_DCC_REC *dcc) +{ + if (IS_DCC_GET(dcc)) + dcc_list_print_file((FILE_DCC_REC *) dcc); +} + +void fe_dcc_get_init(void) +{ + signal_add("dcc request", (SIGNAL_FUNC) dcc_request); + signal_add("dcc connected", (SIGNAL_FUNC) dcc_connected); + signal_add("dcc closed", (SIGNAL_FUNC) dcc_closed); + signal_add("dcc error file create", (SIGNAL_FUNC) dcc_error_file_create); + signal_add("dcc error get not found", (SIGNAL_FUNC) dcc_error_get_not_found); + signal_add("dcc error close not found", (SIGNAL_FUNC) dcc_error_close_not_found); + signal_add("dcc error write", (SIGNAL_FUNC) dcc_error_write); + signal_add("dcc list print", (SIGNAL_FUNC) sig_dcc_list_print); +} + +void fe_dcc_get_deinit(void) +{ + signal_remove("dcc request", (SIGNAL_FUNC) dcc_request); + signal_remove("dcc connected", (SIGNAL_FUNC) dcc_connected); + signal_remove("dcc closed", (SIGNAL_FUNC) dcc_closed); + signal_remove("dcc error file create", (SIGNAL_FUNC) dcc_error_file_create); + signal_remove("dcc error get not found", (SIGNAL_FUNC) dcc_error_get_not_found); + signal_remove("dcc error close not found", (SIGNAL_FUNC) dcc_error_close_not_found); + signal_remove("dcc error write", (SIGNAL_FUNC) dcc_error_write); + signal_remove("dcc list print", (SIGNAL_FUNC) sig_dcc_list_print); +} diff --git a/src/fe-common/irc/dcc/fe-dcc-send.c b/src/fe-common/irc/dcc/fe-dcc-send.c new file mode 100644 index 0000000..cf9b634 --- /dev/null +++ b/src/fe-common/irc/dcc/fe-dcc-send.c @@ -0,0 +1,186 @@ +/* + fe-dcc-send.c : irssi + + Copyright (C) 1999-2001 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/irc/dcc/dcc-file.h> +#include <irssi/src/irc/dcc/dcc-send.h> +#include <irssi/src/irc/dcc/dcc-queue.h> + +#include <irssi/src/fe-common/irc/dcc/module-formats.h> +#include <irssi/src/fe-common/core/printtext.h> +#include <irssi/src/fe-common/core/completion.h> + +#include <irssi/src/fe-common/irc/dcc/fe-dcc.h> + +static void dcc_connected(SEND_DCC_REC *dcc) +{ + if (!IS_DCC_SEND(dcc)) return; + + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_SEND_CONNECTED, + dcc->arg, dcc->nick, dcc->addrstr, dcc->port); +} + +static void dcc_closed(SEND_DCC_REC *dcc) +{ + char *sizestr, timestr[20]; + double kbs; + time_t secs; + + if (!IS_DCC_SEND(dcc)) return; + + secs = dcc->starttime == 0 ? -1 : time(NULL)-dcc->starttime; + kbs = (double) (dcc->transfd-dcc->skipped) / + (secs == 0 ? 1 : secs) / 1024.0; + + if (secs == -1) { + /* aborted */ + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_SEND_ABORTED, + dcc->arg, dcc->nick); + } else { + sizestr = dcc_get_size_str(dcc->transfd); + g_snprintf(timestr, sizeof(timestr), "%02d:%02d:%02d", + (int)(secs/3600), (int)((secs/60)%60), + (int)(secs%60)); + + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_SEND_COMPLETE, + dcc->arg, sizestr, dcc->nick, timestr, kbs); + + g_free(sizestr); + } +} + +static void dcc_error_file_open(const char *nick, const char *fname, + void *error) +{ + g_return_if_fail(nick != NULL); + g_return_if_fail(fname != NULL); + + printformat(NULL, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_SEND_FILE_OPEN_ERROR, fname, + g_strerror(GPOINTER_TO_INT(error))); +} + +static void dcc_error_send_exists(const char *nick, const char *fname) +{ + g_return_if_fail(nick != NULL); + g_return_if_fail(fname != NULL); + + printformat(NULL, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_SEND_EXISTS, fname, nick); +} + +static void dcc_error_send_no_route(const char *nick, const char *fname) +{ + printformat(NULL, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_SEND_NO_ROUTE, nick, fname); +} + +static void dcc_error_close_not_found(const char *type, const char *nick, + const char *fname) +{ + g_return_if_fail(type != NULL); + g_return_if_fail(nick != NULL); + g_return_if_fail(fname != NULL); + if (g_ascii_strcasecmp(type, "SEND") != 0) return; + + if (fname == NULL || *fname == '\0') fname = "(ANY)"; + printformat(NULL, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_SEND_NOT_FOUND, nick, fname); +} + +static void sig_dcc_send_complete(GList **list, WINDOW_REC *window, + const char *word, const char *line, + int *want_space) +{ + char *path; + + g_return_if_fail(list != NULL); + g_return_if_fail(word != NULL); + g_return_if_fail(line != NULL); + + if (*line == '\0' || strchr(line, ' ') != NULL) + return; + + /* completing filename parameter for /DCC SEND */ + path = convert_home(settings_get_str("dcc_upload_path")); + if (*path == '\0') { + /* use the default path */ + g_free_and_null(path); + } + + *list = filename_complete(word, path); + + if (*list != NULL) { + *want_space = FALSE; + signal_stop(); + } +} + +static void sig_dcc_list_print(SEND_DCC_REC *dcc) +{ + GSList *queue; + + if (!IS_DCC_SEND(dcc)) + return; + + dcc_list_print_file((FILE_DCC_REC *) dcc); + + queue = dcc_queue_get_queue(dcc->queue); + for (; queue != NULL; queue = queue->next) { + DCC_QUEUE_REC *rec = queue->data; + + printformat(NULL, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_LIST_LINE_QUEUED_SEND, rec->nick, + rec->servertag == NULL ? "" : rec->servertag, + rec->file); + } +} + +void fe_dcc_send_init(void) +{ + signal_add("dcc connected", (SIGNAL_FUNC) dcc_connected); + signal_add("dcc closed", (SIGNAL_FUNC) dcc_closed); + signal_add("dcc error file open", (SIGNAL_FUNC) dcc_error_file_open); + signal_add("dcc error send exists", (SIGNAL_FUNC) dcc_error_send_exists); + signal_add("dcc error send no route", (SIGNAL_FUNC) dcc_error_send_no_route); + signal_add("dcc error close not found", (SIGNAL_FUNC) dcc_error_close_not_found); + signal_add("complete command dcc send", (SIGNAL_FUNC) sig_dcc_send_complete); + signal_add("dcc list print", (SIGNAL_FUNC) sig_dcc_list_print); +} + +void fe_dcc_send_deinit(void) +{ + signal_remove("dcc connected", (SIGNAL_FUNC) dcc_connected); + signal_remove("dcc closed", (SIGNAL_FUNC) dcc_closed); + signal_remove("dcc error file open", (SIGNAL_FUNC) dcc_error_file_open); + signal_remove("dcc error send exists", (SIGNAL_FUNC) dcc_error_send_exists); + signal_remove("dcc error send no route", (SIGNAL_FUNC) dcc_error_send_no_route); + signal_remove("dcc error close not found", (SIGNAL_FUNC) dcc_error_close_not_found); + signal_remove("complete command dcc send", (SIGNAL_FUNC) sig_dcc_send_complete); + signal_remove("dcc list print", (SIGNAL_FUNC) sig_dcc_list_print); +} diff --git a/src/fe-common/irc/dcc/fe-dcc-server.c b/src/fe-common/irc/dcc/fe-dcc-server.c new file mode 100644 index 0000000..eaab963 --- /dev/null +++ b/src/fe-common/irc/dcc/fe-dcc-server.c @@ -0,0 +1,83 @@ +/* + fe-dcc-server.c : irssi + + Copyright (C) 2003 Mark Trumbull + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/signals.h> +#include <irssi/src/core/commands.h> +#include <irssi/src/core/network.h> +#include <irssi/src/core/levels.h> + +#include <irssi/src/irc/dcc/dcc-server.h> + +#include <irssi/src/fe-common/irc/dcc/module-formats.h> +#include <irssi/src/fe-common/core/printtext.h> +#include <irssi/src/fe-common/core/themes.h> + +static void dcc_server_started(SERVER_DCC_REC *dcc) +{ + if (!IS_DCC_SERVER(dcc)) { + return; + } + + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_SERVER_STARTED, dcc->port); +} + +static void dcc_closed(SERVER_DCC_REC *dcc) +{ + /* We don't want to print a msg if its just starting a chat/get */ + /* and getting rid of the leftover SERVER_DCC_REC */ + if (!IS_DCC_SERVER(dcc) || dcc->connection_established) { + return; + } + + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_SERVER_CLOSED, dcc->port); +} + +static void sig_dcc_list_print(SERVER_DCC_REC *dcc) +{ + /* We don't want to print a msg if its just starting a chat/get */ + /* and getting rid of the leftover SERVER_DCC_REC */ + if (!IS_DCC_SERVER(dcc) || dcc->connection_established) { + return; + } + + /* SERVER: Port(59) - Send(on) - Chat(on) - Fserve(on) */ + printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_LIST_LINE_SERVER, + "SERVER", dcc->port, dcc->accept_send ? "on" : "off", + dcc->accept_chat ? "on" : "off", + dcc->accept_fserve ? "on" : "off"); +} + +void fe_dcc_server_init(void) +{ + signal_add("dcc server started", (SIGNAL_FUNC) dcc_server_started); + signal_add("dcc closed", (SIGNAL_FUNC) dcc_closed); + signal_add("dcc list print", (SIGNAL_FUNC) sig_dcc_list_print); +} + +void fe_dcc_server_deinit(void) +{ + signal_remove("dcc server started", (SIGNAL_FUNC) dcc_server_started); + signal_remove("dcc closed", (SIGNAL_FUNC) dcc_closed); + signal_remove("dcc list print", (SIGNAL_FUNC) sig_dcc_list_print); +} + diff --git a/src/fe-common/irc/dcc/fe-dcc.c b/src/fe-common/irc/dcc/fe-dcc.c new file mode 100644 index 0000000..f5fb3b2 --- /dev/null +++ b/src/fe-common/irc/dcc/fe-dcc.c @@ -0,0 +1,195 @@ +/* + fe-dcc.c : irssi + + Copyright (C) 1999-2001 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/signals.h> +#include <irssi/src/core/commands.h> +#include <irssi/src/core/network.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/irc/dcc/dcc-chat.h> +#include <irssi/src/irc/dcc/dcc-file.h> +#include <irssi/src/irc/dcc/dcc-get.h> +#include <irssi/src/irc/dcc/dcc-send.h> + +#include <irssi/src/fe-common/irc/dcc/module-formats.h> +#include <irssi/src/fe-common/core/printtext.h> +#include <irssi/src/fe-common/core/themes.h> + +void fe_dcc_chat_init(void); +void fe_dcc_chat_deinit(void); + +void fe_dcc_get_init(void); +void fe_dcc_get_deinit(void); + +void fe_dcc_send_init(void); +void fe_dcc_send_deinit(void); + +void fe_dcc_server_init(void); +void fe_dcc_server_deinit(void); + +char *dcc_get_size_str(uoff_t size) +{ + if (size < 1024) + return g_strdup_printf("%"PRIuUOFF_T"B", size); + if (size < 1024*1024) + return g_strdup_printf("%"PRIuUOFF_T"kB", (size+1023) / 1024); + return g_strdup_printf("%"PRIuUOFF_T"MB", size / (1024*1024)); +} + +static void dcc_request(DCC_REC *dcc) +{ + char *service; + + g_return_if_fail(dcc != NULL); + + if (dcc->port < 1024) { + /* warn about connecting to lowports */ + service = net_getservbyport(dcc->port); + + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_LOWPORT, dcc->port, + service != NULL ? service : "unknown"); + } +} + +static void dcc_rejected(DCC_REC *dcc) +{ + g_return_if_fail(dcc != NULL); + + printformat(dcc->server, NULL, MSGLEVEL_DCC, IRCTXT_DCC_CLOSE, + dcc_type2str(dcc->type), dcc->nick, dcc->arg); +} + +static void dcc_request_send(DCC_REC *dcc) +{ + g_return_if_fail(dcc != NULL); + + printformat(dcc->server, NULL, MSGLEVEL_DCC, IRCTXT_DCC_REQUEST_SEND, + dcc_type2str(dcc->type), dcc->nick, dcc->arg); +} + +static void dcc_error_connect(DCC_REC *dcc) +{ + g_return_if_fail(dcc != NULL); + + printformat(dcc->server, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_CONNECT_ERROR, dcc->addrstr, dcc->port); +} + +static void dcc_error_unknown_type(const char *type) +{ + g_return_if_fail(type != NULL); + + printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_TYPE, type); +} + +void dcc_list_print_file(FILE_DCC_REC *dcc) +{ + time_t going, eta; + char *transfd_str, *size_str, etastr[20]; + uoff_t bps; + + going = time(NULL) - dcc->starttime; + if (going <= 0) going = 1; + + transfd_str = dcc_get_size_str(dcc->transfd); + size_str = dcc_get_size_str(dcc->size); + + bps = (dcc->transfd-dcc->skipped) / going; + if (bps == 0) { + strcpy(etastr, "(stalled)"); + } else { + eta = (dcc->size - dcc->transfd) / bps; + g_snprintf(etastr, sizeof(etastr), "%02d:%02d:%02d", + (int)(eta/3600), (int)((eta/60)%60), (int)(eta%60)); + } + + printformat(NULL, NULL, MSGLEVEL_DCC, + IRCTXT_DCC_LIST_LINE_FILE, + dcc->nick, dcc_type2str(dcc->type), + transfd_str, size_str, + dcc->size == 0 ? 0 : (int)((double)dcc->transfd/(double)dcc->size*100.0), + (double)bps/1024.0, dcc->arg, etastr); + + g_free(transfd_str); + g_free(size_str); +} + +static void cmd_dcc_list(const char *data) +{ + GSList *tmp; + + g_return_if_fail(data != NULL); + + printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_LIST_HEADER); + for (tmp = dcc_conns; tmp != NULL; tmp = tmp->next) + signal_emit("dcc list print", 1, tmp->data); + printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_LIST_FOOTER); +} + +static void cmd_dcc(const char *data) +{ + if (*data == '\0') { + cmd_dcc_list(data); + signal_stop(); + } +} + +void fe_irc_dcc_init(void) +{ + fe_dcc_chat_init(); + fe_dcc_get_init(); + fe_dcc_send_init(); + fe_dcc_server_init(); + + signal_add("dcc request", (SIGNAL_FUNC) dcc_request); + signal_add("dcc rejected", (SIGNAL_FUNC) dcc_rejected); + signal_add("dcc request send", (SIGNAL_FUNC) dcc_request_send); + signal_add("dcc error connect", (SIGNAL_FUNC) dcc_error_connect); + signal_add("dcc error unknown type", (SIGNAL_FUNC) dcc_error_unknown_type); + command_bind("dcc", NULL, (SIGNAL_FUNC) cmd_dcc); + command_bind("dcc list", NULL, (SIGNAL_FUNC) cmd_dcc_list); + + theme_register(fecommon_irc_dcc_formats); + settings_check(); + module_register("dcc", "fe-irc"); +} + +void fe_irc_dcc_deinit(void) +{ + fe_dcc_chat_deinit(); + fe_dcc_get_deinit(); + fe_dcc_send_deinit(); + fe_dcc_server_deinit(); + + theme_unregister(); + + signal_remove("dcc request", (SIGNAL_FUNC) dcc_request); + signal_remove("dcc rejected", (SIGNAL_FUNC) dcc_rejected); + signal_remove("dcc request send", (SIGNAL_FUNC) dcc_request_send); + signal_remove("dcc error connect", (SIGNAL_FUNC) dcc_error_connect); + signal_remove("dcc error unknown type", (SIGNAL_FUNC) dcc_error_unknown_type); + command_unbind("dcc", (SIGNAL_FUNC) cmd_dcc); + command_unbind("dcc list", (SIGNAL_FUNC) cmd_dcc_list); +} + +MODULE_ABICHECK(fe_irc_dcc) diff --git a/src/fe-common/irc/dcc/fe-dcc.h b/src/fe-common/irc/dcc/fe-dcc.h new file mode 100644 index 0000000..4d79296 --- /dev/null +++ b/src/fe-common/irc/dcc/fe-dcc.h @@ -0,0 +1,7 @@ +#ifndef IRSSI_FE_COMMON_IRC_DCC_FE_DCC_H +#define IRSSI_FE_COMMON_IRC_DCC_FE_DCC_H + +char *dcc_get_size_str(uoff_t size); +void dcc_list_print_file(FILE_DCC_REC *dcc); + +#endif diff --git a/src/fe-common/irc/dcc/meson.build b/src/fe-common/irc/dcc/meson.build new file mode 100644 index 0000000..296b1d6 --- /dev/null +++ b/src/fe-common/irc/dcc/meson.build @@ -0,0 +1,27 @@ +# this file is part of irssi + +libfe_irc_dcc_a = static_library('fe_irc_dcc', + files( + 'fe-dcc-chat-messages.c', + 'fe-dcc-chat.c', + 'fe-dcc-get.c', + 'fe-dcc-send.c', + 'fe-dcc-server.c', + 'fe-dcc.c', + 'module-formats.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + c_args : [ + def_helpdir, + def_sysconfdir, + ], + dependencies : dep) + +install_headers( + files( + 'fe-dcc.h', + 'module-formats.h', + 'module.h', + ), + subdir : incdir / 'src' / 'fe-common' / 'irc' / 'dcc') diff --git a/src/fe-common/irc/dcc/module-formats.c b/src/fe-common/irc/dcc/module-formats.c new file mode 100644 index 0000000..f973cd9 --- /dev/null +++ b/src/fe-common/irc/dcc/module-formats.c @@ -0,0 +1,79 @@ +/* + module-formats.c : irssi + + Copyright (C) 2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/core/formats.h> + +FORMAT_REC fecommon_irc_dcc_formats[] = { + { MODULE_NAME, "IRC", 0 }, + + /* ---- */ + { NULL, "DCC", 0 }, + + { "own_dcc", "{dccownmsg dcc {dccownnick $1}}$2", 3, { 0, 0, 0 } }, + { "own_dcc_action", "{dccownaction_target $0 $1}$2", 3, { 0, 0, 0 } }, + { "own_dcc_action_query", "{dccownaction $0}$2", 3, { 0, 0, 0 } }, + { "own_dcc_ctcp", "{ownctcp ctcp $0}$1 $2", 3, { 0, 0, 0 } }, + { "dcc_msg", "{dccmsg dcc $0}$1", 2, { 0, 0 } }, + { "action_dcc", "{dccaction $0}$1", 2, { 0, 0 } }, + { "action_dcc_query", "{dccaction $0}$1", 2, { 0, 0 } }, + { "own_dcc_query", "{ownmsgnick {dccownquerynick $0}}$2", 3, { 0, 0, 0 } }, + { "dcc_msg_query", "{privmsgnick $0}$1", 2, { 0, 0 } }, + { "dcc_ctcp", "{dcc >>> DCC CTCP {hilight $1} received from {hilight $0}: $2}", 3, { 0, 0, 0 } }, + { "dcc_chat", "{dcc DCC CHAT from {nick $0} [$1 port $2]}", 3, { 0, 0, 1 } }, + { "dcc_chat_channel", "{dcc DCC CHAT from {nick $0} [$1 port $2] requested in channel {channel $3}}", 4, { 0, 0, 1, 0 } }, + { "dcc_chat_not_found", "{dcc No DCC CHAT connection open to {nick $0}}", 1, { 0 } }, + { "dcc_chat_connected", "{dcc DCC CHAT connection with {nick $0} [$1 port $2] established}", 3, { 0, 0, 1 } }, + { "dcc_chat_disconnected", "{dcc DCC lost chat to {nick $0}}", 1, { 0 } }, + { "dcc_send", "{dcc DCC SEND from {nick $0} [$1 port $2]: $3 [$4]}", 5, { 0, 0, 1, 0, 0 } }, + { "dcc_send_channel", "{dcc DCC SEND from {nick $0} [$1 port $2]: $3 [$4 bytes] requested in channel {channel $5}}", 6, { 0, 0, 1, 0, 0, 0 } }, + { "dcc_send_exists", "{dcc DCC already sending file {dccfile $0} for {nick $1}}", 2, { 0, 0 } }, + { "dcc_send_no_route", "{dcc DCC route lost to nick {nick $0} when trying to send file {dccfile $1}}", 2, { 0, 0 } }, + { "dcc_send_not_found", "{dcc DCC not sending file {dccfile $1} to {nick $0}}", 2, { 0, 0 } }, + { "dcc_send_file_open_error", "{dcc DCC can't open file {dccfile $0}: $1}", 2, { 0, 0 } }, + { "dcc_send_connected", "{dcc DCC sending file {dccfile $0} for {nick $1} [$2 port $3]}", 4, { 0, 0, 0, 1 } }, + { "dcc_send_complete", "{dcc DCC sent file {dccfile $0} [{hilight $1}] for {nick $2} in {hilight $3} [{hilight $4kB/s}]}", 5, { 0, 0, 0, 0, 3 } }, + { "dcc_send_aborted", "{dcc DCC aborted sending file {dccfile $0} for {nick $1}}", 2, { 0, 0 } }, + { "dcc_get_not_found", "{dcc DCC no file offered by {nick $0}}", 1, { 0 } }, + { "dcc_get_connected", "{dcc DCC receiving file {dccfile $0} from {nick $1} [$2 port $3]}", 4, { 0, 0, 0, 1 } }, + { "dcc_get_complete", "{dcc DCC received file {dccfile $0} [$1] from {nick $2} in {hilight $3} [$4kB/s]}", 5, { 0, 0, 0, 0, 3 } }, + { "dcc_get_aborted", "{dcc DCC aborted receiving file {dccfile $0} from {nick $1}}", 2, { 0, 0 } }, + { "dcc_get_write_error", "{dcc DCC error writing to file {dccfile $0}: {comment $1}", 2, { 0, 0 } }, + { "dcc_unknown_ctcp", "{dcc DCC unknown ctcp {hilight $0} from {nick $1} [$2]}", 3, { 0, 0, 0 } }, + { "dcc_unknown_reply", "{dcc DCC unknown reply {hilight $0} from {nick $1} [$2]}", 3, { 0, 0, 0 } }, + { "dcc_unknown_type", "{dcc DCC unknown type {hilight $0}}", 1, { 0 } }, + { "dcc_invalid_ctcp", "{dcc DCC received CTCP {hilight $0} with invalid parameters from {nick $1}}", 4, { 0, 0, 0, 0 } }, + { "dcc_connect_error", "{dcc DCC can't connect to {hilight $0} port {hilight $1}}", 2, { 0, 1 } }, + { "dcc_cant_create", "{dcc DCC can't create file {dccfile $0}: $1}", 2, { 0, 0 } }, + { "dcc_rejected", "{dcc DCC $0 was rejected by {nick $1} [{hilight $2}]}", 3, { 0, 0, 0 } }, + { "dcc_request_send", "{dcc DCC $0 request sent to {nick $1}: $2", 3, { 0, 0, 0 } }, + { "dcc_close", "{dcc DCC $0 close for {nick $1} [{hilight $2}]}", 3, { 0, 0, 0 } }, + { "dcc_lowport", "{dcc Warning: Port sent with DCC request is a lowport ({hilight $0, $1}) - this isn't normal. It is possible the address/port is faked (or maybe someone is just trying to bypass firewall)}", 2, { 1, 0 } }, + { "dcc_list_header", "{dcc DCC connections}", 0 }, + { "dcc_list_line_chat", "{dcc $0 $1}", 2, { 0, 0 } }, + { "dcc_list_line_file", "{dcc $0 $1: %|$2 of $3 ($4%%) - $5kB/s - ETA $7 - $6}", 8, { 0, 0, 0, 0, 1, 3, 0, 0 } }, + { "dcc_list_line_queued_send", "{dcc - $0 $2 (queued)}", 3, { 0, 0, 0 } }, + { "dcc_list_footer", "", 0 }, + { "dcc_list_line_server", "{dcc $0: Port($1) - Send($2) - Chat($3) - Fserve($4)}", 5, { 0, 1, 0, 0, 0 } }, + { "dcc_server_started", "{dcc DCC SERVER started on port {hilight $0}}", 1, { 1 } }, + { "dcc_server_closed", "{dcc DCC SERVER on port {hilight $0} closed}", 1, { 1 } }, + + { NULL, NULL, 0 } +}; diff --git a/src/fe-common/irc/dcc/module-formats.h b/src/fe-common/irc/dcc/module-formats.h new file mode 100644 index 0000000..204c7dd --- /dev/null +++ b/src/fe-common/irc/dcc/module-formats.h @@ -0,0 +1,57 @@ +#include <irssi/src/fe-common/core/formats.h> + +enum { + IRCTXT_MODULE_NAME, + + IRCTXT_FILL_1, + + IRCTXT_OWN_DCC, + IRCTXT_OWN_DCC_ACTION, + IRCTXT_OWN_DCC_ACTION_QUERY, + IRCTXT_OWN_DCC_CTCP, + IRCTXT_DCC_MSG, + IRCTXT_ACTION_DCC, + IRCTXT_ACTION_DCC_QUERY, + IRCTXT_OWN_DCC_QUERY, + IRCTXT_DCC_MSG_QUERY, + IRCTXT_DCC_CTCP, + IRCTXT_DCC_CHAT, + IRCTXT_DCC_CHAT_CHANNEL, + IRCTXT_DCC_CHAT_NOT_FOUND, + IRCTXT_DCC_CHAT_CONNECTED, + IRCTXT_DCC_CHAT_DISCONNECTED, + IRCTXT_DCC_SEND, + IRCTXT_DCC_SEND_CHANNEL, + IRCTXT_DCC_SEND_EXISTS, + IRCTXT_DCC_SEND_NO_ROUTE, + IRCTXT_DCC_SEND_NOT_FOUND, + IRCTXT_DCC_SEND_FILE_OPEN_ERROR, + IRCTXT_DCC_SEND_CONNECTED, + IRCTXT_DCC_SEND_COMPLETE, + IRCTXT_DCC_SEND_ABORTED, + IRCTXT_DCC_GET_NOT_FOUND, + IRCTXT_DCC_GET_CONNECTED, + IRCTXT_DCC_GET_COMPLETE, + IRCTXT_DCC_GET_ABORTED, + IRCTXT_DCC_GET_WRITE_ERROR, + IRCTXT_DCC_UNKNOWN_CTCP, + IRCTXT_DCC_UNKNOWN_REPLY, + IRCTXT_DCC_UNKNOWN_TYPE, + IRCTXT_DCC_INVALID_CTCP, + IRCTXT_DCC_CONNECT_ERROR, + IRCTXT_DCC_CANT_CREATE, + IRCTXT_DCC_REJECTED, + IRCTXT_DCC_REQUEST_SEND, + IRCTXT_DCC_CLOSE, + IRCTXT_DCC_LOWPORT, + IRCTXT_DCC_LIST_HEADER, + IRCTXT_DCC_LIST_LINE_CHAT, + IRCTXT_DCC_LIST_LINE_FILE, + IRCTXT_DCC_LIST_LINE_QUEUED_SEND, + IRCTXT_DCC_LIST_FOOTER, + IRCTXT_DCC_LIST_LINE_SERVER, + IRCTXT_DCC_SERVER_STARTED, + IRCTXT_DCC_SERVER_CLOSED +}; + +extern FORMAT_REC fecommon_irc_dcc_formats[]; diff --git a/src/fe-common/irc/dcc/module.h b/src/fe-common/irc/dcc/module.h new file mode 100644 index 0000000..5493446 --- /dev/null +++ b/src/fe-common/irc/dcc/module.h @@ -0,0 +1,4 @@ +#include <irssi/src/common.h> +#include <irssi/src/irc/core/irc.h> + +#define MODULE_NAME "fe-common/irc/dcc" diff --git a/src/fe-common/irc/fe-cap.c b/src/fe-common/irc/fe-cap.c new file mode 100644 index 0000000..a75f2bb --- /dev/null +++ b/src/fe-common/irc/fe-cap.c @@ -0,0 +1,84 @@ +/* + fe-cap.c : irssi + + Copyright (C) 2018 dequis + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/misc.h> + +#include <irssi/src/irc/core/irc-servers.h> + +#include <irssi/src/fe-common/core/printtext.h> + +static const struct { + const char *command; + const int template; +} fe_cap_messages[] = { + {"LS", IRCTXT_CAP_LS}, + {"ACK", IRCTXT_CAP_ACK}, + {"NAK", IRCTXT_CAP_NAK}, + {"LIST", IRCTXT_CAP_LIST}, + {"NEW", IRCTXT_CAP_NEW}, + {"DEL", IRCTXT_CAP_DEL}, +}; + +static void event_cap(IRC_SERVER_REC *server, char *args, char *nick, char *address) +{ + int i; + char *params, *evt, *list, *star; + + params = event_get_params(args, 4, NULL, &evt, &star, &list); + + if (params == NULL) { + return; + } + + /* With multiline CAP LS, if the '*' parameter isn't present, + * adjust the parameter pointer to compensate for this */ + if (strcmp(star, "*") != 0 && list[0] == '\0') { + list = star; + } + + for (i = 0; i < G_N_ELEMENTS(fe_cap_messages); i++) { + if (!g_ascii_strcasecmp(evt, fe_cap_messages[i].command)) { + printformat(server, NULL, MSGLEVEL_CRAP, fe_cap_messages[i].template, list); + } + } + + g_free(params); +} + +static void sig_server_cap_req(IRC_SERVER_REC *server, char *caps) +{ + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_CAP_REQ, caps); +} + +void fe_cap_init(void) +{ + signal_add("event cap", (SIGNAL_FUNC) event_cap); + signal_add("server cap req", (SIGNAL_FUNC) sig_server_cap_req); +} + +void fe_cap_deinit(void) +{ + signal_remove("event cap", (SIGNAL_FUNC) event_cap); + signal_remove("server cap req", (SIGNAL_FUNC) sig_server_cap_req); +} diff --git a/src/fe-common/irc/fe-common-irc.c b/src/fe-common/irc/fe-common-irc.c new file mode 100644 index 0000000..a36d3ca --- /dev/null +++ b/src/fe-common/irc/fe-common-irc.c @@ -0,0 +1,134 @@ +/* + fe-common-irc.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/modules.h> +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/lib-config/iconfig.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/fe-common/core/themes.h> +#include <irssi/src/fe-common/irc/fe-irc-server.h> +#include <irssi/src/fe-common/irc/fe-irc-channels.h> + +void fe_irc_modules_init(void); +void fe_irc_modules_deinit(void); + +void fe_irc_queries_init(void); +void fe_irc_queries_deinit(void); + +void fe_irc_layout_init(void); +void fe_irc_layout_deinit(void); + +void fe_irc_messages_init(void); +void fe_irc_messages_deinit(void); + +void fe_irc_commands_init(void); +void fe_irc_commands_deinit(void); + +void fe_ircnet_init(void); +void fe_ircnet_deinit(void); + +void fe_ctcp_init(void); +void fe_ctcp_deinit(void); + +void fe_events_init(void); +void fe_events_deinit(void); + +void fe_events_numeric_init(void); +void fe_events_numeric_deinit(void); + +void fe_modes_init(void); +void fe_modes_deinit(void); + +void fe_netsplit_init(void); +void fe_netsplit_deinit(void); + +void fe_netjoin_init(void); +void fe_netjoin_deinit(void); + +void fe_whois_init(void); +void fe_whois_deinit(void); + +void fe_sasl_init(void); +void fe_sasl_deinit(void); + +void fe_cap_init(void); +void fe_cap_deinit(void); + +void irc_completion_init(void); +void irc_completion_deinit(void); + +void fe_common_irc_init(void) +{ + settings_add_bool("lookandfeel", "show_away_once", TRUE); + + theme_register(fecommon_irc_formats); + + fe_irc_channels_init(); + fe_irc_queries_init(); + fe_irc_messages_init(); + fe_irc_commands_init(); + fe_ircnet_init(); + fe_irc_server_init(); + fe_ctcp_init(); + fe_events_init(); + fe_events_numeric_init(); + fe_modes_init(); + fe_netsplit_init(); + fe_netjoin_init(); + fe_whois_init(); + fe_sasl_init(); + fe_cap_init(); + irc_completion_init(); + + settings_check(); + module_register("irc", "fe-common"); + + fe_irc_modules_init(); +} + +void fe_common_irc_deinit(void) +{ + fe_irc_modules_deinit(); + + fe_irc_channels_deinit(); + fe_irc_queries_deinit(); + fe_irc_messages_deinit(); + fe_irc_commands_deinit(); + fe_ircnet_deinit(); + fe_irc_server_deinit(); + fe_ctcp_deinit(); + fe_events_deinit(); + fe_events_numeric_deinit(); + fe_modes_deinit(); + fe_netsplit_deinit(); + fe_netjoin_deinit(); + fe_whois_deinit(); + fe_sasl_deinit(); + fe_cap_deinit(); + irc_completion_deinit(); + + theme_unregister(); +} + +MODULE_ABICHECK(fe_common_irc) diff --git a/src/fe-common/irc/fe-ctcp.c b/src/fe-common/irc/fe-ctcp.c new file mode 100644 index 0000000..1489396 --- /dev/null +++ b/src/fe-common/irc/fe-ctcp.c @@ -0,0 +1,170 @@ +/* + fe-ctcp.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/core/levels.h> +#include <irssi/src/core/servers.h> +#include <irssi/src/core/channels.h> +#include <irssi/src/core/queries.h> +#include <irssi/src/core/ignore.h> + +#include <irssi/src/fe-common/core/fe-windows.h> +#include <irssi/src/fe-common/core/window-items.h> +#include <irssi/src/fe-common/core/printtext.h> + +static void ctcp_default_msg(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr, + const char *target) +{ + const char *p; + char *cmd; + + p = strchr(data, ' '); + if (p == NULL) { + cmd = g_strdup(data); + data = ""; + } else { + cmd = g_strndup(data, (int) (p-data)); + data = p+1; + } + + printformat(server, server_ischannel(SERVER(server), target) ? target : nick, MSGLEVEL_CTCPS, + IRCTXT_CTCP_REQUESTED_UNKNOWN, + nick, addr, cmd, data, target); + g_free(cmd); +} + +static void ctcp_ping_msg(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr, + const char *target) +{ + signal_emit("message irc ctcp", 6, server, "PING", + data, nick, addr, target); +} + +static void ctcp_version_msg(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr, + const char *target) +{ + signal_emit("message irc ctcp", 6, server, "VERSION", + data, nick, addr, target); +} + +static void ctcp_time_msg(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr, + const char *target) +{ + signal_emit("message irc ctcp", 6, server, "TIME", + data, nick, addr, target); +} + +static void ctcp_userinfo_msg(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr, + const char *target) +{ + signal_emit("message irc ctcp", 6, server, "USERINFO", + data, nick, addr, target); +} + +static void ctcp_clientinfo_msg(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr, + const char *target) +{ + signal_emit("message irc ctcp", 6, server, "CLIENTINFO", + data, nick, addr, target); +} + +static void ctcp_default_reply(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr, + const char *target) +{ + const char *ctcpdata; + char *ctcp, *ptr; + + g_return_if_fail(data != NULL); + + ctcp = g_strdup(data); + ptr = strchr(ctcp, ' '); + if (ptr == NULL) + ctcpdata = ""; + else { + *ptr = '\0'; + ctcpdata = ptr+1; + } + + printformat(server, server_ischannel(SERVER(server), target) ? target : nick, MSGLEVEL_CTCPS, + server_ischannel(SERVER(server), target) ? IRCTXT_CTCP_REPLY_CHANNEL : + IRCTXT_CTCP_REPLY, ctcp, nick, ctcpdata, target); + g_free(ctcp); +} + +static void ctcp_ping_reply(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr, + const char *target) +{ + gint64 tv, tv2; + long usecs; + + g_return_if_fail(data != NULL); + + if (sscanf(data, + "%" G_GINT64_FORMAT " " + "%" G_GINT64_FORMAT, + &tv, &tv2) < 1) { + char *tmp = g_strconcat("PING ", data, NULL); + ctcp_default_reply(server, tmp, nick, addr, target); + g_free(tmp); + return; + } + + tv2 += tv * G_TIME_SPAN_SECOND; + tv = g_get_real_time(); + usecs = tv - tv2; + printformat(server, server_ischannel(SERVER(server), target) ? target : nick, MSGLEVEL_CTCPS, + IRCTXT_CTCP_PING_REPLY, nick, usecs / G_TIME_SPAN_SECOND, usecs % G_TIME_SPAN_SECOND); +} + +void fe_ctcp_init(void) +{ + signal_add("default ctcp msg", (SIGNAL_FUNC) ctcp_default_msg); + signal_add("ctcp msg ping", (SIGNAL_FUNC) ctcp_ping_msg); + signal_add("ctcp msg version", (SIGNAL_FUNC) ctcp_version_msg); + signal_add("ctcp msg time", (SIGNAL_FUNC) ctcp_time_msg); + signal_add("ctcp msg userinfo", (SIGNAL_FUNC) ctcp_userinfo_msg); + signal_add("ctcp msg clientinfo", (SIGNAL_FUNC) ctcp_clientinfo_msg); + signal_add("default ctcp reply", (SIGNAL_FUNC) ctcp_default_reply); + signal_add("ctcp reply ping", (SIGNAL_FUNC) ctcp_ping_reply); +} + +void fe_ctcp_deinit(void) +{ + signal_remove("default ctcp msg", (SIGNAL_FUNC) ctcp_default_msg); + signal_remove("ctcp msg ping", (SIGNAL_FUNC) ctcp_ping_msg); + signal_remove("ctcp msg version", (SIGNAL_FUNC) ctcp_version_msg); + signal_remove("ctcp msg time", (SIGNAL_FUNC) ctcp_time_msg); + signal_remove("ctcp msg userinfo", (SIGNAL_FUNC) ctcp_userinfo_msg); + signal_remove("ctcp msg clientinfo", (SIGNAL_FUNC) ctcp_clientinfo_msg); + signal_remove("default ctcp reply", (SIGNAL_FUNC) ctcp_default_reply); + signal_remove("ctcp reply ping", (SIGNAL_FUNC) ctcp_ping_reply); +} diff --git a/src/fe-common/irc/fe-events-numeric.c b/src/fe-common/irc/fe-events-numeric.c new file mode 100644 index 0000000..34ba3fe --- /dev/null +++ b/src/fe-common/irc/fe-events-numeric.c @@ -0,0 +1,903 @@ +/* + fe-events-numeric.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/settings.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/recode.h> + +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-channels.h> +#include <irssi/src/core/nicklist.h> +#include <irssi/src/irc/core/mode-lists.h> + +#include <irssi/src/fe-common/core/module-formats.h> +#include <irssi/src/fe-common/core/printtext.h> +#include <irssi/src/fe-common/core/fe-channels.h> +#include <irssi/src/fe-common/irc/fe-irc-server.h> + +static void print_event_received(IRC_SERVER_REC *server, const char *data, + const char *nick, int target_param); + +static char *last_away_nick = NULL; +static char *last_away_msg = NULL; + +static void event_user_mode(IRC_SERVER_REC *server, const char *data) +{ + char *params, *mode; + + g_return_if_fail(data != NULL); + g_return_if_fail(server != NULL); + + params = event_get_params(data, 2, NULL, &mode); + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_USER_MODE, + g_strchomp(mode)); + g_free(params); +} + +static void event_ison(IRC_SERVER_REC *server, const char *data) +{ + char *params, *online; + + g_return_if_fail(data != NULL); + g_return_if_fail(server != NULL); + + params = event_get_params(data, 2, NULL, &online); + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_ONLINE, online); + g_free(params); +} + +static void event_names_list(IRC_SERVER_REC *server, const char *data) +{ + IRC_CHANNEL_REC *chanrec; + char *params, *channel, *names; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 4, NULL, NULL, &channel, &names); + + chanrec = irc_channel_find(server, channel); + if (chanrec == NULL || chanrec->names_got) { + printformat_module("fe-common/core", server, channel, + MSGLEVEL_CRAP, TXT_NAMES, + channel, 0, 0, 0, 0, 0); + printtext(server, channel, MSGLEVEL_CRAP, "%s", names); + + } + g_free(params); +} + +static void event_end_of_names(IRC_SERVER_REC *server, const char *data, + const char *nick) +{ + IRC_CHANNEL_REC *chanrec; + char *params, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &channel); + + chanrec = irc_channel_find(server, channel); + if (chanrec == NULL || chanrec->names_got) + print_event_received(server, data, nick, FALSE); + g_free(params); +} + +static void event_who(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *channel, *user, *host, *stat, *realname, *hops; + char *serv, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 8, NULL, &channel, &user, + &host, &serv, &nick, &stat, &realname); + + /* split hops/realname */ + hops = realname; + while (*realname != '\0' && *realname != ' ') realname++; + if (*realname == ' ') + *realname++ = '\0'; + + recoded = recode_in(SERVER(server), realname, nick); + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_WHO, + channel, nick, stat, hops, user, host, recoded, serv); + + g_free(params); + g_free(recoded); +} + +static void event_end_of_who(IRC_SERVER_REC *server, const char *data) +{ + char *params, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &channel); + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_END_OF_WHO, channel); + g_free(params); +} + +static void event_ban_list(IRC_SERVER_REC *server, const char *data) +{ + IRC_CHANNEL_REC *chanrec; + BAN_REC *banrec; + const char *channel; + char *params, *ban, *setby, *tims; + long secs; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 5, NULL, &channel, + &ban, &setby, &tims); + secs = *tims == '\0' ? 0 : + (long) (time(NULL) - atol(tims)); + + chanrec = irc_channel_find(server, channel); + banrec = chanrec == NULL ? NULL : banlist_find(chanrec->banlist, ban); + + channel = get_visible_target(server, channel); + printformat(server, channel, MSGLEVEL_CRAP, + *setby == '\0' ? IRCTXT_BANLIST : IRCTXT_BANLIST_LONG, + banrec == NULL ? 0 : g_slist_index(chanrec->banlist, banrec)+1, + channel, ban, setby, secs); + + g_free(params); +} + +static void event_eban_list(IRC_SERVER_REC *server, const char *data) +{ + const char *channel; + char *params, *ban, *setby, *tims; + long secs; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 5, NULL, &channel, + &ban, &setby, &tims); + secs = *tims == '\0' ? 0 : + (long) (time(NULL) - atol(tims)); + + channel = get_visible_target(server, channel); + printformat(server, channel, MSGLEVEL_CRAP, + *setby == '\0' ? IRCTXT_EBANLIST : IRCTXT_EBANLIST_LONG, + channel, ban, setby, secs); + + g_free(params); +} + +static void event_silence_list(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *mask; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &mask); + printformat(server, NULL, MSGLEVEL_CRAP, + IRCTXT_SILENCE_LINE, nick, mask); + g_free(params); +} + +static void event_accept_list(IRC_SERVER_REC *server, const char *data) +{ + char *params, *accepted; + + g_return_if_fail(data != NULL); + g_return_if_fail(server != NULL); + + params = event_get_params(data, 2 | PARAM_FLAG_GETREST, + NULL, &accepted); + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_ACCEPT_LIST, accepted); + g_free(params); +} + +static void event_invite_list(IRC_SERVER_REC *server, const char *data) +{ + const char *channel; + char *params, *invite, *setby, *tims; + long secs; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 5, NULL, &channel, &invite, + &setby, &tims); + secs = *tims == '\0' ? 0 : + (long) (time(NULL) - atol(tims)); + + channel = get_visible_target(server, channel); + printformat(server, channel, MSGLEVEL_CRAP, + *setby == '\0' ? IRCTXT_INVITELIST : IRCTXT_INVITELIST_LONG, + channel, invite, setby, secs); + g_free(params); +} + +static void event_nick_in_use(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &nick); + if (server->connected) { + printformat(server, NULL, MSGLEVEL_CRAP, + IRCTXT_NICK_IN_USE, nick); + } + + g_free(params); +} + +static void event_topic_get(IRC_SERVER_REC *server, const char *data) +{ + const char *channel; + char *params, *topic, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &channel, &topic); + recoded = recode_in(SERVER(server), topic, channel); + channel = get_visible_target(server, channel); + printformat(server, channel, MSGLEVEL_CRAP, + IRCTXT_TOPIC, channel, recoded); + g_free(params); + g_free(recoded); +} + +static void event_topic_info(IRC_SERVER_REC *server, const char *data) +{ + const char *channel; + char *params, *timestr, *bynick, *byhost, *topictime; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 4, NULL, &channel, + &bynick, &topictime); + + timestr = my_asctime((time_t) atol(topictime)); + + byhost = strchr(bynick, '!'); + if (byhost != NULL) + *byhost++ = '\0'; + + channel = get_visible_target(server, channel); + printformat(server, channel, MSGLEVEL_CRAP, IRCTXT_TOPIC_INFO, + bynick, timestr, byhost == NULL ? "" : byhost); + g_free(timestr); + g_free(params); +} + +static void event_channel_mode(IRC_SERVER_REC *server, const char *data) +{ + const char *channel; + char *params, *mode; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3 | PARAM_FLAG_GETREST, + NULL, &channel, &mode); + channel = get_visible_target(server, channel); + printformat(server, channel, MSGLEVEL_CRAP, + IRCTXT_CHANNEL_MODE, channel, g_strchomp(mode)); + g_free(params); +} + +static void event_channel_created(IRC_SERVER_REC *server, const char *data) +{ + const char *channel; + char *params, *createtime, *timestr; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &channel, &createtime); + + timestr = my_asctime((time_t) atol(createtime)); + channel = get_visible_target(server, channel); + printformat(server, channel, MSGLEVEL_CRAP, + IRCTXT_CHANNEL_CREATED, channel, timestr); + g_free(timestr); + g_free(params); +} + +static void event_nowaway(IRC_SERVER_REC *server, const char *data) +{ + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_AWAY); +} + +static void event_unaway(IRC_SERVER_REC *server, const char *data) +{ + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_UNAWAY); +} + +static void event_away(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *awaymsg, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &awaymsg); + recoded = recode_in(SERVER(server), awaymsg, nick); + if (!settings_get_bool("show_away_once") || + last_away_nick == NULL || + g_ascii_strcasecmp(last_away_nick, nick) != 0 || + last_away_msg == NULL || + g_ascii_strcasecmp(last_away_msg, awaymsg) != 0) { + /* don't show the same away message + from the same nick all the time */ + g_free_not_null(last_away_nick); + g_free_not_null(last_away_msg); + last_away_nick = g_strdup(nick); + last_away_msg = g_strdup(awaymsg); + + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_NICK_AWAY, nick, recoded); + } + g_free(params); + g_free(recoded); +} + +static void event_userhost(IRC_SERVER_REC *server, const char *data) +{ + char *params, *hosts; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &hosts); + printtext(server, NULL, MSGLEVEL_CRAP, "%s", hosts); + g_free(params); +} + +static void event_sent_invite(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &channel); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_INVITING, nick, channel); + g_free(params); +} + +static void event_chanserv_url(IRC_SERVER_REC *server, const char *data) +{ + const char *channel; + char *params, *url; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &channel, &url); + channel = get_visible_target(server, channel); + printformat(server, channel, MSGLEVEL_CRAP, + IRCTXT_CHANNEL_URL, channel, url); + g_free(params); +} + +static void event_target_unavailable(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + IRC_CHANNEL_REC *chanrec; + char *params, *target; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &target); + if (!server_ischannel(SERVER(server), target)) { + /* nick unavailable */ + printformat(server, NULL, MSGLEVEL_CRAP, + IRCTXT_NICK_UNAVAILABLE, target); + } else { + chanrec = irc_channel_find(server, target); + if (chanrec != NULL && chanrec->joined) { + /* dalnet - can't change nick while being banned */ + print_event_received(server, data, nick, FALSE); + } else { + /* channel is unavailable. */ + printformat(server, NULL, MSGLEVEL_CRAP, + IRCTXT_JOINERROR_UNAVAIL, target); + } + } + + g_free(params); +} + +static void event_no_such_nick(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *unick; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &unick); + if (!g_strcmp0(unick, "*")) + /* more information will be in the description, + * e.g. * :Target left IRC. Failed to deliver: [hi] */ + print_event_received(server, data, nick, FALSE); + else + printformat(server, unick, MSGLEVEL_CRAP, IRCTXT_NO_SUCH_NICK, unick); + g_free(params); +} + +static void event_no_such_channel(IRC_SERVER_REC *server, const char *data) +{ + char *params, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &channel); + printformat(server, channel, MSGLEVEL_CRAP, + IRCTXT_NO_SUCH_CHANNEL, channel); + g_free(params); +} + +static void cannot_join(IRC_SERVER_REC *server, const char *data, int format) +{ + char *params, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &channel); + printformat(server, NULL, MSGLEVEL_CRAP, format, channel); + g_free(params); +} + +static void event_too_many_channels(IRC_SERVER_REC *server, const char *data) +{ + cannot_join(server, data, IRCTXT_JOINERROR_TOOMANY); +} + +static void event_duplicate_channel(IRC_SERVER_REC *server, const char *data, + const char *nick) +{ + char *params, *channel, *p; + + g_return_if_fail(data != NULL); + + /* this new addition to ircd breaks completely with older + "standards", "nick Duplicate ::!!channel ...." */ + params = event_get_params(data, 3, NULL, NULL, &channel); + p = strchr(channel, ' '); + if (p != NULL) *p = '\0'; + + if (channel[0] == '!' && channel[1] == '!') { + printformat(server, NULL, MSGLEVEL_CRAP, + IRCTXT_JOINERROR_DUPLICATE, channel+1); + } else + print_event_received(server, data, nick, FALSE); + + g_free(params); +} + +static void event_channel_is_full(IRC_SERVER_REC *server, const char *data) +{ + cannot_join(server, data, IRCTXT_JOINERROR_FULL); +} + +static void event_invite_only(IRC_SERVER_REC *server, const char *data) +{ + cannot_join(server, data, IRCTXT_JOINERROR_INVITE); +} + +static void event_banned(IRC_SERVER_REC *server, const char *data) +{ + cannot_join(server, data, IRCTXT_JOINERROR_BANNED); +} + +static void event_bad_channel_key(IRC_SERVER_REC *server, const char *data) +{ + cannot_join(server, data, IRCTXT_JOINERROR_BAD_KEY); +} + +static void event_bad_channel_mask(IRC_SERVER_REC *server, const char *data) +{ + cannot_join(server, data, IRCTXT_JOINERROR_BAD_MASK); +} + +static void event_477(IRC_SERVER_REC *server, const char *data, const char *nick) +{ + /* Numeric 477 can mean many things: + * modeless channel, cannot join/send to channel (+r/+R/+M). + * If we tried to join this channel, display the error in the + * status window. Otherwise display it in the channel window. + */ + IRC_CHANNEL_REC *chanrec; + char *params, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &channel); + + chanrec = irc_channel_find(server, channel); + print_event_received(server, data, nick, chanrec == NULL || chanrec->joined); + g_free(params); +} + +static void event_489(IRC_SERVER_REC *server, const char *data, const char *nick) +{ + /* Numeric 489 can mean one of two things things: + * cannot join to channel (secure only), or not chanop or voice. + * If we tried to join this channel, display the joinerror. + * Otherwise depending on the channel being joined or not + * display the error in the channel or status window. + */ + IRC_CHANNEL_REC *chanrec; + char *params, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &channel); + + chanrec = irc_channel_find(server, channel); + if (chanrec != NULL && !chanrec->joined) { + cannot_join(server, data, IRCTXT_JOINERROR_SECURE_ONLY); + } else { + print_event_received(server, data, nick, chanrec == NULL || chanrec->joined); + } + g_free(params); +} + +static void event_help(IRC_SERVER_REC *server, int formatnum, const char *data) +{ + /* Common handling for umerics 704 (RPL_HELPSTART), 705 (RPL_HELPTXT), + * and 706 (RPL_ENDOFHELP); sent as a reply to HELP or HELPOP command. + */ + char *params, *topic, *help_text; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &topic, &help_text); + + g_return_if_fail(help_text != NULL); + + if (help_text[0] == '\0') { + /* Empty lines can be used by servers for styling; and we need to replace + * them with something non-empty or they would be dropped when displayed. + */ + help_text = " "; + } + + printformat(server, NULL, MSGLEVEL_CRAP, formatnum, topic, help_text); + g_free(params); +} + +static void event_helpstart(IRC_SERVER_REC *server, const char *data, const char *nick) +{ + /* Numeric 704 (RPL_HELPSTART) sent as a reply to HELP or HELPOP command. + */ + event_help(server, IRCTXT_SERVER_HELP_START, data); +} + +static void event_helptxt(IRC_SERVER_REC *server, const char *data, const char *nick) +{ + /* Numeric 705 (RPL_HELPTXT), sent as a reply to HELP or HELPOP command. + */ + event_help(server, IRCTXT_SERVER_HELP_TXT, data); +} + +static void event_endofhelp(IRC_SERVER_REC *server, const char *data, const char *nick) +{ + /* Numeric 706 (RPL_ENDOFHELP), sent as a reply to HELP or HELPOP command. + */ + event_help(server, IRCTXT_SERVER_END_OF_HELP, data); +} + +static void event_target_too_fast(IRC_SERVER_REC *server, const char *data, + const char *nick) +{ + /* Target change too fast, could be nick or channel. + * If we tried to join this channel, display the error in the + * status window. Otherwise display it in the channel window. + */ + IRC_CHANNEL_REC *chanrec; + char *params, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &channel); + + chanrec = irc_channel_find(server, channel); + print_event_received(server, data, nick, chanrec == NULL || chanrec->joined); + g_free(params); +} + +static void event_unknown_mode(IRC_SERVER_REC *server, const char *data) +{ + char *params, *mode; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &mode); + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_UNKNOWN_MODE, mode); + g_free(params); +} + +static void event_numeric(IRC_SERVER_REC *server, const char *data, + const char *nick) +{ + data = strchr(data, ' '); + if (data != NULL) + print_event_received(server, data+1, nick, FALSE); +} + +static void print_event_received(IRC_SERVER_REC *server, const char *data, + const char *nick, int target_param) +{ + char *target, *args, *ptr, *ptr2, *recoded; + int format; + + g_return_if_fail(data != NULL); + + /* first param is our nick, "*" or a channel */ + ptr = strchr(data, ' '); + if (ptr == NULL) + return; + ptr++; + + if (server_ischannel(SERVER(server), data)) /* directed at channel */ + target = g_strndup(data, (int)(ptr - data - 1)); + else if (!target_param || *ptr == ':' || (ptr2 = strchr(ptr, ' ')) == NULL) + target = NULL; + else { + /* target parameter expected and present */ + target = g_strndup(ptr, (int) (ptr2-ptr)); + } + + /* param1 param2 ... :last parameter */ + if (*ptr == ':') { + /* only one parameter */ + args = g_strdup(ptr+1); + } else { + args = g_strdup(ptr); + ptr = strstr(args, " :"); + if (ptr != NULL) + memmove(ptr+1, ptr+2, strlen(ptr+1)); + } + + recoded = recode_in(SERVER(server), args, NULL); + format = nick == NULL || server->real_address == NULL || + g_strcmp0(nick, server->real_address) == 0 ? + IRCTXT_DEFAULT_EVENT : IRCTXT_DEFAULT_EVENT_SERVER; + printformat(server, target, MSGLEVEL_CRAP, format, + nick, recoded, current_server_event); + + g_free(recoded); + g_free(args); + g_free(target); +} + +static void event_received(IRC_SERVER_REC *server, const char *data, + const char *nick) +{ + print_event_received(server, data, nick, FALSE); +} + +static void event_target_received(IRC_SERVER_REC *server, const char *data, + const char *nick) +{ + print_event_received(server, data, nick, TRUE); +} + +static void event_motd(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + /* don't ignore motd anymore after 3 seconds of connection time - + we might have called /MOTD */ + if (settings_get_bool("skip_motd") && !server->motd_got) + return; + + print_event_received(server, data, nick, FALSE); +} + +static void sig_empty(void) +{ +} + +void fe_events_numeric_init(void) +{ + last_away_nick = NULL; + last_away_msg = NULL; + + /* clang-format off */ + signal_add("event 221", (SIGNAL_FUNC) event_user_mode); + signal_add("event 303", (SIGNAL_FUNC) event_ison); + signal_add("event 353", (SIGNAL_FUNC) event_names_list); + signal_add_first("event 366", (SIGNAL_FUNC) event_end_of_names); + signal_add("event 352", (SIGNAL_FUNC) event_who); + signal_add("event 315", (SIGNAL_FUNC) event_end_of_who); + signal_add("event 271", (SIGNAL_FUNC) event_silence_list); + signal_add("event 272", (SIGNAL_FUNC) sig_empty); + signal_add("event 281", (SIGNAL_FUNC) event_accept_list); + signal_add("event 367", (SIGNAL_FUNC) event_ban_list); + signal_add("event 348", (SIGNAL_FUNC) event_eban_list); + signal_add("event 346", (SIGNAL_FUNC) event_invite_list); + signal_add("event 433", (SIGNAL_FUNC) event_nick_in_use); + signal_add("event 332", (SIGNAL_FUNC) event_topic_get); + signal_add("event 333", (SIGNAL_FUNC) event_topic_info); + signal_add("event 324", (SIGNAL_FUNC) event_channel_mode); + signal_add("event 329", (SIGNAL_FUNC) event_channel_created); + signal_add("event 306", (SIGNAL_FUNC) event_nowaway); + signal_add("event 305", (SIGNAL_FUNC) event_unaway); + signal_add("event 301", (SIGNAL_FUNC) event_away); + signal_add("event 328", (SIGNAL_FUNC) event_chanserv_url); + signal_add("event 302", (SIGNAL_FUNC) event_userhost); + signal_add("event 341", (SIGNAL_FUNC) event_sent_invite); + + signal_add("event 437", (SIGNAL_FUNC) event_target_unavailable); + signal_add("event 401", (SIGNAL_FUNC) event_no_such_nick); + signal_add("event 403", (SIGNAL_FUNC) event_no_such_channel); + signal_add("event 405", (SIGNAL_FUNC) event_too_many_channels); + signal_add("event 407", (SIGNAL_FUNC) event_duplicate_channel); + signal_add("event 471", (SIGNAL_FUNC) event_channel_is_full); + signal_add("event 472", (SIGNAL_FUNC) event_unknown_mode); + signal_add("event 473", (SIGNAL_FUNC) event_invite_only); + signal_add("event 474", (SIGNAL_FUNC) event_banned); + signal_add("event 475", (SIGNAL_FUNC) event_bad_channel_key); + signal_add("event 476", (SIGNAL_FUNC) event_bad_channel_mask); + signal_add("event 477", (SIGNAL_FUNC) event_477); + signal_add("event 489", (SIGNAL_FUNC) event_489); /* cannot join to channel (secure only), or not chanop or voice. */ + signal_add("event 375", (SIGNAL_FUNC) event_motd); + signal_add("event 376", (SIGNAL_FUNC) event_motd); + signal_add("event 372", (SIGNAL_FUNC) event_motd); + signal_add("event 422", (SIGNAL_FUNC) event_motd); + signal_add("event 439", (SIGNAL_FUNC) event_target_too_fast); + signal_add("event 704", (SIGNAL_FUNC) event_helpstart); + signal_add("event 705", (SIGNAL_FUNC) event_helptxt); + signal_add("event 706", (SIGNAL_FUNC) event_endofhelp); + signal_add("event 707", (SIGNAL_FUNC) event_target_too_fast); + + signal_add("default event numeric", (SIGNAL_FUNC) event_numeric); + /* Because default event numeric only fires if there is no specific + * event, add all numerics with a handler elsewhere in irssi that + * should not be printed specially here. + */ + signal_add("event 001", (SIGNAL_FUNC) event_received); + signal_add("event 004", (SIGNAL_FUNC) event_received); + signal_add("event 005", (SIGNAL_FUNC) event_received); + signal_add("event 254", (SIGNAL_FUNC) event_received); + signal_add("event 354", (SIGNAL_FUNC) event_received); + signal_add("event 364", (SIGNAL_FUNC) event_received); + signal_add("event 365", (SIGNAL_FUNC) event_received); + signal_add("event 381", (SIGNAL_FUNC) event_received); + signal_add("event 396", (SIGNAL_FUNC) event_received); + signal_add("event 421", (SIGNAL_FUNC) event_received); + signal_add("event 432", (SIGNAL_FUNC) event_received); + signal_add("event 436", (SIGNAL_FUNC) event_received); + signal_add("event 438", (SIGNAL_FUNC) event_received); + signal_add("event 465", (SIGNAL_FUNC) event_received); + signal_add("event 470", (SIGNAL_FUNC) event_received); + signal_add("event 479", (SIGNAL_FUNC) event_received); + + signal_add("event 344", (SIGNAL_FUNC) event_target_received); /* reop list */ + signal_add("event 345", (SIGNAL_FUNC) event_target_received); /* end of reop list */ + signal_add("event 347", (SIGNAL_FUNC) event_target_received); /* end of invite exception list */ + signal_add("event 349", (SIGNAL_FUNC) event_target_received); /* end of ban exception list */ + signal_add("event 368", (SIGNAL_FUNC) event_target_received); /* end of ban list */ + signal_add("event 386", (SIGNAL_FUNC) event_target_received); /* owner list; old rsa challenge (harmless) */ + signal_add("event 387", (SIGNAL_FUNC) event_target_received); /* end of owner list */ + signal_add("event 388", (SIGNAL_FUNC) event_target_received); /* protect list */ + signal_add("event 389", (SIGNAL_FUNC) event_target_received); /* end of protect list */ + signal_add("event 404", (SIGNAL_FUNC) event_target_received); /* cannot send to channel */ + signal_add("event 408", (SIGNAL_FUNC) event_target_received); /* cannot send (+c) */ + signal_add("event 442", (SIGNAL_FUNC) event_target_received); /* you're not on that channel */ + signal_add("event 478", (SIGNAL_FUNC) event_target_received); /* ban list is full */ + signal_add("event 482", (SIGNAL_FUNC) event_target_received); /* not chanop */ + signal_add("event 486", (SIGNAL_FUNC) event_target_received); /* cannot /msg (+R) */ + signal_add("event 494", (SIGNAL_FUNC) event_target_received); /* cannot /msg (own +R) */ + signal_add("event 506", (SIGNAL_FUNC) event_target_received); /* cannot send (+R) */ + signal_add("event 716", (SIGNAL_FUNC) event_target_received); /* cannot /msg (+g) */ + signal_add("event 717", (SIGNAL_FUNC) event_target_received); /* +g notified */ + signal_add("event 728", (SIGNAL_FUNC) event_target_received); /* quiet (or other) list */ + signal_add("event 729", (SIGNAL_FUNC) event_target_received); /* end of quiet (or other) list */ + /* clang-format on */ +} + +void fe_events_numeric_deinit(void) +{ + g_free_not_null(last_away_nick); + g_free_not_null(last_away_msg); + + signal_remove("event 221", (SIGNAL_FUNC) event_user_mode); + signal_remove("event 303", (SIGNAL_FUNC) event_ison); + signal_remove("event 353", (SIGNAL_FUNC) event_names_list); + signal_remove("event 366", (SIGNAL_FUNC) event_end_of_names); + signal_remove("event 352", (SIGNAL_FUNC) event_who); + signal_remove("event 315", (SIGNAL_FUNC) event_end_of_who); + signal_remove("event 271", (SIGNAL_FUNC) event_silence_list); + signal_remove("event 272", (SIGNAL_FUNC) sig_empty); + signal_remove("event 281", (SIGNAL_FUNC) event_accept_list); + signal_remove("event 367", (SIGNAL_FUNC) event_ban_list); + signal_remove("event 348", (SIGNAL_FUNC) event_eban_list); + signal_remove("event 346", (SIGNAL_FUNC) event_invite_list); + signal_remove("event 433", (SIGNAL_FUNC) event_nick_in_use); + signal_remove("event 332", (SIGNAL_FUNC) event_topic_get); + signal_remove("event 333", (SIGNAL_FUNC) event_topic_info); + signal_remove("event 324", (SIGNAL_FUNC) event_channel_mode); + signal_remove("event 329", (SIGNAL_FUNC) event_channel_created); + signal_remove("event 306", (SIGNAL_FUNC) event_nowaway); + signal_remove("event 305", (SIGNAL_FUNC) event_unaway); + signal_remove("event 301", (SIGNAL_FUNC) event_away); + signal_remove("event 328", (SIGNAL_FUNC) event_chanserv_url); + signal_remove("event 302", (SIGNAL_FUNC) event_userhost); + signal_remove("event 341", (SIGNAL_FUNC) event_sent_invite); + + signal_remove("event 437", (SIGNAL_FUNC) event_target_unavailable); + signal_remove("event 401", (SIGNAL_FUNC) event_no_such_nick); + signal_remove("event 403", (SIGNAL_FUNC) event_no_such_channel); + signal_remove("event 405", (SIGNAL_FUNC) event_too_many_channels); + signal_remove("event 407", (SIGNAL_FUNC) event_duplicate_channel); + signal_remove("event 471", (SIGNAL_FUNC) event_channel_is_full); + signal_remove("event 472", (SIGNAL_FUNC) event_unknown_mode); + signal_remove("event 473", (SIGNAL_FUNC) event_invite_only); + signal_remove("event 474", (SIGNAL_FUNC) event_banned); + signal_remove("event 475", (SIGNAL_FUNC) event_bad_channel_key); + signal_remove("event 476", (SIGNAL_FUNC) event_bad_channel_mask); + signal_remove("event 477", (SIGNAL_FUNC) event_477); + signal_remove("event 489", (SIGNAL_FUNC) event_489); + signal_remove("event 375", (SIGNAL_FUNC) event_motd); + signal_remove("event 376", (SIGNAL_FUNC) event_motd); + signal_remove("event 372", (SIGNAL_FUNC) event_motd); + signal_remove("event 422", (SIGNAL_FUNC) event_motd); + signal_remove("event 439", (SIGNAL_FUNC) event_target_too_fast); + signal_remove("event 704", (SIGNAL_FUNC) event_helpstart); + signal_remove("event 705", (SIGNAL_FUNC) event_helptxt); + signal_remove("event 706", (SIGNAL_FUNC) event_endofhelp); + signal_remove("event 707", (SIGNAL_FUNC) event_target_too_fast); + + signal_remove("default event numeric", (SIGNAL_FUNC) event_numeric); + signal_remove("event 001", (SIGNAL_FUNC) event_received); + signal_remove("event 004", (SIGNAL_FUNC) event_received); + signal_remove("event 005", (SIGNAL_FUNC) event_received); + signal_remove("event 254", (SIGNAL_FUNC) event_received); + signal_remove("event 354", (SIGNAL_FUNC) event_received); + signal_remove("event 364", (SIGNAL_FUNC) event_received); + signal_remove("event 365", (SIGNAL_FUNC) event_received); + signal_remove("event 381", (SIGNAL_FUNC) event_received); + signal_remove("event 396", (SIGNAL_FUNC) event_received); + signal_remove("event 421", (SIGNAL_FUNC) event_received); + signal_remove("event 432", (SIGNAL_FUNC) event_received); + signal_remove("event 436", (SIGNAL_FUNC) event_received); + signal_remove("event 438", (SIGNAL_FUNC) event_received); + signal_remove("event 465", (SIGNAL_FUNC) event_received); + signal_remove("event 470", (SIGNAL_FUNC) event_received); + signal_remove("event 479", (SIGNAL_FUNC) event_received); + + signal_remove("event 344", (SIGNAL_FUNC) event_target_received); + signal_remove("event 345", (SIGNAL_FUNC) event_target_received); + signal_remove("event 347", (SIGNAL_FUNC) event_target_received); + signal_remove("event 349", (SIGNAL_FUNC) event_target_received); + signal_remove("event 368", (SIGNAL_FUNC) event_target_received); + signal_remove("event 386", (SIGNAL_FUNC) event_target_received); + signal_remove("event 387", (SIGNAL_FUNC) event_target_received); + signal_remove("event 388", (SIGNAL_FUNC) event_target_received); + signal_remove("event 389", (SIGNAL_FUNC) event_target_received); + signal_remove("event 404", (SIGNAL_FUNC) event_target_received); + signal_remove("event 408", (SIGNAL_FUNC) event_target_received); + signal_remove("event 442", (SIGNAL_FUNC) event_target_received); + signal_remove("event 478", (SIGNAL_FUNC) event_target_received); + signal_remove("event 482", (SIGNAL_FUNC) event_target_received); + signal_remove("event 486", (SIGNAL_FUNC) event_target_received); + signal_remove("event 494", (SIGNAL_FUNC) event_target_received); + signal_remove("event 506", (SIGNAL_FUNC) event_target_received); + signal_remove("event 716", (SIGNAL_FUNC) event_target_received); + signal_remove("event 717", (SIGNAL_FUNC) event_target_received); + signal_remove("event 728", (SIGNAL_FUNC) event_target_received); + signal_remove("event 729", (SIGNAL_FUNC) event_target_received); +} diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c new file mode 100644 index 0000000..b6b3e75 --- /dev/null +++ b/src/fe-common/irc/fe-events.c @@ -0,0 +1,550 @@ +/* + fe-events.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/core/levels.h> +#include <irssi/src/core/servers.h> +#include <irssi/src/irc/core/servers-redirect.h> +#include <irssi/src/core/servers-reconnect.h> +#include <irssi/src/core/queries.h> +#include <irssi/src/core/ignore.h> +#include <irssi/src/core/recode.h> + +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-channels.h> +#include <irssi/src/irc/core/irc-nicklist.h> +#include <irssi/src/irc/core/irc-masks.h> + +#include <irssi/src/fe-common/core/printtext.h> +#include <irssi/src/fe-common/core/fe-queries.h> +#include <irssi/src/fe-common/core/fe-windows.h> +#include <irssi/src/fe-common/irc/fe-irc-server.h> +#include <irssi/src/fe-common/irc/fe-irc-channels.h> + +static void event_privmsg(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *target, *msg, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); + if (nick == NULL) nick = server->real_address; + if (addr == NULL) addr = ""; + + if (fe_channel_is_opchannel(server, target)) { + /* Hybrid 6 feature, send msg to all ops in channel */ + const char *cleantarget = fe_channel_skip_prefix(server, target); + recoded = recode_in(SERVER(server), msg, cleantarget); + + /* pass the original target to the signal, with the @+ here + * the other one is only needed for recode_in*/ + signal_emit("message irc op_public", 5, + server, recoded, nick, addr, target); + } else { + recoded = recode_in(SERVER(server), msg, server_ischannel(SERVER(server), target) ? target : nick); + signal_emit(server_ischannel(SERVER(server), target) ? + "message public" : "message private", 5, + server, recoded, nick, addr, + get_visible_target(server, target)); + } + + g_free(params); + g_free(recoded); +} + +static void ctcp_action(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr, + const char *target) +{ + char *recoded; + + g_return_if_fail(data != NULL); + recoded = recode_in(SERVER(server), data, target); + signal_emit("message irc action", 5, + server, recoded, nick, addr, + get_visible_target(server, target)); + g_free(recoded); +} + +static void event_notice(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *target, *msg, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); + recoded = recode_in(SERVER(server), msg, target); + if (nick == NULL) { + nick = server->real_address == NULL ? + server->connrec->address : + server->real_address; + } + + signal_emit("message irc notice", 5, server, recoded, nick, addr, + get_visible_target(server, target)); + g_free(params); + g_free(recoded); +} + +static void event_join(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *channel, *tmp, *account, *realname; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, &channel, &account, &realname); + tmp = strchr(channel, 7); /* ^G does something weird.. */ + if (tmp != NULL) *tmp = '\0'; + + signal_emit("message join", 6, server, + get_visible_target(server, channel), nick, addr, account, realname); + g_free(params); +} + +static void event_chghost(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *user, *host, *new_addr; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, &user, &host); + new_addr = g_strconcat(user, "@", host, NULL); + + signal_emit("message host_changed", 4, server, nick, new_addr, addr); + + g_free(new_addr); + g_free(params); +} + +static void event_account(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *account; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 1, &account); + + signal_emit("message account_changed", 4, server, nick, addr, account); + + g_free(params); +} + +static void event_part(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *channel, *reason, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2 | PARAM_FLAG_GETREST, + &channel, &reason); + recoded = recode_in(SERVER(server), reason, channel); + signal_emit("message part", 5, server, + get_visible_target(server, channel), nick, addr, recoded); + g_free(params); + g_free(recoded); +} + +static void event_quit(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *recoded; + + g_return_if_fail(data != NULL); + + if (*data == ':') data++; /* quit message */ + recoded = recode_in(SERVER(server), data, nick); + signal_emit("message quit", 4, server, nick, addr, recoded); + g_free(recoded); +} + +static void event_kick(IRC_SERVER_REC *server, const char *data, + const char *kicker, const char *addr) +{ + char *params, *channel, *nick, *reason, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3 | PARAM_FLAG_GETREST, + &channel, &nick, &reason); + recoded = recode_in(SERVER(server), reason, channel); + signal_emit("message kick", 6, + server, get_visible_target(server, channel), + nick, kicker, addr, recoded); + g_free(params); + g_free(recoded); +} + +static void event_kill(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *path, *reason; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2 | PARAM_FLAG_GETREST, + NULL, &path); + reason = strstr(path, " ("); + if (reason == NULL || reason[strlen(reason)-1] != ')') { + /* weird server, maybe it didn't give path */ + reason = path; + path = ""; + } else { + /* reason inside (...) */ + *reason = '\0'; + reason += 2; + reason[strlen(reason)-1] = '\0'; + } + + if (addr != NULL) { + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_KILL, + nick, addr, reason, path); + } else { + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_KILL_SERVER, + nick, reason, path); + } + + g_free(params); +} + +static void event_nick(IRC_SERVER_REC *server, const char *data, + const char *sender, const char *addr) +{ + char *params, *newnick; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 1, &newnick); + + /* NOTE: server->nick was already changed in irc/core/irc-nicklist.c */ + signal_emit(g_ascii_strcasecmp(newnick, server->nick) == 0 ? + "message own_nick" : "message nick", 4, + server, newnick, sender, addr); + + g_free(params); +} + +static void event_mode(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *channel, *mode; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2 | PARAM_FLAG_GETREST, + &channel, &mode); + + signal_emit("message irc mode", 5, + server, get_visible_target(server, channel), + nick, addr, g_strchomp(mode)); + g_free(params); +} + +static void event_away_notify(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *awaymsg; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 1 | PARAM_FLAG_GETREST, + &awaymsg); + + signal_emit("message away_notify", 4, + server, nick, addr, awaymsg); + g_free(params); +} + +static void event_pong(IRC_SERVER_REC *server, const char *data, const char *nick) +{ + char *params, *host, *reply; + + g_return_if_fail(data != NULL); + if (nick == NULL) nick = server->real_address; + + params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &host, &reply); + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_PONG, host, reply); + g_free(params); +} + +static void event_invite(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *invited, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, &invited, &channel); + if (server->nick_comp_func(invited, server->nick) == 0) { + signal_emit("message invite", 4, + server, get_visible_target(server, channel), nick, addr); + } else { + signal_emit("message invite_other", 5, + server, get_visible_target(server, channel), invited, nick, addr); + } + g_free(params); +} + +static void event_topic(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *channel, *topic, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2 | PARAM_FLAG_GETREST, + &channel, &topic); + recoded = recode_in(SERVER(server), topic, channel); + signal_emit("message topic", 5, server, + get_visible_target(server, channel), recoded, nick, addr); + g_free(params); + g_free(recoded); +} + +static void event_error(IRC_SERVER_REC *server, const char *data) +{ + g_return_if_fail(data != NULL); + + if (*data == ':') data++; + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_ERROR, data); +} + +static void event_wallops(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) +{ + g_return_if_fail(data != NULL); + + if (*data == ':') data++; + if (ignore_check(SERVER(server), nick, addr, NULL, data, MSGLEVEL_WALLOPS)) + return; + + if (g_ascii_strncasecmp(data, "\001ACTION ", 8) != 0) + printformat(server, NULL, MSGLEVEL_WALLOPS, IRCTXT_WALLOPS, nick, data); + else { + /* Action in WALLOP */ + int len; + char *tmp; + + tmp = g_strdup(data+8); + len = strlen(tmp); + if (len >= 1 && tmp[len-1] == 1) tmp[len-1] = '\0'; + printformat(server, NULL, MSGLEVEL_WALLOPS, IRCTXT_ACTION_WALLOPS, nick, tmp); + g_free(tmp); + } +} + +static void event_silence(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) +{ + g_return_if_fail(data != NULL); + + g_return_if_fail(*data == '+' || *data == '-'); + + printformat(server, NULL, MSGLEVEL_CRAP, *data == '+' ? IRCTXT_SILENCED : IRCTXT_UNSILENCED, data+1); +} + +static void channel_sync(CHANNEL_REC *channel) +{ + g_return_if_fail(channel != NULL); + + printformat(channel->server, channel->visible_name, + MSGLEVEL_CLIENTNOTICE|MSGLEVEL_NO_ACT, + IRCTXT_CHANNEL_SYNCED, channel->visible_name, + (long) (time(NULL)-channel->createtime)); +} + +static void event_connected(IRC_SERVER_REC *server) +{ + const char *nick; + + g_return_if_fail(server != NULL); + + nick = server->connrec->nick; + if (g_ascii_strcasecmp(server->nick, nick) == 0) + return; + + /* someone has our nick, find out who. */ + server_redirect_event(server, "whois", 1, nick, TRUE, NULL, + "event 311", "nickfind event whois", + "", "event empty", NULL); + irc_send_cmdv(server, "WHOIS %s", nick); +} + +static void event_nickfind_whois(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *user, *host, *realname; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 6, NULL, &nick, &user, &host, NULL, &realname); + printformat(server, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_YOUR_NICK_OWNED, nick, user, host, realname); + g_free(params); +} + +static void event_ban_type_changed(void *ban_typep) +{ + GString *str; + int ban_type; + + ban_type = GPOINTER_TO_INT(ban_typep); + + if (ban_type == 0) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + IRCTXT_BANTYPE, "Error, using Normal"); + return; + } + + if (ban_type == (IRC_MASK_USER|IRC_MASK_DOMAIN)) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_BANTYPE, "Normal"); + } else if (ban_type == (IRC_MASK_HOST|IRC_MASK_DOMAIN)) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_BANTYPE, "Host"); + } else if (ban_type == IRC_MASK_DOMAIN) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_BANTYPE, "Domain"); + } else { + str = g_string_new("Custom:"); + if (ban_type & IRC_MASK_NICK) + g_string_append(str, " Nick"); + if (ban_type & IRC_MASK_USER) + g_string_append(str, " User"); + if (ban_type & IRC_MASK_HOST) + g_string_append(str, " Host"); + if (ban_type & IRC_MASK_DOMAIN) + g_string_append(str, " Domain"); + + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_BANTYPE, str->str); + g_string_free(str, TRUE); + } +} + +static void sig_whois_event_not_found(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &nick); + printformat(server, nick, MSGLEVEL_CRAP, IRCTXT_WHOIS_NOT_FOUND, nick); + g_free(params); +} + +static void sig_whowas_event_end(IRC_SERVER_REC *server, const char *data, + const char *sender, const char *addr) +{ + char *params, *nick; + + g_return_if_fail(data != NULL); + + if (server->whowas_found) { + signal_emit("event 369", 4, server, data, sender, addr); + return; + } + + params = event_get_params(data, 2, NULL, &nick); + printformat(server, nick, MSGLEVEL_CRAP, IRCTXT_WHOIS_NOT_FOUND, nick); + g_free(params); +} + +static void event_received(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + if (!i_isdigit(*data)) { + printtext(server, NULL, MSGLEVEL_CRAP, "%s", data); + return; + } + + /* numeric event. */ + signal_emit("default event numeric", 4, server, data, nick, addr); +} + +void fe_events_init(void) +{ + signal_add("event privmsg", (SIGNAL_FUNC) event_privmsg); + signal_add("ctcp action", (SIGNAL_FUNC) ctcp_action); + signal_add("event notice", (SIGNAL_FUNC) event_notice); + signal_add("event join", (SIGNAL_FUNC) event_join); + signal_add("event chghost", (SIGNAL_FUNC) event_chghost); + signal_add("event account", (SIGNAL_FUNC) event_account); + signal_add("event part", (SIGNAL_FUNC) event_part); + signal_add("event quit", (SIGNAL_FUNC) event_quit); + signal_add("event kick", (SIGNAL_FUNC) event_kick); + signal_add("event kill", (SIGNAL_FUNC) event_kill); + signal_add("event nick", (SIGNAL_FUNC) event_nick); + signal_add("event mode", (SIGNAL_FUNC) event_mode); + signal_add("event pong", (SIGNAL_FUNC) event_pong); + signal_add("event invite", (SIGNAL_FUNC) event_invite); + signal_add("event topic", (SIGNAL_FUNC) event_topic); + signal_add("event error", (SIGNAL_FUNC) event_error); + signal_add("event wallops", (SIGNAL_FUNC) event_wallops); + signal_add("event silence", (SIGNAL_FUNC) event_silence); + signal_add("event away", (SIGNAL_FUNC) event_away_notify); + + signal_add("default event", (SIGNAL_FUNC) event_received); + + signal_add("channel sync", (SIGNAL_FUNC) channel_sync); + signal_add("event connected", (SIGNAL_FUNC) event_connected); + signal_add("nickfind event whois", (SIGNAL_FUNC) event_nickfind_whois); + signal_add("ban type changed", (SIGNAL_FUNC) event_ban_type_changed); + signal_add("whois event not found", (SIGNAL_FUNC) sig_whois_event_not_found); + signal_add("whowas event end", (SIGNAL_FUNC) sig_whowas_event_end); +} + +void fe_events_deinit(void) +{ + signal_remove("event privmsg", (SIGNAL_FUNC) event_privmsg); + signal_remove("ctcp action", (SIGNAL_FUNC) ctcp_action); + signal_remove("event notice", (SIGNAL_FUNC) event_notice); + signal_remove("event join", (SIGNAL_FUNC) event_join); + signal_remove("event chghost", (SIGNAL_FUNC) event_chghost); + signal_remove("event account", (SIGNAL_FUNC) event_account); + signal_remove("event part", (SIGNAL_FUNC) event_part); + signal_remove("event quit", (SIGNAL_FUNC) event_quit); + signal_remove("event kick", (SIGNAL_FUNC) event_kick); + signal_remove("event kill", (SIGNAL_FUNC) event_kill); + signal_remove("event nick", (SIGNAL_FUNC) event_nick); + signal_remove("event mode", (SIGNAL_FUNC) event_mode); + signal_remove("event pong", (SIGNAL_FUNC) event_pong); + signal_remove("event invite", (SIGNAL_FUNC) event_invite); + signal_remove("event topic", (SIGNAL_FUNC) event_topic); + signal_remove("event error", (SIGNAL_FUNC) event_error); + signal_remove("event wallops", (SIGNAL_FUNC) event_wallops); + signal_remove("event silence", (SIGNAL_FUNC) event_silence); + signal_remove("event away", (SIGNAL_FUNC) event_away_notify); + + signal_remove("default event", (SIGNAL_FUNC) event_received); + + signal_remove("channel sync", (SIGNAL_FUNC) channel_sync); + signal_remove("event connected", (SIGNAL_FUNC) event_connected); + signal_remove("nickfind event whois", (SIGNAL_FUNC) event_nickfind_whois); + signal_remove("ban type changed", (SIGNAL_FUNC) event_ban_type_changed); + signal_remove("whois event not found", (SIGNAL_FUNC) sig_whois_event_not_found); + signal_remove("whowas event end", (SIGNAL_FUNC) sig_whowas_event_end); +} diff --git a/src/fe-common/irc/fe-irc-channels.c b/src/fe-common/irc/fe-irc-channels.c new file mode 100644 index 0000000..93ff360 --- /dev/null +++ b/src/fe-common/irc/fe-irc-channels.c @@ -0,0 +1,111 @@ +/* + fe-irc-channels.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> + +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-channels.h> +#include <irssi/src/irc/core/channel-rejoin.h> + +#include <irssi/src/fe-common/core/printtext.h> +#include <irssi/src/fe-common/core/fe-windows.h> +#include <irssi/src/fe-common/core/window-items.h> + +int fe_channel_is_opchannel(IRC_SERVER_REC *server, const char *target) +{ + const char *statusmsg; + + /* Quick check */ + if (server == NULL || server->prefix[(int)(unsigned char)*target] == 0) + return FALSE; + + statusmsg = g_hash_table_lookup(server->isupport, "statusmsg"); + if (statusmsg == NULL) + statusmsg = "@"; + + return strchr(statusmsg, *target) != NULL; +} + +const char *fe_channel_skip_prefix(IRC_SERVER_REC *server, const char *target) +{ + const char *statusmsg; + + /* Quick check */ + if (server == NULL || server->prefix[(int)(unsigned char)*target] == 0) + return target; + + /* Exit early if target doesn't name a channel */ + if (server_ischannel(SERVER(server), target) == FALSE) + return target; + + statusmsg = g_hash_table_lookup(server->isupport, "statusmsg"); + + /* Hack: for bahamut 1.4 which sends neither STATUSMSG nor + * WALLCHOPS in 005 */ + if (statusmsg == NULL) + statusmsg = "@"; + + /* Strip the leading statusmsg prefixes */ + while (strchr(statusmsg, *target) != NULL) { + target++; + } + + return target; +} + +static void sig_channel_rejoin(SERVER_REC *server, REJOIN_REC *rec) +{ + g_return_if_fail(rec != NULL); + + printformat(server, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_CHANNEL_REJOIN, rec->channel); +} + +static void sig_event_forward(SERVER_REC *server, const char *data, + const char *nick) +{ + IRC_CHANNEL_REC *channel; + char *params, *from, *to; + + params = event_get_params(data, 3, NULL, &from, &to); + if (from != NULL && to != NULL && server_ischannel(server, from) && server_ischannel(server, to)) { + channel = irc_channel_find(server, from); + if (channel != NULL && irc_channel_find(server, to) == NULL) { + window_bind_add(window_item_window(channel), + server->tag, to); + } + } + g_free(params); +} + +void fe_irc_channels_init(void) +{ + signal_add("channel rejoin new", (SIGNAL_FUNC) sig_channel_rejoin); + signal_add_first("event 470", (SIGNAL_FUNC) sig_event_forward); +} + +void fe_irc_channels_deinit(void) +{ + signal_remove("channel rejoin new", (SIGNAL_FUNC) sig_channel_rejoin); + signal_remove("event 470", (SIGNAL_FUNC) sig_event_forward); +} diff --git a/src/fe-common/irc/fe-irc-channels.h b/src/fe-common/irc/fe-irc-channels.h new file mode 100644 index 0000000..a577010 --- /dev/null +++ b/src/fe-common/irc/fe-irc-channels.h @@ -0,0 +1,10 @@ +#ifndef IRSSI_FE_COMMON_IRC_FE_IRC_CHANNELS_H +#define IRSSI_FE_COMMON_IRC_FE_IRC_CHANNELS_H + +int fe_channel_is_opchannel(IRC_SERVER_REC *server, const char *target); +const char *fe_channel_skip_prefix(IRC_SERVER_REC *server, const char *target); + +void fe_irc_channels_init(void); +void fe_irc_channels_deinit(void); + +#endif diff --git a/src/fe-common/irc/fe-irc-commands.c b/src/fe-common/irc/fe-irc-commands.c new file mode 100644 index 0000000..40ad36e --- /dev/null +++ b/src/fe-common/irc/fe-irc-commands.c @@ -0,0 +1,448 @@ +/* + fe-irc-commands.c : irssi + + Copyright (C) 1999-2001 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/special-vars.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/core/levels.h> +#include <irssi/src/core/servers.h> +#include <irssi/src/irc/core/mode-lists.h> +#include <irssi/src/core/nicklist.h> +#include <irssi/src/irc/core/irc-commands.h> +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-channels.h> +#include <irssi/src/irc/core/irc-queries.h> + +#include <irssi/src/fe-common/core/fe-queries.h> +#include <irssi/src/fe-common/core/fe-windows.h> +#include <irssi/src/fe-common/core/window-items.h> +#include <irssi/src/fe-common/core/printtext.h> +#include <irssi/src/fe-common/core/keyboard.h> + +/* SYNTAX: ME <message> */ +static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) +{ + const char *target; + char *subdata; + char **splitdata; + int n = 0; + + CMD_IRC_SERVER(server); + if (!IS_IRC_ITEM(item)) + return; + + if (server == NULL || !server->connected) + cmd_return_error(CMDERR_NOT_CONNECTED); + + target = window_item_get_target(item); + splitdata = irc_server_split_action(server, target, data); + while ((subdata = splitdata[n++])) { + irc_server_send_action(server, target, subdata); + signal_emit("message irc own_action", 3, server, subdata, + item->visible_name); + } + g_strfreev(splitdata); +} + +/* SYNTAX: ACTION [-<server tag>] <target> <message> */ +static void cmd_action(const char *data, IRC_SERVER_REC *server) +{ + GHashTable *optlist; + const char *target, *text; + char *subtext; + char **splittexts; + int n = 0; + void *free_arg; + + CMD_IRC_SERVER(server); + + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | + PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, + "action", &optlist, &target, &text)) + return; + if (*target == '\0' || *text == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + server = IRC_SERVER(cmd_options_get_server("action", optlist, SERVER(server))); + if (server == NULL || !server->connected) + cmd_param_error(CMDERR_NOT_CONNECTED); + + splittexts = irc_server_split_action(server, target, text); + while ((subtext = splittexts[n++])) { + irc_server_send_action(server, target, subtext); + signal_emit("message irc own_action", 3, server, subtext, + target); + } + + g_strfreev(splittexts); + cmd_params_free(free_arg); +} + +static void cmd_notice(const char *data, IRC_SERVER_REC *server, + WI_ITEM_REC *item) +{ + const char *target, *msg; + void *free_arg; + + CMD_IRC_SERVER(server); + + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, + &target, &msg)) + return; + if (g_strcmp0(target, "*") == 0) + target = item == NULL ? "" : window_item_get_target(item); + + if (*target == '\0' || *msg == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + signal_emit("message irc own_notice", 3, server, msg, target); + + cmd_params_free(free_arg); +} + +static void cmd_ctcp(const char *data, IRC_SERVER_REC *server, + WI_ITEM_REC *item) +{ + const char *target; + char *ctcpcmd, *ctcpdata; + void *free_arg; + + CMD_IRC_SERVER(server); + + if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, + &target, &ctcpcmd, &ctcpdata)) + return; + if (g_strcmp0(target, "*") == 0) + target = item == NULL ? "" : window_item_get_target(item); + if (*target == '\0' || *ctcpcmd == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + if (*target == '=') { + /* don't handle DCC CTCPs */ + cmd_params_free(free_arg); + return; + } + + ascii_strup(ctcpcmd); + signal_emit("message irc own_ctcp", 4, + server, ctcpcmd, ctcpdata, target); + + cmd_params_free(free_arg); +} + +static void cmd_nctcp(const char *data, IRC_SERVER_REC *server, + WI_ITEM_REC *item) +{ + const char *target, *text; + void *free_arg; + + CMD_IRC_SERVER(server); + + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, + &target, &text)) + return; + if (g_strcmp0(target, "*") == 0) + target = item == NULL ? "" : window_item_get_target(item); + if (*target == '\0' || *text == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + signal_emit("message irc own_notice", 3, server, text, target); + cmd_params_free(free_arg); +} + +static void cmd_wall(const char *data, IRC_SERVER_REC *server, + WI_ITEM_REC *item) +{ + IRC_CHANNEL_REC *chanrec; + const char *channame, *msg; + void *free_arg; + + CMD_IRC_SERVER(server); + + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | + PARAM_FLAG_GETREST, item, &channame, &msg)) + return; + if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + chanrec = irc_channel_find(server, channame); + if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND); + + signal_emit("message irc own_wall", 3, server, msg, + chanrec->visible_name); + + cmd_params_free(free_arg); +} + +static void bans_ask_channel(const char *channel, IRC_SERVER_REC *server, + WI_ITEM_REC *item) +{ + GString *str; + + str = g_string_new(NULL); + g_string_printf(str, "%s b", channel); + signal_emit("command mode", 3, str->str, server, item); + if (server->emode_known) { + g_string_printf(str, "%s e", channel); + signal_emit("command mode", 3, str->str, server, item); + } + g_string_free(str, TRUE); +} + +static void bans_show_channel(IRC_CHANNEL_REC *channel, IRC_SERVER_REC *server) +{ + GSList *tmp; + int counter; + + if (channel->banlist == NULL) { + printformat(server, channel->visible_name, + MSGLEVEL_CLIENTNOTICE, + IRCTXT_NO_BANS, channel->visible_name); + return; + } + + /* show bans.. */ + counter = 1; + for (tmp = channel->banlist; tmp != NULL; tmp = tmp->next) { + BAN_REC *rec = tmp->data; + + printformat(server, channel->visible_name, MSGLEVEL_CRAP, + (rec->setby == NULL || *rec->setby == '\0') ? + IRCTXT_BANLIST : IRCTXT_BANLIST_LONG, + counter, channel->visible_name, + rec->ban, rec->setby, + (int) (time(NULL)-rec->time)); + counter++; + } +} + +/* SYNTAX: BAN [<channel>] [<nicks>] */ +static void cmd_ban(const char *data, IRC_SERVER_REC *server, + WI_ITEM_REC *item) +{ + IRC_CHANNEL_REC *chanrec; + char *channel, *nicks; + void *free_arg; + + CMD_IRC_SERVER(server); + + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, + item, &channel, &nicks)) + return; + + if (*nicks != '\0') { + /* setting ban - don't handle here */ + cmd_params_free(free_arg); + return; + } + + /* display bans */ + chanrec = IRC_CHANNEL(item); + if (chanrec == NULL && *channel == '\0') + cmd_param_error(CMDERR_NOT_JOINED); + + if (*channel != '\0' && g_strcmp0(channel, "*") != 0) + chanrec = irc_channel_find(server, channel); + + if (chanrec == NULL || !chanrec->synced) { + /* not joined to such channel or not yet synced, + ask ban lists from server */ + bans_ask_channel(channel, server, item); + } else { + bans_show_channel(chanrec, server); + } + + signal_stop(); + cmd_params_free(free_arg); +} + +/* SYNTAX: VER [<nick> | <channel> | *] */ +static void cmd_ver(gchar *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) +{ + char *str; + + g_return_if_fail(data != NULL); + + CMD_IRC_SERVER(server); + if (*data == '\0' && !IS_QUERY(item)) + cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); + + str = g_strdup_printf("%s VERSION", *data == '\0' ? + window_item_get_target(item) : data); + signal_emit("command ctcp", 3, str, server, item); + g_free(str); +} + +static void cmd_topic(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + CHANNEL_REC *channel; + char *timestr, *bynick, *byhost; + + g_return_if_fail(data != NULL); + + channel = *data != '\0' ? channel_find(server, data) : CHANNEL(item); + if (channel == NULL) return; + + printformat(server, channel->visible_name, MSGLEVEL_CRAP, + (channel->topic == NULL || *channel->topic == '\0') ? IRCTXT_NO_TOPIC : IRCTXT_TOPIC, + channel->visible_name, channel->topic); + + if (channel->topic_time > 0) { + byhost = strchr(channel->topic_by, '!'); + if (byhost == NULL) { + bynick = g_strdup(channel->topic_by); + byhost = ""; + } else { + bynick = g_strndup(channel->topic_by, + (int) (byhost-channel->topic_by)); + byhost++; + } + + timestr = my_asctime(channel->topic_time); + printformat(server, channel->visible_name, MSGLEVEL_CRAP, + IRCTXT_TOPIC_INFO, bynick, timestr, byhost); + g_free(timestr); + g_free(bynick); + } + signal_stop(); +} + +/* SYNTAX: TS */ +static void cmd_ts(const char *data) +{ + GSList *tmp; + + g_return_if_fail(data != NULL); + + for (tmp = channels; tmp != NULL; tmp = tmp->next) { + CHANNEL_REC *rec = tmp->data; + + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_TOPIC, + rec->visible_name, + rec->topic == NULL ? "" : rec->topic); + } +} + +typedef struct { + char *server_tag; + char *nick; +} OPER_PASS_REC; + +static void cmd_oper_got_pass(const char *password, OPER_PASS_REC *rec) +{ + SERVER_REC *server_rec = server_find_tag(rec->server_tag); + if (*password != '\0' && IS_IRC_SERVER(server_rec)) + irc_send_cmdv((IRC_SERVER_REC *) server_rec, "OPER %s %s", rec->nick, password); + g_free(rec->nick); + g_free(rec->server_tag); + g_free(rec); +} + +static void cmd_oper(const char *data, IRC_SERVER_REC *server) +{ + char *nick, *password, *format; + void *free_arg; + + g_return_if_fail(data != NULL); + if (!IS_IRC_SERVER(server) || !server->connected) + cmd_return_error(CMDERR_NOT_CONNECTED); + + if (!cmd_get_params(data, &free_arg, 2, &nick, &password)) + return; + if (*password == '\0') { + /* password not given, ask it. + irc/core handles the /OPER when password is given */ + OPER_PASS_REC *rec; + + rec = g_new(OPER_PASS_REC, 1); + rec->server_tag = g_strdup(server->tag); + rec->nick = g_strdup(*nick != '\0' ? nick : server->nick); + + format = format_get_text(MODULE_NAME, NULL, server, NULL, + IRCTXT_ASK_OPER_PASS); + + keyboard_entry_redirect((SIGNAL_FUNC) cmd_oper_got_pass, + format, + ENTRY_REDIRECT_FLAG_HIDDEN, rec); + g_free(format); + + signal_stop(); + } + + cmd_params_free(free_arg); +} + +/* SYNTAX: SETHOST <host> <password> (non-ircops) + SETHOST <ident> <host> (ircops) */ +static void cmd_sethost(const char *data, IRC_SERVER_REC *server) +{ + GSList *tmp; + + g_return_if_fail(data != NULL); + if (!IS_IRC_SERVER(server) || !server->connected) + cmd_return_error(CMDERR_NOT_CONNECTED); + + /* Save all the joined channels in server to window binds, since + the server will soon /PART + /JOIN us in all channels. */ + for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { + CHANNEL_REC *channel = tmp->data; + + window_bind_add(window_item_window(channel), + server->tag, channel->visible_name); + } + + irc_send_cmdv(server, "SETHOST %s", data); +} + +void fe_irc_commands_init(void) +{ + command_bind_irc_last("me", NULL, (SIGNAL_FUNC) cmd_me); + command_bind_irc_last("action", NULL, (SIGNAL_FUNC) cmd_action); + command_bind_irc("notice", NULL, (SIGNAL_FUNC) cmd_notice); + command_bind_irc("ctcp", NULL, (SIGNAL_FUNC) cmd_ctcp); + command_bind_irc("nctcp", NULL, (SIGNAL_FUNC) cmd_nctcp); + command_bind_irc("wall", NULL, (SIGNAL_FUNC) cmd_wall); + command_bind_irc("ban", NULL, (SIGNAL_FUNC) cmd_ban); + command_bind_irc("ver", NULL, (SIGNAL_FUNC) cmd_ver); + command_bind_irc("topic", NULL, (SIGNAL_FUNC) cmd_topic); + command_bind_irc("ts", NULL, (SIGNAL_FUNC) cmd_ts); + command_bind_irc("oper", NULL, (SIGNAL_FUNC) cmd_oper); + command_bind_irc("sethost", NULL, (SIGNAL_FUNC) cmd_sethost); +} + +void fe_irc_commands_deinit(void) +{ + command_unbind("me", (SIGNAL_FUNC) cmd_me); + command_unbind("action", (SIGNAL_FUNC) cmd_action); + command_unbind("notice", (SIGNAL_FUNC) cmd_notice); + command_unbind("ctcp", (SIGNAL_FUNC) cmd_ctcp); + command_unbind("nctcp", (SIGNAL_FUNC) cmd_nctcp); + command_unbind("wall", (SIGNAL_FUNC) cmd_wall); + command_unbind("ban", (SIGNAL_FUNC) cmd_ban); + command_unbind("ver", (SIGNAL_FUNC) cmd_ver); + command_unbind("topic", (SIGNAL_FUNC) cmd_topic); + command_unbind("ts", (SIGNAL_FUNC) cmd_ts); + command_unbind("oper", (SIGNAL_FUNC) cmd_oper); + command_unbind("sethost", (SIGNAL_FUNC) cmd_sethost); +} diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c new file mode 100644 index 0000000..5d820bb --- /dev/null +++ b/src/fe-common/irc/fe-irc-messages.c @@ -0,0 +1,373 @@ +/* + fe-irc-messages.c : irssi + + Copyright (C) 2001 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/channels.h> +#include <irssi/src/core/ignore.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-channels.h> +#include <irssi/src/irc/core/irc-queries.h> + +#include <irssi/src/fe-common/core/module-formats.h> +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/fe-common/core/printtext.h> +#include <irssi/src/fe-common/core/fe-messages.h> + +#include <irssi/src/fe-common/core/fe-queries.h> +#include <irssi/src/fe-common/core/hilight-text.h> +#include <irssi/src/fe-common/core/window-items.h> +#include <irssi/src/fe-common/irc/fe-irc-channels.h> +#include <irssi/src/fe-common/irc/fe-irc-server.h> + +static void sig_message_own_public(SERVER_REC *server, const char *msg, + const char *target, const char *origtarget) +{ + const char *oldtarget; + char *nickmode; + + if (!IS_IRC_SERVER(server)) + return; + oldtarget = target; + target = fe_channel_skip_prefix(IRC_SERVER(server), target); + if (target != oldtarget) { + /* Hybrid 6 / Bahamut feature, send msg to all + ops / ops+voices in channel */ + nickmode = channel_get_nickmode(channel_find(server, target), + server->nick); + + printformat_module("fe-common/core", server, target, + MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT | + MSGLEVEL_NO_ACT, + TXT_OWN_MSG_CHANNEL, + server->nick, oldtarget, msg, nickmode); + g_free(nickmode); + signal_stop(); + } + +} + +/* received msg to all ops in channel. + TODO: this code is a duplication of sig_message_public */ +static void sig_message_irc_op_public(SERVER_REC *server, const char *msg, + const char *nick, const char *address, + const char *target) +{ + CHANNEL_REC *chanrec; + char *nickmode, *optarget, *prefix, *color, *freemsg = NULL; + const char *cleantarget; + int for_me, level; + HILIGHT_REC *hilight; + TEXT_DEST_REC dest; + + /* only skip here so the difference can be stored in prefix */ + cleantarget = fe_channel_skip_prefix(IRC_SERVER(server), target); + prefix = g_strndup(target, cleantarget - target); + + /* and clean the rest here */ + cleantarget = get_visible_target(IRC_SERVER(server), cleantarget); + + chanrec = channel_find(server, cleantarget); + + nickmode = channel_get_nickmode(chanrec, nick); + + optarget = g_strconcat(prefix, cleantarget, NULL); + + /* Check for hilights */ + for_me = !settings_get_bool("hilight_nick_matches") ? FALSE : + !settings_get_bool("hilight_nick_matches_everywhere") ? + nick_match_msg(chanrec, msg, server->nick) : + nick_match_msg_everywhere(chanrec, msg, server->nick); + hilight = for_me ? NULL : + hilight_match_nick(server, cleantarget, nick, address, MSGLEVEL_PUBLIC, msg); + color = (hilight == NULL) ? NULL : hilight_get_color(hilight); + + level = MSGLEVEL_PUBLIC; + if (for_me) + level |= MSGLEVEL_HILIGHT; + + if (ignore_check_plus(server, nick, address, cleantarget, msg, &level, TRUE)) { + g_free(nickmode); + g_free(color); + g_free(optarget); + g_free(prefix); + return; + } + + if (level & MSGLEVEL_NOHILIGHT) { + for_me = FALSE; + g_free_and_null(color); + level &= ~MSGLEVEL_HILIGHT; + } + + if (settings_get_bool("emphasis")) + msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg); + + if (color != NULL) { + format_create_dest(&dest, server, cleantarget, level, NULL); + dest.address = address; + dest.nick = nick; + hilight_update_text_dest(&dest,hilight); + printformat_module_dest("fe-common/core", &dest, + TXT_PUBMSG_HILIGHT_CHANNEL, + color, nick, optarget, msg, nickmode); + } else { + printformat_module("fe-common/core", server, cleantarget, level, + for_me ? TXT_PUBMSG_ME_CHANNEL : TXT_PUBMSG_CHANNEL, + nick, optarget, msg, nickmode); + } + + g_free(nickmode); + g_free(freemsg); + g_free(color); + g_free(optarget); + g_free(prefix); +} + +static void sig_message_own_wall(SERVER_REC *server, const char *msg, + const char *target) +{ + char *nickmode, *optarget; + + nickmode = channel_get_nickmode(channel_find(server, target), + server->nick); + + /* this is always @, skip_prefix is not needed here */ + optarget = g_strconcat("@", target, NULL); + printformat_module("fe-common/core", server, target, + MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT | + MSGLEVEL_NO_ACT, + TXT_OWN_MSG_CHANNEL, + server->nick, optarget, msg, nickmode); + g_free(nickmode); + g_free(optarget); +} + +static void sig_message_own_action(IRC_SERVER_REC *server, const char *msg, + const char *target) +{ + void *item; + const char *oldtarget; + char *freemsg = NULL; + + oldtarget = target; + target = fe_channel_skip_prefix(IRC_SERVER(server), target); + if (server_ischannel(SERVER(server), target)) + item = channel_find(SERVER(server), target); + else + item = irc_query_find(server, target); + + if (settings_get_bool("emphasis")) + msg = freemsg = expand_emphasis(item, msg); + + printformat(server, target, + MSGLEVEL_ACTIONS | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT | + (server_ischannel(SERVER(server), target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS), + item != NULL && oldtarget == target ? IRCTXT_OWN_ACTION : IRCTXT_OWN_ACTION_TARGET, + server->nick, msg, oldtarget); + g_free_not_null(freemsg); +} + +static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg, + const char *nick, const char *address, + const char *target) +{ + void *item; + const char *oldtarget; + char *freemsg = NULL; + int level; + int own = FALSE; + + oldtarget = target; + target = fe_channel_skip_prefix(IRC_SERVER(server), target); + + level = MSGLEVEL_ACTIONS | + (server_ischannel(SERVER(server), target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS); + + if (ignore_check_plus(SERVER(server), nick, address, target, msg, &level, TRUE)) + return; + + if (server_ischannel(SERVER(server), target)) { + item = channel_find(SERVER(server), target); + } else { + own = (!g_strcmp0(nick, server->nick)); + item = privmsg_get_query(SERVER(server), own ? target : nick, FALSE, level); + } + + if (settings_get_bool("emphasis")) + msg = freemsg = expand_emphasis(item, msg); + + if (server_ischannel(SERVER(server), target)) { + /* channel action */ + if (window_item_is_active(item) && target == oldtarget) { + /* message to active channel in window */ + printformat(server, target, level, + IRCTXT_ACTION_PUBLIC, nick, msg); + } else { + /* message to not existing/active channel, or to @/+ */ + printformat(server, target, level, + IRCTXT_ACTION_PUBLIC_CHANNEL, + nick, oldtarget, msg); + } + } else { + if (own) { + /* own action bounced */ + printformat(server, target, + MSGLEVEL_ACTIONS | MSGLEVEL_MSGS, + item != NULL && oldtarget == target ? IRCTXT_OWN_ACTION : IRCTXT_OWN_ACTION_TARGET, + server->nick, msg, oldtarget); + } else { + /* private action */ + printformat(server, nick, MSGLEVEL_ACTIONS | MSGLEVEL_MSGS, + item == NULL ? IRCTXT_ACTION_PRIVATE : + IRCTXT_ACTION_PRIVATE_QUERY, + nick, address == NULL ? "" : address, msg); + } + } + + g_free_not_null(freemsg); +} + +static char *notice_channel_context(SERVER_REC *server, const char *msg) +{ + if (!settings_get_bool("notice_channel_context")) + return NULL; + + if (*msg == '[') { + char *end, *channel; + end = strpbrk(msg, " ,]"); + if (end != NULL && *end == ']') { + channel = g_strndup(msg + 1, end - msg - 1); + if (server_ischannel(server, channel)) { + return channel; + } + g_free(channel); + } + } + return NULL; +} + +static void sig_message_own_notice(IRC_SERVER_REC *server, const char *msg, const char *target) +{ + char *channel; + /* check if this is a cnotice */ + channel = notice_channel_context((SERVER_REC *) server, msg); + printformat(server, channel != NULL ? channel : fe_channel_skip_prefix(server, target), + MSGLEVEL_NOTICES | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, IRCTXT_OWN_NOTICE, + target, msg); + g_free(channel); +} + +static void sig_message_irc_notice(SERVER_REC *server, const char *msg, + const char *nick, const char *address, + const char *target) +{ + const char *oldtarget; + int level = MSGLEVEL_NOTICES; + + oldtarget = target; + target = fe_channel_skip_prefix(IRC_SERVER(server), target); + + if (address == NULL || *address == '\0') { + level = MSGLEVEL_SNOTES; + /* notice from server */ + if (!ignore_check_plus(server, nick, "", + target, msg, &level, TRUE)) { + printformat(server, target, level, + IRCTXT_NOTICE_SERVER, nick, msg); + } + return; + } + + if (ignore_check_plus(server, nick, address, + server_ischannel(SERVER(server), target) ? target : NULL, + msg, &level, TRUE)) + return; + + if (server_ischannel(SERVER(server), target)) { + /* notice in some channel */ + printformat(server, target, level, + IRCTXT_NOTICE_PUBLIC, nick, oldtarget, msg); + } else { + char *channel; + /* check if this is a cnotice */ + channel = notice_channel_context(server, msg); + + if (channel == NULL) { + /* private notice */ + privmsg_get_query(SERVER(server), nick, FALSE, MSGLEVEL_NOTICES); + } + printformat(server, channel == NULL ? nick : channel, level, IRCTXT_NOTICE_PRIVATE, + nick, address, msg); + + g_free(channel); + } +} + +static void sig_message_own_ctcp(IRC_SERVER_REC *server, const char *cmd, + const char *data, const char *target) +{ + printformat(server, fe_channel_skip_prefix(server, target), MSGLEVEL_CTCPS | + MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, + IRCTXT_OWN_CTCP, target, cmd, data); +} + +static void sig_message_irc_ctcp(IRC_SERVER_REC *server, const char *cmd, + const char *data, const char *nick, + const char *addr, const char *target) +{ + const char *oldtarget; + + oldtarget = target; + target = fe_channel_skip_prefix(server, target); + printformat(server, server_ischannel(SERVER(server), target) ? target : nick, MSGLEVEL_CTCPS, + IRCTXT_CTCP_REQUESTED, nick, addr, cmd, data, oldtarget); +} + +void fe_irc_messages_init(void) +{ + settings_add_bool("misc", "notice_channel_context", TRUE); + + signal_add_last("message own_public", (SIGNAL_FUNC) sig_message_own_public); + signal_add_last("message irc op_public", (SIGNAL_FUNC) sig_message_irc_op_public); + signal_add_last("message irc own_wall", (SIGNAL_FUNC) sig_message_own_wall); + signal_add_last("message irc own_action", (SIGNAL_FUNC) sig_message_own_action); + signal_add_last("message irc action", (SIGNAL_FUNC) sig_message_irc_action); + signal_add_last("message irc own_notice", (SIGNAL_FUNC) sig_message_own_notice); + signal_add_last("message irc notice", (SIGNAL_FUNC) sig_message_irc_notice); + signal_add_last("message irc own_ctcp", (SIGNAL_FUNC) sig_message_own_ctcp); + signal_add_last("message irc ctcp", (SIGNAL_FUNC) sig_message_irc_ctcp); +} + +void fe_irc_messages_deinit(void) +{ + signal_remove("message own_public", (SIGNAL_FUNC) sig_message_own_public); + signal_remove("message irc op_public", (SIGNAL_FUNC) sig_message_irc_op_public); + signal_remove("message irc own_wall", (SIGNAL_FUNC) sig_message_own_wall); + signal_remove("message irc own_action", (SIGNAL_FUNC) sig_message_own_action); + signal_remove("message irc action", (SIGNAL_FUNC) sig_message_irc_action); + signal_remove("message irc own_notice", (SIGNAL_FUNC) sig_message_own_notice); + signal_remove("message irc notice", (SIGNAL_FUNC) sig_message_irc_notice); + signal_remove("message irc own_ctcp", (SIGNAL_FUNC) sig_message_own_ctcp); + signal_remove("message irc ctcp", (SIGNAL_FUNC) sig_message_irc_ctcp); +} diff --git a/src/fe-common/irc/fe-irc-queries.c b/src/fe-common/irc/fe-irc-queries.c new file mode 100644 index 0000000..7a13542 --- /dev/null +++ b/src/fe-common/irc/fe-irc-queries.c @@ -0,0 +1,101 @@ +/* + fe-irc-queries.c : irssi + + Copyright (C) 2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/signals.h> +#include <irssi/src/core/settings.h> +#include <irssi/src/core/servers.h> +#include <irssi/src/core/queries.h> +#include <irssi/src/core/nicklist.h> + +static QUERY_REC *query_find_address(SERVER_REC *server, const char *address) +{ + GSList *tmp; + + g_return_val_if_fail(IS_SERVER(server), NULL); + + for (tmp = server->queries; tmp != NULL; tmp = tmp->next) { + QUERY_REC *rec = tmp->data; + + if (*rec->name != '=' && rec->address != NULL && + g_ascii_strcasecmp(address, rec->address) == 0) + return rec; + } + + return NULL; +} + +static int server_has_nick(SERVER_REC *server, const char *nick) +{ + GSList *tmp; + + for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { + CHANNEL_REC *channel = tmp->data; + + if (nicklist_find(channel, nick) != NULL) + return TRUE; + } + + return FALSE; +} + +static void event_privmsg(SERVER_REC *server, const char *data, + const char *nick, const char *address) +{ + QUERY_REC *query; + + g_return_if_fail(data != NULL); + + if (nick == NULL || address == NULL || server_ischannel(server, data) || + !settings_get_bool("query_track_nick_changes")) + return; + + query = query_find(server, nick); + if (query == NULL) { + /* check if there's query with another nick from the same + address. it was probably a nick change or reconnect to + server, so rename the query. */ + query = query_find_address(server, address); + if (query != NULL) { + /* make sure the old nick doesn't exist anymore */ + if (!server_has_nick(server, query->name)) + query_change_nick(query, nick); + } + } else { + /* process the changes to the query structure now, before the + * privmsg is dispatched. */ + if (g_strcmp0(query->name, nick) != 0) + query_change_nick(query, nick); + if (address != NULL && g_strcmp0(query->address, address) != 0) + query_change_address(query, address); + } +} + +void fe_irc_queries_init(void) +{ + settings_add_bool("lookandfeel", "query_track_nick_changes", TRUE); + + signal_add_first("event privmsg", (SIGNAL_FUNC) event_privmsg); +} + +void fe_irc_queries_deinit(void) +{ + signal_remove("event privmsg", (SIGNAL_FUNC) event_privmsg); +} diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c new file mode 100644 index 0000000..4aad7ee --- /dev/null +++ b/src/fe-common/irc/fe-irc-server.c @@ -0,0 +1,201 @@ +/* + fe-irc-server.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/commands.h> +#include <irssi/src/core/misc.h> + +#include <irssi/src/core/servers-setup.h> + +#include <irssi/src/core/levels.h> +#include <irssi/src/irc/core/irc-chatnets.h> +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-channels.h> +#include <irssi/src/core/servers-reconnect.h> +#include <irssi/src/irc/core/irc-servers-setup.h> + +#include <irssi/src/fe-common/core/fe-windows.h> +#include <irssi/src/fe-common/core/printtext.h> + +const char *get_visible_target(IRC_SERVER_REC *server, const char *target) +{ + IRC_CHANNEL_REC *channel; + + if (*target == '!') { + /* visible_name of !channels is different - don't bother + checking other types for now, they'll just slow up */ + channel = irc_channel_find(server, target); + if (channel != NULL) + return channel->visible_name; + } + + return target; +} + +/* SYNTAX: SERVER ADD|MODIFY [-4 | -6] [-cap | -nocap] [-tls_cert <cert>] [-tls_pkey <pkey>] + [-tls_pass <password>] [-tls_verify] [-tls_cafile <cafile>] + [-tls_capath <capath>] [-tls_ciphers <list>] [-tls | -notls] + [-starttls | -nostarttls | -disallow_starttls | -nodisallow_starttls] + [-auto | -noauto] [-network <network>] [-host <hostname>] + [-cmdspeed <ms>] [-cmdmax <count>] [-port <port>] <address> [<port> + [<password>]] */ +/* NOTE: -network replaces the old -ircnet flag. */ +static void sig_server_add_fill(IRC_SERVER_SETUP_REC *rec, + GHashTable *optlist) +{ + IRC_CHATNET_REC *ircnet; + char *value; + + value = g_hash_table_lookup(optlist, "network"); + /* For backwards compatibility, also allow the old name 'ircnet'. + But of course only if -network was not given. */ + if (!value) + value = g_hash_table_lookup(optlist, "ircnet"); + + if (value != NULL) { + g_free_and_null(rec->chatnet); + if (*value != '\0') { + ircnet = ircnet_find(value); + rec->chatnet = ircnet != NULL ? + g_strdup(ircnet->name) : g_strdup(value); + } + } + + value = g_hash_table_lookup(optlist, "cmdspeed"); + if (value != NULL && *value != '\0') rec->cmd_queue_speed = atoi(value); + value = g_hash_table_lookup(optlist, "cmdmax"); + if (value != NULL && *value != '\0') rec->max_cmds_at_once = atoi(value); + value = g_hash_table_lookup(optlist, "querychans"); + if (value != NULL && *value != '\0') rec->max_query_chans = atoi(value); + if (g_hash_table_lookup(optlist, "nodisallow_starttls") || + g_hash_table_lookup(optlist, "nostarttls")) + rec->starttls = STARTTLS_NOTSET; + if (g_hash_table_lookup(optlist, "disallow_starttls")) + rec->starttls = STARTTLS_DISALLOW; + if (g_hash_table_lookup(optlist, "starttls")) { + rec->starttls = STARTTLS_ENABLED; + rec->use_tls = 0; + } + if (g_hash_table_lookup(optlist, "nocap")) + rec->no_cap = 1; + if (g_hash_table_lookup(optlist, "cap")) + rec->no_cap = 0; +} + +static void sig_server_waiting_info(IRC_SERVER_REC *server, const char *version) +{ + if (!IS_IRC_SERVER(server)) + return; + + printformat(server, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_SERVER_WAITING_CAP_LS, server, + version); +} + +/* SYNTAX: SERVER LIST */ +static void cmd_server_list(const char *data) +{ + GString *str; + GSList *tmp; + + str = g_string_new(NULL); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_SETUPSERVER_HEADER); + for (tmp = setupservers; tmp != NULL; tmp = tmp->next) { + IRC_SERVER_SETUP_REC *rec = tmp->data; + + if (!IS_IRC_SERVER_SETUP(rec)) + continue; + + g_string_truncate(str, 0); + if (rec->password != NULL) + g_string_append(str, "(pass), "); + if (rec->autoconnect) + g_string_append(str, "autoconnect, "); + if (rec->no_proxy) + g_string_append(str, "noproxy, "); + if (rec->no_cap) + g_string_append(str, "nocap, "); + if (rec->starttls == STARTTLS_DISALLOW) + g_string_append(str, "disallow_starttls, "); + if (rec->starttls == STARTTLS_ENABLED) + g_string_append(str, "starttls, "); + if (rec->use_tls) + g_string_append(str, "tls, "); + if (rec->tls_cert) { + g_string_append_printf(str, "tls_cert: %s, ", rec->tls_cert); + if (rec->tls_pkey) + g_string_append_printf(str, "tls_pkey: %s, ", rec->tls_pkey); + if (rec->tls_pass) + g_string_append_printf(str, "(pass), "); + } + if (!rec->tls_verify) + g_string_append(str, "notls_verify, "); + if (rec->tls_cafile) + g_string_append_printf(str, "tls_cafile: %s, ", rec->tls_cafile); + if (rec->tls_capath) + g_string_append_printf(str, "tls_capath: %s, ", rec->tls_capath); + if (rec->tls_ciphers) + g_string_append_printf(str, "tls_ciphers: %s, ", rec->tls_ciphers); + if (rec->tls_pinned_cert) + g_string_append_printf(str, "tls_pinned_cert: %s, ", rec->tls_pinned_cert); + if (rec->tls_pinned_pubkey) + g_string_append_printf(str, "tls_pinned_pubkey: %s, ", + rec->tls_pinned_pubkey); + + if (rec->max_cmds_at_once > 0) + g_string_append_printf(str, "cmdmax: %d, ", rec->max_cmds_at_once); + if (rec->cmd_queue_speed > 0) + g_string_append_printf(str, "cmdspeed: %d, ", rec->cmd_queue_speed); + if (rec->max_query_chans > 0) + g_string_append_printf(str, "querychans: %d, ", rec->max_query_chans); + if (rec->own_host != NULL) + g_string_append_printf(str, "host: %s, ", rec->own_host); + + if (str->len > 1) g_string_truncate(str, str->len-2); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_SETUPSERVER_LINE, + rec->address, rec->port, + rec->chatnet == NULL ? "" : rec->chatnet, + str->str); + } + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_SETUPSERVER_FOOTER); + g_string_free(str, TRUE); +} + +void fe_irc_server_init(void) +{ + signal_add("server add fill", (SIGNAL_FUNC) sig_server_add_fill); + signal_add("server waiting cap ls", (SIGNAL_FUNC) sig_server_waiting_info); + command_bind("server list", NULL, (SIGNAL_FUNC) cmd_server_list); + + command_set_options("server add", + "-ircnet -network -cmdspeed -cmdmax -querychans starttls " + "nostarttls disallow_starttls nodisallow_starttls cap nocap"); + command_set_options("server modify", + "-ircnet -network -cmdspeed -cmdmax -querychans starttls nostarttls " + "disallow_starttls nodisallow_starttls cap nocap"); +} + +void fe_irc_server_deinit(void) +{ + signal_remove("server add fill", (SIGNAL_FUNC) sig_server_add_fill); + signal_remove("server waiting cap ls", (SIGNAL_FUNC) sig_server_waiting_info); + command_unbind("server list", (SIGNAL_FUNC) cmd_server_list); +} diff --git a/src/fe-common/irc/fe-irc-server.h b/src/fe-common/irc/fe-irc-server.h new file mode 100644 index 0000000..28a709e --- /dev/null +++ b/src/fe-common/irc/fe-irc-server.h @@ -0,0 +1,9 @@ +#ifndef IRSSI_FE_COMMON_IRC_FE_IRC_SERVER_H +#define IRSSI_FE_COMMON_IRC_FE_IRC_SERVER_H + +const char *get_visible_target(IRC_SERVER_REC *server, const char *target); + +void fe_irc_server_init(void); +void fe_irc_server_deinit(void); + +#endif diff --git a/src/fe-common/irc/fe-ircnet.c b/src/fe-common/irc/fe-ircnet.c new file mode 100644 index 0000000..3484d92 --- /dev/null +++ b/src/fe-common/irc/fe-ircnet.c @@ -0,0 +1,249 @@ +/* + fe-ircnet.c : irssi + + Copyright (C) 2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/commands.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/chatnets.h> + +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-chatnets.h> +#include <irssi/src/fe-common/core/printtext.h> +#include <irssi/src/core/servers-setup.h> +#include <irssi/src/core/channels-setup.h> + +static void cmd_network_list(void) +{ + GString *str; + GSList *tmp; + + str = g_string_new(NULL); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NETWORK_HEADER); + for (tmp = chatnets; tmp != NULL; tmp = tmp->next) { + IRC_CHATNET_REC *rec = tmp->data; + + if (!IS_IRCNET(rec)) + continue; + + g_string_truncate(str, 0); + if (rec->nick != NULL) + g_string_append_printf(str, "nick: %s, ", rec->nick); + if (rec->alternate_nick != NULL) + g_string_append_printf(str, "alternate_nick: %s, ", rec->alternate_nick); + if (rec->username != NULL) + g_string_append_printf(str, "username: %s, ", rec->username); + if (rec->realname != NULL) + g_string_append_printf(str, "realname: %s, ", rec->realname); + if (rec->own_host != NULL) + g_string_append_printf(str, "host: %s, ", rec->own_host); + if (rec->autosendcmd != NULL) + g_string_append_printf(str, "autosendcmd: %s, ", rec->autosendcmd); + if (rec->usermode != NULL) + g_string_append_printf(str, "usermode: %s, ", rec->usermode); + if (rec->sasl_mechanism != NULL) + g_string_append_printf(str, "sasl_mechanism: %s, ", rec->sasl_mechanism); + if (rec->sasl_username != NULL) + g_string_append_printf(str, "sasl_username: %s, ", rec->sasl_username); + if (rec->sasl_password != NULL) + g_string_append_printf(str, "sasl_password: (pass), "); + if (rec->cmd_queue_speed > 0) + g_string_append_printf(str, "cmdspeed: %d, ", rec->cmd_queue_speed); + if (rec->max_cmds_at_once > 0) + g_string_append_printf(str, "cmdmax: %d, ", rec->max_cmds_at_once); + if (rec->max_query_chans > 0) + g_string_append_printf(str, "querychans: %d, ", rec->max_query_chans); + + if (rec->max_kicks > 0) + g_string_append_printf(str, "max_kicks: %d, ", rec->max_kicks); + if (rec->max_msgs > 0) + g_string_append_printf(str, "max_msgs: %d, ", rec->max_msgs); + if (rec->max_modes > 0) + g_string_append_printf(str, "max_modes: %d, ", rec->max_modes); + if (rec->max_whois > 0) + g_string_append_printf(str, "max_whois: %d, ", rec->max_whois); + + if (str->len > 1) g_string_truncate(str, str->len-2); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, + IRCTXT_NETWORK_LINE, rec->name, str->str); + } + g_string_free(str, TRUE); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NETWORK_FOOTER); +} + +static void cmd_network_add_modify(const char *data, gboolean add) +{ + GHashTable *optlist; + char *name, *value; + void *free_arg; + IRC_CHATNET_REC *rec; + + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS, + "network add", &optlist, &name)) + return; + + if (*name == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + rec = ircnet_find(name); + if (rec == NULL) { + if (add == FALSE) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_NETWORK_NOT_FOUND, name); + cmd_params_free(free_arg); + return; + } + + rec = g_new0(IRC_CHATNET_REC, 1); + rec->name = g_strdup(name); + } else { + if (g_hash_table_lookup(optlist, "nick")) g_free_and_null(rec->nick); + if (g_hash_table_lookup(optlist, "alternate_nick")) g_free_and_null(rec->alternate_nick); + if (g_hash_table_lookup(optlist, "user")) g_free_and_null(rec->username); + if (g_hash_table_lookup(optlist, "realname")) g_free_and_null(rec->realname); + if (g_hash_table_lookup(optlist, "host")) { + g_free_and_null(rec->own_host); + rec->own_ip4 = rec->own_ip6 = NULL; + } + if (g_hash_table_lookup(optlist, "usermode")) g_free_and_null(rec->usermode); + if (g_hash_table_lookup(optlist, "autosendcmd")) g_free_and_null(rec->autosendcmd); + if (g_hash_table_lookup(optlist, "sasl_mechanism")) g_free_and_null(rec->sasl_mechanism); + if (g_hash_table_lookup(optlist, "sasl_username")) g_free_and_null(rec->sasl_username); + if (g_hash_table_lookup(optlist, "sasl_password")) g_free_and_null(rec->sasl_password); + } + + value = g_hash_table_lookup(optlist, "kicks"); + if (value != NULL) rec->max_kicks = atoi(value); + value = g_hash_table_lookup(optlist, "msgs"); + if (value != NULL) rec->max_msgs = atoi(value); + value = g_hash_table_lookup(optlist, "modes"); + if (value != NULL) rec->max_modes = atoi(value); + value = g_hash_table_lookup(optlist, "whois"); + if (value != NULL) rec->max_whois = atoi(value); + + value = g_hash_table_lookup(optlist, "cmdspeed"); + if (value != NULL) rec->cmd_queue_speed = atoi(value); + value = g_hash_table_lookup(optlist, "cmdmax"); + if (value != NULL) rec->max_cmds_at_once = atoi(value); + value = g_hash_table_lookup(optlist, "querychans"); + if (value != NULL) rec->max_query_chans = atoi(value); + + value = g_hash_table_lookup(optlist, "nick"); + if (value != NULL && *value != '\0') rec->nick = g_strdup(value); + value = g_hash_table_lookup(optlist, "alternate_nick"); + if (value != NULL && *value != '\0') rec->alternate_nick = g_strdup(value); + value = g_hash_table_lookup(optlist, "user"); + if (value != NULL && *value != '\0') rec->username = g_strdup(value); + value = g_hash_table_lookup(optlist, "realname"); + if (value != NULL && *value != '\0') rec->realname = g_strdup(value); + + value = g_hash_table_lookup(optlist, "host"); + if (value != NULL && *value != '\0') { + rec->own_host = g_strdup(value); + rec->own_ip4 = rec->own_ip6 = NULL; + } + + value = g_hash_table_lookup(optlist, "usermode"); + if (value != NULL && *value != '\0') rec->usermode = g_strdup(value); + value = g_hash_table_lookup(optlist, "autosendcmd"); + if (value != NULL && *value != '\0') rec->autosendcmd = g_strdup(value); + + /* the validity of the parameters is checked in sig_server_setup_fill_chatnet */ + value = g_hash_table_lookup(optlist, "sasl_mechanism"); + if (value != NULL) rec->sasl_mechanism = *value != '\0' ? g_strdup(value) : NULL; + value = g_hash_table_lookup(optlist, "sasl_username"); + if (value != NULL) rec->sasl_username = *value != '\0' ? g_strdup(value) : NULL; + value = g_hash_table_lookup(optlist, "sasl_password"); + if (value != NULL) rec->sasl_password = *value != '\0' ? g_strdup(value) : NULL; + + ircnet_create(rec); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETWORK_ADDED, name); + + cmd_params_free(free_arg); +} + +/* SYNTAX: NETWORK ADD|MODIFY [-nick <nick>] [-alternate_nick <nick>] [-user <user>] [-realname <name>] + [-host <host>] [-usermode <mode>] [-autosendcmd <cmd>] + [-querychans <count>] [-whois <count>] [-msgs <count>] + [-kicks <count>] [-modes <count>] [-cmdspeed <ms>] + [-cmdmax <count>] [-sasl_mechanism <mechanism>] + [-sasl_username <username>] [-sasl_password <password>] + <name> */ +static void cmd_network_add(const char *data) +{ + cmd_network_add_modify(data, TRUE); +} + +static void cmd_network_modify(const char *data) +{ + cmd_network_add_modify(data, FALSE); +} + +/* SYNTAX: NETWORK REMOVE <network> */ +static void cmd_network_remove(const char *data) +{ + IRC_CHATNET_REC *rec; + + if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); + + rec = ircnet_find(data); + if (rec == NULL) + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETWORK_NOT_FOUND, data); + else { + server_setup_remove_chatnet(data); + channel_setup_remove_chatnet(data); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETWORK_REMOVED, data); + chatnet_remove(CHATNET(rec)); + } +} + +static void cmd_network(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + if (*data == '\0') + cmd_network_list(); + else + command_runsub("network", data, server, item); +} + +void fe_ircnet_init(void) +{ + command_bind("ircnet", NULL, (SIGNAL_FUNC) cmd_network); + command_bind("network", NULL, (SIGNAL_FUNC) cmd_network); + command_bind("network list", NULL, (SIGNAL_FUNC) cmd_network_list); + command_bind("network add", NULL, (SIGNAL_FUNC) cmd_network_add); + command_bind("network modify", NULL, (SIGNAL_FUNC) cmd_network_modify); + command_bind("network remove", NULL, (SIGNAL_FUNC) cmd_network_remove); + + command_set_options("network add", "-kicks -msgs -modes -whois -cmdspeed " + "-cmdmax -nick -alternate_nick -user -realname -host -autosendcmd -querychans -usermode -sasl_mechanism -sasl_username -sasl_password"); + command_set_options("network modify", "-kicks -msgs -modes -whois -cmdspeed " + "-cmdmax -nick -alternate_nick -user -realname -host -autosendcmd -querychans -usermode -sasl_mechanism -sasl_username -sasl_password"); +} + +void fe_ircnet_deinit(void) +{ + command_unbind("ircnet", (SIGNAL_FUNC) cmd_network); + command_unbind("network", (SIGNAL_FUNC) cmd_network); + command_unbind("network list", (SIGNAL_FUNC) cmd_network_list); + command_unbind("network add", (SIGNAL_FUNC) cmd_network_add); + command_unbind("network modify", (SIGNAL_FUNC) cmd_network_modify); + command_unbind("network remove", (SIGNAL_FUNC) cmd_network_remove); +} diff --git a/src/fe-common/irc/fe-modes.c b/src/fe-common/irc/fe-modes.c new file mode 100644 index 0000000..623fca0 --- /dev/null +++ b/src/fe-common/irc/fe-modes.c @@ -0,0 +1,236 @@ +/* + fe-modes.c : irssi + + Copyright (C) 2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-channels.h> +#include <irssi/src/irc/core/modes.h> +#include <irssi/src/core/ignore.h> + +#include <irssi/src/fe-common/core/printtext.h> + +#define MODE_WAIT_TIME 3 /* how many seconds to wait for identical modes */ + +typedef struct { + IRC_CHANNEL_REC *channel; + int level; + char *mode; + GSList *nicks; + time_t last_mode; +} MODE_REC; + +static int mode_tag, group_multi_mode; +static GSList *modes; + +static MODE_REC *mode_find_channel(IRC_CHANNEL_REC *channel) +{ + GSList *tmp; + + g_return_val_if_fail(channel != NULL, NULL); + + for (tmp = modes; tmp != NULL; tmp = tmp->next) { + MODE_REC *rec = tmp->data; + + if (rec->channel == channel) + return rec; + } + + return NULL; +} + +static void mode_destroy(MODE_REC *mode) +{ + g_return_if_fail(mode != NULL); + + modes = g_slist_remove(modes, mode); + g_slist_foreach(mode->nicks, (GFunc) g_free, NULL); + g_slist_free(mode->nicks); + g_free(mode->mode); + g_free(mode); +} + +static void print_mode(MODE_REC *rec) +{ + GSList *tmp; + char *nicks; + + if (g_slist_find(channels, rec->channel) == NULL) { + /* channel was destroyed while we were waiting.. */ + return; + } + + tmp = modes; modes = NULL; + + nicks = i_slist_to_string(rec->nicks, ", "); + printformat(rec->channel->server, rec->channel->visible_name, rec->level, + IRCTXT_CHANMODE_CHANGE, rec->channel->visible_name, rec->mode, nicks, ""); + g_free(nicks); + + modes = tmp; +} + +/* something is going to be printed to screen, print our current netsplit + message before it. */ +static void sig_print_starting(void) +{ + while (modes != NULL) { + print_mode(modes->data); + mode_destroy(modes->data); + } + + signal_remove("print starting", sig_print_starting); +} + +static int sig_check_modes(void) +{ + GSList *tmp, *next; + + if (modes == NULL) + return 1; + + for (tmp = modes; tmp != NULL; tmp = next) { + MODE_REC *rec = tmp->data; + + next = tmp->next; + if (time(NULL)-rec->last_mode >= MODE_WAIT_TIME) { + print_mode(rec); + mode_destroy(rec); + } + } + + if (modes == NULL) + signal_remove("print starting", (SIGNAL_FUNC) sig_print_starting); + return 1; +} + +static void msg_multi_mode(IRC_CHANNEL_REC *channel, int level, const char *sender, + const char *addr, const char *mode) +{ + MODE_REC *rec; + + if (modes == NULL) + signal_add("print starting", (SIGNAL_FUNC) sig_print_starting); + + rec = mode_find_channel(channel); + if (rec != NULL && g_strcmp0(rec->mode, mode) != 0) { + /* different mode than last time, show and remove the old */ + print_mode(rec); + mode_destroy(rec); + rec = NULL; + } + + if (rec == NULL) { + /* no previous mode, create new */ + rec = g_new0(MODE_REC, 1); + modes = g_slist_append(modes, rec); + + rec->level = level; + rec->channel = channel; + rec->mode = g_strdup(mode); + } + /* the levels (everything below MSGLEVEL_ALL) are combined (|) + whereas the flags (anything above) must all match (&) */ + rec->level = ((rec->level | level) & MSGLEVEL_ALL) | (rec->level & level); + rec->nicks = g_slist_append(rec->nicks, g_strdup(sender)); + rec->last_mode = time(NULL); + + signal_stop(); +} + +/* FIXME: should be moved to fe-irc-messages.c.. */ +static void sig_message_mode(IRC_SERVER_REC *server, const char *channel, + const char *nick, const char *addr, + const char *mode) +{ + int level = MSGLEVEL_MODES; + + if (nick == NULL) nick = server->real_address; + + if (ignore_check_plus(SERVER(server), nick, addr, channel, + mode, &level, TRUE)) + return; + + if (!server_ischannel(SERVER(server), channel)) { + /* user mode change */ + printformat(server, NULL, level, + IRCTXT_USERMODE_CHANGE, mode, channel); + } else if (addr == NULL) { + /* channel mode changed by server */ + printformat(server, channel, level, + IRCTXT_SERVER_CHANMODE_CHANGE, + channel, mode, nick); + } else { + /* channel mode changed by normal user */ + IRC_CHANNEL_REC *chanrec; + + chanrec = !group_multi_mode ? NULL : + irc_channel_find(server, channel); + + if (chanrec != NULL && g_ascii_strcasecmp(nick, server->nick) != 0) + msg_multi_mode(chanrec, level, nick, addr, mode); + else { + printformat(server, channel, level, + IRCTXT_CHANMODE_CHANGE, + channel, mode, nick, addr); + } + } +} + +static void read_settings(void) +{ + int old_group; + + old_group = group_multi_mode; + group_multi_mode = settings_get_bool("group_multi_mode"); + + if (old_group && !group_multi_mode) { + g_source_remove(mode_tag); + mode_tag = -1; + } else if (!old_group && group_multi_mode) { + mode_tag = g_timeout_add(1000, (GSourceFunc) sig_check_modes, NULL); + } +} + +void fe_modes_init(void) +{ + settings_add_bool("misc", "group_multi_mode", TRUE); + mode_tag = -1; + + read_settings(); + signal_add("message irc mode", (SIGNAL_FUNC) sig_message_mode); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); +} + +void fe_modes_deinit(void) +{ + if (mode_tag != -1) + g_source_remove(mode_tag); + + signal_remove("message irc mode", (SIGNAL_FUNC) sig_message_mode); + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); + + signal_remove("print starting", (SIGNAL_FUNC) sig_print_starting); +} diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c new file mode 100644 index 0000000..ea41f7f --- /dev/null +++ b/src/fe-common/irc/fe-netjoin.c @@ -0,0 +1,515 @@ +/* + fe-netjoin.c : irssi + + Copyright (C) 2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/modes.h> +#include <irssi/src/core/ignore.h> +#include <irssi/src/irc/core/netsplit.h> + +#include <irssi/src/fe-common/core/printtext.h> + +#define NETJOIN_WAIT_TIME 5 /* how many seconds to wait for the netsplitted JOIN messages to stop */ +#define NETJOIN_MAX_WAIT 30 /* how many seconds to wait for nick to join to the rest of the channels she was before the netsplit */ + +typedef struct { + char *nick; + GSList *old_channels; + GSList *now_channels; +} NETJOIN_REC; + +typedef struct { + IRC_SERVER_REC *server; + time_t last_netjoin; + + GSList *netjoins; +} NETJOIN_SERVER_REC; + +typedef struct { + int count; + GString *nicks; +} TEMP_PRINT_REC; + +static int join_tag; +static int netjoin_max_nicks, hide_netsplit_quits; +static int printing_joins; +static GSList *joinservers; + +static NETJOIN_SERVER_REC *netjoin_find_server(IRC_SERVER_REC *server) +{ + GSList *tmp; + + g_return_val_if_fail(server != NULL, NULL); + + for (tmp = joinservers; tmp != NULL; tmp = tmp->next) { + NETJOIN_SERVER_REC *rec = tmp->data; + + if (rec->server == server) + return rec; + } + + return NULL; +} + +static NETJOIN_REC *netjoin_add(IRC_SERVER_REC *server, const char *nick, + GSList *channels) +{ + NETJOIN_REC *rec; + NETJOIN_SERVER_REC *srec; + + g_return_val_if_fail(server != NULL, NULL); + g_return_val_if_fail(nick != NULL, NULL); + + rec = g_new0(NETJOIN_REC, 1); + rec->nick = g_strdup(nick); + while (channels != NULL) { + NETSPLIT_CHAN_REC *channel = channels->data; + + rec->old_channels = g_slist_append(rec->old_channels, + g_strdup(channel->name)); + channels = channels->next; + } + + srec = netjoin_find_server(server); + if (srec == NULL) { + srec = g_new0(NETJOIN_SERVER_REC, 1); + srec->server = server; + joinservers = g_slist_append(joinservers, srec); + } + + srec->last_netjoin = time(NULL); + srec->netjoins = g_slist_append(srec->netjoins, rec); + return rec; +} + +static NETJOIN_REC *netjoin_find(IRC_SERVER_REC *server, const char *nick) +{ + NETJOIN_SERVER_REC *srec; + GSList *tmp; + + g_return_val_if_fail(server != NULL, NULL); + g_return_val_if_fail(nick != NULL, NULL); + + srec = netjoin_find_server(server); + if (srec == NULL) return NULL; + + for (tmp = srec->netjoins; tmp != NULL; tmp = tmp->next) { + NETJOIN_REC *rec = tmp->data; + + if (g_ascii_strcasecmp(rec->nick, nick) == 0) + return rec; + } + + return NULL; +} + +static void netjoin_remove(NETJOIN_SERVER_REC *server, NETJOIN_REC *rec) +{ + server->netjoins = g_slist_remove(server->netjoins, rec); + + g_slist_foreach(rec->old_channels, (GFunc) g_free, NULL); + g_slist_foreach(rec->now_channels, (GFunc) g_free, NULL); + g_slist_free(rec->old_channels); + g_slist_free(rec->now_channels); + + g_free(rec->nick); + g_free(rec); +} + +static void netjoin_server_remove(NETJOIN_SERVER_REC *server) +{ + joinservers = g_slist_remove(joinservers, server); + + while (server->netjoins != NULL) + netjoin_remove(server, server->netjoins->data); + g_free(server); +} + +static void print_channel_netjoins(char *channel, TEMP_PRINT_REC *rec, + NETJOIN_SERVER_REC *server) +{ + if (rec->nicks->len > 0) + g_string_truncate(rec->nicks, rec->nicks->len-2); + + printformat(server->server, channel, MSGLEVEL_JOINS, + rec->count > netjoin_max_nicks ? + IRCTXT_NETSPLIT_JOIN_MORE : IRCTXT_NETSPLIT_JOIN, + rec->nicks->str, rec->count-netjoin_max_nicks); + + g_string_free(rec->nicks, TRUE); + g_free(rec); + g_free(channel); +} + +static void print_netjoins(NETJOIN_SERVER_REC *server, const char *filter_channel) +{ + TEMP_PRINT_REC *temp; + GHashTable *channels; + GSList *tmp, *tmp2, *next, *next2, *old; + + g_return_if_fail(server != NULL); + + printing_joins = TRUE; + + /* save nicks to string, clear now_channels and remove the same + channels from old_channels list */ + channels = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); + for (tmp = server->netjoins; tmp != NULL; tmp = next) { + NETJOIN_REC *rec = tmp->data; + + next = g_slist_next(tmp); + + for (tmp2 = rec->now_channels; tmp2 != NULL; tmp2 = next2) { + char *channel = tmp2->data; + char *realchannel = channel + 1; + + next2 = g_slist_next(tmp2); + + /* Filter the results by channel if asked to do so */ + if (filter_channel != NULL && + strcasecmp(realchannel, filter_channel) != 0) + continue; + + temp = g_hash_table_lookup(channels, realchannel); + if (temp == NULL) { + temp = g_new0(TEMP_PRINT_REC, 1); + temp->nicks = g_string_new(NULL); + g_hash_table_insert(channels, + g_strdup(realchannel), + temp); + } + + temp->count++; + if (temp->count <= netjoin_max_nicks) { + if (*channel != ' ') + g_string_append_c(temp->nicks, + *channel); + g_string_append_printf(temp->nicks, "%s, ", + rec->nick); + } + + /* remove the channel from old_channels too */ + old = i_slist_find_icase_string(rec->old_channels, realchannel); + if (old != NULL) { + void *data = old->data; + rec->old_channels = + g_slist_remove(rec->old_channels, data); + g_free(data); + } + + /* drop tmp2 from the list */ + rec->now_channels = g_slist_delete_link(rec->now_channels, tmp2); + g_free(channel); + } + + if (rec->old_channels == NULL) + netjoin_remove(server, rec); + } + + g_hash_table_foreach(channels, (GHFunc) print_channel_netjoins, + server); + g_hash_table_destroy(channels); + + if (server->netjoins == NULL) + netjoin_server_remove(server); + + printing_joins = FALSE; +} + +/* something is going to be printed to screen, print our current netsplit + message before it. */ +static void sig_print_starting(TEXT_DEST_REC *dest) +{ + NETJOIN_SERVER_REC *rec; + + if (printing_joins) + return; + + if (!IS_IRC_SERVER(dest->server)) + return; + + rec = netjoin_find_server(IRC_SERVER(dest->server)); + if (rec != NULL && rec->netjoins != NULL) { + /* if netjoins exists, the server rec should be + still valid. otherwise, calling server->ischannel + may not be safe. */ + if (dest->target != NULL && + !server_ischannel((SERVER_REC *) rec->server, dest->target)) + return; + + print_netjoins(rec, NULL); + } +} + +static int sig_check_netjoins(void) +{ + GSList *tmp, *next; + int diff; + time_t now; + + now = time(NULL); + /* first print all netjoins which haven't had any new joins + * for NETJOIN_WAIT_TIME; this may cause them to be removed + * (all users who rejoined, rejoined all channels) */ + for (tmp = joinservers; tmp != NULL; tmp = next) { + NETJOIN_SERVER_REC *server = tmp->data; + + next = tmp->next; + diff = now-server->last_netjoin; + if (diff <= NETJOIN_WAIT_TIME) { + /* wait for more JOINs */ + continue; + } + + if (server->netjoins != NULL) + print_netjoins(server, NULL); + } + + /* now remove all netjoins which haven't had any new joins + * for NETJOIN_MAX_WAIT (user rejoined some but not all channels + * after split) */ + for (tmp = joinservers; tmp != NULL; tmp = next) { + NETJOIN_SERVER_REC *server = tmp->data; + + next = tmp->next; + diff = now-server->last_netjoin; + if (diff >= NETJOIN_MAX_WAIT) { + /* waited long enough, forget about the rest */ + netjoin_server_remove(server); + } + } + + if (joinservers == NULL) { + g_source_remove(join_tag); + signal_remove("print starting", (SIGNAL_FUNC) sig_print_starting); + join_tag = -1; + } + return 1; +} + +static void msg_quit(IRC_SERVER_REC *server, const char *nick, + const char *address, const char *reason) +{ + if (IS_IRC_SERVER(server) && quitmsg_is_split(reason)) + signal_stop(); +} + +static void msg_join(IRC_SERVER_REC *server, const char *channel, + const char *nick, const char *address) +{ + NETSPLIT_REC *split; + NETJOIN_REC *netjoin; + GSList *channels; + int rejoin = 1; + + if (!IS_IRC_SERVER(server)) + return; + + if (ignore_check(SERVER(server), nick, address, + channel, NULL, MSGLEVEL_JOINS)) + return; + + split = netsplit_find(server, nick, address); + netjoin = netjoin_find(server, nick); + if (split == NULL && netjoin == NULL) + return; + + /* if this was not a channel they split from, treat it normally */ + if (netjoin != NULL) { + if (!i_slist_find_icase_string(netjoin->old_channels, channel)) + return; + } else { + channels = split->channels; + while (channels != NULL) { + NETSPLIT_CHAN_REC *schannel = channels->data; + + if (!strcasecmp(schannel->name, channel)) + break; + channels = channels->next; + } + /* we still need to create a NETJOIN_REC now as the + * NETSPLIT_REC will be destroyed */ + if (channels == NULL) + rejoin = 0; + } + + if (join_tag == -1) { + join_tag = g_timeout_add(1000, (GSourceFunc) + sig_check_netjoins, NULL); + signal_add("print starting", (SIGNAL_FUNC) sig_print_starting); + } + + if (netjoin == NULL) + netjoin = netjoin_add(server, nick, split->channels); + + if (rejoin) + { + netjoin->now_channels = g_slist_append(netjoin->now_channels, + g_strconcat(" ", channel, NULL)); + signal_stop(); + } +} + +static int netjoin_set_nickmode(IRC_SERVER_REC *server, NETJOIN_REC *rec, + const char *channel, char prefix) +{ + GSList *pos; + const char *flags; + char *found_chan = NULL; + + for (pos = rec->now_channels; pos != NULL; pos = pos->next) { + char *chan = pos->data; + if (strcasecmp(chan+1, channel) == 0) { + found_chan = chan; + break; + } + } + + if (found_chan == NULL) + return FALSE; + + flags = server->get_nick_flags(SERVER(server)); + while (*flags != '\0') { + if (found_chan[0] == *flags) + break; + if (prefix == *flags) { + found_chan[0] = prefix; + break; + } + flags++; + } + return TRUE; +} + +static void msg_mode(IRC_SERVER_REC *server, const char *channel, + const char *sender, const char *addr, const char *data) +{ + NETJOIN_REC *rec; + char *params, *mode, *nicks; + char **nicklist, **nick, type, prefix; + int show; + + g_return_if_fail(data != NULL); + if (!server_ischannel(SERVER(server), channel) || addr != NULL) + return; + + params = event_get_params(data, 2 | PARAM_FLAG_GETREST, + &mode, &nicks); + + /* parse server mode changes - hide operator status changes and + show them in the netjoin message instead as @ before the nick */ + nick = nicklist = g_strsplit(nicks, " ", -1); + + type = '+'; show = FALSE; + for (; *mode != '\0'; mode++) { + if (*mode == '+' || *mode == '-') { + type = *mode; + continue; + } + + if (*nick != NULL && GET_MODE_PREFIX(server, *mode)) { + /* give/remove ops */ + rec = netjoin_find(server, *nick); + prefix = GET_MODE_PREFIX(server, *mode); + if (rec == NULL || type != '+' || prefix == '\0' || + !netjoin_set_nickmode(server, rec, channel, prefix)) + show = TRUE; + nick++; + } else { + if (HAS_MODE_ARG(server, type, *mode) && *nick != NULL) + nick++; + show = TRUE; + } + } + + if (!show) signal_stop(); + + g_strfreev(nicklist); + g_free(params); +} + +static void read_settings(void) +{ + int old_hide; + + old_hide = hide_netsplit_quits; + hide_netsplit_quits = settings_get_bool("hide_netsplit_quits"); + netjoin_max_nicks = settings_get_int("netjoin_max_nicks"); + + if (old_hide && !hide_netsplit_quits) { + signal_remove("message quit", (SIGNAL_FUNC) msg_quit); + signal_remove("message join", (SIGNAL_FUNC) msg_join); + signal_remove("message irc mode", (SIGNAL_FUNC) msg_mode); + } else if (!old_hide && hide_netsplit_quits) { + signal_add("message quit", (SIGNAL_FUNC) msg_quit); + signal_add("message join", (SIGNAL_FUNC) msg_join); + signal_add("message irc mode", (SIGNAL_FUNC) msg_mode); + } +} + +static void sig_server_disconnected(IRC_SERVER_REC *server) +{ + NETJOIN_SERVER_REC *netjoin_server; + + g_return_if_fail(server != NULL); + + if (!IS_IRC_SERVER(server)) + return; + + if ((netjoin_server = netjoin_find_server(server))) { + netjoin_server_remove(netjoin_server); + } +} + +void fe_netjoin_init(void) +{ + settings_add_bool("misc", "hide_netsplit_quits", TRUE); + settings_add_int("misc", "netjoin_max_nicks", 10); + + join_tag = -1; + printing_joins = FALSE; + + read_settings(); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); + signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); +} + +void fe_netjoin_deinit(void) +{ + while (joinservers != NULL) + netjoin_server_remove(joinservers->data); + if (join_tag != -1) { + g_source_remove(join_tag); + signal_remove("print starting", (SIGNAL_FUNC) sig_print_starting); + } + + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); + signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); + + signal_remove("message quit", (SIGNAL_FUNC) msg_quit); + signal_remove("message join", (SIGNAL_FUNC) msg_join); + signal_remove("message irc mode", (SIGNAL_FUNC) msg_mode); +} diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c new file mode 100644 index 0000000..b76d4ce --- /dev/null +++ b/src/fe-common/irc/fe-netsplit.c @@ -0,0 +1,389 @@ +/* + fe-netsplit.c : irssi + + Copyright (C) 2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-commands.h> +#include <irssi/src/core/ignore.h> +#include <irssi/src/irc/core/netsplit.h> + +#include <irssi/src/fe-common/core/printtext.h> + +#define SPLIT_WAIT_TIME 5 /* how many seconds to wait for the QUIT split messages to stop */ + +static int split_tag; +static int netsplit_max_nicks, netsplit_nicks_hide_threshold; +static int printing_splits; + +static int get_last_split(IRC_SERVER_REC *server) +{ + GSList *tmp; + time_t last; + + last = 0; + for (tmp = server->split_servers; tmp != NULL; tmp = tmp->next) { + NETSPLIT_SERVER_REC *rec = tmp->data; + + if (rec->last > last) last = rec->last; + } + + return last; +} + +typedef struct { + char *name; + int nick_count, maxnickpos; + GString *nicks; +} TEMP_SPLIT_CHAN_REC; + +typedef struct { + IRC_SERVER_REC *server_rec; + GSList *servers; /* if many servers splitted from the same one */ + GSList *channels; +} TEMP_SPLIT_REC; + +static GSList *get_source_servers(const char *server, GSList **servers) +{ + GSList *list, *next, *tmp; + + list = NULL; + for (tmp = *servers; tmp != NULL; tmp = next) { + NETSPLIT_SERVER_REC *rec = tmp->data; + next = tmp->next; + + if (g_ascii_strcasecmp(rec->server, server) == 0) { + rec->prints = 0; + list = g_slist_append(list, rec); + *servers = g_slist_remove(*servers, rec); + } + } + + return list; +} + +static TEMP_SPLIT_CHAN_REC *find_split_chan(TEMP_SPLIT_REC *rec, + const char *name) +{ + GSList *tmp; + + for (tmp = rec->channels; tmp != NULL; tmp = tmp->next) { + TEMP_SPLIT_CHAN_REC *chanrec = tmp->data; + + if (g_ascii_strcasecmp(chanrec->name, name) == 0) + return chanrec; + } + + return NULL; +} + +static void get_server_splits(void *key, NETSPLIT_REC *split, + TEMP_SPLIT_REC *rec) +{ + TEMP_SPLIT_CHAN_REC *chanrec; + GSList *tmp; + + if (split->printed || + g_slist_find(rec->servers, split->server) == NULL) + return; + + split->printed = TRUE; + for (tmp = split->channels; tmp != NULL; tmp = tmp->next) { + NETSPLIT_CHAN_REC *splitchan = tmp->data; + + if (ignore_check(SERVER(rec->server_rec), split->nick, + split->address, splitchan->name, "", + MSGLEVEL_QUITS)) + continue; + + chanrec = find_split_chan(rec, splitchan->name); + if (chanrec == NULL) { + chanrec = g_new0(TEMP_SPLIT_CHAN_REC, 1); + chanrec->name = splitchan->name; + chanrec->nicks = g_string_new(NULL); + + rec->channels = g_slist_append(rec->channels, chanrec); + } + + split->server->prints++; + chanrec->nick_count++; + if (netsplit_nicks_hide_threshold <= 0 || + chanrec->nick_count <= netsplit_nicks_hide_threshold) { + if (splitchan->op) + g_string_append_c(chanrec->nicks, '@'); + else if (splitchan->voice) + g_string_append_c(chanrec->nicks, '+'); + g_string_append_printf(chanrec->nicks, "%s, ", split->nick); + + if (chanrec->nick_count == netsplit_max_nicks) + chanrec->maxnickpos = chanrec->nicks->len; + } + } +} + +static void print_server_splits(IRC_SERVER_REC *server, TEMP_SPLIT_REC *rec, const char *filter_channel) +{ + GString *destservers; + char *sourceserver; + GSList *tmp; + + g_return_if_fail(rec->servers != NULL); + + destservers = g_string_new(NULL); + for (tmp = rec->servers; tmp != NULL; tmp = tmp->next) { + NETSPLIT_SERVER_REC *rec = tmp->data; + + if (rec->prints > 0) { + g_string_append_printf(destservers, "%s, ", + rec->destserver); + } + } + if (destservers->len == 0) { + /* no nicks to print in this server */ + g_string_free(destservers, TRUE); + return; + } + g_string_truncate(destservers, destservers->len-2); + + sourceserver = ((NETSPLIT_SERVER_REC *) (rec->servers->data))->server; + for (tmp = rec->channels; tmp != NULL; tmp = tmp->next) { + TEMP_SPLIT_CHAN_REC *chan = tmp->data; + + if (filter_channel != NULL && + strcasecmp(chan->name, filter_channel) != 0) + continue; + + g_string_truncate(chan->nicks, chan->nicks->len-2); + + if (netsplit_max_nicks > 0 && + chan->nick_count > netsplit_max_nicks) { + g_string_truncate(chan->nicks, chan->maxnickpos); + printformat(server, chan->name, MSGLEVEL_QUITS, + IRCTXT_NETSPLIT_MORE, sourceserver, + destservers->str, chan->nicks->str, + chan->nick_count - netsplit_max_nicks); + } else { + printformat(server, chan->name, MSGLEVEL_QUITS, + IRCTXT_NETSPLIT, sourceserver, + destservers->str, chan->nicks->str); + } + } + + g_string_free(destservers, TRUE); +} + +static void temp_split_chan_free(TEMP_SPLIT_CHAN_REC *rec) +{ + g_string_free(rec->nicks, TRUE); + g_free(rec); +} + +static void print_splits(IRC_SERVER_REC *server, const char *filter_channel) +{ + TEMP_SPLIT_REC temp; + GSList *servers; + + printing_splits = TRUE; + + servers = g_slist_copy(server->split_servers); + while (servers != NULL) { + NETSPLIT_SERVER_REC *sserver = servers->data; + + /* get all the splitted servers that have the same + source server */ + temp.servers = get_source_servers(sserver->server, &servers); + temp.server_rec = server; + temp.channels = NULL; + + g_hash_table_foreach(server->splits, + (GHFunc) get_server_splits, &temp); + print_server_splits(server, &temp, filter_channel); + + g_slist_foreach(temp.channels, + (GFunc) temp_split_chan_free, NULL); + g_slist_free(temp.servers); + g_slist_free(temp.channels); + } + + printing_splits = FALSE; +} + +static int check_server_splits(IRC_SERVER_REC *server) +{ + time_t last; + + g_return_val_if_fail(IS_IRC_SERVER(server), FALSE); + + last = get_last_split(server); + if (time(NULL)-last < SPLIT_WAIT_TIME) + return FALSE; + + print_splits(server, NULL); + return TRUE; +} + +/* something is going to be printed to screen, print our current netsplit + message before it. */ +static void sig_print_starting(TEXT_DEST_REC *dest) +{ + IRC_SERVER_REC *rec; + + if (printing_splits) + return; + + if (!IS_IRC_SERVER(dest->server)) + return; + + rec = IRC_SERVER(dest->server); + if (rec->split_servers != NULL) { + /* if split_servers exists, the server rec should be + still valid. otherwise, calling server->ischannel + may not be safe. */ + if (dest->target != NULL && !server_ischannel((SERVER_REC *) rec, dest->target)) + return; + + print_splits(rec, NULL); + } +} + +static int sig_check_splits(void) +{ + GSList *tmp; + int stop; + + stop = TRUE; + for (tmp = servers; tmp != NULL; tmp = tmp->next) { + IRC_SERVER_REC *rec = tmp->data; + + if (!IS_IRC_SERVER(rec)) + continue; + + if (rec->split_servers != NULL) { + if (!check_server_splits(rec)) + stop = FALSE; + } + } + + if (stop) { + g_source_remove(split_tag); + signal_remove("print starting", (SIGNAL_FUNC) sig_print_starting); + split_tag = -1; + } + return 1; +} + +static void sig_netsplit_servers(void) +{ + if (settings_get_bool("hide_netsplit_quits") && split_tag == -1) { + split_tag = g_timeout_add(1000, + (GSourceFunc) sig_check_splits, + NULL); + signal_add("print starting", (SIGNAL_FUNC) sig_print_starting); + } +} + +static int split_equal(NETSPLIT_REC *n1, NETSPLIT_REC *n2) +{ + return g_ascii_strcasecmp(n1->nick, n2->nick); +} + +static void split_get(void *key, NETSPLIT_REC *rec, GSList **list) +{ + *list = g_slist_insert_sorted(*list, rec, + (GCompareFunc) split_equal); +} + +static void split_print(NETSPLIT_REC *rec, SERVER_REC *server) +{ + NETSPLIT_CHAN_REC *chan; + char *chanstr; + + chan = rec->channels->data; + chanstr = chan == NULL ? + g_strdup("") : + g_strconcat(chan->op ? "@" : (chan->voice ? "+" : ""), chan->name, NULL); + + printformat(server, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NETSPLITS_LINE, + rec->nick, chanstr, rec->server->server, + rec->server->destserver); + + g_free(chanstr); +} + +/* SYNTAX: NETSPLIT */ +static void cmd_netsplit(const char *data, IRC_SERVER_REC *server) +{ + GSList *list; + + CMD_IRC_SERVER(server); + + if (server->split_servers == NULL) { + printformat(server, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_NO_NETSPLITS); + return; + } + + printformat(server, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NETSPLITS_HEADER); + + list = NULL; + g_hash_table_foreach(server->splits, (GHFunc) split_get, &list); + g_slist_foreach(list, (GFunc) split_print, server); + g_slist_free(list); + + printformat(server, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NETSPLITS_FOOTER); +} + +static void read_settings(void) +{ + netsplit_max_nicks = settings_get_int("netsplit_max_nicks"); + netsplit_nicks_hide_threshold = + settings_get_int("netsplit_nicks_hide_threshold"); + if (netsplit_nicks_hide_threshold < netsplit_max_nicks) + netsplit_max_nicks = netsplit_nicks_hide_threshold; +} + +void fe_netsplit_init(void) +{ + settings_add_int("misc", "netsplit_max_nicks", 10); + settings_add_int("misc", "netsplit_nicks_hide_threshold", 15); + split_tag = -1; + printing_splits = FALSE; + + read_settings(); + signal_add("netsplit new", (SIGNAL_FUNC) sig_netsplit_servers); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); + command_bind_irc("netsplit", NULL, (SIGNAL_FUNC) cmd_netsplit); +} + +void fe_netsplit_deinit(void) +{ + if (split_tag != -1) { + g_source_remove(split_tag); + signal_remove("print starting", (SIGNAL_FUNC) sig_print_starting); + } + + signal_remove("netsplit new", (SIGNAL_FUNC) sig_netsplit_servers); + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); + command_unbind("netsplit", (SIGNAL_FUNC) cmd_netsplit); +} diff --git a/src/fe-common/irc/fe-sasl.c b/src/fe-common/irc/fe-sasl.c new file mode 100644 index 0000000..72fec58 --- /dev/null +++ b/src/fe-common/irc/fe-sasl.c @@ -0,0 +1,53 @@ +/* + fe-sasl.c : irssi + + Copyright (C) 2015-2017 The Lemon Man + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/irc/core/sasl.h> + +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/fe-common/core/printtext.h> + +static void sig_sasl_success(IRC_SERVER_REC *server) +{ + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_SASL_SUCCESS); +} + +static void sig_sasl_failure(IRC_SERVER_REC *server, const char *reason) +{ + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_SASL_ERROR, reason); +} + +void fe_sasl_init(void) +{ + signal_add("server sasl success", (SIGNAL_FUNC) sig_sasl_success); + signal_add("server sasl failure", (SIGNAL_FUNC) sig_sasl_failure); +} + +void fe_sasl_deinit(void) +{ + signal_remove("server sasl success", (SIGNAL_FUNC) sig_sasl_success); + signal_remove("server sasl failure", (SIGNAL_FUNC) sig_sasl_failure); +} diff --git a/src/fe-common/irc/fe-whois.c b/src/fe-common/irc/fe-whois.c new file mode 100644 index 0000000..b0eeb19 --- /dev/null +++ b/src/fe-common/irc/fe-whois.c @@ -0,0 +1,456 @@ +/* Copyright (C) 1999-2004 Timo Sirainen */ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/settings.h> +#include <irssi/src/core/recode.h> + +#include <irssi/src/irc/core/irc-servers.h> + +#include <irssi/src/fe-common/core/printtext.h> + +static void event_whois(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *user, *host, *realname, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 6, NULL, &nick, &user, + &host, NULL, &realname); + recoded = recode_in(SERVER(server), realname, nick); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS, nick, user, host, recoded); + g_free(params); + g_free(recoded); +} + +static void event_whois_special(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *str; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3 | PARAM_FLAG_GETREST, NULL, &nick, &str); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_SPECIAL, nick, str); + g_free(params); +} + +static void event_whois_idle(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *secstr, *signonstr, *rest, *timestr; + long days, hours, mins, secs; + time_t signon; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 5 | PARAM_FLAG_GETREST, NULL, + &nick, &secstr, &signonstr, &rest); + + secs = atol(secstr); + signon = strstr(rest, "signon time") == NULL ? 0 : + (time_t) atol(signonstr); + + days = secs/3600/24; + hours = (secs%(3600*24))/3600; + mins = (secs%3600)/60; + secs %= 60; + + if (signon == 0) + printformat(server, nick, MSGLEVEL_CRAP, IRCTXT_WHOIS_IDLE, + nick, days, hours, mins, secs); + else { + timestr = my_asctime(signon); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_IDLE_SIGNON, + nick, days, hours, mins, secs, timestr); + g_free(timestr); + } + g_free(params); +} + +static void event_whois_server(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *whoserver, *desc; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 4, NULL, &nick, &whoserver, &desc); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_SERVER, nick, whoserver, desc); + g_free(params); +} + +static void event_whois_oper(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *type; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &type); + + /* Bugfix: http://bugs.irssi.org/?do=details&task_id=99 + * Author: Geert Hauwaerts <geert@irssi.org> + * Date: Wed Sep 15 20:17:24 CEST 2004 + */ + + if ((!strncmp(type, "is an ", 6)) || (!strncmp(type, "is a ", 5))) { + type += 5; + if (*type == ' ') type++; + } + + if (*type == '\0') + type = "IRC Operator"; + + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_OPER, nick, type); + g_free(params); +} + +static void event_whois_modes(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *modes; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3 | PARAM_FLAG_GETREST, + NULL, &nick, &modes); + if (!strncmp(modes, "is using modes ", 15)) + modes += 15; + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_MODES, nick, modes); + g_free(params); +} + +static void event_whois_realhost(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *txt_real, *txt_hostname, *hostname; + + g_return_if_fail(data != NULL); + + /* <yournick> real hostname <nick> <hostname> */ + params = event_get_params(data, 5, NULL, &nick, &txt_real, + &txt_hostname, &hostname); + if (g_strcmp0(txt_real, "real") != 0 || + g_strcmp0(txt_hostname, "hostname") != 0) { + /* <yournick> <nick> :... from <hostname> */ + g_free(params); + params = event_get_params(data, 3, NULL, &nick, &hostname); + + hostname = strstr(hostname, "from "); + if (hostname != NULL) hostname += 5; + } + + if (hostname != NULL) { + if (!strncmp(hostname, "*@", 2)) + hostname += 2; + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_REALHOST, nick, hostname, ""); + } else { + event_whois_special(server, data); + } + g_free(params); +} + +static void event_whois_usermode326(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *usermode; + + g_return_if_fail(data != NULL); + + /* <yournick> <nick> :has oper privs: <mode> */ + params = event_get_params(data, 3, NULL, &nick, &usermode); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_USERMODE, nick, usermode); + g_free(params); +} + +static void event_whois_realhost327(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *hostname, *ip, *text; + + g_return_if_fail(data != NULL); + + /* <yournick> <hostname> <ip> :Real hostname/IP */ + params = event_get_params(data, 5, NULL, &nick, &hostname, &ip, &text); + if (*text != '\0') { + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_REALHOST, nick, hostname, ip); + } else { + event_whois_special(server, data); + } + g_free(params); +} + +static void event_whois_realhost338(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *arg1, *arg2, *arg3; + + g_return_if_fail(data != NULL); + + /* + * :<server> 338 <yournick> <nick> <user>@<host> <ip> :Actual user@host, actual IP + * (ircu) or + * :<server> 338 <yournick> <nick> <ip> :actually using host + * (ratbox) + */ + params = event_get_params(data, 5, NULL, &nick, &arg1, &arg2, &arg3); + if (*arg3 != '\0') { + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_REALHOST, nick, arg1, arg2); + } else if (*arg2 != '\0') { + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_REALHOST, nick, arg1, ""); + } else { + event_whois_special(server, data); + } + g_free(params); +} + +static void event_whois_usermode(IRC_SERVER_REC *server, const char *data) +{ + char *params, *txt_usermodes, *nick, *usermode; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 4, NULL, &txt_usermodes, + &nick, &usermode); + + if (g_strcmp0(txt_usermodes, "usermodes") == 0) { + /* <yournick> usermodes <nick> usermode */ + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_USERMODE, nick, usermode); + } else { + event_whois_special(server, data); + } + g_free(params); +} + +static void hide_safe_channel_id(IRC_SERVER_REC *server, char *chans) +{ + const char *idchan, *nick_flags; + char *p, *dest, *end, id; + int count, length, chanstart; + + if (!server->isupport_sent) + idchan = "!:5"; + else { + idchan = g_hash_table_lookup(server->isupport, "IDCHAN"); + if (idchan == NULL) + return; + } + nick_flags = server->get_nick_flags(SERVER(server)); + + while (*idchan != '\0') { + id = *idchan; + if (idchan[1] != ':') + return; + + length = strtoul(idchan+2, &end, 10); + if (*end == ',') + end++; + else if (*end != '\0') + return; + idchan = end; + + count = 0; + chanstart = TRUE; + for (dest = p = chans; *p != '\0'; p++) { + if (count > 0) + count--; + else { + if (*p == ' ') + chanstart = TRUE; + else { + if (chanstart && *p == id) + count = length; + chanstart = chanstart && strchr(nick_flags, *p); + } + *dest++ = *p; + } + } + *dest = '\0'; + } +} + +static void event_whois_channels(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *chans, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &chans); + + /* sure - we COULD print the channel names as-is, but since the + colors, bolds, etc. are mostly just to fool people, I think we + should show the channel names as they REALLY are so they could + even be joined without any extra tricks. */ + chans = show_lowascii(chans); + if (settings_get_bool("whois_hide_safe_channel_id")) + hide_safe_channel_id(server, chans); + recoded = recode_in(SERVER(server), chans, nick); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_CHANNELS, nick, recoded); + g_free(chans); + + g_free(params); + g_free(recoded); +} + +static void event_whois_away(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *awaymsg, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &awaymsg); + recoded = recode_in(SERVER(server), awaymsg, nick); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_AWAY, nick, recoded); + g_free(params); + g_free(recoded); +} + +static void event_end_of_whois(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &nick); + if (server->whois_found) { + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_END_OF_WHOIS, nick); + } + g_free(params); +} + +static void event_whois_auth(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *text; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &text); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_EXTRA, nick, text); + g_free(params); +} + +static void event_whowas(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *user, *host, *realname, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 6, NULL, &nick, &user, + &host, NULL, &realname); + recoded = recode_in(SERVER(server), realname, nick); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOWAS, nick, user, host, recoded); + g_free(params); + g_free(recoded); +} + +static void event_end_of_whowas(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &nick); + if (server->whowas_found) { + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_END_OF_WHOWAS, nick); + } + g_free(params); +} + +struct whois_event_table { + int num; + void (*func)(IRC_SERVER_REC *, const char *); +}; + +static struct whois_event_table events[] = { + { 312, event_whois_server }, + { 326, event_whois_usermode326 }, + { 327, event_whois_realhost327 }, + { 338, event_whois_realhost338 }, + { 379, event_whois_modes }, + { 378, event_whois_realhost }, + { 377, event_whois_usermode }, + { 317, event_whois_idle }, + { 330, event_whois_auth }, + { 319, event_whois_channels }, + { 0, NULL } +}; + +static void event_whois_default(IRC_SERVER_REC *server, const char *data) +{ + int i, num; + + num = atoi(current_server_event); + for (i = 0; events[i].num != 0; i++) { + if (events[i].num == num) { + events[i].func(server, data); + return; + } + } + + event_whois_special(server, data); +} + +void fe_whois_init(void) +{ + settings_add_bool("lookandfeel", "whois_hide_safe_channel_id", TRUE); + + signal_add("event 311", (SIGNAL_FUNC) event_whois); + signal_add("event 312", (SIGNAL_FUNC) event_whois_server); + /* readding this events fixes the printing of /whois -yes * + Bug http://bugs.irssi.org/?do=details&task_id=123 */ + signal_add("event 317", (SIGNAL_FUNC) event_whois_idle); + signal_add("event 319", (SIGNAL_FUNC) event_whois_channels); + signal_add("event 313", (SIGNAL_FUNC) event_whois_oper); + signal_add("event 330", (SIGNAL_FUNC) event_whois_auth); + signal_add("whois account", (SIGNAL_FUNC) event_whois_auth); + signal_add("event 377", (SIGNAL_FUNC) event_whois_usermode); + signal_add("event 378", (SIGNAL_FUNC) event_whois_realhost); + signal_add("event 379", (SIGNAL_FUNC) event_whois_modes); + signal_add("event 327", (SIGNAL_FUNC) event_whois_realhost327); + signal_add("event 326", (SIGNAL_FUNC) event_whois_usermode326); + signal_add("event 338", (SIGNAL_FUNC) event_whois_realhost338); + signal_add("whois away", (SIGNAL_FUNC) event_whois_away); + signal_add("whois oper", (SIGNAL_FUNC) event_whois_oper); + signal_add("whowas away", (SIGNAL_FUNC) event_whois_away); + signal_add("whois default event", (SIGNAL_FUNC) event_whois_default); + signal_add("event 318", (SIGNAL_FUNC) event_end_of_whois); + signal_add("event 314", (SIGNAL_FUNC) event_whowas); + signal_add("event 369", (SIGNAL_FUNC) event_end_of_whowas); +} + +void fe_whois_deinit(void) +{ + signal_remove("event 311", (SIGNAL_FUNC) event_whois); + signal_remove("event 312", (SIGNAL_FUNC) event_whois_server); + signal_remove("event 317", (SIGNAL_FUNC) event_whois_idle); + signal_remove("event 319", (SIGNAL_FUNC) event_whois_channels); + signal_remove("event 313", (SIGNAL_FUNC) event_whois_oper); + signal_remove("event 330", (SIGNAL_FUNC) event_whois_auth); + signal_remove("whois account", (SIGNAL_FUNC) event_whois_auth); + signal_remove("event 377", (SIGNAL_FUNC) event_whois_usermode); + signal_remove("event 378", (SIGNAL_FUNC) event_whois_realhost); + signal_remove("event 379", (SIGNAL_FUNC) event_whois_modes); + signal_remove("event 327", (SIGNAL_FUNC) event_whois_realhost327); + signal_remove("event 326", (SIGNAL_FUNC) event_whois_usermode326); + signal_remove("event 338", (SIGNAL_FUNC) event_whois_realhost338); + signal_remove("whois away", (SIGNAL_FUNC) event_whois_away); + signal_remove("whois oper", (SIGNAL_FUNC) event_whois_oper); + signal_remove("whowas away", (SIGNAL_FUNC) event_whois_away); + signal_remove("whois default event", (SIGNAL_FUNC) event_whois_default); + signal_remove("event 318", (SIGNAL_FUNC) event_end_of_whois); + signal_remove("event 314", (SIGNAL_FUNC) event_whowas); + signal_remove("event 369", (SIGNAL_FUNC) event_end_of_whowas); +} diff --git a/src/fe-common/irc/irc-completion.c b/src/fe-common/irc/irc-completion.c new file mode 100644 index 0000000..71e2e0c --- /dev/null +++ b/src/fe-common/irc/irc-completion.c @@ -0,0 +1,41 @@ +/* + irc-completion.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/signals.h> +#include <irssi/src/fe-common/core/chat-completion.h> + +static void sig_complete_stats(GList **list, WINDOW_REC *window, + const char *word, const char *line, + int *want_space) +{ + *list = completion_get_servers(word); + if (*list != NULL) signal_stop(); +} + +void irc_completion_init(void) +{ + signal_add("complete command stats", (SIGNAL_FUNC) sig_complete_stats); +} + +void irc_completion_deinit(void) +{ + signal_remove("complete command stats", (SIGNAL_FUNC) sig_complete_stats); +} diff --git a/src/fe-common/irc/irc-modules.c b/src/fe-common/irc/irc-modules.c new file mode 100644 index 0000000..3bf1f32 --- /dev/null +++ b/src/fe-common/irc/irc-modules.c @@ -0,0 +1,4 @@ +void fe_irc_dcc_init(void);void fe_irc_notifylist_init(void); +void fe_irc_notifylist_deinit(void);void fe_irc_dcc_deinit(void); +void fe_irc_modules_init(void) { fe_irc_dcc_init(); fe_irc_notifylist_init(); } +void fe_irc_modules_deinit(void) { fe_irc_notifylist_deinit(); fe_irc_dcc_deinit(); } diff --git a/src/fe-common/irc/meson.build b/src/fe-common/irc/meson.build new file mode 100644 index 0000000..1789133 --- /dev/null +++ b/src/fe-common/irc/meson.build @@ -0,0 +1,44 @@ +# this file is part of irssi + +libfe_common_irc_a = static_library('fe_common_irc', + files( + 'fe-cap.c', + 'fe-common-irc.c', + 'fe-ctcp.c', + 'fe-events-numeric.c', + 'fe-events.c', + 'fe-irc-channels.c', + 'fe-irc-commands.c', + 'fe-irc-messages.c', + 'fe-irc-queries.c', + 'fe-irc-server.c', + 'fe-ircnet.c', + 'fe-modes.c', + 'fe-netjoin.c', + 'fe-netsplit.c', + 'fe-sasl.c', + 'fe-whois.c', + 'irc-completion.c', + 'module-formats.c', + + 'irc-modules.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + c_args : [ + def_helpdir, + def_themesdir, + ], + dependencies : dep) + +install_headers( + files( + 'fe-irc-channels.h', + 'fe-irc-server.h', + 'module-formats.h', + 'module.h', + ), + subdir : incdir / 'src' / 'fe-common' / 'irc') + +subdir('dcc') +subdir('notifylist') diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c new file mode 100644 index 0000000..0adb268 --- /dev/null +++ b/src/fe-common/irc/module-formats.c @@ -0,0 +1,184 @@ +/* + module-formats.c : irssi + + Copyright (C) 2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/core/formats.h> + +/* clang-format off */ +FORMAT_REC fecommon_irc_formats[] = { + { MODULE_NAME, "IRC", 0 }, + + /* ---- */ + { NULL, "Server", 0 }, + + { "netsplit", "{netsplit Netsplit} {server $0} <-> {server $1} quits: $2", 3, { 0, 0, 0 } }, + { "netsplit_more", "{netsplit Netsplit} {server $0} <-> {server $1} quits: $2 (+$3 more, use /NETSPLIT to show all of them)", 4, { 0, 0, 0, 1 } }, + { "netsplit_join", "{netjoin Netsplit} over, joins: $0", 1, { 0 } }, + { "netsplit_join_more", "{netjoin Netsplit} over, joins: $0 (+$1 more)", 2, { 0, 1 } }, + { "no_netsplits", "There are no net splits", 0 }, + { "netsplits_header", "%#Nick Channel Server Split server", 0 }, + { "netsplits_line", "%#$[9]0 $[10]1 $[20]2 $3", 4, { 0, 0, 0, 0 } }, + { "netsplits_footer", "", 0 }, + { "network_added", "Network $0 saved", 1, { 0 } }, + { "network_removed", "Network $0 removed", 1, { 0 } }, + { "network_not_found", "Network $0 not found", 1, { 0 } }, + { "network_header", "%#Networks:", 0 }, + { "network_line", "%#$0: $1", 2, { 0, 0 } }, + { "network_footer", "", 0 }, + { "setupserver_header", "%#Server Port Network Settings", 0 }, + { "setupserver_line", "%#%|$[!20]0 $[5]1 $[10]2 $3", 4, { 0, 1, 0, 0 } }, + { "setupserver_footer", "", 0 }, + { "server_waiting_cap_ls", "Waiting for CAP LS response...", 2, { 0, 0 } }, + { "sasl_success", "SASL authentication succeeded", 0 }, + { "sasl_error", "Cannot authenticate via SASL ($0)", 1, { 0 } }, + { "cap_req", "Capabilities requested: $0", 1, { 0 } }, + { "cap_ls", "Capabilities supported: $0", 1, { 0 } }, + { "cap_ack", "Capabilities acknowledged: $0", 1, { 0 } }, + { "cap_nak", "Capabilities refused: $0", 1, { 0 } }, + { "cap_list", "Capabilities currently enabled: $0", 1, { 0 } }, + { "cap_new", "Capabilities now available: $0", 1, { 0 } }, + { "cap_del", "Capabilities removed: $0", 1, { 0 } }, + + /* ---- */ + { NULL, "Channels", 0 }, + + { "joinerror_toomany", "Cannot join to channel {channel $0} (You have joined to too many channels)", 1, { 0 } }, + { "joinerror_full", "Cannot join to channel {channel $0} (Channel is full)", 1, { 0 } }, + { "joinerror_invite", "Cannot join to channel {channel $0} (You must be invited)", 1, { 0 } }, + { "joinerror_banned", "Cannot join to channel {channel $0} (You are banned)", 1, { 0 } }, + { "joinerror_bad_key", "Cannot join to channel {channel $0} (Bad channel key)", 1, { 0 } }, + { "joinerror_bad_mask", "Cannot join to channel {channel $0} (Bad channel mask)", 1, { 0 } }, + { "joinerror_secure_only", "Cannot join to channel {channel $0} (Secure clients only)", 1, { 0 } }, + { "joinerror_unavail", "Cannot join to channel {channel $0} (Channel is temporarily unavailable)", 1, { 0 } }, + { "joinerror_duplicate", "Channel {channel $0} already exists - cannot create it", 1, { 0 } }, + { "channel_rejoin", "Channel {channel $0} is temporarily unavailable, this is normally because of netsplits. Irssi will now automatically try to rejoin back to this channel until the join is successful. Use /RMREJOINS command if you wish to abort this.", 1, { 0 } }, + { "inviting", "Inviting {nick $0} to {channel $1}", 2, { 0, 0 } }, + { "channel_created", "Channel {channelhilight $0} created $1", 2, { 0, 0 } }, + { "url", "Home page for {channelhilight $0}: $1", 2, { 0, 0 } }, + { "topic", "Topic for {channelhilight $0}: $1", 2, { 0, 0 } }, + { "no_topic", "No topic set for {channelhilight $0}", 1, { 0 } }, + { "topic_info", "Topic set by {nick $0} {nickhost $2} {comment $1}", 3, { 0, 0, 0 } }, + { "chanmode_change", "mode/{channelhilight $0} {mode $1} by {nick $2}", 4, { 0, 0, 0, 0 } }, + { "server_chanmode_change", "{netsplit ServerMode}/{channelhilight $0} {mode $1} by {nick $2}", 3, { 0, 0, 0 } }, + { "channel_mode", "mode/{channelhilight $0} {mode $1}", 2, { 0, 0 } }, + { "bantype", "Ban type changed to {channel $0}", 1, { 0 } }, + { "no_bans", "No bans in channel {channel $0}", 1, { 0 } }, + { "banlist", "$0 - {channel $1}: ban {ban $2}", 3, { 1, 0, 0 } }, + { "banlist_long", "$0 - {channel $1}: ban {ban $2} {comment by {nick $3}, $4 secs ago}", 5, { 1, 0, 0, 0, 1 } }, + { "ebanlist", "{channel $0}: ban exception {ban $1}", 2, { 0, 0 } }, + { "ebanlist_long", "{channel $0}: ban exception {ban $1} {comment by {nick $2}, $3 secs ago}", 4, { 0, 0, 0, 1 } }, + { "no_invitelist", "Invite list is empty in channel {channel $0}", 1, { 0 } }, + { "invitelist", "{channel $0}: invite {ban $1}", 2, { 0, 0 } }, + { "invitelist_long", "{channel $0}: invite {ban $1} {comment by {nick $2}, $3 secs ago}", 4, { 0, 0, 0, 1 } }, + { "no_such_channel", "{channel $0}: No such channel", 1, { 0 } }, + { "channel_synced", "Join to {channel $0} was synced in {hilight $1} secs", 2, { 0, 2 } }, + { "server_help_start", "$1", 2, { 0, 0 } }, + { "server_help_txt", "$1", 2, { 0, 0 } }, + { "server_end_of_help", "$1", 2, { 0, 0 } }, + + /* ---- */ + { NULL, "Nick", 0 }, + + { "usermode_change", "Mode change {mode $0} for user {nick $1}", 2, { 0, 0 } }, + { "user_mode", "Your user mode is {mode $0}", 1, { 0 } }, + { "away", "You have been marked as being away", 0 }, + { "unaway", "You are no longer marked as being away", 0 }, + { "nick_away", "{nick $0} is away: $1", 2, { 0, 0 } }, + { "no_such_nick", "{nick $0}: No such nick/channel", 1, { 0 } }, + { "nick_in_use", "Nick {nick $0} is already in use", 1, { 0 } }, + { "nick_unavailable", "Nick {nick $0} is temporarily unavailable", 1, { 0 } }, + { "your_nick_owned", "Your nick is in use by {nick $3} {comment $1@$2}", 4, { 0, 0, 0, 0 } }, + + /* ---- */ + { NULL, "Who queries", 0 }, + + { "whois", "{nick $0} {nickhost $1@$2}%:{whois ircname $3}", 4, { 0, 0, 0, 0 } }, + { "whowas", "{nick $0} {nickhost $1@$2}%:{whois was $3}", 4, { 0, 0, 0, 0 } }, + { "whois_idle", "{whois idle %|$1 days $2 hours $3 mins $4 secs}", 5, { 0, 1, 1, 1, 1 } }, + { "whois_idle_signon", "{whois idle %|$1 days $2 hours $3 mins $4 secs {comment signon: $5}}", 6, { 0, 1, 1, 1, 1, 0 } }, + { "whois_server", "{whois server %|$1 {comment $2}}", 3, { 0, 0, 0 } }, + { "whois_oper", "{whois {hilight $1}}", 2, { 0, 0 } }, + { "whois_modes", "{whois modes $1}", 2, { 0, 0 } }, + { "whois_realhost", "{whois hostname $1-}", 3, { 0, 0, 0 } }, + { "whois_usermode", "{whois usermode $1}", 2, { 0, 0 } }, + { "whois_channels", "{whois channels %|$1}", 2, { 0, 0 } }, + { "whois_away", "{whois away %|$1}", 2, { 0, 0 } }, + { "whois_special", "{whois %|$1}", 2, { 0, 0 } }, + { "whois_extra", "{whois account %|$1}", 2, { 0, 0 } }, + { "end_of_whois", "End of WHOIS", 1, { 0 } }, + { "end_of_whowas", "End of WHOWAS", 1, { 0 } }, + { "whois_not_found", "There is no such nick $0", 1, { 0 } }, + { "who", "%#{channelhilight $[-10]0} %|{nick $[!9]1} $[!3]2 $[!2]3 $4@$5 {comment {hilight $6}}", 8, { 0, 0, 0, 0, 0, 0, 0, 0 } }, + { "end_of_who", "End of /WHO list", 1, { 0 } }, + + /* ---- */ + { NULL, "Your messages", 0 }, + + { "own_notice", "{ownnotice notice $0}$1", 2, { 0, 0 } }, + { "own_action", "{ownaction $0}$1", 3, { 0, 0, 0 } }, + { "own_action_target", "{ownaction_target $0 $2}$1", 3, { 0, 0, 0 } }, + { "own_ctcp", "{ownctcp ctcp $0}$1 $2", 3, { 0, 0, 0 } }, + + /* ---- */ + { NULL, "Received messages", 0 }, + + { "notice_server", "{servernotice $0}$1", 2, { 0, 0 } }, + { "notice_public", "{notice $0{pubnotice_channel $1}}$2", 3, { 0, 0, 0 } }, + { "notice_private", "{notice $0{pvtnotice_host $1}}$2", 3, { 0, 0, 0 } }, + { "action_private", "{pvtaction $0}$2", 3, { 0, 0, 0 } }, + { "action_private_query", "{pvtaction_query $0}$2", 3, { 0, 0, 0 } }, + { "action_public", "{pubaction $0}$1", 2, { 0, 0 } }, + { "action_public_channel", "{pubaction $0{msgchannel $1}}$2", 3, { 0, 0, 0 } }, + + /* ---- */ + { NULL, "CTCPs", 0 }, + + { "ctcp_reply", "CTCP {hilight $0} reply from {nick $1}: $2", 3, { 0, 0, 0 } }, + { "ctcp_reply_channel", "CTCP {hilight $0} reply from {nick $1} in channel {channel $3}: $2", 4, { 0, 0, 0, 0 } }, + { "ctcp_ping_reply", "CTCP {hilight PING} reply from {nick $0}: $1.$[-3.0]2 seconds", 3, { 0, 2, 2 } }, + { "ctcp_requested", "{ctcp {hilight $0} {comment $1} requested CTCP {hilight $2} from {nick $4}}: $3", 5, { 0, 0, 0, 0, 0 } }, + { "ctcp_requested_unknown", "{ctcp {hilight $0} {comment $1} requested unknown CTCP {hilight $2} from {nick $4}}: $3", 5, { 0, 0, 0, 0, 0 } }, + + /* ---- */ + { NULL, "Other server events", 0 }, + + { "online", "Users online: {hilight $0}", 1, { 0 } }, + { "pong", "PONG received from $0: $1", 2, { 0, 0 } }, + { "wallops", "{wallop WALLOP {wallop_nick $0}} $1", 2, { 0, 0 } }, + { "action_wallops", "{wallop WALLOP {wallop_action $0}} $1", 2, { 0, 0 } }, + { "kill", "You were {error killed} by {nick $0} {nickhost $1} {reason $2} {comment Path: $3}", 4, { 0, 0, 0, 0 } }, + { "kill_server", "You were {error killed} by {server $0} {reason $1} {comment Path: $2}", 3, { 0, 0, 0 } }, + { "error", "{error ERROR} $0", 1, { 0 } }, + { "unknown_mode", "Unknown mode character $0", 1, { 0 } }, + { "default_event", "$1", 3, { 0, 0, 0 } }, + { "default_event_server", "[$0] $1", 3, { 0, 0, 0 } }, + + /* ---- */ + { NULL, "Misc", 0 }, + + { "silenced", "Silenced {nick $0}", 1, { 0 } }, + { "unsilenced", "Unsilenced {nick $0}", 1, { 0 } }, + { "silence_line", "{nick $0}: silence {ban $1}", 2, { 0, 0 } }, + { "ask_oper_pass", "Operator password:", 0 }, + { "accept_list", "Accepted users: {hilight $0}", 1, { 0 } }, + + { NULL, NULL, 0 } +}; +/* clang-format on */ diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h new file mode 100644 index 0000000..a9d29cb --- /dev/null +++ b/src/fe-common/irc/module-formats.h @@ -0,0 +1,154 @@ +#include <irssi/src/fe-common/core/formats.h> + +/* clang-format off */ +enum { + IRCTXT_MODULE_NAME, + + IRCTXT_FILL_1, + + IRCTXT_NETSPLIT, + IRCTXT_NETSPLIT_MORE, + IRCTXT_NETSPLIT_JOIN, + IRCTXT_NETSPLIT_JOIN_MORE, + IRCTXT_NO_NETSPLITS, + IRCTXT_NETSPLITS_HEADER, + IRCTXT_NETSPLITS_LINE, + IRCTXT_NETSPLITS_FOOTER, + IRCTXT_NETWORK_ADDED, + IRCTXT_NETWORK_REMOVED, + IRCTXT_NETWORK_NOT_FOUND, + IRCTXT_NETWORK_HEADER, + IRCTXT_NETWORK_LINE, + IRCTXT_NETWORK_FOOTER, + IRCTXT_SETUPSERVER_HEADER, + IRCTXT_SETUPSERVER_LINE, + IRCTXT_SETUPSERVER_FOOTER, + IRCTXT_SERVER_WAITING_CAP_LS, + IRCTXT_SASL_SUCCESS, + IRCTXT_SASL_ERROR, + IRCTXT_CAP_REQ, + IRCTXT_CAP_LS, + IRCTXT_CAP_ACK, + IRCTXT_CAP_NAK, + IRCTXT_CAP_LIST, + IRCTXT_CAP_NEW, + IRCTXT_CAP_DEL, + + IRCTXT_FILL_2, + + IRCTXT_JOINERROR_TOOMANY, + IRCTXT_JOINERROR_FULL, + IRCTXT_JOINERROR_INVITE, + IRCTXT_JOINERROR_BANNED, + IRCTXT_JOINERROR_BAD_KEY, + IRCTXT_JOINERROR_BAD_MASK, + IRCTXT_JOINERROR_SECURE_ONLY, + IRCTXT_JOINERROR_UNAVAIL, + IRCTXT_JOINERROR_DUPLICATE, + IRCTXT_CHANNEL_REJOIN, + IRCTXT_INVITING, + IRCTXT_CHANNEL_CREATED, + IRCTXT_CHANNEL_URL, + IRCTXT_TOPIC, + IRCTXT_NO_TOPIC, + IRCTXT_TOPIC_INFO, + IRCTXT_CHANMODE_CHANGE, + IRCTXT_SERVER_CHANMODE_CHANGE, + IRCTXT_CHANNEL_MODE, + IRCTXT_BANTYPE, + IRCTXT_NO_BANS, + IRCTXT_BANLIST, + IRCTXT_BANLIST_LONG, + IRCTXT_EBANLIST, + IRCTXT_EBANLIST_LONG, + IRCTXT_NO_INVITELIST, + IRCTXT_INVITELIST, + IRCTXT_INVITELIST_LONG, + IRCTXT_NO_SUCH_CHANNEL, + IRCTXT_CHANNEL_SYNCED, + IRCTXT_SERVER_HELP_START, + IRCTXT_SERVER_HELP_TXT, + IRCTXT_SERVER_END_OF_HELP, + + IRCTXT_FILL_4, + + IRCTXT_USERMODE_CHANGE, + IRCTXT_USER_MODE, + IRCTXT_AWAY, + IRCTXT_UNAWAY, + IRCTXT_NICK_AWAY, + IRCTXT_NO_SUCH_NICK, + IRCTXT_NICK_IN_USE, + IRCTXT_NICK_UNAVAILABLE, + IRCTXT_YOUR_NICK_OWNED, + + IRCTXT_FILL_5, + + IRCTXT_WHOIS, + IRCTXT_WHOWAS, + IRCTXT_WHOIS_IDLE, + IRCTXT_WHOIS_IDLE_SIGNON, + IRCTXT_WHOIS_SERVER, + IRCTXT_WHOIS_OPER, + IRCTXT_WHOIS_MODES, + IRCTXT_WHOIS_REALHOST, + IRCTXT_WHOIS_USERMODE, + IRCTXT_WHOIS_CHANNELS, + IRCTXT_WHOIS_AWAY, + IRCTXT_WHOIS_SPECIAL, + IRCTXT_WHOIS_EXTRA, + IRCTXT_END_OF_WHOIS, + IRCTXT_END_OF_WHOWAS, + IRCTXT_WHOIS_NOT_FOUND, + IRCTXT_WHO, + IRCTXT_END_OF_WHO, + + IRCTXT_FILL_6, + + IRCTXT_OWN_NOTICE, + IRCTXT_OWN_ACTION, + IRCTXT_OWN_ACTION_TARGET, + IRCTXT_OWN_CTCP, + + IRCTXT_FILL_7, + + IRCTXT_NOTICE_SERVER, + IRCTXT_NOTICE_PUBLIC, + IRCTXT_NOTICE_PRIVATE, + IRCTXT_ACTION_PRIVATE, + IRCTXT_ACTION_PRIVATE_QUERY, + IRCTXT_ACTION_PUBLIC, + IRCTXT_ACTION_PUBLIC_CHANNEL, + + IRCTXT_FILL_8, + + IRCTXT_CTCP_REPLY, + IRCTXT_CTCP_REPLY_CHANNEL, + IRCTXT_CTCP_PING_REPLY, + IRCTXT_CTCP_REQUESTED, + IRCTXT_CTCP_REQUESTED_UNKNOWN, + + IRCTXT_FILL_10, + + IRCTXT_ONLINE, + IRCTXT_PONG, + IRCTXT_WALLOPS, + IRCTXT_ACTION_WALLOPS, + IRCTXT_KILL, + IRCTXT_KILL_SERVER, + IRCTXT_ERROR, + IRCTXT_UNKNOWN_MODE, + IRCTXT_DEFAULT_EVENT, + IRCTXT_DEFAULT_EVENT_SERVER, + + IRCTXT_FILL_11, + + IRCTXT_SILENCED, + IRCTXT_UNSILENCED, + IRCTXT_SILENCE_LINE, + IRCTXT_ASK_OPER_PASS, + IRCTXT_ACCEPT_LIST +}; +/* clang-format on */ + +extern FORMAT_REC fecommon_irc_formats[]; diff --git a/src/fe-common/irc/module.h b/src/fe-common/irc/module.h new file mode 100644 index 0000000..ad63c95 --- /dev/null +++ b/src/fe-common/irc/module.h @@ -0,0 +1,4 @@ +#include <irssi/src/common.h> +#include <irssi/src/irc/core/irc.h> + +#define MODULE_NAME "fe-common/irc" diff --git a/src/fe-common/irc/notifylist/Makefile.am b/src/fe-common/irc/notifylist/Makefile.am new file mode 100644 index 0000000..5eecb5f --- /dev/null +++ b/src/fe-common/irc/notifylist/Makefile.am @@ -0,0 +1,18 @@ +noinst_LIBRARIES = libfe_irc_notifylist.a + +AM_CPPFLAGS = \ + -I$(top_builddir) \ + $(GLIB_CFLAGS) \ + -DHELPDIR=\""$(datadir)/irssi/help"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" + +libfe_irc_notifylist_a_SOURCES = \ + fe-notifylist.c \ + module-formats.c + +pkginc_fe_common_irc_notifylistdir=$(pkgincludedir)/src/fe-common/irc/notifylist +pkginc_fe_common_irc_notifylist_HEADERS = \ + module.h \ + module-formats.h + +EXTRA_DIST = meson.build diff --git a/src/fe-common/irc/notifylist/Makefile.in b/src/fe-common/irc/notifylist/Makefile.in new file mode 100644 index 0000000..733e022 --- /dev/null +++ b/src/fe-common/irc/notifylist/Makefile.in @@ -0,0 +1,725 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 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__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +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 = src/fe-common/irc/notifylist +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/glib-2.0.m4 \ + $(top_srcdir)/m4/glibtests.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/libotr.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am \ + $(pkginc_fe_common_irc_notifylist_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/irssi-config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libfe_irc_notifylist_a_AR = $(AR) $(ARFLAGS) +libfe_irc_notifylist_a_LIBADD = +am_libfe_irc_notifylist_a_OBJECTS = fe-notifylist.$(OBJEXT) \ + module-formats.$(OBJEXT) +libfe_irc_notifylist_a_OBJECTS = $(am_libfe_irc_notifylist_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/fe-notifylist.Po \ + ./$(DEPDIR)/module-formats.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libfe_irc_notifylist_a_SOURCES) +DIST_SOURCES = $(libfe_irc_notifylist_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +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)$(pkginc_fe_common_irc_notifylistdir)" +HEADERS = $(pkginc_fe_common_irc_notifylist_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHAT_MODULES = @CHAT_MODULES@ +COMMON_LIBS = @COMMON_LIBS@ +COMMON_NOUI_LIBS = @COMMON_NOUI_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +FUZZER_LIBS = @FUZZER_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBOTR_CFLAGS = @LIBOTR_CFLAGS@ +LIBOTR_LIBS = @LIBOTR_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +OTR_CFLAGS = @OTR_CFLAGS@ +OTR_LDFLAGS = @OTR_LDFLAGS@ +OTR_LINK_FLAGS = @OTR_LINK_FLAGS@ +OTR_LINK_LIBS = @OTR_LINK_LIBS@ +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@ +PERL_CFLAGS = @PERL_CFLAGS@ +PERL_EXTRA_OPTS = @PERL_EXTRA_OPTS@ +PERL_FE_LINK_LIBS = @PERL_FE_LINK_LIBS@ +PERL_LDFLAGS = @PERL_LDFLAGS@ +PERL_LINK_FLAGS = @PERL_LINK_FLAGS@ +PERL_LINK_LIBS = @PERL_LINK_LIBS@ +PERL_MM_OPT = @PERL_MM_OPT@ +PERL_MM_PARAMS = @PERL_MM_PARAMS@ +PERL_STATIC_LIBS = @PERL_STATIC_LIBS@ +PERL_USE_LIB = @PERL_USE_LIB@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROG_LIBS = @PROG_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TEXTUI_LIBS = @TEXTUI_LIBS@ +VERSION = @VERSION@ +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@ +installed_test_metadir = @installed_test_metadir@ +installed_testdir = @installed_testdir@ +irc_MODULES = @irc_MODULES@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +otr_module_lib = @otr_module_lib@ +otr_static_lib = @otr_static_lib@ +pdfdir = @pdfdir@ +perl_module_fe_lib = @perl_module_fe_lib@ +perl_module_lib = @perl_module_lib@ +perl_static_fe_lib = @perl_static_fe_lib@ +perl_static_lib = @perl_static_lib@ +perlpath = @perlpath@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sedpath = @sedpath@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libfe_irc_notifylist.a +AM_CPPFLAGS = \ + -I$(top_builddir) \ + $(GLIB_CFLAGS) \ + -DHELPDIR=\""$(datadir)/irssi/help"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" + +libfe_irc_notifylist_a_SOURCES = \ + fe-notifylist.c \ + module-formats.c + +pkginc_fe_common_irc_notifylistdir = $(pkgincludedir)/src/fe-common/irc/notifylist +pkginc_fe_common_irc_notifylist_HEADERS = \ + module.h \ + module-formats.h + +EXTRA_DIST = meson.build +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 src/fe-common/irc/notifylist/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/fe-common/irc/notifylist/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__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + 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): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libfe_irc_notifylist.a: $(libfe_irc_notifylist_a_OBJECTS) $(libfe_irc_notifylist_a_DEPENDENCIES) $(EXTRA_libfe_irc_notifylist_a_DEPENDENCIES) + $(AM_V_at)-rm -f libfe_irc_notifylist.a + $(AM_V_AR)$(libfe_irc_notifylist_a_AR) libfe_irc_notifylist.a $(libfe_irc_notifylist_a_OBJECTS) $(libfe_irc_notifylist_a_LIBADD) + $(AM_V_at)$(RANLIB) libfe_irc_notifylist.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fe-notifylist.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/module-formats.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-pkginc_fe_common_irc_notifylistHEADERS: $(pkginc_fe_common_irc_notifylist_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginc_fe_common_irc_notifylist_HEADERS)'; test -n "$(pkginc_fe_common_irc_notifylistdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_fe_common_irc_notifylistdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkginc_fe_common_irc_notifylistdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkginc_fe_common_irc_notifylistdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_fe_common_irc_notifylistdir)" || exit $$?; \ + done + +uninstall-pkginc_fe_common_irc_notifylistHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginc_fe_common_irc_notifylist_HEADERS)'; test -n "$(pkginc_fe_common_irc_notifylistdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkginc_fe_common_irc_notifylistdir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + 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-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + 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: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + 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: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(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 $(LIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(pkginc_fe_common_irc_notifylistdir)"; 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-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/fe-notifylist.Po + -rm -f ./$(DEPDIR)/module-formats.Po + -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-pkginc_fe_common_irc_notifylistHEADERS + +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 -f ./$(DEPDIR)/fe-notifylist.Po + -rm -f ./$(DEPDIR)/module-formats.Po + -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-pkginc_fe_common_irc_notifylistHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLIBRARIES \ + cscopelist-am ctags ctags-am 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-pdf \ + install-pdf-am install-pkginc_fe_common_irc_notifylistHEADERS \ + 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 tags-am uninstall uninstall-am \ + uninstall-pkginc_fe_common_irc_notifylistHEADERS + +.PRECIOUS: Makefile + + +# 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/src/fe-common/irc/notifylist/fe-notifylist.c b/src/fe-common/irc/notifylist/fe-notifylist.c new file mode 100644 index 0000000..68b98a0 --- /dev/null +++ b/src/fe-common/irc/notifylist/fe-notifylist.c @@ -0,0 +1,250 @@ +/* + fe-notifylist.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/irc/notifylist/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/commands.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/chatnets.h> +#include <irssi/src/lib-config/iconfig.h> +#include <irssi/src/core/settings.h> + +#include <irssi/src/core/levels.h> +#include <irssi/src/irc/core/irc-servers.h> +#include <irssi/src/irc/core/irc-chatnets.h> +#include <irssi/src/irc/notifylist/notifylist.h> + +#include <irssi/src/fe-common/core/themes.h> +#include <irssi/src/fe-common/core/printtext.h> + +/* add the nick of a hostmask to list if it isn't there already */ +static GSList *mask_add_once(GSList *list, const char *mask) +{ + char *str, *ptr; + + g_return_val_if_fail(mask != NULL, NULL); + + ptr = strchr(mask, '!'); + str = ptr == NULL ? g_strdup(mask) : + g_strndup(mask, (int) (ptr-mask)); + + if (i_slist_find_icase_string(list, str) == NULL) + return g_slist_append(list, str); + + g_free(str); + return list; +} + +/* search for online people, print them and update offline list */ +static void print_notify_onserver(IRC_SERVER_REC *server, GSList *nicks, + GSList **offline, const char *desc) +{ + GSList *tmp; + GString *str; + + g_return_if_fail(IS_IRC_SERVER(server)); + g_return_if_fail(offline != NULL); + g_return_if_fail(desc != NULL); + + str = g_string_new(NULL); + for (tmp = nicks; tmp != NULL; tmp = tmp->next) { + char *nick = tmp->data; + + if (!notifylist_ison_server(server, nick)) + continue; + + g_string_append_printf(str, "%s, ", nick); + *offline = g_slist_remove(*offline, nick); + } + + if (str->len > 0) { + g_string_truncate(str, str->len-2); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NOTIFY_ONLINE, desc, str->str); + } + + g_string_free(str, TRUE); +} + +/* show the notify list, displaying who is on which net */ +static void cmd_notify_show(void) +{ + GSList *nicks, *offline, *tmp; + IRC_SERVER_REC *server; + + if (notifies == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_NOTIFY_LIST_EMPTY); + return; + } + + /* build a list containing only the nicks */ + nicks = NULL; + for (tmp = notifies; tmp != NULL; tmp = tmp->next) { + NOTIFYLIST_REC *rec = tmp->data; + + nicks = mask_add_once(nicks, rec->mask); + } + offline = g_slist_copy(nicks); + + /* print the notifies on specific ircnets */ + for (tmp = chatnets; tmp != NULL; tmp = tmp->next) { + IRC_CHATNET_REC *rec = tmp->data; + + if (!IS_IRCNET(rec)) + continue; + + server = (IRC_SERVER_REC *) server_find_chatnet(rec->name); + if (!IS_IRC_SERVER(server)) + continue; + + print_notify_onserver(server, nicks, &offline, rec->name); + } + + /* print the notifies on servers without a specified ircnet */ + for (tmp = servers; tmp != NULL; tmp = tmp->next) { + server = tmp->data; + + if (!IS_IRC_SERVER(server) || server->connrec->chatnet != NULL) + continue; + print_notify_onserver(server, nicks, &offline, server->tag); + } + + /* print offline people */ + if (offline != NULL) { + GString *str; + + str = g_string_new(NULL); + for (tmp = offline; tmp != NULL; tmp = tmp->next) + g_string_append_printf(str, "%s, ", (char *) tmp->data); + + g_string_truncate(str, str->len-2); + printformat(NULL,NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NOTIFY_OFFLINE, str->str); + g_string_free(str, TRUE); + + g_slist_free(offline); + } + + g_slist_foreach(nicks, (GFunc) g_free, NULL); + g_slist_free(nicks); +} + +static void notifylist_print(NOTIFYLIST_REC *rec) +{ + char *ircnets; + + ircnets = rec->ircnets == NULL ? NULL : + g_strjoinv(",", rec->ircnets); + + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NOTIFY_LIST, + rec->mask, ircnets != NULL ? ircnets : "", + rec->away_check ? "-away" : ""); + + g_free_not_null(ircnets); +} + +static void cmd_notifylist_show(void) +{ + if (notifies == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_NOTIFY_LIST_EMPTY); + } else { + g_slist_foreach(notifies, (GFunc) notifylist_print, NULL); + } +} + +static void cmd_notify(const char *data) +{ + if (*data == '\0') { + cmd_notify_show(); + signal_stop(); + } + + if (g_ascii_strncasecmp(data, "-list", 4) == 0) { + cmd_notifylist_show(); + signal_stop(); + } +} + +static void notifylist_joined(IRC_SERVER_REC *server, const char *nick, + const char *username, const char *host, + const char *realname, const char *awaymsg) +{ + g_return_if_fail(nick != NULL); + + printformat(server, nick, MSGLEVEL_CLIENTNOTICE, + IRCTXT_NOTIFY_JOIN, nick, username, host, realname, + server->connrec->chatnet == NULL ? "IRC" : server->connrec->chatnet); +} + +static void notifylist_left(IRC_SERVER_REC *server, const char *nick, + const char *username, const char *host, + const char *realname, const char *awaymsg) +{ + g_return_if_fail(nick != NULL); + + printformat(server, nick, MSGLEVEL_CLIENTNOTICE, IRCTXT_NOTIFY_PART, + nick, username, host, realname, + server->connrec->chatnet == NULL ? "IRC" : server->connrec->chatnet); +} + +static void notifylist_away(IRC_SERVER_REC *server, const char *nick, + const char *username, const char *host, + const char *realname, const char *awaymsg) +{ + g_return_if_fail(nick != NULL); + + if (awaymsg != NULL) { + printformat(server, nick, MSGLEVEL_CLIENTNOTICE, + IRCTXT_NOTIFY_AWAY, nick, username, host, realname, awaymsg, + server->connrec->chatnet == NULL ? "IRC" : server->connrec->chatnet); + } else { + printformat(server, nick, MSGLEVEL_CLIENTNOTICE, + IRCTXT_NOTIFY_UNAWAY, nick, username, host, realname, + server->connrec->chatnet == NULL ? "IRC" : server->connrec->chatnet); + } +} + +void fe_irc_notifylist_init(void) +{ + theme_register(fecommon_irc_notifylist_formats); + + command_bind("notify", NULL, (SIGNAL_FUNC) cmd_notify); + signal_add("notifylist joined", (SIGNAL_FUNC) notifylist_joined); + signal_add("notifylist left", (SIGNAL_FUNC) notifylist_left); + signal_add("notifylist away changed", (SIGNAL_FUNC) notifylist_away); + + command_set_options("notify", "list"); + + settings_check(); + module_register("notifylist", "fe-irc"); +} + +void fe_irc_notifylist_deinit(void) +{ + theme_unregister(); + + command_unbind("notify", (SIGNAL_FUNC) cmd_notify); + signal_remove("notifylist joined", (SIGNAL_FUNC) notifylist_joined); + signal_remove("notifylist left", (SIGNAL_FUNC) notifylist_left); + signal_remove("notifylist away changed", (SIGNAL_FUNC) notifylist_away); +} + +MODULE_ABICHECK(fe_irc_notifylist) diff --git a/src/fe-common/irc/notifylist/meson.build b/src/fe-common/irc/notifylist/meson.build new file mode 100644 index 0000000..2e66c78 --- /dev/null +++ b/src/fe-common/irc/notifylist/meson.build @@ -0,0 +1,21 @@ +# this file is part of irssi + +libfe_irc_notifylist_a = static_library('fe_irc_notifylist', + files( + 'fe-notifylist.c', + 'module-formats.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + c_args : [ + def_helpdir, + def_sysconfdir, + ], + dependencies : dep) + +install_headers( + files( + 'module-formats.h', + 'module.h', + ), + subdir : incdir / 'src' / 'fe-common' / 'irc' / 'notifylist') diff --git a/src/fe-common/irc/notifylist/module-formats.c b/src/fe-common/irc/notifylist/module-formats.c new file mode 100644 index 0000000..12f41fb --- /dev/null +++ b/src/fe-common/irc/notifylist/module-formats.c @@ -0,0 +1,41 @@ +/* + module-formats.c : irssi + + Copyright (C) 2000 Timo Sirainen + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/fe-common/core/formats.h> + +FORMAT_REC fecommon_irc_notifylist_formats[] = +{ + { MODULE_NAME, "Notifylist", 0 }, + + /* ---- */ + { NULL, "Notifylist", 0 }, + + { "notify_join", "{nick $0} [$1@$2] [{hilight $3}] has joined to $4", 5, { 0, 0, 0, 0, 0 } }, + { "notify_part", "{nick $0} has left $4", 5, { 0, 0, 0, 0, 0 } }, + { "notify_away", "{nick $0} [$5] [$1@$2] [{hilight $3}] is now away: $4", 6, { 0, 0, 0, 0, 0, 0 } }, + { "notify_unaway", "{nick $0} [$4] [$1@$2] [{hilight $3}] is now unaway", 5, { 0, 0, 0, 0, 0 } }, + { "notify_online", "On $0: {hilight $1}", 2, { 0, 0 } }, + { "notify_offline", "Offline: $0", 1, { 0 } }, + { "notify_list", "$0: $1 $2", 4, { 0, 0, 0, 0 } }, + { "notify_list_empty", "The notify list is empty", 0 }, + + { NULL, NULL, 0 }, +}; diff --git a/src/fe-common/irc/notifylist/module-formats.h b/src/fe-common/irc/notifylist/module-formats.h new file mode 100644 index 0000000..ff3085e --- /dev/null +++ b/src/fe-common/irc/notifylist/module-formats.h @@ -0,0 +1,18 @@ +#include <irssi/src/fe-common/core/formats.h> + +enum { + IRCTXT_MODULE_NAME, + + IRCTXT_FILL_1, + + IRCTXT_NOTIFY_JOIN, + IRCTXT_NOTIFY_PART, + IRCTXT_NOTIFY_AWAY, + IRCTXT_NOTIFY_UNAWAY, + IRCTXT_NOTIFY_ONLINE, + IRCTXT_NOTIFY_OFFLINE, + IRCTXT_NOTIFY_LIST, + IRCTXT_NOTIFY_LIST_EMPTY +}; + +extern FORMAT_REC fecommon_irc_notifylist_formats[]; diff --git a/src/fe-common/irc/notifylist/module.h b/src/fe-common/irc/notifylist/module.h new file mode 100644 index 0000000..0e5ca45 --- /dev/null +++ b/src/fe-common/irc/notifylist/module.h @@ -0,0 +1,4 @@ +#include <irssi/src/common.h> +#include <irssi/src/irc/core/irc.h> + +#define MODULE_NAME "fe-common/irc/notifylist" |