summaryrefslogtreecommitdiffstats
path: root/src/klammail
diff options
context:
space:
mode:
authorMavridis Philippe <mavridisf@gmail.com>2021-01-13 19:26:24 +0200
committerMavridis Philippe <mavridisf@gmail.com>2021-01-13 19:26:24 +0200
commit8c20dc919f7d54eb48fb60f39ba5e1d466a70763 (patch)
tree44d89f278d5dd066603e5ab9c0b270bc8eb4ad51 /src/klammail
downloadklamav-8c20dc919f7d54eb48fb60f39ba5e1d466a70763.tar.gz
klamav-8c20dc919f7d54eb48fb60f39ba5e1d466a70763.zip
Initial commit
Signed-off-by: Mavridis Philippe <mavridisf@gmail.com>
Diffstat (limited to 'src/klammail')
-rw-r--r--src/klammail/Makefile.am8
-rw-r--r--src/klammail/Makefile.in711
-rw-r--r--src/klammail/cfgparser.c305
-rw-r--r--src/klammail/cfgparser.h54
-rwxr-xr-xsrc/klammail/clamdmail.c626
-rwxr-xr-xsrc/klammail/client.c168
-rw-r--r--src/klammail/defaults.h27
-rw-r--r--src/klammail/memory.c47
-rw-r--r--src/klammail/memory.h27
-rwxr-xr-xsrc/klammail/options.c358
-rwxr-xr-xsrc/klammail/options.h46
-rw-r--r--src/klammail/output.c369
-rw-r--r--src/klammail/output.h43
-rw-r--r--src/klammail/shared.h36
-rw-r--r--src/klammail/str.h26
-rwxr-xr-xsrc/klammail/target.h68
16 files changed, 2919 insertions, 0 deletions
diff --git a/src/klammail/Makefile.am b/src/klammail/Makefile.am
new file mode 100644
index 0000000..56eae7b
--- /dev/null
+++ b/src/klammail/Makefile.am
@@ -0,0 +1,8 @@
+bin_PROGRAMS = klammail
+klammail_SOURCES = clamdmail.c options.c output.c memory.c cfgparser.c client.c
+
+# set the include path found by configure
+INCLUDES= $(all_includes)
+# the library search path.
+klammail_LDADD = $(LIB_CLAM)
+#AM_CFLAGS=-O0 -g3 \ No newline at end of file
diff --git a/src/klammail/Makefile.in b/src/klammail/Makefile.in
new file mode 100644
index 0000000..818d5f9
--- /dev/null
+++ b/src/klammail/Makefile.in
@@ -0,0 +1,711 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 1.3 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 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@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+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@
+target_triplet = @target@
+bin_PROGRAMS = klammail$(EXEEXT)
+subdir = src/klammail
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_klammail_OBJECTS = clamdmail.$(OBJEXT) options.$(OBJEXT) \
+ output.$(OBJEXT) memory.$(OBJEXT) cfgparser.$(OBJEXT) \
+ client.$(OBJEXT)
+#>- klammail_OBJECTS = $(am_klammail_OBJECTS)
+#>+ 6
+klammail_final_OBJECTS = clamdmail.o options.o output.o memory.o cfgparser.o client.o
+klammail_nofinal_OBJECTS = clamdmail.$(OBJEXT) options.$(OBJEXT) \
+ output.$(OBJEXT) memory.$(OBJEXT) cfgparser.$(OBJEXT) \
+ client.$(OBJEXT)
+@KDE_USE_FINAL_FALSE@klammail_OBJECTS = $(klammail_nofinal_OBJECTS)
+@KDE_USE_FINAL_TRUE@klammail_OBJECTS = $(klammail_final_OBJECTS)
+am__DEPENDENCIES_1 =
+klammail_DEPENDENCIES = $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(klammail_SOURCES)
+DIST_SOURCES = $(klammail_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_FPIE = @KDE_USE_FPIE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_USE_PIE = @KDE_USE_PIE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_CLAM = @LIB_CLAM@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDED = @LIB_KDED@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KDNSSD = @LIB_KDNSSD@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMPROXY = @LIB_KIMPROXY@
+LIB_KIO = @LIB_KIO@
+LIB_KJS = @LIB_KJS@
+LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUNITTEST = @LIB_KUNITTEST@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_SQLITE = @LIB_SQLITE@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKGCONFIGFOUND = @PKGCONFIGFOUND@
+PKG_CONFIG = @PKG_CONFIG@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SQLITE_CFLAGS = @SQLITE_CFLAGS@
+SQLITE_LIBS = @SQLITE_LIBS@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+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@
+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@
+include_ARTS_FALSE = @include_ARTS_FALSE@
+include_ARTS_TRUE = @include_ARTS_TRUE@
+include_x11_FALSE = @include_x11_FALSE@
+include_x11_TRUE = @include_x11_TRUE@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+unsermake_enable_pch_FALSE = @unsermake_enable_pch_FALSE@
+unsermake_enable_pch_TRUE = @unsermake_enable_pch_TRUE@
+with_included_sqlite_FALSE = @with_included_sqlite_FALSE@
+with_included_sqlite_TRUE = @with_included_sqlite_TRUE@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+klammail_SOURCES = clamdmail.c options.c output.c memory.c cfgparser.c client.c
+
+# set the include path found by configure
+INCLUDES = $(all_includes)
+# the library search path.
+klammail_LDADD = $(LIB_CLAM)
+#>- all: all-am
+#>+ 1
+all: docs-am all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/klammail/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu src/klammail/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/klammail/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/klammail/Makefile
+ cd $(top_srcdir) && perl admin/am_edit src/klammail/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+klammail$(EXEEXT): $(klammail_OBJECTS) $(klammail_DEPENDENCIES)
+ @rm -f klammail$(EXEEXT)
+ $(LINK) $(klammail_LDFLAGS) $(klammail_OBJECTS) $(klammail_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfgparser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clamdmail.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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 $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; 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:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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
+#>+ 1
+clean: kde-rpo-clean clean-am
+
+#>- clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+#>+ 1
+clean-am: clean-bcheck clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-info-am
+
+#AM_CFLAGS=-O0 -g3
+# 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:
+
+#>+ 2
+KDE_DIST=cfgparser.h shared.h options.h defaults.h output.h str.h Makefile.in target.h Makefile.am memory.h
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/klammail/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/klammail/Makefile
+ cd $(top_srcdir) && perl admin/am_edit src/klammail/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-am
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 3
+final:
+ $(MAKE) klammail_OBJECTS="$(klammail_final_OBJECTS)" all-am
+
+#>+ 3
+final-install:
+ $(MAKE) klammail_OBJECTS="$(klammail_final_OBJECTS)" install-am
+
+#>+ 3
+no-final:
+ $(MAKE) klammail_OBJECTS="$(klammail_nofinal_OBJECTS)" all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) klammail_OBJECTS="$(klammail_nofinal_OBJECTS)" install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/src/klammail/cfgparser.c b/src/klammail/cfgparser.c
new file mode 100644
index 0000000..a48fe85
--- /dev/null
+++ b/src/klammail/cfgparser.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "options.h"
+#include "cfgparser.h"
+#include "defaults.h"
+#include "str.h"
+#include "memory.h"
+
+static int isnumb(const char *str)
+{
+ int i;
+
+ for(i = 0; i < strlen(str); i++)
+ if(!isdigit(str[i]))
+ return 0;
+
+ return 1;
+}
+
+struct cfgstruct *parsecfg(const char *cfgfile)
+{
+ char buff[LINE_LENGTH], *name, *arg;
+ FILE *fs;
+ int line = 0, i, found, ctype, calc;
+ struct cfgstruct *copt = NULL;
+ struct cfgoption *pt;
+
+ struct cfgoption cfg_options[] = {
+ {"LogFile", OPT_STR},
+ {"LogFileUnlock", OPT_NOARG},
+ {"LogFileMaxSize", OPT_COMPSIZE},
+ {"LogTime", OPT_NOARG},
+ {"LogClean", OPT_NOARG},
+ {"LogVerbose", OPT_NOARG}, /* clamd + freshclam */
+ {"LogSyslog", OPT_NOARG},
+ {"LogFacility", OPT_STR},
+ {"PidFile", OPT_STR},
+ {"TemporaryDirectory", OPT_STR},
+ {"MaxFileSize", OPT_COMPSIZE},
+ {"ScanMail", OPT_NOARG},
+ {"ScanOLE2", OPT_NOARG},
+ {"ScanArchive", OPT_NOARG},
+ {"ScanRAR", OPT_NOARG},
+ {"ArchiveMaxFileSize", OPT_COMPSIZE},
+ {"ArchiveMaxRecursion", OPT_NUM},
+ {"ArchiveMaxFiles", OPT_NUM},
+ {"ArchiveMaxCompressionRatio", OPT_NUM},
+ {"ArchiveLimitMemoryUsage", OPT_NOARG},
+ {"ArchiveBlockEncrypted", OPT_NOARG},
+ {"DataDirectory", OPT_STR}, /* obsolete */
+ {"DatabaseDirectory", OPT_STR}, /* clamd + freshclam */
+ {"TCPAddr", OPT_STR},
+ {"TCPSocket", OPT_NUM},
+ {"LocalSocket", OPT_STR},
+ {"MaxConnectionQueueLength", OPT_NUM},
+ {"StreamSaveToDisk", OPT_NOARG},
+ {"StreamMaxLength", OPT_COMPSIZE},
+ {"MaxThreads", OPT_NUM},
+ {"ReadTimeout", OPT_NUM},
+ {"MaxDirectoryRecursion", OPT_NUM},
+ {"FollowDirectorySymlinks", OPT_NOARG},
+ {"FollowFileSymlinks", OPT_NOARG},
+ {"Foreground", OPT_NOARG},
+ {"Debug", OPT_NOARG},
+ {"LeaveTemporaryFiles", OPT_NOARG},
+ {"FixStaleSocket", OPT_NOARG},
+ {"User", OPT_STR},
+ {"AllowSupplementaryGroups", OPT_NOARG},
+ {"SelfCheck", OPT_NUM},
+ {"VirusEvent", OPT_FULLSTR},
+ {"ClamukoScanOnLine", OPT_NOARG}, /* old name */
+ {"ClamukoScanOnAccess", OPT_NOARG},
+ {"ClamukoScanOnOpen", OPT_NOARG},
+ {"ClamukoScanOnClose", OPT_NOARG},
+ {"ClamukoScanOnExec", OPT_NOARG},
+ {"ClamukoIncludePath", OPT_STR},
+ {"ClamukoExcludePath", OPT_STR},
+ {"ClamukoMaxFileSize", OPT_COMPSIZE},
+ {"ClamukoScanArchive", OPT_NOARG},
+ {"DatabaseOwner", OPT_STR}, /* freshclam */
+ {"Checks", OPT_NUM}, /* freshclam */
+ {"UpdateLogFile", OPT_STR}, /* freshclam */
+ {"DatabaseMirror", OPT_STR}, /* freshclam */
+ {"MaxAttempts", OPT_NUM}, /* freshclam */
+ {"HTTPProxyServer", OPT_STR}, /* freshclam */
+ {"HTTPProxyPort", OPT_NUM}, /* freshclam */
+ {"HTTPProxyUsername", OPT_STR}, /* freshclam */
+ {"HTTPProxyPassword", OPT_STR}, /* freshclam */
+ {"NotifyClamd", OPT_OPTARG}, /* freshclam */
+ {"OnUpdateExecute", OPT_FULLSTR}, /* freshclam */
+ {"OnErrorExecute", OPT_FULLSTR}, /* freshclam */
+ {0, 0}
+ };
+
+
+ if((fs = fopen(cfgfile, "r")) == NULL) {
+ return NULL;
+ }
+
+
+ while(fgets(buff, LINE_LENGTH, fs)) {
+
+ line++;
+
+ if(buff[0] == '#')
+ continue;
+
+ if(!strncmp("Example", buff, 7)) {
+ fprintf(stderr, "ERROR: Please edit the example config file %s.\n", cfgfile);
+ return NULL;
+ }
+
+
+ if((name = cli_strtok(buff, 0, " \r\n"))) {
+ arg = cli_strtok(buff, 1, " \r\n");
+ found = 0;
+ for(i = 0; ; i++) {
+ pt = &cfg_options[i];
+ if(pt->name) {
+ if(!strcmp(name, pt->name)) {
+ found = 1;
+ switch(pt->argtype) {
+ case OPT_STR:
+ if(!arg) {
+ fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires string as argument.\n", line, name);
+ return NULL;
+ }
+ copt = regcfg(copt, name, arg, 0);
+ break;
+ case OPT_FULLSTR:
+ if(!arg) {
+ fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires string as argument.\n", line, name);
+ return NULL;
+ }
+ /* FIXME: this one is an ugly hack of the above case */
+ free(arg);
+ arg = strstr(buff, " ");
+ arg = strdup(++arg);
+ copt = regcfg(copt, name, arg, 0);
+ break;
+ case OPT_NUM:
+ if(!arg || !isnumb(arg)) {
+ fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical argument.\n", line, name);
+ return NULL;
+ }
+ copt = regcfg(copt, name, NULL, atoi(arg));
+ free(arg);
+ break;
+ case OPT_COMPSIZE:
+ if(!arg) {
+ fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires argument.\n", line, name);
+ return NULL;
+ }
+ ctype = tolower(arg[strlen(arg) - 1]);
+ if(ctype == 'm' || ctype == 'k') {
+ char *cpy = (char *) mcalloc(strlen(arg), sizeof(char));
+ strncpy(cpy, arg, strlen(arg) - 1);
+ if(!isnumb(cpy)) {
+ fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical (raw/K/M) argument.\n", line, name);
+ return NULL;
+ }
+ if(ctype == 'm')
+ calc = atoi(cpy) * 1024 * 1024;
+ else
+ calc = atoi(cpy) * 1024;
+ free(cpy);
+ } else {
+ if(!isnumb(arg)) {
+ fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical (raw/K/M) argument.\n", line, name);
+ return NULL;
+ }
+ calc = atoi(arg);
+ }
+ copt = regcfg(copt, name, NULL, calc);
+ free(arg);
+ break;
+ case OPT_NOARG:
+ if(arg) {
+ fprintf(stderr, "ERROR: Parse error at line %d: Option %s doesn't support arguments (got '%s').\n", line, name, arg);
+ return NULL;
+ }
+ copt = regcfg(copt, name, NULL, 0);
+ break;
+ case OPT_OPTARG:
+ copt = regcfg(copt, name, arg, 0);
+ break;
+ default:
+ fprintf(stderr, "ERROR: Parse error at line %d: Option %s is of unknown type %d\n", line, name, pt->argtype);
+ free(name);
+ free(arg);
+ break;
+ }
+ }
+ } else
+ break;
+ }
+
+ if(!found) {
+ fprintf(stderr, "ERROR: Parse error at line %d: Unknown option %s.\n", line, name);
+ return NULL;
+ }
+ }
+ }
+
+ fclose(fs);
+ return copt;
+}
+
+void freecfg(struct cfgstruct *copt)
+{
+ struct cfgstruct *handler;
+ struct cfgstruct *arg;
+
+ while (copt) {
+ arg = copt->nextarg;
+ while (arg) {
+ if(arg->strarg) {
+ free(arg->optname);
+ free(arg->strarg);
+ handler = arg;
+ arg=arg->nextarg;
+ free(handler);
+ }
+ }
+ if(copt->optname) {
+ free(copt->optname);
+ }
+ if(copt->strarg) {
+ free(copt->strarg);
+ }
+ handler = copt;
+ copt = copt->next;
+ free(handler);
+ }
+ return;
+}
+
+struct cfgstruct *regcfg(struct cfgstruct *copt, char *optname, char *strarg, int numarg)
+{
+ struct cfgstruct *newnode, *pt;
+
+ newnode = (struct cfgstruct *) mmalloc(sizeof(struct cfgstruct));
+ newnode->optname = optname;
+ newnode->nextarg = NULL;
+ newnode->next = NULL;
+
+ if(strarg)
+ newnode->strarg = strarg;
+ else {
+ newnode->strarg = NULL;
+ newnode->numarg = numarg;
+ }
+
+ if((pt = cfgopt(copt, optname))) {
+ while(pt->nextarg)
+ pt = pt->nextarg;
+
+ pt->nextarg = newnode;
+ return copt;
+ } else {
+ newnode->next = copt;
+ return newnode;
+ }
+}
+
+struct cfgstruct *cfgopt(const struct cfgstruct *copt, const char *optname)
+{
+ struct cfgstruct *handler;
+
+ handler = (struct cfgstruct *) copt;
+
+ while(1) {
+ if(handler) {
+ if(handler->optname)
+ if(!strcmp(handler->optname, optname))
+ return handler;
+ } else break;
+ handler = handler->next;
+ }
+
+ return NULL;
+}
+
diff --git a/src/klammail/cfgparser.h b/src/klammail/cfgparser.h
new file mode 100644
index 0000000..e031475
--- /dev/null
+++ b/src/klammail/cfgparser.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __CFGPARSER_H
+#define __CFGPARSER_H
+
+#define LINE_LENGTH 1024
+
+
+#define OPT_STR 1 /* string argument */
+#define OPT_NUM 2 /* numerical argument */
+#define OPT_COMPSIZE 3 /* convert kilobytes (k) and megabytes (m) to bytes */
+#define OPT_NOARG 4 /* no argument */
+#define OPT_OPTARG 5 /* argument is optional, it's registered as string */
+#define OPT_FULLSTR 6 /* string argument, but get a full line */
+
+struct cfgoption {
+ const char *name;
+ int argtype;
+};
+
+struct cfgstruct {
+ char *optname;
+ char *strarg;
+ int numarg;
+ struct cfgstruct *nextarg;
+ struct cfgstruct *next;
+};
+
+
+struct cfgstruct *parsecfg(const char *cfgfile);
+
+struct cfgstruct *regcfg(struct cfgstruct *copt, char *optname, char *strarg, int numarg);
+
+struct cfgstruct *cfgopt(const struct cfgstruct *copt, const char *optname);
+
+void freecfg(struct cfgstruct *copt);
+
+#endif
diff --git a/src/klammail/clamdmail.c b/src/klammail/clamdmail.c
new file mode 100755
index 0000000..19f985e
--- /dev/null
+++ b/src/klammail/clamdmail.c
@@ -0,0 +1,626 @@
+/*
+*
+* Clamdmail.c is based loosely on clamdscan.c by Tomasz Kojm.
+*
+* This program takes a mail message as input from stdin, uses rfc822.c to extract
+* attachments to a temp directory, gets clamd to scan them, and
+* handles the message appropriately.
+*
+* Copyright (C) 2003 Robert Hogan <robert@roberthogan.net>
+*
+* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <clamav.h>
+
+#include "options.h"
+#include "defaults.h"
+#include "memory.h"
+#include "../version.h"
+#include "../../config.h"
+
+#define BUFFSIZE 1024
+
+
+
+/* this local macro takes care about freeing memory at exit */
+/*
+#define mexit(i) if(opt) free_opt(opt); \
+ mprintf("*Memory freed. Exit code: %d\n", i); \
+ exit(i);
+*/
+#define mexit(i) exit(i)
+
+struct s_info {
+ int signs; /* number of signatures loaded */
+ int dirs; /* number of scanned directories */
+ int files; /* number of scanned files */
+ int ifiles; /* number of infected files */
+ int notremoved; /* number of not removed files (if --remove) */
+ int notmoved; /* number of not moved files (if --move) */
+ int errors; /* ... of errors */
+ long int blocks; /* number of read 16kb blocks */
+};
+
+
+void help(void);
+void printtag(void);
+void startclamd(struct optstruct *opt);
+
+struct s_info claminfo;
+short printinfected = 0;
+short int mprintf_stdout;
+
+int clamdscan(struct optstruct *opt)
+{
+ int ds, dms;
+
+ struct timeval t1, t2;
+ struct timezone tz;
+ const char *bndrystore;
+ const char *tmpdir;
+ char *tmpfil;
+ char *pfx;
+ char *tmper;
+ char *dir;
+ struct passwd *user = NULL;
+ FILE *tmp;
+ FILE *fs;
+ int bytes;
+ char buff[BUFFSIZE];
+ struct cl_node *trie = NULL;
+ int threads = 0;
+ int fd, fdtmp, ret, no = 0;
+ unsigned long int size = 0;
+ long double mb;
+ const char *virname;
+ struct cl_engine *engine = NULL;
+#ifndef SUPPORT_CLAMAV_V095
+ struct cl_limits limits;
+#endif
+ struct stat sb;
+
+ if(optc(opt, 'V')) {
+ mprintf("clamdmail "KLAMAV_VERSION" \n");
+ mexit(0);
+ }
+
+ if(optc(opt, 'h')) {
+ free_opt(opt);
+ help();
+ }
+
+ if(optc(opt, 'i')) printinfected = 1;
+ else printinfected = 0;
+
+
+
+ memset(&claminfo, 0, sizeof(struct s_info));
+
+ gettimeofday(&t1, &tz);
+
+ //if(user)
+
+
+ char name[19];
+ char *tmpnm;
+ char *mdir;
+
+ if((mdir = getenv("TMPDIR")) == NULL)
+ #ifdef P_tmpdir
+ mdir = P_tmpdir;
+ #else
+ mdir = "/tmp";
+ #endif
+
+ tmpnm = (char*) mcalloc(strlen(mdir) + 1 + 16 + 1 + 7, sizeof(char));
+ if(tmpnm == NULL) {
+ exit(2);
+ }
+
+ sprintf(tmpnm, "%s/", mdir);
+ snprintf(name, sizeof(name), "klammailXXXXXX");
+ strncat(tmpnm, name, 19);
+ mkstemp(tmpnm);
+
+
+
+ fd = open(tmpnm,O_RDWR|O_CREAT, S_IRWXU);
+
+ while((bytes = read(0, buff, BUFFSIZE)) > 0) {
+
+ if(write(fd, buff, bytes) != bytes) {
+ close(fd);
+ return CL_EMEM;
+ }
+ }
+
+ if(fsync(fd) == -1) {
+ close(fd);
+#ifdef SUPPORT_CLAMAV_V095
+ return CL_ETMPFILE;
+#else
+ return CL_EIO;
+#endif
+ }
+
+ close(fd);
+
+ if((fd = open(tmpnm, O_RDONLY)) == -1) {
+ printf("Can't open file %s\n", tmpnm);
+ exit(2);
+ }
+
+ ret = 0;
+ ret = client(tmpnm, opt, &virname);
+
+
+
+ /* Clamd isn't running, scan the file ourselves */
+ if((ret == 2)) {
+ /* Clamd isn't running, start it so it is available next time. */
+ startclamd(opt);
+#ifdef SUPPORT_CLAMAV_V095
+ if((engine = cl_engine_new()) == NULL) {
+ printf("Database initialization error: %s\n", cl_strerror(ret));;
+ cl_engine_free(engine);
+ close(fd);
+ exit(2);
+ }
+#endif
+ if(optc(opt, 'd')) {
+#ifdef SUPPORT_CLAMAV_V095
+ if((ret = cl_load(getargc(opt, 'd'), engine, &no, CL_DB_STDOPT))) {
+#else
+ if((ret = cl_load(getargc(opt, 'd'), &engine, &no, CL_DB_STDOPT))) {
+#endif
+ printf("cl_load: %s\n", cl_strerror(ret));
+ close(fd);
+ return 50;
+ }
+ }else{
+#ifdef SUPPORT_CLAMAV_V095
+ if((ret = cl_load(cl_retdbdir(), engine, &no, CL_DB_STDOPT))) {
+#else
+ if((ret = cl_loaddbdir(cl_retdbdir(), &engine, &no, CL_DB_STDOPT))) {
+#endif
+ printf("cl_loaddbdir: %s\n", cl_strerror(ret));
+ close(fd);
+ exit(2);
+ }
+ }
+
+ /* build engine */
+#ifdef SUPPORT_CLAMAV_V095
+ if((ret = cl_engine_compile(engine))) {
+#else
+ if((ret = cl_build(engine))) {
+#endif
+ printf("Database initialization error: %s\n", cl_strerror(ret));;
+#ifdef SUPPORT_CLAMAV_V095
+ cl_engine_free(engine);
+#else
+ cl_free(engine);
+#endif
+ close(fd);
+ exit(2);
+ }
+
+#ifndef SUPPORT_CLAMAV_V095
+ /* set up archive limits */
+ memset(&limits, 0, sizeof(struct cl_limits));
+ limits.maxfiles = 1000; /* max files */
+ limits.maxfilesize = 10 * 1048576; /* maximum size of archived/compressed
+ * file (files exceeding this limit
+ * will be ignored)
+ */
+ /*limits.maxreclevel = 5;*/ /* maximum recursion level for archives */
+ /*limits.maxmailrec = 64;*/ /* maximum recursion level for mail files */
+ /*limits.maxratio = 200;*/ /* maximum compression ratio */
+ limits.archivememlim = 1;
+#endif
+#ifdef SUPPORT_CLAMAV_V095
+ ret = cl_scandesc(fd, &virname, &size, engine,
+ CL_SCAN_STDOPT | CL_SCAN_ARCHIVE | CL_SCAN_MAIL | CL_SCAN_OLE2 | CL_SCAN_HTML);
+ printf("scandesc returned: %i\n", cl_strerror(ret));;
+#else
+ ret = cl_scandesc(fd, &virname, &size, engine, &limits,
+ CL_SCAN_STDOPT | CL_ARCHIVE | CL_MAIL | CL_OLE2 | CL_SCAN_HTML);
+#endif
+ }
+
+ /* scan descriptor (with archive and mail scanning enabled) */
+ close(fd);
+ fd = open(tmpnm,O_RDWR, S_IRWXU);
+
+ spoolstdin(tmpnm, fd, ret, &virname, &bndrystore, opt);
+
+ if((ret == 2))
+#ifdef SUPPORT_CLAMAV_V095
+ cl_engine_free(engine);
+#else
+ cl_free(engine);
+#endif
+
+ unlink(tmpnm);
+
+ mexit(0);
+}
+
+int spoolstdin(char *tmpnm, int fd, int ret, char **virname, const char **bndrystore, struct optstruct *opt)
+{
+ int bytes;
+ int i, j;
+ long int size = 0;
+ char buff[BUFFSIZE];
+ char string[1000];
+ char To[1000];
+ char ReplyTo[1000];
+ char DelivTo[1000];
+ char From[1000];
+ char ToR[1000];
+ char FromR[1000];
+ char boundary[1000];
+ char host[256]; /* could be HOST_NAME_MAX+1 on POSIX 1003.1-2001 */
+ struct timeval tv;
+ struct timezone tz;
+ char *s;
+ char *storage;
+ FILE *tmp;
+ int pcount = 0;
+ time_t starttime;
+ struct tm *tm;
+ char *out = NULL;
+ const char *format;
+ size_t out_length = 0;
+ time_t when;
+ int childpid;
+
+
+ strcpy (To, "To:");
+ strcpy (From, "From:");
+ strcpy (ReplyTo, "Reply-To:");
+ strcpy (DelivTo, "Delivered");
+
+ gethostname(host, sizeof(host));
+ gettimeofday(&tv, &tz);
+ time(&when);
+ tm = localtime(&when);
+ format = "%a, %_d %b %Y %H:%M:%S %z";
+ do {
+ out_length += 200;
+ out = (char *) realloc (out, out_length);
+ out[0] = '\1';
+ } while (strftime (out, out_length, format, tm) == 0 && out[0] != '\0');
+
+ if(ret == CL_VIRUS) {
+ if(!(optc(opt, 'f'))){
+
+ lseek(fd, 0, SEEK_SET);
+ if (!(tmp = fdopen(fd,"r"))){
+ mprintf("@Can't open file %s\n", tmpnm);
+ return 54;
+ }
+
+ mprintf_stdout = 1;
+
+ while (fgets(string, sizeof(string), tmp)) {
+ if (strstr(string, To) && !(strstr(string, ReplyTo)) && !(strstr(string,DelivTo))){
+ strcpy(To, string);
+ strcpy(ToR, string);
+ }
+ if (strstr(string, From)){
+ strcpy(FromR, string);
+ }
+ if (strncmp(string, "\n", 1) == 0 && pcount != 0){
+ break;
+ }
+ ++pcount;
+ }
+
+ if (strcmp(To,"To:") == 0){
+ strcat(To, " ");
+ strcat(To, getargl(opt, "admin"));
+ strcat(To, "\n");
+ }
+ strcat(From, " ");
+ strcat(From, "KlamAV");
+ strcat(From, "\n");
+ strcat(ReplyTo, " ");
+ strcat(ReplyTo, "KlamAV");
+ strcat(ReplyTo, "\n");
+ mprintf("%s", From);
+ mprintf("%s", ReplyTo);
+ mprintf("%s", To);
+ mprintf("Subject: Virus %s found in attached mail by KlamAV.\n", *virname);
+ mprintf("Date: %s\n", out);
+ if(!(optl(opt, "quar"))){
+ mprintf("MIME-Version: 1.0\n");
+ mprintf("Content-Type: multipart/mixed;\n");
+ mprintf(" boundary=\"----------=_%d\"\n",tv.tv_sec);
+ mprintf("X-Virus-Status: Yes\n");
+ mprintf("X-Virus-Checker: Scanned by KlamAV %s on %s (virus-found %s);\n\t%s\n",
+ KLAMAV_VERSION, host, *virname, out);
+ mprintf("\n");
+ mprintf("\n");
+ mprintf("------------=_%d\n",tv.tv_sec);
+ }
+ mprintf("Content-Type: text/plain;\n");
+ mprintf(" charset=\"us-ascii\"\n");
+ mprintf("Content-Transfer-Encoding: quoted-printable\n");
+ if((optl(opt, "quar"))){
+ mprintf("X-Virus-Status: Yes\n");
+ mprintf("X-Virus-Checker: Scanned by KlamAV %s on %s (virus-found %s);\n\t%s\n",
+ KLAMAV_VERSION, host, *virname, out);
+ mprintf("\n");
+ mprintf("KlamAV anti-virus scanner has intercepted and quarantined a message addressed to you.\n");
+ }
+ else
+ {
+ mprintf("\n");
+ mprintf("KlamAV anti-virus scanner has detected a virus in the attached message.\n");
+ }
+ mprintf("\n");
+ mprintf("The following is a summary of the infected message:\n");
+ mprintf("\n");
+ mprintf("Virus name: %s\n", *virname);
+ mprintf("%s", FromR);
+ mprintf("%s", ToR);
+ mprintf("\n");
+ mprintf("Please be aware that a virus spread by email normally forges the \n");
+ mprintf("address of the sender. There is a good chance that the infected message\n");
+ mprintf("was not received from the sender listed above. \n");
+ mprintf("\n");
+ if(!(optl(opt, "quar"))){
+ mprintf("------------=_%d\n",tv.tv_sec);
+ mprintf("Content-Type: message/rfc822; x-virus-type=original\n");
+ mprintf("Content-Description: Infected Message - Open At Your Own Risk\n");
+ mprintf("Content-Disposition: inline\n");
+ mprintf("Content-Transfer-Encoding: 8bit\n");
+ mprintf("\n");
+ fflush(stdout);
+
+ lseek(fd, 0, SEEK_SET);
+ while((bytes = read(fd, buff, BUFFSIZE)) > 0) {
+
+ if(write(1, buff, bytes) != bytes) {
+ close(fd);
+ return CL_EMEM;
+ }
+ }
+ mprintf("------------=_%d--\n",tv.tv_sec);
+ }
+ fflush(stdout);
+
+ fclose(tmp);
+ }else{
+ int bcnt = 0;
+ lseek(fd, 0, SEEK_SET);
+ if (!(tmp = fdopen(fd,"r"))){
+ mprintf("@Can't open file %s\n", tmpnm);
+ return 54;
+ }
+
+ mprintf_stdout = 1;
+
+ while (fgets(string, sizeof(string), tmp)) {
+ if (*string == '\n') {
+ mprintf("X-Virus-Status: Yes\n");
+ mprintf("X-Virus-Checker: Scanned by KlamAV %s on %s (virus-found %s);\n\t%s\n",
+ KLAMAV_VERSION, host, *virname, out);
+ break;
+ }
+ fputs(string, stdout);
+ }
+ while (fgets(string, sizeof(string), tmp)) {
+ fputs(string, stdout);
+ }
+
+ if(optl(opt, "tag")) {
+ if (!(*bndrystore))
+ printtag();
+ }
+ fclose(tmp);
+ }
+
+ if ( ( childpid=fork() ) == -1 ) {
+ perror("Failed to fork; quitting\n");
+ exit(2);
+ }
+
+ if ( childpid == 0 ) {
+ char *dialogmessage;
+ dialogmessage = malloc(77+sizeof(virname)+sizeof(FromR)+sizeof(ToR)+4+84+54);
+ sprintf(dialogmessage,"KlamAV has found an infected mail with the following details:\nVirus name: %s\n%s\n%s\nThe mail has been handled according to the filter rules set up in your mail client (probably put in your trash/deleted items directory).",*virname,FromR,ToR);
+
+ if (setenv("PATH","/usr/local/sbin:/usr/sbin:/sbin:/usr/bin:/bin:/usr/local/bin:/opt/kde/bin",1) == 0)
+ execlp("kdialog", "kdialog", "--msgbox", dialogmessage, "--title", "Virus found by KlamAV:", NULL);
+ free(dialogmessage);
+ }
+ } else if(ret == CL_CLEAN) {
+ int bcnt = 0;
+ lseek(fd, 0, SEEK_SET);
+ if (!(tmp = fdopen(fd,"r"))){
+ mprintf("@Can't open file %s\n", tmpnm);
+ return 54;
+ }
+
+ mprintf_stdout = 1;
+
+ while (fgets(string, sizeof(string), tmp)) {
+ if (*string == '\n') {
+ mprintf("X-Virus-Status: No\n");
+ mprintf("X-Virus-Checker: Scanned by KlamAV %s on %s (no viruses);\n\t%s\n\n",
+ KLAMAV_VERSION, host, out);
+ break;
+ }
+ fputs(string, stdout);
+ }
+ while (fgets(string, sizeof(string), tmp)) {
+ fputs(string, stdout);
+ }
+
+ if(optl(opt, "tag"))
+ if (!(*bndrystore))
+ printtag();
+
+ fclose(tmp);
+ } else {
+ if(!printinfected)
+ mprintf("stdin: %s\n", cl_strerror(ret));
+ }
+ return ret;
+}
+
+void printtag(void)
+{
+
+ mprintf_stdout = 1;
+ mprintf("\n");
+ mprintf("----------------------------------------------------------------------------\n");
+ mprintf(" This message was scanned by\n");
+ mprintf(" ClamAV Open Source Anti-Virus Technology\n");
+ mprintf(" using KlamAV\n");
+ mprintf("\n");
+ mprintf(" http://www.clamav.net\n");
+ mprintf(" http://klamav.sf.net\n");
+ mprintf("----------------------------------------------------------------------------\n");
+ mprintf("\n");
+ fflush(stdout);
+
+}
+
+void help(void)
+{
+
+ mprintf_stdout = 1;
+
+ mprintf("\n");
+ mprintf(" KlamAV Mail Processing Client "KLAMAV_VERSION"\n");
+ mprintf(" (c) 2004 Robert Hogan <robert@roberthogan.net>\n");
+ mprintf(" Uses a lot of code written by:\n");
+ mprintf(" Tomasz Kojm <zolw@konarski.edu.pl>\n");
+ mprintf(" Nigel Horne <njh@bandsman.co.uk>\n");
+ mprintf(" \n");
+ mprintf(" --help -h Show help\n");
+ mprintf(" --version -V Print version number and exit\n");
+ mprintf(" -f Header Flag Only.\n");
+ mprintf(" --tag Tag messages as scanned.\n");
+ mprintf(" -d Location of virus definition database.\n");
+
+ exit(0);
+}
+
+void startclamd(struct optstruct *opt)
+{
+
+ int pfds[2];
+ int childpid;
+ int fd;
+ char tmpnm[19];
+ char conffile[31];
+ struct stat sb;
+ FILE *tmp;
+ char *fullpath;
+ char cwd[200];
+ char *scancmd;
+
+ snprintf(tmpnm, sizeof(tmpnm), "klammailXXXXXX");
+ mkstemp(tmpnm);
+
+ fd = open(tmpnm,O_RDWR|O_CREAT, S_IRWXU);
+
+
+ lseek(fd, 0, SEEK_SET);
+ if (!(tmp = fdopen(fd,"w"))){
+ mprintf("@Can't open file \n");
+ }
+
+ fprintf(tmp,"LocalSocket /tmp/KlamMailSock\n");
+ fprintf(tmp,"MaxDirectoryRecursion 15\n");
+ fprintf(tmp,"SelfCheck 900\n");
+ //fprintf(tmp,"ScanArchive\n");
+ if(optc(opt, 'd')) {
+ stat(getargc(opt, 'd'), &sb);
+ switch(sb.st_mode & S_IFMT) {
+ case S_IFREG:
+ fprintf(tmp,"DatabaseDirectory %s\n",getargc(opt, 'd'));
+ break;
+ case S_IFDIR:
+ fprintf(tmp,"DatabaseDirectory %s\n",getargc(opt, 'd'));
+ break;
+ default:
+ mprintf("@%s: Not supported database file type\n", getargc(opt, 'd'));
+ break;
+ }
+ }else{
+ fprintf(tmp,"DatabaseDirectory /usr/local/share/clamav\n");
+ }
+ //fprintf(tmp,"ScanMail\n");
+ if ((strstr(cl_retver(), "0.8")) || (strstr(cl_retver(), "0.7")))
+ fprintf(tmp,"FixStaleSocket\n");
+ else
+#ifdef SUPPORT_CLAMAV_V095
+ fprintf(tmp,"FixStaleSocket yes\n");
+#else
+ fprintf(tmp,"FixStaleSocket TRUE\n");
+#endif
+
+ fflush(tmp);
+
+ fclose(tmp);
+ close(fd);
+
+ fullpath = (char*) mcalloc(200 + strlen(tmpnm) + 10, sizeof(char));
+
+ if(!getcwd(cwd, 200)) {
+ mprintf("@Can't get absolute pathname of current working directory.\n");
+ return;
+ }
+ sprintf(fullpath, "%s/%s", cwd, tmpnm);
+
+
+ if ( pipe(pfds) == -1 ) {
+ perror("Failed to create pipe; quitting\n");
+ exit(1);
+ }
+
+ if ( ( childpid=fork() ) == -1 ) {
+ perror("Failed to fork; quitting\n");
+ exit(2);
+ }
+
+ /* instead of STDIN -> clamdmail -> STDOUT, do
+ STDIN -> clamdmail -> spamc -> STDOUT
+ (previously incorrect as STDIN -> spamc -> clamdmail -> STDOUT)
+ */
+ if ( childpid == 0 ) {
+ if (setenv("PATH","/usr/local/sbin:/usr/sbin:/sbin:/usr/bin:/bin:/usr/local/bin:/opt/kde/bin",1) == 0)
+ execlp("clamd", "clamd", "-c", fullpath, NULL);
+ }
+
+ sleep(1);
+ unlink(fullpath);
+}
diff --git a/src/klammail/client.c b/src/klammail/client.c
new file mode 100755
index 0000000..6382785
--- /dev/null
+++ b/src/klammail/client.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl>
+ *
+ * Modified slightly by Robert Hogan <robert@roberthogan.net> as part of
+ * clamdmail package. 2003.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <dirent.h>
+
+//#include "others.h"
+#include "cfgparser.h"
+#include "memory.h"
+#include "options.h"
+#include "defaults.h"
+//#include "shared.h"
+#include <clamav.h>
+
+int client(const char *dirname, struct optstruct *opt, char **virname)
+{
+ char buff[4096], cwd[200], *file, *scancmd;
+ struct sockaddr_un server;
+ struct sockaddr_in server2;
+ struct cfgstruct *copt, *cpt;
+ int sockd, bread;
+ /*const char *clamav_conf = getargl(opt, "config-file");*/
+ const char *clamav_conf;
+ FILE *fd;
+ DIR *dd;
+ struct dirent *dent;
+ struct stat statbuf;
+ char *fname;
+ int scanret = 0;
+
+/*
+ if(!clamav_conf)
+ clamav_conf = DEFAULT_CFG;
+
+ if((copt = parsecfg(clamav_conf)) == NULL) {
+ mprintf("@Can't parse configuration file.\n");
+ return 2;
+ }
+
+ if(cfgopt(copt, "TCPSocket") && cfgopt(copt, "LocalSocket")) {
+ mprintf("@Clamd is not configured properly.\n");
+ return 2;
+ } else if((cpt = cfgopt(copt, "LocalSocket"))) {
+*/
+ server.sun_family = AF_UNIX;
+ strncpy(server.sun_path, "/tmp/KlamMailSock", sizeof(server.sun_path));
+
+ if((sockd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ //perror("socket()");
+ //mprintf("@Can't create the socket.\n");
+ return 2;
+ }
+
+ if(connect(sockd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
+ close(sockd);
+ //perror("connect()");
+ //mprintf("@Can't connect to clamd.\n");
+ return 2;
+ }
+/*
+ } else if((cpt = cfgopt(copt, "TCPSocket"))) {
+
+#ifdef PF_INET
+ if((sockd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+#else
+ if((sockd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+#endif
+ perror("socket()");
+ mprintf("@Can't create the socket.\n");
+ return 0;
+ }
+
+ server2.sin_family = AF_INET;
+ server2.sin_addr.s_addr = inet_addr("127.0.0.1");
+ server2.sin_port = htons(cpt->numarg);
+
+ if(connect(sockd, (struct sockaddr *) &server2, sizeof(struct sockaddr_in)) < 0) {
+ close(sockd);
+ perror("connect()");
+ mprintf("@Can't connect to clamd.\n");
+ return 0;
+ }
+
+ } else {
+ mprintf("@Clamd is not configured properly.\n");
+ return 2;
+ }
+*/
+
+
+ scanret = passfile(dirname, sockd, virname);
+
+
+ return scanret;
+}
+
+int passfile(const char *file, int sockd, char **virname)
+{
+
+ char buff[4096];
+ char *fullpath, cwd[200];
+ char *scancmd;
+ FILE *fd;
+
+// fullpath = mcalloc(200 + strlen(file) + 10, sizeof(char));
+//
+// if(!getcwd(cwd, 200)) {
+// mprintf("@Can't get absolute pathname of current working directory.\n");
+// return 0;
+// }
+// sprintf(fullpath, "%s/%s", cwd, file);
+
+ scancmd = (char *) mcalloc(strlen(file) + 20, sizeof(char));
+ sprintf(scancmd, "CONTSCAN %s", file);
+
+ if(write(sockd, scancmd, strlen(scancmd)) < 0) {
+ mprintf("@Can't write to the socket.\n");
+ close(sockd);
+ return 2;
+ }
+
+ if((fd = fdopen(sockd, "r")) == NULL) {
+ mprintf("@Can't open descriptor %d to read.\n", sockd);
+ return 2;
+ }
+
+ while(fgets(buff, sizeof(buff), fd)) {
+ if(strstr(buff, "FOUND\n")) {
+ strtok(buff, " ");
+ *virname = strtok(NULL, " ");
+ return 1;
+ }
+ }
+
+ fclose(fd);
+ return 0;
+}
diff --git a/src/klammail/defaults.h b/src/klammail/defaults.h
new file mode 100644
index 0000000..db8ebe0
--- /dev/null
+++ b/src/klammail/defaults.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#define CONFDIR "/etc"
+#define DEFAULT_CFG CONFDIR"/clamav/clamav.conf"
+#ifdef CLAMAVUSER
+#define UNPUSER CLAMAVUSER
+#else
+#define UNPUSER "clamav"
+#endif
+
+void *cli_malloc(size_t nmemb);
+
diff --git a/src/klammail/memory.c b/src/klammail/memory.c
new file mode 100644
index 0000000..63ac0a6
--- /dev/null
+++ b/src/klammail/memory.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+void *mmalloc(size_t size)
+{
+ void *alloc;
+
+ alloc = malloc(size);
+
+ if(!alloc) {
+ fprintf(stderr, "CRITICAL: Can't allocate memory (%ld bytes).\n", (long int) size);
+ _exit(71);
+ return NULL; /* shut up gcc */
+ } else return alloc;
+}
+
+void *mcalloc(size_t nmemb, size_t size)
+{
+ void *alloc;
+
+ alloc = calloc(nmemb, size);
+
+ if(!alloc) {
+ fprintf(stderr, "CRITICAL: Can't allocate memory (%ld bytes).\n", (long int) nmemb * size);
+ _exit(70);
+ return NULL;
+ } else return alloc;
+}
diff --git a/src/klammail/memory.h b/src/klammail/memory.h
new file mode 100644
index 0000000..d5c7a2f
--- /dev/null
+++ b/src/klammail/memory.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MEMORY_H
+#define __MEMORY_H
+
+#include <stdlib.h>
+
+void *mmalloc(size_t size);
+void *mcalloc(size_t nmemb, size_t size);
+
+#endif
diff --git a/src/klammail/options.c b/src/klammail/options.c
new file mode 100755
index 0000000..ffefd48
--- /dev/null
+++ b/src/klammail/options.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2001-2002 Tomasz Kojm <zolw@konarski.edu.pl>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Sat Sep 14 22:18:20 CEST 2002: included getfirst*(), getnext*() functions
+ * from Alejandro Dubrovsky <s328940@student.uq.edu.au>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <clamav.h>
+#define _GNU_SOURCE
+#include "getopt.h"
+
+#if defined(C_LINUX) && defined(CL_DEBUG)
+#include <sys/resource.h>
+#endif
+
+#include "options.h"
+//#include "others.h"
+//#include "shared.h"
+#include "memory.h"
+
+void clamdscan(struct optstruct *opt);
+
+int main(int argc, char **argv)
+{
+ int ret, opt_index, i, len;
+ struct optstruct *opt;
+
+ const char *getopt_parameters = "hvfd:wriVql:";
+
+ static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"quiet", 0, 0, 0},
+ {"verbose", 0, 0, 'v'},
+ {"version", 0, 0, 'V'},
+ {"config-file", 1, 0, 0},
+ {"tempdir", 1, 0, 0},
+ {"database", 1, 0, 'd'},
+ {"quick", 0, 0, 'q'},
+ {"whole-file", 0, 0, 'w'}, /* not used */
+ {"force", 0, 0, 0},
+ {"recursive", 0, 0, 'r'},
+ {"disable-summary", 0, 0, 0},
+ {"infected", 0, 0, 'i'},
+ {"log", 1, 0, 'l'},
+ {"log-verbose", 0, 0, 0},
+ {"threads", 1, 0, 0},
+ {"one-virus", 0, 0, 0}, /* not used */
+
+ {"remove", 0, 0, 0},
+ {"exclude", 1, 0, 0},
+ {"include", 1, 0, 0},
+ {"max-files", 1, 0, 0},
+ {"max-space", 1, 0, 0},
+ {"max-recursion", 1, 0, 0},
+ {"disable-archive", 0, 0, 0},
+
+ {"tag", 0, 0, 0},
+ {"foobar", 0, 0, 'f'},
+ {"admin", 1, 0, 0},
+ {"quar", 1, 0, 0},
+ {"mta", 1, 0, 0},
+ {"spam", 0, 0, 0},
+ {"unzip", 2, 0, 0},
+ {"unrar", 2, 0, 0},
+ {"unace", 2, 0, 0},
+ {"unarj", 2, 0, 0},
+ {"zoo", 2, 0, 0},
+ {"lha", 2, 0, 0},
+ {"jar", 2, 0, 0},
+ {"tar", 2, 0, 0},
+ {"tgz", 2, 0, 0},
+ {"deb", 2, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+#if defined(C_LINUX) && defined(CL_DEBUG)
+ /* njh@bandsman.co.uk: create a dump if needed */
+ struct rlimit rlim;
+
+ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
+ if(setrlimit(RLIMIT_CORE, &rlim) < 0)
+ perror("setrlimit");
+#endif
+
+ opt=(struct optstruct*) mmalloc(sizeof(struct optstruct));
+ opt->optlist = NULL;
+
+ while(1) {
+
+ opt_index=0;
+ ret=getopt_long(argc, argv, getopt_parameters, long_options, &opt_index);
+
+ if (ret == -1)
+ break;
+
+ switch (ret) {
+ case 0:
+ register_long_option(opt, long_options[opt_index].name);
+ break;
+
+ default:
+ if(strchr(getopt_parameters, ret))
+ register_char_option(opt, ret);
+ else {
+ mprintf("!Unknown option passed.\n");
+ free_opt(opt);
+ exit(40);
+ }
+ }
+ }
+
+ if (optind < argc) {
+
+ len=0;
+
+ /* count length of non-option arguments */
+
+ for(i=optind; i<argc; i++)
+ len+=strlen(argv[i]);
+
+ len=len+argc-optind-1; /* add spaces between arguments */
+ opt->filename=(char*)mcalloc(len + 256, sizeof(char));
+
+ for(i=optind; i<argc; i++) {
+ strncat(opt->filename, argv[i], strlen(argv[i]));
+ if(i != argc-1)
+ strncat(opt->filename, " ", 1);
+ }
+
+ } else
+ /* FIXME !!! Without this, we have segfault */
+ opt->filename=(char*)mcalloc(1, sizeof(char));
+
+
+ clamdscan(opt);
+
+ return(0);
+}
+
+void register_char_option(struct optstruct *opt, char ch)
+{
+ struct optnode *newnode;
+
+ newnode = (struct optnode *) mmalloc(sizeof(struct optnode));
+ newnode->optchar = ch;
+ if(optarg != NULL) {
+ newnode->optarg = (char *) mcalloc(strlen(optarg) + 1, sizeof(char));
+ strcpy(newnode->optarg, optarg);
+ } else newnode->optarg = NULL;
+
+ newnode->optname = NULL;
+ newnode->next = opt->optlist;
+ opt->optlist = newnode;
+}
+
+void register_long_option(struct optstruct *opt, const char *optname)
+{
+ struct optnode *newnode;
+
+ newnode = (struct optnode *) mmalloc(sizeof(struct optnode));
+ newnode->optchar = 0;
+ if(optarg != NULL) {
+ newnode->optarg = (char *) mcalloc(strlen(optarg) + 1, sizeof(char));
+ strcpy(newnode->optarg, optarg);
+ } else newnode->optarg = NULL;
+
+ newnode->optname = (char *) mcalloc(strlen(optname) + 1, sizeof(char));
+ strcpy(newnode->optname, optname);
+ newnode->next = opt->optlist;
+ opt->optlist = newnode;
+}
+
+int optc(const struct optstruct *opt, char ch)
+{
+ struct optnode *handler;
+
+ handler = opt->optlist;
+
+ while(1) {
+ if(handler) {
+ if(handler->optchar == ch) return 1;
+ } else break;
+ handler = handler->next;
+ }
+
+ return(0);
+}
+
+int optl(const struct optstruct *opt, const char *optname)
+{
+ struct optnode *handler;
+
+ handler = opt->optlist;
+
+ while(1) {
+ if(handler) {
+ if(handler->optname)
+ if(!strcmp(handler->optname, optname)) return 1;
+ } else break;
+ handler = handler->next;
+ }
+
+ return(0);
+}
+
+char *getargc(const struct optstruct *opt, char ch)
+{
+ struct optnode *handler;
+
+ handler = opt->optlist;
+
+ while(1) {
+ if(handler) {
+ if(handler->optchar == ch) return handler->optarg;
+ } else break;
+ handler = handler->next;
+ }
+
+ return(NULL);
+}
+
+char *getfirstargc(const struct optstruct *opt, char ch, struct optnode **optnode)
+{
+ struct optnode *handler;
+
+ handler = opt->optlist;
+
+ while(1) {
+ if(handler) {
+ if(handler->optchar == ch) {
+ *optnode = handler;
+ return handler->optarg;
+ }
+ } else break;
+ handler = handler->next;
+ }
+ *optnode = NULL;
+ return(NULL);
+}
+
+char *getnextargc(struct optnode **optnode, char ch)
+{
+ struct optnode *handler;
+
+ handler = (*optnode)->next;
+
+ while(1) {
+ if(handler) {
+ if(handler->optchar == ch) {
+ *optnode = handler;
+ return handler->optarg;
+ }
+ } else break;
+ handler = handler->next;
+ }
+ *optnode = NULL;
+ return(NULL);
+}
+
+char *getargl(const struct optstruct *opt, const char *optname)
+{
+ struct optnode *handler;
+
+ handler = opt->optlist;
+
+ while(1) {
+ if(handler) {
+ if(handler->optname)
+ if(!strcmp(handler->optname, optname)) return handler->optarg;
+ } else break;
+ handler = handler->next;
+ }
+
+ return(NULL);
+}
+
+char *getfirstargl(const struct optstruct *opt, const char *optname, struct optnode **optnode)
+{
+ struct optnode *handler;
+
+ handler = opt->optlist;
+
+ while(1) {
+ if(handler) {
+ if(handler->optname)
+ if(!strcmp(handler->optname, optname)) {
+ *optnode = handler;
+ return handler->optarg;
+ }
+ } else break;
+ handler = handler->next;
+ }
+
+ *optnode = NULL;
+ return(NULL);
+}
+
+char *getnextargl(struct optnode **optnode, const char *optname)
+{
+ struct optnode *handler;
+
+ handler = (*optnode)->next;
+
+ while(1) {
+ if(handler) {
+ if(handler->optname)
+ if(!strcmp(handler->optname, optname)) {
+ *optnode = handler;
+ return handler->optarg;
+ }
+ } else break;
+ handler = handler->next;
+ }
+
+ *optnode = NULL;
+ return(NULL);
+}
+
+void free_opt(struct optstruct *opt)
+{
+ struct optnode *handler, *prev;
+
+ if(!opt || !opt->optlist)
+ return;
+
+ mprintf("*Freeing option list... ");
+ handler = opt->optlist;
+
+ while(handler != NULL) {
+ handler->optchar = 0;
+ if(handler->optarg) free(handler->optarg);
+ if(handler->optname) free(handler->optname);
+ prev = handler;
+ handler = handler->next;
+ free(prev);
+ }
+
+ free(opt->filename);
+ free(opt);
+ mprintf("*done\n");
+}
diff --git a/src/klammail/options.h b/src/klammail/options.h
new file mode 100755
index 0000000..e42994f
--- /dev/null
+++ b/src/klammail/options.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __OPTIONS_H
+#define __OPTIONS_H
+
+struct optnode {
+ char optchar;
+ char *optarg;
+ char *optname;
+ struct optnode *next;
+};
+
+struct optstruct {
+ struct optnode *optlist;
+ char *filename;
+};
+
+int optc(const struct optstruct *opt, char ch);
+int optl(const struct optstruct *opt, const char *optname);
+void register_char_option(struct optstruct *opt, char ch);
+void register_long_option(struct optstruct *opt, const char *optname);
+char *getargc(const struct optstruct *opt, char ch);
+char *getfirstargc(const struct optstruct *opt, char ch, struct optnode **optnode);
+char *getnextargc(struct optnode **optnode, char ch);
+char *getargl(const struct optstruct *opt, const char *optname);
+char *getfirstargl(const struct optstruct *opt, const char *optname, struct optnode **optnode);
+char *getnextargl(struct optnode **optnode, const char *optname);
+void free_opt(struct optstruct *opt);
+
+#endif
diff --git a/src/klammail/output.c b/src/klammail/output.c
new file mode 100644
index 0000000..7efc77a
--- /dev/null
+++ b/src/klammail/output.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if defined(USE_SYSLOG) && !defined(C_AIX)
+#include <syslog.h>
+#endif
+
+#include "output.h"
+#include "memory.h"
+
+#ifdef CL_THREAD_SAFE
+#include <pthread.h>
+pthread_mutex_t logg_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+FILE *logg_fd = NULL;
+
+short int logg_verbose = 0, logg_lock = 0, logg_time = 0;
+int logg_size = 0;
+const char *logg_file = NULL;
+#if defined(USE_SYSLOG) && !defined(C_AIX)
+short logg_syslog = 0;
+#endif
+
+short int mprintf_disabled = 0, mprintf_verbose = 0, mprintf_quiet = 0,
+ mprintf_stdout = 0;
+
+int mdprintf(int desc, const char *str, ...)
+{
+ va_list args;
+ char buff[512];
+ int bytes;
+
+ va_start(args, str);
+ bytes = vsnprintf(buff, 512, str, args);
+ va_end(args);
+ write(desc, buff, bytes);
+ return bytes;
+}
+
+void logg_close(void) {
+
+#ifdef CL_THREAD_SAFE
+ pthread_mutex_lock(&logg_mutex);
+#endif
+ if (logg_fd) {
+ fclose(logg_fd);
+ logg_fd = NULL;
+ }
+#ifdef CL_THREAD_SAFE
+ pthread_mutex_unlock(&logg_mutex);
+#endif
+
+#if defined(USE_SYSLOG) && !defined(C_AIX)
+ if(logg_syslog) {
+ closelog();
+ }
+#endif
+}
+
+int logg(const char *str, ...)
+{
+ va_list args;
+ struct flock fl;
+ char *pt, *timestr, vbuff[1025];
+ time_t currtime;
+ struct stat sb;
+ mode_t old_umask;
+
+
+ va_start(args, str);
+
+ if(logg_file) {
+#ifdef CL_THREAD_SAFE
+ pthread_mutex_lock(&logg_mutex);
+#endif
+ if(!logg_fd) {
+ old_umask = umask(0037);
+ if((logg_fd = fopen(logg_file, "a")) == NULL) {
+ umask(old_umask);
+#ifdef CL_THREAD_SAFE
+ pthread_mutex_unlock(&logg_mutex);
+#endif
+ printf("ERROR: Can't open %s in append mode.\n", logg_file);
+ return -1;
+ } else umask(old_umask);
+
+ if(logg_lock) {
+ memset(&fl, 0, sizeof(fl));
+ fl.l_type = F_WRLCK;
+ if(fcntl(fileno(logg_fd), F_SETLK, &fl) == -1) {
+#ifdef CL_THREAD_SAFE
+ pthread_mutex_unlock(&logg_mutex);
+#endif
+ return -1;
+ }
+ }
+ }
+
+ /* Need to avoid logging time for verbose messages when logverbose
+ is not set or we get a bunch of timestamps in the log without
+ newlines... */
+ if(logg_time && ((*str != '*') || logg_verbose)) {
+ time(&currtime);
+ pt = ctime(&currtime);
+ timestr = mcalloc(strlen(pt), sizeof(char));
+ strncpy(timestr, pt, strlen(pt) - 1);
+ fprintf(logg_fd, "%s -> ", timestr);
+ free(timestr);
+ }
+
+ if(logg_size) {
+ if(stat(logg_file, &sb) != -1) {
+ if(sb.st_size > logg_size) {
+ logg_file = NULL;
+ fprintf(logg_fd, "Log size = %d, maximal = %d\n", (int) sb.st_size, logg_size);
+ fprintf(logg_fd, "LOGGING DISABLED (Maximal log file size exceeded).\n");
+ fclose(logg_fd);
+ logg_fd = NULL;
+#ifdef CL_THREAD_SAFE
+ pthread_mutex_unlock(&logg_mutex);
+#endif
+ return 0;
+ }
+ }
+ }
+
+
+ if(*str == '!') {
+ fprintf(logg_fd, "ERROR: ");
+ vfprintf(logg_fd, str + 1, args);
+ } else if(*str == '^') {
+ fprintf(logg_fd, "WARNING: ");
+ vfprintf(logg_fd, str + 1, args);
+ } else if(*str == '*') {
+ if(logg_verbose)
+ vfprintf(logg_fd, str + 1, args);
+ } else vfprintf(logg_fd, str, args);
+
+
+ fflush(logg_fd);
+
+#ifdef CL_THREAD_SAFE
+ pthread_mutex_unlock(&logg_mutex);
+#endif
+ }
+
+#if defined(USE_SYSLOG) && !defined(C_AIX)
+ if(logg_syslog) {
+
+ /* due to a problem with superfluous control characters (which
+ * vsnprintf() handles correctly) in (v)syslog we have to remove
+ * them in a final string
+ *
+ * FIXME: substitute %% instead of _
+ */
+ vsnprintf(vbuff, 1024, str, args);
+ vbuff[1024] = 0;
+
+ while((pt = strchr(vbuff, '%')))
+ *pt = '_';
+
+ if(vbuff[0] == '!') {
+ syslog(LOG_ERR, vbuff + 1);
+ } else if(vbuff[0] == '^') {
+ syslog(LOG_WARNING, vbuff + 1);
+ } else if(vbuff[0] == '*') {
+ if(logg_verbose) {
+ syslog(LOG_DEBUG, vbuff + 1);
+ }
+ } else syslog(LOG_INFO, vbuff);
+
+ }
+#endif
+
+ va_end(args);
+ return 0;
+}
+
+void mprintf(const char *str, ...)
+{
+ va_list args;
+ FILE *fd;
+ char logbuf[512];
+
+
+ if(mprintf_disabled) {
+ if(*str == '@') {
+ va_start(args, str);
+#ifdef NO_SNPRINTF
+ vsprintf(logbuf, ++str, args);
+#else
+ vsnprintf(logbuf, sizeof(logbuf), ++str, args);
+#endif
+ va_end(args);
+ logg("ERROR: %s", logbuf);
+ }
+ return;
+ }
+
+ if(mprintf_stdout)
+ fd = stdout;
+ else
+ fd = stderr;
+
+/* legend:
+ * ! - error
+ * @ - error with logging
+ * ...
+ */
+
+/*
+ * ERROR WARNING STANDARD
+ * normal yes yes yes
+ *
+ * verbose yes yes yes
+ *
+ * quiet yes no no
+ */
+
+
+ va_start(args, str);
+
+ if(*str == '!') {
+ fprintf(fd, "ERROR: ");
+ vfprintf(fd, ++str, args);
+ } else if(*str == '@') {
+ fprintf(fd, "ERROR: ");
+ vfprintf(fd, ++str, args);
+#ifdef NO_SNPRINTF
+ vsprintf(logbuf, str, args);
+#else
+ vsnprintf(logbuf, sizeof(logbuf), str, args);
+#endif
+ logg("ERROR: %s", logbuf);
+ } else if(!mprintf_quiet) {
+ if(*str == '^') {
+ fprintf(fd, "WARNING: ");
+ vfprintf(fd, ++str, args);
+ } else if(*str == '*') {
+ if(mprintf_verbose)
+ vfprintf(fd, ++str, args);
+ } else vfprintf(fd, str, args);
+ }
+
+ va_end(args);
+
+ if(fd == stdout)
+ fflush(stdout);
+
+}
+
+struct facstruct {
+ const char *name;
+ int code;
+};
+
+#if defined(USE_SYSLOG) && !defined(C_AIX)
+static const struct facstruct facilitymap[] = {
+#ifdef LOG_AUTH
+ { "LOG_AUTH", LOG_AUTH },
+#endif
+#ifdef LOG_AUTHPRIV
+ { "LOG_AUTHPRIV", LOG_AUTHPRIV },
+#endif
+#ifdef LOG_CRON
+ { "LOG_CRON", LOG_CRON },
+#endif
+#ifdef LOG_DAEMON
+ { "LOG_DAEMON", LOG_DAEMON },
+#endif
+#ifdef LOG_FTP
+ { "LOG_FTP", LOG_FTP },
+#endif
+#ifdef LOG_KERN
+ { "LOG_KERN", LOG_KERN },
+#endif
+#ifdef LOG_LPR
+ { "LOG_LPR", LOG_LPR },
+#endif
+#ifdef LOG_MAIL
+ { "LOG_MAIL", LOG_MAIL },
+#endif
+#ifdef LOG_NEWS
+ { "LOG_NEWS", LOG_NEWS },
+#endif
+#ifdef LOG_AUTH
+ { "LOG_AUTH", LOG_AUTH },
+#endif
+#ifdef LOG_SYSLOG
+ { "LOG_SYSLOG", LOG_SYSLOG },
+#endif
+#ifdef LOG_USER
+ { "LOG_USER", LOG_USER },
+#endif
+#ifdef LOG_UUCP
+ { "LOG_UUCP", LOG_UUCP },
+#endif
+#ifdef LOG_LOCAL0
+ { "LOG_LOCAL0", LOG_LOCAL0 },
+#endif
+#ifdef LOG_LOCAL1
+ { "LOG_LOCAL1", LOG_LOCAL1 },
+#endif
+#ifdef LOG_LOCAL2
+ { "LOG_LOCAL2", LOG_LOCAL2 },
+#endif
+#ifdef LOG_LOCAL3
+ { "LOG_LOCAL3", LOG_LOCAL3 },
+#endif
+#ifdef LOG_LOCAL4
+ { "LOG_LOCAL4", LOG_LOCAL4 },
+#endif
+#ifdef LOG_LOCAL5
+ { "LOG_LOCAL5", LOG_LOCAL5 },
+#endif
+#ifdef LOG_LOCAL6
+ { "LOG_LOCAL6", LOG_LOCAL6 },
+#endif
+#ifdef LOG_LOCAL7
+ { "LOG_LOCAL7", LOG_LOCAL7 },
+#endif
+ { NULL, -1 }
+};
+
+int logg_facility(const char *name)
+{
+ int i;
+
+ for(i = 0; facilitymap[i].name; i++)
+ if(!strcmp(facilitymap[i].name, name))
+ return facilitymap[i].code;
+
+ return -1;
+}
+#endif
diff --git a/src/klammail/output.h b/src/klammail/output.h
new file mode 100644
index 0000000..7ce004f
--- /dev/null
+++ b/src/klammail/output.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __OUTPUT_H
+#define __OUTPUT_H
+
+
+
+#include <stdlib.h>
+#include "cfgparser.h"
+
+int mdprintf(int desc, const char *str, ...);
+
+int logg(const char *str, ...);
+void logg_close(void);
+extern short int logg_verbose, logg_lock, logg_time;
+extern int logg_size;
+extern const char *logg_file;
+
+#if defined(USE_SYSLOG) && !defined(C_AIX)
+extern short logg_syslog;
+int logg_facility(const char *name);
+#endif
+
+void mprintf(const char *str, ...);
+extern short int mprintf_disabled, mprintf_verbose, mprintf_quiet, mprintf_stdout;
+
+#endif
diff --git a/src/klammail/shared.h b/src/klammail/shared.h
new file mode 100644
index 0000000..cdcd8b7
--- /dev/null
+++ b/src/klammail/shared.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __SHARED_H
+#define __SHARED_H
+
+struct s_info {
+ int signs; /* number of signatures loaded */
+ int dirs; /* number of scanned directories */
+ int files; /* number of scanned files */
+ int ifiles; /* number of infected files */
+ int notremoved; /* number of not removed files (if --remove) */
+ int notmoved; /* number of not moved files (if --move) */
+ int errors; /* ... of errors */
+ long int blocks; /* number of read 16kb blocks */
+};
+
+extern struct s_info claminfo;
+extern short recursion, printinfected, bell;
+
+#endif
diff --git a/src/klammail/str.h b/src/klammail/str.h
new file mode 100644
index 0000000..d3d9de5
--- /dev/null
+++ b/src/klammail/str.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __STRINGS_H
+#define __STRINGS_H
+
+int cli_strbcasestr(const char *haystack, const char *needle);
+void cli_chomp(char *string);
+char *cli_strtok(const char *line, int field, const char *delim);
+
+#endif
diff --git a/src/klammail/target.h b/src/klammail/target.h
new file mode 100755
index 0000000..556a669
--- /dev/null
+++ b/src/klammail/target.h
@@ -0,0 +1,68 @@
+/* automatically generated by configure */
+/* on Wed Aug 11 20:45:37 IST 2004 */
+/* target uppercase defines */
+
+#ifndef TARGET_OS_LINUX_GNU
+#define TARGET_OS_LINUX_GNU "linux-gnu"
+#endif
+
+#ifndef TARGET_OS_LINUX
+#define TARGET_OS_LINUX "linux-gnu"
+#endif
+
+#ifndef TARGET_OS_TYPE
+#define TARGET_OS_TYPE "linux-gnu"
+#endif
+
+#ifndef TARGET_CPU_I686
+#define TARGET_CPU_I686 "i686"
+#endif
+
+#ifndef TARGET_CPU_I
+#define TARGET_CPU_I "i686"
+#endif
+
+#ifndef TARGET_CPU_TYPE
+#define TARGET_CPU_TYPE "i686"
+#endif
+
+#ifndef TARGET_ARCH_I386
+#define TARGET_ARCH_I386 "i386"
+#endif
+
+#ifndef TARGET_ARCH_TYPE
+#define TARGET_ARCH_TYPE "i386"
+#endif
+/* host uppercase defines */
+
+#ifndef HOST_OS_LINUX_GNU
+#define HOST_OS_LINUX_GNU "linux-gnu"
+#endif
+
+#ifndef HOST_OS_LINUX
+#define HOST_OS_LINUX "linux-gnu"
+#endif
+
+#ifndef HOST_OS_TYPE
+#define HOST_OS_TYPE "linux-gnu"
+#endif
+
+#ifndef HOST_CPU_I686
+#define HOST_CPU_I686 "i686"
+#endif
+
+#ifndef HOST_CPU_I
+#define HOST_CPU_I "i686"
+#endif
+
+#ifndef HOST_CPU_TYPE
+#define HOST_CPU_TYPE "i686"
+#endif
+
+#ifndef HOST_ARCH_I386
+#define HOST_ARCH_I386 "i386"
+#endif
+
+#ifndef HOST_ARCH_TYPE
+#define HOST_ARCH_TYPE "i386"
+#endif