diff --git a/.gitignore b/.gitignore
index f213c79b..b562c588 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,16 @@
*.lib
*.key
*.pem
+*.so
+bin/3proxy
+bin/proxy
+bin/socks
+bin/tcppm
+bin/udppm
+bin/pop3p
+bin/smtpp
+bin/ftppr
+bin/mycrypt
bin64/
dll/
tmp/
@@ -24,6 +34,8 @@ tmp/
res
version.c
version
+version.sh
+buildlinux.sh
3proxy.res
src/3proxy
@@ -44,7 +56,6 @@ doc/html/man8/
*.var
verfile.sh
Makefile
-Changelog
copytgz.sh
*~.nib
local.properties
diff --git a/DEVEL b/DEVEL
new file mode 100644
index 00000000..4be3a61d
--- /dev/null
+++ b/DEVEL
@@ -0,0 +1 @@
+10-devel
\ No newline at end of file
diff --git a/Dockerfile.full b/Dockerfile.full
new file mode 100644
index 00000000..e9f59a3b
--- /dev/null
+++ b/Dockerfile.full
@@ -0,0 +1,55 @@
+# 3proxy.full is fully functional 3proxy build based on busibox:glibc
+#
+#to build:
+# docker build -f Dockerfile.full -t 3proxy.full .
+#to run:
+# by default 3proxy uses safe chroot environment with chroot to /usr/local/3proxy with uid/gid 65535/65535 and expects
+# configuration file to be placed in /usr/local/etc/3proxy.
+# Paths in configuration file must be relative to /usr/local/3proxy, that is use /logs instead of
+# /usr/local/3proxy/logs. nserver in chroot is required for DNS resolution. An example:
+#
+# echo nserver 8.8.8.8 >/path/to/local/config/directory/3proxy.cfg
+# echo proxy -p3129 >>/path/to/local/config/directory/3proxy.cfg
+# docker run -p 3129:3129 -v /path/to/local/config/directory:/usr/local/3proxy/conf -name 3proxy.full 3proxy.full
+#
+# /path/to/local/config/directory in this example must conrain 3proxy.cfg
+# if you need 3proxy to be executed without chroot with root permissions, replace /etc/3proxy/3proxy.cfg by e.g. mounting config
+# dir to /etc/3proxy ot by providing config file /etc/3proxy/3proxy.cfg
+# docker run -p 3129:3129 -v /path/to/local/config/directory:/etc/3proxy -name 3proxy.full 3proxy.full
+#
+# use "log" without pathname in config to log to stdout.
+# plugins are located in /usr/local/3proxy/libexec (/libexec for chroot config).
+
+
+FROM gcc AS buildenv
+COPY . 3proxy
+RUN cd 3proxy &&\
+ echo "">> Makefile.Linux &&\
+ echo PLUGINS = StringsPlugin TrafficPlugin PCREPlugin TransparentPlugin SSLPlugin>>Makefile.Linux &&\
+ echo LIBS = -l:libcrypto.a -l:libssl.a -ldl >>Makefile.Linux &&\
+ make -f Makefile.Linux &&\
+ strip bin/3proxy &&\
+ strip bin/StringsPlugin.ld.so &&\
+ strip bin/TrafficPlugin.ld.so &&\
+ strip bin/PCREPlugin.ld.so &&\
+ strip bin/TransparentPlugin.ld.so &&\
+ strip bin/SSLPlugin.ld.so
+
+FROM busybox:glibc
+COPY --from=buildenv /lib/x86_64-linux-gnu/libdl.so.* /lib/
+COPY --from=buildenv 3proxy/bin/3proxy /bin/
+COPY --from=buildenv 3proxy/bin/*.ld.so /usr/local/3proxy/libexec/
+RUN mkdir /usr/local/3proxy/logs &&\
+ mkdir /usr/local/3proxy/conf &&\
+ chown -R 65535:65535 /usr/local/3proxy &&\
+ chmod -R 550 /usr/local/3proxy &&\
+ chmod 750 /usr/local/3proxy/logs &&\
+ chmod -R 555 /usr/local/3proxy/libexec &&\
+ chown -R root /usr/local/3proxy/libexec &&\
+ mkdir /etc/3proxy/ &&\
+ echo chroot /usr/local/3proxy 65535 65535 >/etc/3proxy/3proxy.cfg &&\
+ echo include /conf/3proxy.cfg >>/etc/3proxy/3proxy.cfg &&\
+ chmod 440 /etc/3proxy/3proxy.cfg
+
+
+CMD ["/bin/3proxy", "/etc/3proxy/3proxy.cfg"]
diff --git a/Dockerfile.minimal b/Dockerfile.minimal
new file mode 100644
index 00000000..4ea1d506
--- /dev/null
+++ b/Dockerfile.minimal
@@ -0,0 +1,42 @@
+# dockerfile for "interactive" minimal 3proxy execution, no configuration mounting is required, configuration
+# is accepted from stdin. Use "end" command to indicate the end of configuration. Use "log" for stdout logging.
+#
+# This is busybox based docker with only 3proxy static executable and empty non-writable "run" directory.
+#
+# "plugin" is not supported
+#
+# Build:
+#
+# docker build -f Dockerfile.minimal -t 3proxy.minimal .
+#
+# Run example:
+#
+# docker run -i -p 3129:3129 --name 3proxy 3proxy.minimal
+#or
+# docker start -i 3proxy
+#>Makefile.Linux&&\
+ echo LDFLAGS = -fPIE -O2 -fno-strict-aliasing -pthread >>Makefile.Linux&&\
+ echo PLUGINS = >>Makefile.Linux&&\
+ echo LIBS = >>Makefile.Linux&&\
+ echo CFLAGS = -g -fPIC -O2 -fno-strict-aliasing -c -pthread -DWITHSPLICE -D_GNU_SOURCE -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_NETFILTER -DNOPLUGINS >>Makefile.Linux&&\
+ make -f Makefile.Linux&&\
+ strip bin/3proxy
+
+
+FROM busybox:glibc
+COPY --from=buildenv /3proxy/bin/3proxy /bin/3proxy
+RUN mkdir /run && chmod 555 /run
+CMD ["/bin/3proxy"]
diff --git a/Makefile.FreeBSD b/Makefile.FreeBSD
index 0d004f42..5bab5a77 100644
--- a/Makefile.FreeBSD
+++ b/Makefile.FreeBSD
@@ -28,6 +28,7 @@ OBJSUFFICS = .o
DEFINEOPTION = -D
COMPFILES = *~
REMOVECOMMAND = rm -f
+AFTERCLEAN = find src/ -type f -name "*.o" -delete && find src/ -type f -name "Makefile.var" -delete && find bin/ -type f -perm +111 -delete
TYPECOMMAND = cat
COMPATLIBS =
MAKEFILE = Makefile.FreeBSD
@@ -35,23 +36,105 @@ PLUGINS = StringsPlugin TrafficPlugin PCREPlugin PamAuth TransparentPlugin
include Makefile.inc
-install: all
- if [ ! -d /usr/local/3proxy/bin ]; then mkdir -p /usr/local/3proxy/bin/; fi
- install bin/3proxy /usr/local/3proxy/bin/3proxy
- install bin/mycrypt /usr/local/3proxy/bin/mycrypt
- install scripts/add3proxyuser.sh /usr/local/3proxy/bin/
- if [ -s /usr/local/etc/3proxy/3proxy.cfg ]; then
- echo /usr/local/3proxy/3proxy.cfg already exists
- else
- install scripts/3proxy.cfg /usr/local/etc/3proxy/
- if [ ! -d /var/log/3proxy/ ]; then
- mkdir /var/log/3proxy/
- fi
- touch /usr/local/3proxy/passwd
- touch /usr/local/3proxy/counters
- touch /usr/local/3proxy/bandlimiters
- echo Run /usr/local/3proxy/bin/add3proxyuser.sh to add \'admin\' user
- fi
allplugins:
@list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; cd ../.. ; done
+
+DESTDIR =
+prefix =
+exec_prefix = $(prefix)
+man_prefix = /usr/share
+chroot_prefix = /usr/local
+
+INSTALL = /usr/bin/install
+INSTALL_BIN = $(INSTALL) -m 755
+INSTALL_DATA = $(INSTALL) -m 644
+INSTALL_OBJS = bin/3proxy \
+ bin/ftppr \
+ bin/mycrypt \
+ bin/pop3p \
+ bin/proxy \
+ bin/socks \
+ bin/tcppm \
+ bin/udppm
+
+
+INSTALL_CFG = scripts/3proxy.cfg.chroot
+INSTALL_CFG_OBJS = scripts/3proxy.cfg \
+ scripts/add3proxyuser.sh
+
+INSTALL_CFG_OBJS2 = counters bandlimiters
+
+INSTALL_INITD_SCRIPT = scripts/init.d/3proxy.sh
+INSTALL_SYSTEMD_SCRIPT = scripts/3proxy.service
+
+CHROOTDIR = $(DESTDIR)$(chroot_prefix)/3proxy
+CHROOTREL = ../..$(chroot_prefix)/3proxy
+MANDIR1 = $(DESTDIR)$(man_prefix)/man/man1
+MANDIR3 = $(DESTDIR)$(man_prefix)/man/man3
+MANDIR8 = $(DESTDIR)$(man_prefix)/man/man8
+BINDIR = $(DESTDIR)$(exec_prefix)/bin
+ETCDIR = $(DESTDIR)/etc/3proxy
+INITDDIR = $(DESTDIR)/etc/init.d
+RUNBASE = $(DESTDIR)/var/run
+RUNDIR = $(RUNBASE)/3proxy
+LOGBASE = $(DESTDIR)/var/log
+LOGDIR = $(LOGBASE)/3proxy
+INSTALL_CFG_DEST = $(ETCDIR)/conf
+SYSTEMDDIR = $(DESTDIR)/usr/lib/systemd/system/
+
+install-bin:
+ $(INSTALL_BIN) -d $(BINDIR)
+ $(INSTALL_BIN) -s $(INSTALL_OBJS) $(BINDIR)
+ $(INSTALL_BIN) -s bin/*.ld.so $(CHROOTDIR)/libexec
+ chmod -R a-w $(CHROOTDIR)/libexec
+
+install-etc-dir:
+ $(INSTALL_BIN) -d $(ETCDIR)
+
+install-chroot-dir:
+ $(INSTALL_BIN) -d $(CHROOTDIR)
+ $(INSTALL_BIN) -d $(CHROOTDIR)/conf
+ $(INSTALL_BIN) -d $(CHROOTDIR)/logs
+ $(INSTALL_BIN) -d $(CHROOTDIR)/count
+ $(INSTALL_BIN) -d $(CHROOTDIR)/libexec
+ chmod -R o-rwx $(CHROOTDIR)
+
+install-etc-default-config:
+ if [ ! -d $(INSTALL_CFG_DEST) ]; then \
+ ln -s $(CHROOTREL)/conf $(INSTALL_CFG_DEST); \
+ $(INSTALL_BIN) $(INSTALL_CFG) $(ETCDIR)/3proxy.cfg; \
+ $(INSTALL_BIN) $(INSTALL_CFG_OBJS) $(INSTALL_CFG_DEST); \
+ fi
+
+install-etc: install-etc-dir install-etc-default-config
+ for file in $(INSTALL_CFG_OBJS2); \
+ do \
+ touch $(INSTALL_CFG_DEST)/$$file; chmod 0600 $(INSTALL_CFG_DEST)/$$file; \
+ done;
+
+install-man:
+ $(INSTALL_BIN) -d $(MANDIR3)
+ $(INSTALL_BIN) -d $(MANDIR8)
+ $(INSTALL_DATA) man/*.3 $(MANDIR3)
+ $(INSTALL_DATA) man/*.8 $(MANDIR8)
+
+install-init:
+ $(INSTALL_BIN) -d $(INITDDIR)
+ $(INSTALL_BIN) $(INSTALL_INITD_SCRIPT) $(INITDDIR)/3proxy
+ $(INSTALL_BIN) -d $(SYSTEMDDIR)
+ $(INSTALL_DATA) $(INSTALL_SYSTEMD_SCRIPT) $(SYSTEMDDIR)
+
+install-run:
+ $(INSTALL_BIN) -d $(RUNDIR)
+
+install-log:
+ $(INSTALL_BIN) -d $(LOGBASE)
+ @if [ ! -d $(LOGDIR) ]; then \
+ ln -s $(CHROOTREL)/logs $(LOGDIR);\
+ fi
+
+install: install-chroot-dir install-bin install-etc install-log install-man install-run install-init
+ @if [ "$(DESTDIR)" = "" ]; then \
+ sh scripts/postinst; \
+ fi
diff --git a/Makefile.Linux b/Makefile.Linux
index 45e4295f..ff763da4 100644
--- a/Makefile.Linux
+++ b/Makefile.Linux
@@ -12,7 +12,7 @@ CC = gcc
CFLAGS = -g -fPIC -O2 -fno-strict-aliasing -c -pthread -DWITHSPLICE -D_GNU_SOURCE -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_NETFILTER
COUT = -o
-LN = gcc
+LN = $(CC)
DCFLAGS =
LDFLAGS = -fPIE -O2 -fno-strict-aliasing -pthread
DLFLAGS = -shared
@@ -26,6 +26,7 @@ OBJSUFFICS = .o
DEFINEOPTION = -D
COMPFILES = *~
REMOVECOMMAND = rm -f
+AFTERCLEAN = find src/ -type f -name "*.o" -delete && find src/ -type f -name "Makefile.var" -delete && find bin/ -type f -executable -delete
TYPECOMMAND = cat
COMPATLIBS =
MAKEFILE = Makefile.Linux
@@ -45,6 +46,7 @@ DESTDIR =
prefix =
exec_prefix = $(prefix)
man_prefix = /usr/share
+chroot_prefix = /usr/local
INSTALL = /usr/bin/install
INSTALL_BIN = $(INSTALL) -m 755
@@ -66,19 +68,22 @@ INSTALL_CFG_OBJS = scripts/3proxy.cfg \
INSTALL_CFG_OBJS2 = counters bandlimiters
INSTALL_INITD_SCRIPT = scripts/init.d/3proxy.sh
+INSTALL_SYSTEMD_SCRIPT = scripts/3proxy.service
-CHROOTDIR = $(DESTDIR)/usr/local/3proxy
+CHROOTDIR = $(DESTDIR)$(chroot_prefix)/3proxy
+CHROOTREL = ../..$(chroot_prefix)/3proxy
MANDIR1 = $(DESTDIR)$(man_prefix)/man/man1
MANDIR3 = $(DESTDIR)$(man_prefix)/man/man3
MANDIR8 = $(DESTDIR)$(man_prefix)/man/man8
BINDIR = $(DESTDIR)$(exec_prefix)/bin
-ETCDIR = $(DESTDIR)$(prefix)/etc/3proxy
-INITDDIR = $(DESTDIR)$(prefix)/etc/init.d
-RUNBASE = $(DESTDIR)$(prefix)/var/run
+ETCDIR = $(DESTDIR)/etc/3proxy
+INITDDIR = $(DESTDIR)/etc/init.d
+RUNBASE = $(DESTDIR)/var/run
RUNDIR = $(RUNBASE)/3proxy
-LOGBASE = $(DESTDIR)$(prefix)/var/log
+LOGBASE = $(DESTDIR)/var/log
LOGDIR = $(LOGBASE)/3proxy
INSTALL_CFG_DEST = $(ETCDIR)/conf
+SYSTEMDDIR = $(DESTDIR)/usr/lib/systemd/system/
install-bin:
$(INSTALL_BIN) -d $(BINDIR)
@@ -99,7 +104,7 @@ install-chroot-dir:
install-etc-default-config:
if [ ! -d $(INSTALL_CFG_DEST) ]; then \
- ln -s $(CHROOTDIR)/conf $(INSTALL_CFG_DEST); \
+ ln -s $(CHROOTREL)/conf $(INSTALL_CFG_DEST); \
$(INSTALL_BIN) $(INSTALL_CFG) $(ETCDIR)/3proxy.cfg; \
$(INSTALL_BIN) $(INSTALL_CFG_OBJS) $(INSTALL_CFG_DEST); \
fi
@@ -117,46 +122,22 @@ install-man:
$(INSTALL_DATA) man/*.8 $(MANDIR8)
install-init:
- if [ -d $(INITDIR) ]; then \
- $(INSTALL_BIN) $(INSTALL_INITD_SCRIPT) $(INITDDIR)/3proxy; \
- fi
- if [ -f /usr/sbin/update-rc.d ]; then \
- /usr/sbin/update-rc.d 3proxy defaults; \
- /usr/sbin/update-rc.d 3proxy enable; \
- fi
+ $(INSTALL_BIN) -d $(INITDDIR)
+ $(INSTALL_BIN) $(INSTALL_INITD_SCRIPT) $(INITDDIR)/3proxy
+ $(INSTALL_BIN) -d $(SYSTEMDDIR)
+ $(INSTALL_DATA) $(INSTALL_SYSTEMD_SCRIPT) $(SYSTEMDDIR)
install-run:
$(INSTALL_BIN) -d $(RUNDIR)
install-log:
- @if [ -d $(LOGBASE) ] && [ ! -d $(LOGDIR) ]; then \
- ln -s $(CHROOTDIR)/logs $(LOGDIR);\
+ $(INSTALL_BIN) -d $(LOGBASE)
+ @if [ ! -d $(LOGDIR) ]; then \
+ ln -s $(CHROOTREL)/logs $(LOGDIR);\
fi
install: install-chroot-dir install-bin install-etc install-log install-man install-run install-init
- @getent passwd proxy || useradd -UMr -s /bin/false -c 3proxy proxy
- @if [ ! -f $(INSTALL_CFG_DEST)/passwd ]; then \
- touch $(INSTALL_CFG_DEST)/passwd;\
- fi
- @chown -R proxy:proxy $(CHROOTDIR)
- @chmod 550 $(CHROOTDIR)/
- @chmod 550 $(CHROOTDIR)/conf/
- @chmod 440 $(CHROOTDIR)/conf/*
- @echo ""
- @echo 3proxy installed.
- @echo use
- @echo " "service 3proxy start
- @echo to start proxy
- @echo " "service 3proxy stop
- @echo to stop proxy
- @echo " "$(INSTALL_CFG_DEST)/add3proxyuser.sh
- @echo to add users
- @echo ""
- @echo Default config uses Google\'s DNS.
- @echo It\'s recommended to use provider supplied DNS or install local recursor, e.g. pdns-recursor.
- @echo Configure preferred DNS in $(INSTALL_CFG_DEST)/3proxy.cfg.
- @echo run \'$(INSTALL_CFG_DEST)/add3proxyuser.sh admin password\' to configure \'admin\' user
- @if [ -f /usr/sbin/service ]; then \
- /usr/sbin/service 3proxy stop ;\
- /usr/sbin/service 3proxy start ;\
+ @if [ "$(DESTDIR)" = "" ]; then \
+ sh scripts/debian/preinst; \
+ sh scripts/debian/postinst; \
fi
diff --git a/Makefile.Solaris b/Makefile.Solaris
index 158ed7f1..8e84f20e 100644
--- a/Makefile.Solaris
+++ b/Makefile.Solaris
@@ -11,7 +11,7 @@ BUILDDIR = ../bin/
CC = cc
CFLAGS = -xO3 -c -D_SOLARIS -D_THREAD_SAFE -DGETHOSTBYNAME_R -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL
COUT = -o ./
-LN = cc
+LN = $(CC)
LDFLAGS = -xO3
DCFLAGS = -fPIC
DLFLAGS = -shared
@@ -25,6 +25,7 @@ OBJSUFFICS = .o
DEFINEOPTION = -D
COMPFILES = *~
REMOVECOMMAND = rm -f
+AFTERCLEAN = find src/ -type f -name "*.o" -delete && find src/ -type f -name "Makefile.var" -delete && find bin/ -type f -executable -delete
TYPECOMMAND = cat
COMPATLIBS =
MAKEFILE = Makefile.Solaris
@@ -34,3 +35,102 @@ include Makefile.inc
allplugins:
@list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; cd ../.. ; done
+
+DESTDIR =
+prefix =
+exec_prefix = $(prefix)
+man_prefix = /usr/share
+chroot_prefix = /usr/local
+
+INSTALL = /usr/bin/install
+INSTALL_BIN = $(INSTALL) -m 755
+INSTALL_DATA = $(INSTALL) -m 644
+INSTALL_OBJS = bin/3proxy \
+ bin/ftppr \
+ bin/mycrypt \
+ bin/pop3p \
+ bin/proxy \
+ bin/socks \
+ bin/tcppm \
+ bin/udppm
+
+
+INSTALL_CFG = scripts/3proxy.cfg.chroot
+INSTALL_CFG_OBJS = scripts/3proxy.cfg \
+ scripts/add3proxyuser.sh
+
+INSTALL_CFG_OBJS2 = counters bandlimiters
+
+INSTALL_INITD_SCRIPT = scripts/init.d/3proxy.sh
+INSTALL_SYSTEMD_SCRIPT = scripts/3proxy.service
+
+CHROOTDIR = $(DESTDIR)$(chroot_prefix)/3proxy
+CHROOTREL = ../..$(chroot_prefix)/3proxy
+MANDIR1 = $(DESTDIR)$(man_prefix)/man/man1
+MANDIR3 = $(DESTDIR)$(man_prefix)/man/man3
+MANDIR8 = $(DESTDIR)$(man_prefix)/man/man8
+BINDIR = $(DESTDIR)$(exec_prefix)/bin
+ETCDIR = $(DESTDIR)/etc/3proxy
+INITDDIR = $(DESTDIR)/etc/init.d
+RUNBASE = $(DESTDIR)/var/run
+RUNDIR = $(RUNBASE)/3proxy
+LOGBASE = $(DESTDIR)/var/log
+LOGDIR = $(LOGBASE)/3proxy
+INSTALL_CFG_DEST = $(ETCDIR)/conf
+SYSTEMDDIR = $(DESTDIR)/usr/lib/systemd/system/
+
+install-bin:
+ $(INSTALL_BIN) -d $(BINDIR)
+ $(INSTALL_BIN) -s $(INSTALL_OBJS) $(BINDIR)
+ $(INSTALL_BIN) -s bin/*.ld.so $(CHROOTDIR)/libexec
+ chmod -R a-w $(CHROOTDIR)/libexec
+
+install-etc-dir:
+ $(INSTALL_BIN) -d $(ETCDIR)
+
+install-chroot-dir:
+ $(INSTALL_BIN) -d $(CHROOTDIR)
+ $(INSTALL_BIN) -d $(CHROOTDIR)/conf
+ $(INSTALL_BIN) -d $(CHROOTDIR)/logs
+ $(INSTALL_BIN) -d $(CHROOTDIR)/count
+ $(INSTALL_BIN) -d $(CHROOTDIR)/libexec
+ chmod -R o-rwx $(CHROOTDIR)
+
+install-etc-default-config:
+ if [ ! -d $(INSTALL_CFG_DEST) ]; then \
+ ln -s $(CHROOTREL)/conf $(INSTALL_CFG_DEST); \
+ $(INSTALL_BIN) $(INSTALL_CFG) $(ETCDIR)/3proxy.cfg; \
+ $(INSTALL_BIN) $(INSTALL_CFG_OBJS) $(INSTALL_CFG_DEST); \
+ fi
+
+install-etc: install-etc-dir install-etc-default-config
+ for file in $(INSTALL_CFG_OBJS2); \
+ do \
+ touch $(INSTALL_CFG_DEST)/$$file; chmod 0600 $(INSTALL_CFG_DEST)/$$file; \
+ done;
+
+install-man:
+ $(INSTALL_BIN) -d $(MANDIR3)
+ $(INSTALL_BIN) -d $(MANDIR8)
+ $(INSTALL_DATA) man/*.3 $(MANDIR3)
+ $(INSTALL_DATA) man/*.8 $(MANDIR8)
+
+install-init:
+ $(INSTALL_BIN) -d $(INITDDIR)
+ $(INSTALL_BIN) $(INSTALL_INITD_SCRIPT) $(INITDDIR)/3proxy
+ $(INSTALL_BIN) -d $(SYSTEMDDIR)
+ $(INSTALL_DATA) $(INSTALL_SYSTEMD_SCRIPT) $(SYSTEMDDIR)
+
+install-run:
+ $(INSTALL_BIN) -d $(RUNDIR)
+
+install-log:
+ $(INSTALL_BIN) -d $(LOGBASE)
+ @if [ ! -d $(LOGDIR) ]; then \
+ ln -s $(CHROOTREL)/logs $(LOGDIR);\
+ fi
+
+install: install-chroot-dir install-bin install-etc install-log install-man install-run install-init
+ @if [ "$(DESTDIR)" = "" ]; then \
+ sh scripts/postinst; \
+ fi
diff --git a/Makefile.Solaris-gcc b/Makefile.Solaris-gcc
index 65ded9bb..6d3bba3c 100644
--- a/Makefile.Solaris-gcc
+++ b/Makefile.Solaris-gcc
@@ -12,7 +12,7 @@ BUILDDIR = ../bin/
CC = gcc
CFLAGS = -O2 -fno-strict-aliasing -c -D_SOLARIS -D_THREAD_SAFE -DGETHOSTBYNAME_R -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL
COUT = -o ./
-LN = gcc
+LN = $(CC)
LDFLAGS = -O3
DCFLAGS = -fPIC
DLFLAGS = -shared
@@ -26,6 +26,7 @@ OBJSUFFICS = .o
DEFINEOPTION = -D
COMPFILES = *~
REMOVECOMMAND = rm -f
+AFTERCLEAN = find src/ -type f -name "*.o" -delete && find src/ -type f -name "Makefile.var" -delete && find bin/ -type f -executable -delete
TYPECOMMAND = cat
COMPATLIBS =
MAKEFILE = Makefile.Solaris-gcc
@@ -35,3 +36,102 @@ include Makefile.inc
allplugins:
@list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; cd ../.. ; done
+
+DESTDIR =
+prefix =
+exec_prefix = $(prefix)
+man_prefix = /usr/share
+chroot_prefix = /usr/local
+
+INSTALL = /usr/bin/install
+INSTALL_BIN = $(INSTALL) -m 755
+INSTALL_DATA = $(INSTALL) -m 644
+INSTALL_OBJS = bin/3proxy \
+ bin/ftppr \
+ bin/mycrypt \
+ bin/pop3p \
+ bin/proxy \
+ bin/socks \
+ bin/tcppm \
+ bin/udppm
+
+
+INSTALL_CFG = scripts/3proxy.cfg.chroot
+INSTALL_CFG_OBJS = scripts/3proxy.cfg \
+ scripts/add3proxyuser.sh
+
+INSTALL_CFG_OBJS2 = counters bandlimiters
+
+INSTALL_INITD_SCRIPT = scripts/init.d/3proxy.sh
+INSTALL_SYSTEMD_SCRIPT = scripts/3proxy.service
+
+CHROOTDIR = $(DESTDIR)$(chroot_prefix)/3proxy
+CHROOTREL = ../..$(chroot_prefix)/3proxy
+MANDIR1 = $(DESTDIR)$(man_prefix)/man/man1
+MANDIR3 = $(DESTDIR)$(man_prefix)/man/man3
+MANDIR8 = $(DESTDIR)$(man_prefix)/man/man8
+BINDIR = $(DESTDIR)$(exec_prefix)/bin
+ETCDIR = $(DESTDIR)/etc/3proxy
+INITDDIR = $(DESTDIR)/etc/init.d
+RUNBASE = $(DESTDIR)/var/run
+RUNDIR = $(RUNBASE)/3proxy
+LOGBASE = $(DESTDIR)/var/log
+LOGDIR = $(LOGBASE)/3proxy
+INSTALL_CFG_DEST = $(ETCDIR)/conf
+SYSTEMDDIR = $(DESTDIR)/usr/lib/systemd/system/
+
+install-bin:
+ $(INSTALL_BIN) -d $(BINDIR)
+ $(INSTALL_BIN) -s $(INSTALL_OBJS) $(BINDIR)
+ $(INSTALL_BIN) -s bin/*.ld.so $(CHROOTDIR)/libexec
+ chmod -R a-w $(CHROOTDIR)/libexec
+
+install-etc-dir:
+ $(INSTALL_BIN) -d $(ETCDIR)
+
+install-chroot-dir:
+ $(INSTALL_BIN) -d $(CHROOTDIR)
+ $(INSTALL_BIN) -d $(CHROOTDIR)/conf
+ $(INSTALL_BIN) -d $(CHROOTDIR)/logs
+ $(INSTALL_BIN) -d $(CHROOTDIR)/count
+ $(INSTALL_BIN) -d $(CHROOTDIR)/libexec
+ chmod -R o-rwx $(CHROOTDIR)
+
+install-etc-default-config:
+ if [ ! -d $(INSTALL_CFG_DEST) ]; then \
+ ln -s $(CHROOTREL)/conf $(INSTALL_CFG_DEST); \
+ $(INSTALL_BIN) $(INSTALL_CFG) $(ETCDIR)/3proxy.cfg; \
+ $(INSTALL_BIN) $(INSTALL_CFG_OBJS) $(INSTALL_CFG_DEST); \
+ fi
+
+install-etc: install-etc-dir install-etc-default-config
+ for file in $(INSTALL_CFG_OBJS2); \
+ do \
+ touch $(INSTALL_CFG_DEST)/$$file; chmod 0600 $(INSTALL_CFG_DEST)/$$file; \
+ done;
+
+install-man:
+ $(INSTALL_BIN) -d $(MANDIR3)
+ $(INSTALL_BIN) -d $(MANDIR8)
+ $(INSTALL_DATA) man/*.3 $(MANDIR3)
+ $(INSTALL_DATA) man/*.8 $(MANDIR8)
+
+install-init:
+ $(INSTALL_BIN) -d $(INITDDIR)
+ $(INSTALL_BIN) $(INSTALL_INITD_SCRIPT) $(INITDDIR)/3proxy
+ $(INSTALL_BIN) -d $(SYSTEMDDIR)
+ $(INSTALL_DATA) $(INSTALL_SYSTEMD_SCRIPT) $(SYSTEMDDIR)
+
+install-run:
+ $(INSTALL_BIN) -d $(RUNDIR)
+
+install-log:
+ $(INSTALL_BIN) -d $(LOGBASE)
+ @if [ ! -d $(LOGDIR) ]; then \
+ ln -s $(CHROOTREL)/logs $(LOGDIR);\
+ fi
+
+install: install-chroot-dir install-bin install-etc install-log install-man install-run install-init
+ @if [ "$(DESTDIR)" = "" ]; then \
+ sh scripts/postinst; \
+ fi
diff --git a/Makefile.inc b/Makefile.inc
index 4e088ee3..928aecd7 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -3,10 +3,11 @@
#
all:
- $(TYPECOMMAND) $(MAKEFILE) > src/Makefile.var
+ @$(TYPECOMMAND) $(MAKEFILE) > src/Makefile.var
@cd src && $(MAKE)
clean:
- @$(REMOVECOMMAND) *$(OBJSUFFICS) $(COMPFILES)
- @cd src && $(MAKE) clean
+ @cd src && $(REMOVECOMMAND) *$(OBJSUFFICS) $(COMPFILES) && cd ..
+ @$(AFTERCLEAN)
+
diff --git a/Makefile.intl b/Makefile.intl
deleted file mode 100644
index 56ab7d9c..00000000
--- a/Makefile.intl
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# 3 proxy Makefile for Intel C compiler for Windows (for both make and nmake)
-#
-# You can try to remove -DWITH_STD_MALLOC to CFLAGS to use optimized malloc
-# libraries
-#
-# Add /DSAFESQL to CFLAGS if you are using poorely written/tested ODBC driver
-
-
-BUILDDIR = ../bin/
-CC = icl
-CFLAGS = /nologo /MD /W3 /G6 /GX /O2 /D "WITH_STD_MALLOC" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /YX /FD /c
-COUT = /Fo
-LN = xilink
-LDFLAGS = /nologo /subsystem:console /incremental:no /machine:I386
-LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib
-DLFLAGS = /DLL
-DLSUFFICS = .dll
-LNOUT = /out:
-EXESUFFICS = .exe
-OBJSUFFICS = .obj
-DEFINEOPTION = /D
-COMPFILES = *.pch *.idb
-REMOVECOMMAND = del 2>NUL
-TYPECOMMAND = type
-COMPATLIBS =
-MAKEFILE = Makefile.intl
-PLUGINS = WindowsAuthentication TrafficPlugin PCREPlugin
-
-include Makefile.inc
-
-allplugins:
- for /D %%i in ($(PLUGINS)) do (copy Makefile Makefile.var plugins\%%i && cd plugins\%%i && nmake && del *.obj *.idb &&cd ..\..)
diff --git a/Makefile.llvm b/Makefile.llvm
index f3b892ed..a4d2115c 100644
--- a/Makefile.llvm
+++ b/Makefile.llvm
@@ -12,7 +12,7 @@ BUILDDIR = ../bin/
CC = clang
CFLAGS = -O2 -fno-strict-aliasing -c -pthread -static -DWITH_STD_MALLOC -DNOIPV6
COUT = -o
-LN = clang
+LN = $(CC)
LDFLAGS = -O2 -fno-strict-aliasing -static -s
DLFLAGS = -shared
DLSUFFICS = .dll
@@ -25,6 +25,7 @@ OBJSUFFICS = .o
DEFINEOPTION = -D
COMPFILES = *.tmp
REMOVECOMMAND = rm -f
+AFTERCLEAN = find src/ -type f -name "*.o" -delete && find src/ -type f -name "Makefile.var" -delete && find bin/ -type f -executable -delete
TYPECOMMAND = cat
COMPATLIBS =
MAKEFILE = Makefile.win
@@ -34,3 +35,102 @@ include Makefile.inc
allplugins:
for /D %%i in ($(PLUGINS)) do (copy Makefile plugins\%%i && copy Makefile.var plugins\%%i && cd plugins\%%i && nmake && del *.o &&cd ..\..)
+
+DESTDIR =
+prefix =
+exec_prefix = $(prefix)
+man_prefix = /usr/share
+chroot_prefix = /usr/local
+
+INSTALL = /usr/bin/install
+INSTALL_BIN = $(INSTALL) -m 755
+INSTALL_DATA = $(INSTALL) -m 644
+INSTALL_OBJS = bin/3proxy \
+ bin/ftppr \
+ bin/mycrypt \
+ bin/pop3p \
+ bin/proxy \
+ bin/socks \
+ bin/tcppm \
+ bin/udppm
+
+
+INSTALL_CFG = scripts/3proxy.cfg.chroot
+INSTALL_CFG_OBJS = scripts/3proxy.cfg \
+ scripts/add3proxyuser.sh
+
+INSTALL_CFG_OBJS2 = counters bandlimiters
+
+INSTALL_INITD_SCRIPT = scripts/init.d/3proxy.sh
+INSTALL_SYSTEMD_SCRIPT = scripts/3proxy.service
+
+CHROOTDIR = $(DESTDIR)$(chroot_prefix)/3proxy
+CHROOTREL = ../..$(chroot_prefix)/3proxy
+MANDIR1 = $(DESTDIR)$(man_prefix)/man/man1
+MANDIR3 = $(DESTDIR)$(man_prefix)/man/man3
+MANDIR8 = $(DESTDIR)$(man_prefix)/man/man8
+BINDIR = $(DESTDIR)$(exec_prefix)/bin
+ETCDIR = $(DESTDIR)/etc/3proxy
+INITDDIR = $(DESTDIR)/etc/init.d
+RUNBASE = $(DESTDIR)/var/run
+RUNDIR = $(RUNBASE)/3proxy
+LOGBASE = $(DESTDIR)/var/log
+LOGDIR = $(LOGBASE)/3proxy
+INSTALL_CFG_DEST = $(ETCDIR)/conf
+SYSTEMDDIR = $(DESTDIR)/usr/lib/systemd/system/
+
+install-bin:
+ $(INSTALL_BIN) -d $(BINDIR)
+ $(INSTALL_BIN) -s $(INSTALL_OBJS) $(BINDIR)
+ $(INSTALL_BIN) -s bin/*.ld.so $(CHROOTDIR)/libexec
+ chmod -R a-w $(CHROOTDIR)/libexec
+
+install-etc-dir:
+ $(INSTALL_BIN) -d $(ETCDIR)
+
+install-chroot-dir:
+ $(INSTALL_BIN) -d $(CHROOTDIR)
+ $(INSTALL_BIN) -d $(CHROOTDIR)/conf
+ $(INSTALL_BIN) -d $(CHROOTDIR)/logs
+ $(INSTALL_BIN) -d $(CHROOTDIR)/count
+ $(INSTALL_BIN) -d $(CHROOTDIR)/libexec
+ chmod -R o-rwx $(CHROOTDIR)
+
+install-etc-default-config:
+ if [ ! -d $(INSTALL_CFG_DEST) ]; then \
+ ln -s $(CHROOTREL)/conf $(INSTALL_CFG_DEST); \
+ $(INSTALL_BIN) $(INSTALL_CFG) $(ETCDIR)/3proxy.cfg; \
+ $(INSTALL_BIN) $(INSTALL_CFG_OBJS) $(INSTALL_CFG_DEST); \
+ fi
+
+install-etc: install-etc-dir install-etc-default-config
+ for file in $(INSTALL_CFG_OBJS2); \
+ do \
+ touch $(INSTALL_CFG_DEST)/$$file; chmod 0600 $(INSTALL_CFG_DEST)/$$file; \
+ done;
+
+install-man:
+ $(INSTALL_BIN) -d $(MANDIR3)
+ $(INSTALL_BIN) -d $(MANDIR8)
+ $(INSTALL_DATA) man/*.3 $(MANDIR3)
+ $(INSTALL_DATA) man/*.8 $(MANDIR8)
+
+install-init:
+ $(INSTALL_BIN) -d $(INITDDIR)
+ $(INSTALL_BIN) $(INSTALL_INITD_SCRIPT) $(INITDDIR)/3proxy
+ $(INSTALL_BIN) -d $(SYSTEMDDIR)
+ $(INSTALL_DATA) $(INSTALL_SYSTEMD_SCRIPT) $(SYSTEMDDIR)
+
+install-run:
+ $(INSTALL_BIN) -d $(RUNDIR)
+
+install-log:
+ $(INSTALL_BIN) -d $(LOGBASE)
+ @if [ ! -d $(LOGDIR) ]; then \
+ ln -s $(CHROOTREL)/logs $(LOGDIR);\
+ fi
+
+install: install-chroot-dir install-bin install-etc install-log install-man install-run install-init
+ @if [ "$(DESTDIR)" = "" ]; then \
+ sh scripts/postinst; \
+ fi
diff --git a/Makefile.msvc b/Makefile.msvc
index b33e3fb7..08db98fc 100644
--- a/Makefile.msvc
+++ b/Makefile.msvc
@@ -8,7 +8,7 @@
BUILDDIR = ../bin/
CC = cl
-CFLAGS = /nologo /MT /W3 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
+CFLAGS = /nologo /MT /W3 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
COUT = /Fo
LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no /machine:I386
@@ -24,23 +24,21 @@ EXESUFFICS = .exe
OBJSUFFICS = .obj
DEFINEOPTION = /D
COMPFILES = *.pch *.idb
-REMOVECOMMAND = del 2>NUL >NUL
+REMOVECOMMAND = del
TYPECOMMAND = type
COMPATLIBS =
MAKEFILE = Makefile.msvc
PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin FilePlugin SSLPlugin
-VERFILE = $(VERFILE)
+VERFILE = 3proxy.res $(VERFILE)
VERSION = $(VERSION)
+VERSIONDEP = 3proxy.res $(VERSIONDEP)
BUILDDATE = $(BUILDDATE)
-
+AFTERCLEAN = if exist src\*.res (del src\*.res) && if exist src\*.err (del src\*.err)
include Makefile.inc
-../3proxy.res:
- rc /fo../3proxy.res ../3proxy.rc $(VERSION) $(BUILDDATE)
-
-3proxyres.obj: ../3proxy.res
- cvtres /out:3proxyres.obj /MACHINE:I386 ../3proxy.res
+3proxy.res:
+ rc 3proxy.rc
allplugins:
for /D %%i in ($(PLUGINS)) do (copy Makefile plugins\%%i && copy Makefile.var plugins\%%i && cd plugins\%%i && nmake && del *.obj *.idb &&cd ..\..)
diff --git a/Makefile.msvc64 b/Makefile.msvc64
index 92f9e6b7..b9e0f074 100644
--- a/Makefile.msvc64
+++ b/Makefile.msvc64
@@ -8,7 +8,7 @@
BUILDDIR = ../bin64/
CC = cl
-CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
+CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
COUT = /Fo
LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no /machine:x64
@@ -27,20 +27,15 @@ COMPFILES = *.pch *.idb
REMOVECOMMAND = del 2>NUL >NUL
TYPECOMMAND = type
COMPATLIBS =
-MAKEFILE = Makefile.msvc64
+VERFILE = 3proxy.res $(VERFILE)
+VERSIONDEP = 3proxy.res $(VERSIONDEP)
PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin FilePlugin SSLPlugin
-VERFILE = $(VERFILE)
-
-#../3proxy.res:
-# rc /fo../3proxy.res ../3proxy.rc
-
-#3proxyres.obj: ../3proxy.res
-# cvtres /out:3proxyres.obj /MACHINE:X64 ../3proxy.res
+AFTERCLEAN = del src\*.res
include Makefile.inc
-../3proxy.res:
- rc /fo../3proxy.res ../3proxy.rc $(VERSION) $(BUILDDATE)
+3proxy.res:
+ rc 3proxy.rc
3proxyres.obj: ../3proxy.res
cvtres /out:3proxyres.obj /machine:x64 ../3proxy.res
diff --git a/Makefile.msvcARM64 b/Makefile.msvcARM64
index 9eb1e651..2897a351 100644
--- a/Makefile.msvcARM64
+++ b/Makefile.msvcARM64
@@ -8,7 +8,7 @@
BUILDDIR = ../bin64/
CC = cl
-CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
+CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
COUT = /Fo
LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no /machine:arm64
@@ -29,18 +29,15 @@ TYPECOMMAND = type
COMPATLIBS =
MAKEFILE = Makefile.msvcARM64
PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin FilePlugin
-VERFILE = $(VERFILE)
+VERFILE = 3proxy.res $(VERFILE)
+VERSIONDEP = 3proxy.res $(VERSIONDEP)
+AFTERCLEAN = del src\*.res
-#../3proxy.res:
-# rc /fo../3proxy.res ../3proxy.rc
-
-#3proxyres.obj: ../3proxy.res
-# cvtres /out:3proxyres.obj /MACHINE:X64 ../3proxy.res
include Makefile.inc
-../3proxy.res:
- rc /fo../3proxy.res ../3proxy.rc $(VERSION) $(BUILDDATE)
+3proxy.res:
+ rc 3proxy.rc
3proxyres.obj: ../3proxy.res
cvtres /out:3proxyres.obj /machine:x64 ../3proxy.res
diff --git a/Makefile.msvcCE b/Makefile.msvcCE
deleted file mode 100644
index bbff3fae..00000000
--- a/Makefile.msvcCE
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# 3 proxy Makefile for Microsoft Visual C compiler (for both make and nmake)
-#
-# You can try to remove -DWITH_STD_MALLOC to CFLAGS to use optimized malloc
-# libraries
-#
-# Add /DSAFESQL to CFLAGS if you are using poorely written/tested ODBC driver
-
-BUILDDIR = ../bin/
-CC = cl
-CFLAGS = /DARM /D "NOODBC" /nologo /MT /W3 /Wp64 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "_WINCE" /D "WITH_STD_MALLOC" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c
-COUT = /Fo
-LN = link
-LDFLAGS = /nologo /subsystem:console /incremental:no
-DLFLAGS = /DLL
-DLSUFFICS = .dll
-LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib
-LIBEXT = .lib
-LNOUT = /out:
-EXESUFFICS = .exe
-OBJSUFFICS = .obj
-DEFINEOPTION = /D
-COMPFILES = *.pch *.idb
-REMOVECOMMAND = del 2>NUL >NUL
-TYPECOMMAND = type
-COMPATLIBS =
-MAKEFILE = Makefile.msvc
-PLUGINS = WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin
-
-
-include Makefile.inc
-
-allplugins:
- for /D %%i in ($(PLUGINS)) do (copy Makefile plugins\%%i && copy Makefile.var plugins\%%i && cd plugins\%%i && nmake && del *.obj *.idb &&cd ..\..)
-
\ No newline at end of file
diff --git a/Makefile.openwrt-mips b/Makefile.openwrt-mips
index 3445b440..e6eecc5f 100644
--- a/Makefile.openwrt-mips
+++ b/Makefile.openwrt-mips
@@ -12,7 +12,7 @@ CC = mips-openwrt-linux-gcc
CFLAGS = -g -O2 -fno-strict-aliasing -c -pthread -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_NETFILTER
COUT = -o
-LN = mips-openwrt-linux-gcc
+LN = $(CC)
DCFLAGS = -fPIC
LDFLAGS = -O2 -fno-strict-aliasing -pthread -s
DLFLAGS = -shared
@@ -26,6 +26,7 @@ OBJSUFFICS = .o
DEFINEOPTION = -D
COMPFILES = *~
REMOVECOMMAND = rm -f
+AFTERCLEAN = find src/ -type f -name "*.o" -delete && find src/ -type f -name "Makefile.var" -delete && find bin/ -type f -executable -delete
TYPECOMMAND = cat
COMPATLIBS =
MAKEFILE = Makefile.openwrt-mips
@@ -42,53 +43,76 @@ allplugins:
@list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; cd ../.. ; done
DESTDIR =
-prefix = /usr/local
+prefix =
exec_prefix = $(prefix)
-man_prefix = $(prefix)/share
+man_prefix = /usr/share
+chroot_prefix = /usr/local
INSTALL = /usr/bin/install
INSTALL_BIN = $(INSTALL) -m 755
INSTALL_DATA = $(INSTALL) -m 644
-INSTALL_OBJS = src/3proxy \
- src/ftppr \
- src/mycrypt \
- src/pop3p \
- src/proxy \
- src/socks \
- src/tcppm \
- src/udppm
+INSTALL_OBJS = bin/3proxy \
+ bin/ftppr \
+ bin/mycrypt \
+ bin/pop3p \
+ bin/proxy \
+ bin/socks \
+ bin/tcppm \
+ bin/udppm
+INSTALL_CFG = scripts/3proxy.cfg.chroot
INSTALL_CFG_OBJS = scripts/3proxy.cfg \
scripts/add3proxyuser.sh
-INSTALL_CFG_DEST = config
-INSTALL_CFG_OBJS2 = passwd counters bandlimiters
+INSTALL_CFG_OBJS2 = counters bandlimiters
+INSTALL_INITD_SCRIPT = scripts/init.d/3proxy.sh
+INSTALL_SYSTEMD_SCRIPT = scripts/3proxy.service
+
+CHROOTDIR = $(DESTDIR)$(chroot_prefix)/3proxy
+CHROOTREL = ../..$(chroot_prefix)/3proxy
MANDIR1 = $(DESTDIR)$(man_prefix)/man/man1
MANDIR3 = $(DESTDIR)$(man_prefix)/man/man3
MANDIR8 = $(DESTDIR)$(man_prefix)/man/man8
BINDIR = $(DESTDIR)$(exec_prefix)/bin
-ETCDIR = $(DESTDIR)$(prefix)/etc/3proxy
+ETCDIR = $(DESTDIR)/etc/3proxy
+INITDDIR = $(DESTDIR)/etc/init.d
+RUNBASE = $(DESTDIR)/var/run
+RUNDIR = $(RUNBASE)/3proxy
+LOGBASE = $(DESTDIR)/var/log
+LOGDIR = $(LOGBASE)/3proxy
+INSTALL_CFG_DEST = $(ETCDIR)/conf
+SYSTEMDDIR = $(DESTDIR)/usr/lib/systemd/system/
install-bin:
$(INSTALL_BIN) -d $(BINDIR)
$(INSTALL_BIN) -s $(INSTALL_OBJS) $(BINDIR)
+ $(INSTALL_BIN) -s bin/*.ld.so $(CHROOTDIR)/libexec
+ chmod -R a-w $(CHROOTDIR)/libexec
install-etc-dir:
$(INSTALL_BIN) -d $(ETCDIR)
+install-chroot-dir:
+ $(INSTALL_BIN) -d $(CHROOTDIR)
+ $(INSTALL_BIN) -d $(CHROOTDIR)/conf
+ $(INSTALL_BIN) -d $(CHROOTDIR)/logs
+ $(INSTALL_BIN) -d $(CHROOTDIR)/count
+ $(INSTALL_BIN) -d $(CHROOTDIR)/libexec
+ chmod -R o-rwx $(CHROOTDIR)
+
install-etc-default-config:
- if [ -f $(ETCDIR)/$(INSTALL_CFG_DEST) ]; then \
- : ; \
- else \
- $(INSTALL_DATA) $(INSTALL_CFG_OBJS) $(ETCDIR)/$(INSTALL_CFG_DEST) \
+ if [ ! -d $(INSTALL_CFG_DEST) ]; then \
+ ln -s $(CHROOTREL)/conf $(INSTALL_CFG_DEST); \
+ $(INSTALL_BIN) $(INSTALL_CFG) $(ETCDIR)/3proxy.cfg; \
+ $(INSTALL_BIN) $(INSTALL_CFG_OBJS) $(INSTALL_CFG_DEST); \
fi
-install-etc: install-etc-dir
+install-etc: install-etc-dir install-etc-default-config
for file in $(INSTALL_CFG_OBJS2); \
do \
- touch $(ETCDIR)/$$file; chmod 0600 $(ETCDIR)/$$file; \
+ touch $(INSTALL_CFG_DEST)/$$file; chmod 0600 $(INSTALL_CFG_DEST)/$$file; \
done;
install-man:
@@ -97,5 +121,22 @@ install-man:
$(INSTALL_DATA) man/*.3 $(MANDIR3)
$(INSTALL_DATA) man/*.8 $(MANDIR8)
-install: install-bin install-etc install-man
+install-init:
+ $(INSTALL_BIN) -d $(INITDDIR)
+ $(INSTALL_BIN) $(INSTALL_INITD_SCRIPT) $(INITDDIR)/3proxy
+ $(INSTALL_BIN) -d $(SYSTEMDDIR)
+ $(INSTALL_DATA) $(INSTALL_SYSTEMD_SCRIPT) $(SYSTEMDDIR)
+
+install-run:
+ $(INSTALL_BIN) -d $(RUNDIR)
+install-log:
+ $(INSTALL_BIN) -d $(LOGBASE)
+ @if [ ! -d $(LOGDIR) ]; then \
+ ln -s $(CHROOTREL)/logs $(LOGDIR);\
+ fi
+
+install: install-chroot-dir install-bin install-etc install-log install-man install-run install-init
+ @if [ "$(DESTDIR)" = "" ]; then \
+ sh scripts/postinst; \
+ fi
diff --git a/Makefile.unix b/Makefile.unix
index cb26a0c2..742c5aa9 100644
--- a/Makefile.unix
+++ b/Makefile.unix
@@ -13,7 +13,7 @@ CC = gcc
# you may need -L/usr/pkg/lib for older NetBSD versions
CFLAGS = -g -O2 -fno-strict-aliasing -c -pthread -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL
COUT = -o
-LN = gcc
+LN = $(CC)
LDFLAGS = -O2 -fno-strict-aliasing -pthread
# -lpthreads may be reuqired on some platforms instead of -pthreads
# -ldl or -lld may be required for some platforms
@@ -29,6 +29,7 @@ OBJSUFFICS = .o
DEFINEOPTION = -D
COMPFILES = *~
REMOVECOMMAND = rm -f
+AFTERCLEAN = find src/ -type f -name "*.o" -delete && find src/ -type f -name "Makefile.var" -delete && find bin/ -type f -executable -delete
TYPECOMMAND = cat
COMPATLIBS =
MAKEFILE = Makefile.unix
@@ -36,24 +37,104 @@ PLUGINS = StringsPlugin TrafficPlugin PCREPlugin PamAuth TransparentPlugin
include Makefile.inc
-install: all
- if [ ! -d /usr/local/etc/3proxy/bin ]; then mkdir -p /usr/local/etc/3proxy/bin/; fi
- install bin/3proxy /usr/local/etc/3proxy/bin/3proxy
- install bin/mycrypt /usr/local/etc/3proxy/bin/mycrypt
- install scripts/rc.d/proxy.sh /usr/local/etc/rc.d/proxy.sh
- install scripts/add3proxyuser.sh /usr/local/etc/3proxy/bin/
- if [ -s /usr/local/etc/3proxy/3proxy.cfg ]; then
- echo /usr/local/etc/3proxy/3proxy.cfg already exists
- else
- install scripts/3proxy.cfg /usr/local/etc/3proxy/
- if [ ! -d /var/log/3proxy/ ]; then
- mkdir /var/log/3proxy/
+allplugins:
+ @list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; cd ../.. ; done
+
+DESTDIR =
+prefix =
+exec_prefix = $(prefix)
+man_prefix = /usr/share
+chroot_prefix = /usr/local
+
+INSTALL = /usr/bin/install
+INSTALL_BIN = $(INSTALL) -m 755
+INSTALL_DATA = $(INSTALL) -m 644
+INSTALL_OBJS = bin/3proxy \
+ bin/ftppr \
+ bin/mycrypt \
+ bin/pop3p \
+ bin/proxy \
+ bin/socks \
+ bin/tcppm \
+ bin/udppm
+
+
+INSTALL_CFG = scripts/3proxy.cfg.chroot
+INSTALL_CFG_OBJS = scripts/3proxy.cfg \
+ scripts/add3proxyuser.sh
+
+INSTALL_CFG_OBJS2 = counters bandlimiters
+
+INSTALL_INITD_SCRIPT = scripts/init.d/3proxy.sh
+INSTALL_SYSTEMD_SCRIPT = scripts/3proxy.service
+
+CHROOTDIR = $(DESTDIR)$(chroot_prefix)/3proxy
+CHROOTREL = ../..$(chroot_prefix)/3proxy
+MANDIR1 = $(DESTDIR)$(man_prefix)/man/man1
+MANDIR3 = $(DESTDIR)$(man_prefix)/man/man3
+MANDIR8 = $(DESTDIR)$(man_prefix)/man/man8
+BINDIR = $(DESTDIR)$(exec_prefix)/bin
+ETCDIR = $(DESTDIR)/etc/3proxy
+INITDDIR = $(DESTDIR)/etc/init.d
+RUNBASE = $(DESTDIR)/var/run
+RUNDIR = $(RUNBASE)/3proxy
+LOGBASE = $(DESTDIR)/var/log
+LOGDIR = $(LOGBASE)/3proxy
+INSTALL_CFG_DEST = $(ETCDIR)/conf
+SYSTEMDDIR = $(DESTDIR)/usr/lib/systemd/system/
+
+install-bin:
+ $(INSTALL_BIN) -d $(BINDIR)
+ $(INSTALL_BIN) -s $(INSTALL_OBJS) $(BINDIR)
+ $(INSTALL_BIN) -s bin/*.ld.so $(CHROOTDIR)/libexec
+ chmod -R a-w $(CHROOTDIR)/libexec
+
+install-etc-dir:
+ $(INSTALL_BIN) -d $(ETCDIR)
+
+install-chroot-dir:
+ $(INSTALL_BIN) -d $(CHROOTDIR)
+ $(INSTALL_BIN) -d $(CHROOTDIR)/conf
+ $(INSTALL_BIN) -d $(CHROOTDIR)/logs
+ $(INSTALL_BIN) -d $(CHROOTDIR)/count
+ $(INSTALL_BIN) -d $(CHROOTDIR)/libexec
+ chmod -R o-rwx $(CHROOTDIR)
+
+install-etc-default-config:
+ if [ ! -d $(INSTALL_CFG_DEST) ]; then \
+ ln -s $(CHROOTREL)/conf $(INSTALL_CFG_DEST); \
+ $(INSTALL_BIN) $(INSTALL_CFG) $(ETCDIR)/3proxy.cfg; \
+ $(INSTALL_BIN) $(INSTALL_CFG_OBJS) $(INSTALL_CFG_DEST); \
fi
- touch /usr/local/etc/3proxy/passwd
- touch /usr/local/etc/3proxy/counters
- touch /usr/local/etc/3proxy/bandlimiters
- echo Run /usr/local/etc/3proxy/bin/add3proxyuser.sh to add \'admin\' user
+
+install-etc: install-etc-dir install-etc-default-config
+ for file in $(INSTALL_CFG_OBJS2); \
+ do \
+ touch $(INSTALL_CFG_DEST)/$$file; chmod 0600 $(INSTALL_CFG_DEST)/$$file; \
+ done;
+
+install-man:
+ $(INSTALL_BIN) -d $(MANDIR3)
+ $(INSTALL_BIN) -d $(MANDIR8)
+ $(INSTALL_DATA) man/*.3 $(MANDIR3)
+ $(INSTALL_DATA) man/*.8 $(MANDIR8)
+
+install-init:
+ $(INSTALL_BIN) -d $(INITDDIR)
+ $(INSTALL_BIN) $(INSTALL_INITD_SCRIPT) $(INITDDIR)/3proxy
+ $(INSTALL_BIN) -d $(SYSTEMDDIR)
+ $(INSTALL_DATA) $(INSTALL_SYSTEMD_SCRIPT) $(SYSTEMDDIR)
+
+install-run:
+ $(INSTALL_BIN) -d $(RUNDIR)
+
+install-log:
+ $(INSTALL_BIN) -d $(LOGBASE)
+ @if [ ! -d $(LOGDIR) ]; then \
+ ln -s $(CHROOTREL)/logs $(LOGDIR);\
fi
-allplugins:
- @list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; cd ../.. ; done
+install: install-chroot-dir install-bin install-etc install-log install-man install-run install-init
+ @if [ "$(DESTDIR)" = "" ]; then \
+ sh scripts/postinst; \
+ fi
diff --git a/Makefile.unix-install b/Makefile.unix-install
deleted file mode 100644
index d9c8fe08..00000000
--- a/Makefile.unix-install
+++ /dev/null
@@ -1,59 +0,0 @@
-DESTDIR =
-prefix = /usr/local
-exec_prefix = $(prefix)
-man_prefix = $(prefix)/share
-
-INSTALL = /usr/bin/install
-INSTALL_BIN = $(INSTALL) -m 755
-INSTALL_DATA = $(INSTALL) -m 644
-INSTALL_OBJS = bin/3proxy \
- bin/ftppr \
- bin/mycrypt \
- bin/pop3p \
- bin/proxy \
- bin/socks \
- bin/tcppm \
- bin/udppm \
- scripts/add3proxyuser.sh
-
-INSTALL_CFG_OBJS = scripts/3proxy.cfg
-INSTALL_CFG_DEST = config
-
-INSTALL_CFG_OBJS2 = passwd counters bandlimiters
-
-MANDIR1 = $(DESTDIR)$(man_prefix)/man/man1
-MANDIR3 = $(DESTDIR)$(man_prefix)/man/man3
-MANDIR8 = $(DESTDIR)$(man_prefix)/man/man8
-BINDIR = $(DESTDIR)$(exec_prefix)/bin
-ETCDIR = $(DESTDIR)$(prefix)/etc/3proxy
-
-install-bin:
- $(INSTALL_BIN) -d $(BINDIR)
- $(INSTALL_BIN) -s $(INSTALL_OBJS) $(BINDIR)
-
-install-etc-dir:
- $(INSTALL_BIN) -d $(ETCDIR)
-
-install-etc-default-config:
- if [ -f $(ETCDIR)/$(INSTALL_CFG_DEST) ]; then \
- : ; \
- else \
- $(INSTALL_DATA) $(INSTALL_CFG_OBJS) $(ETCDIR)/$(INSTALL_CFG_DEST) \
- fi
-
-install-etc: install-etc-dir
- for file in $(INSTALL_CFG_OBJS2); \
- do \
- touch $(ETCDIR)/$$file; chmod 0600 $(ETCDIR)/$$file; \
- done;
-
-install-man:
- $(INSTALL_BIN) -d $(MANDIR1)
- $(INSTALL_BIN) -d $(MANDIR3)
- $(INSTALL_BIN) -d $(MANDIR8)
- $(INSTALL_DATA) man/*.1 $(MANDIR1)
- $(INSTALL_DATA) man/*.3 $(MANDIR3)
- $(INSTALL_DATA) man/*.8 $(MANDIR8)
-
-install: install-bin install-etc install-man
-
diff --git a/Makefile.watcom b/Makefile.watcom
index 18898832..f2b9dace 100644
--- a/Makefile.watcom
+++ b/Makefile.watcom
@@ -8,7 +8,7 @@
BUILDDIR = ../bin/
CC = cl
-CFLAGS = /nologo /Ox /MT /D "NOIPV6" /D "NODEBUG" /D "NOODBC" /D "NORADIUS" /D"WATCOM" /D "MSVC" /D "WITH_STD_MALLOC" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /c $(VERSION) $(BUILDDATE)
+CFLAGS = /nologo /Ox /MT /D "NOIPV6" /D "NODEBUG" /D "NOODBC" /D "NORADIUS" /D"WATCOM" /D "MSVC" /D "WITH_STD_MALLOC" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /c $(VERSION) $(BUILDDATE)
COUT = /Fo
LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no
@@ -30,14 +30,43 @@ COMPATLIBS =
MAKEFILE = Makefile.watcom
PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin
VERFILE = $(VERFILE)
+VERSION = $(VERSION)
+VERSIONDEP = 3proxy.res $(VERSIONDEP)
+BUILDDATE = $(BUILDDATE)
include Makefile.inc
-../3proxy.res:
- rc /fo../3proxy.res ../3proxy.rc $(VERSION) $(BUILDDATE)
-
-3proxyres.obj: ../3proxy.res
- cvtres /out:3proxyres.obj ../3proxy.res
+3proxy.res:
+ rc 3proxy.rc
allplugins:
- call ../makeplugins.bat
\ No newline at end of file
+ copy Makefile plugins\utf8tocp1251
+ copy Makefile.var plugins\utf8tocp1251
+ cd plugins\utf8tocp1251
+ nmake
+ del *.obj *.idb
+ cd ../../
+ copy Makefile plugins\WindowsAuthentication
+ copy Makefile.var plugins\WindowsAuthentication
+ cd plugins\WindowsAuthentication
+ nmake
+ del *.obj *.idb
+ cd ../../
+ copy Makefile plugins\TrafficPlugin
+ copy Makefile.var plugins\TrafficPlugin
+ cd plugins\TrafficPlugin
+ nmake
+ del *.obj *.idb
+ cd ../../
+ copy Makefile plugins\StringsPlugin
+ copy Makefile.var plugins\StringsPlugin
+ cd plugins\StringsPlugin
+ nmake
+ del *.obj *.idb
+ cd ../../
+ copy Makefile plugins\PCREPlugin
+ copy Makefile.var plugins\PCREPlugin
+ cd plugins\PCREPlugin
+ nmake
+ del *.obj *.idb
+ cd ../../
diff --git a/README b/README
index 0fc98be7..b8526d8c 100644
--- a/README
+++ b/README
@@ -1,5 +1,11 @@
# 3APA3A 3proxy tiny proxy server
-(c) 2002-2019 by Vladimir '3APA3A' Dubrovin <3proxy@3proxy.ru>
+(c) 2002-2020 by Vladimir '3APA3A' Dubrovin <3proxy@3proxy.ru>
+
+
+Branches:
+Master (stable) branch - 3proxy 0.9
+Devel branch - 3proxy 10
+
Download:
https://github.com/z3APA3A/3proxy/releases
@@ -26,8 +32,22 @@ ln -s Makefile.Linux Makefile
make
sudo make install
- use /etc/3proxy/add3proxyuser.sh script to add users.
+Default configuration (for Linux/Unix):
+3proxy uses 2 configuration files:
+/etc/3proxy/3proxy.cfg (before-chroot). This configuration file is executed before chroot and should not be modified.
+/usr/local/3proxy/conf/3proxy.cfg symlinked from /etc/3proxy/conf/3proxy.cfg (after-chroot) is a main configuration file. Modify this file, if required.
+All paths in /usr/local/3proxy/conf/3proxy.cfg are relative to chroot directory (/usr/local/3proxy). For future versions it's planned to move
+3proxy chroot direcory to /var.
+Log files are created in /usr/local/3proxy/logs symlinked from /var/log/3proxy.
+By default, socks is started on 0.0.0.0:1080 and proxy on 0.0.0.0:3128 with basic auth, no users are added by default.
+use /etc/3proxy/conf/add3proxyuser.sh script to add users.
+
+usage: /etc/3proxy/conf/add3proxyuser.sh username password [day_limit] [bandwidth]
+ day_limit - traffic limit in MB per day
+ bandwidth - bandwith in bits per second 1048576 = 1Mbps
+
+or modify /etc/3proxy/conf/ files directly.
Please read doc/html/index.html and man pages.
@@ -58,7 +78,7 @@ Please read doc/html/index.html and man pages.
+ Threaded application (no child process).
+ Web administration and statistics
+ Plugins for functionality extension
- + Native 64 bit application
+ + Native 32/64 bit application
2. Proxy chaining and network connections
+ Can be used as a bridge between client and different proxy type
(e.g. convert incoming HTTP proxy request from client to SOCKSv5
@@ -78,9 +98,8 @@ Please read doc/html/index.html and man pages.
+ syslog logging (Unix)
+ ODBC logging
+ RADIUS accounting
- + log file rotation (hourly, daily, weekly, monthly)
- + automatic log file comperssion with external archiver (for files)
- + automatic removal of older log files
+ + log file rotation
+ + automatic log file processing with external archiver (for files)
+ Character filtering for log files
+ different log files for different servces are supported
4. Access control
@@ -89,12 +108,13 @@ Please read doc/html/index.html and man pages.
(POST, PUT, GET, etc), weekday and daytime.
+ ACL-driven (user/source/destination/protocol/weekday/daytime or
combined) bandwith limitation for incoming and (!)outgoing trafic.
- + ACL-driven (user/source/destination/protocol/weekday/daytime or
- combined) traffic limitation per day, week or month for incoming and
+ + ACL-driven traffic limitation per day, week or month for incoming and
outgoing traffic
+ + Connection limitation and ratelimting
+ User authentication by username / password
+ RADIUS Authentication and Authorization
+ User authentication by DNS hostname
+ + Authentication cache with possibility to limit user to single IP address
+ Access control by username/password for SOCKSv5 and HTTP/HTTPS/FTP
+ Cleartext or encrypted (crypt/MD5 or NT) passwords.
+ Connection redirection
@@ -183,7 +203,6 @@ mycrypt Program to obtain crypted password fro cleartext. Supports
produces NT password
mycrypt salt password
produces MD5/crypt password with salt "salt".
-dighosts Utility for building networks list from web page.
Run utility with --help option for command line reference.
diff --git a/copying b/copying
index fbd81457..318c0fe9 100644
--- a/copying
+++ b/copying
@@ -1,12 +1,8 @@
-3proxy 0.9 Public License Agreement
+3proxy 10 Public License Agreement
-(c) 2000-2019 by 3APA3A (3APA3A@3proxy.ru)
-(c) 2000-2019 by 3proxy.org (http://3proxy.org/)
-(c) 2000-2019 by Vladimir Dubrovin (vlad@3proxy.ru)
-
-This software uses:
- RSA Data Security, Inc. MD4 Message-Digest Algorithm
- RSA Data Security, Inc. MD5 Message-Digest Algorithm
+(c) 2000-2020 by 3APA3A (3APA3A@3proxy.ru)
+(c) 2000-2020 by 3proxy.org (https://3proxy.org/)
+(c) 2000-2020 by Vladimir Dubrovin (vlad@3proxy.ru)
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
diff --git a/doc/html/faqe.html b/doc/html/faqe.html
index f966b0a6..a4600027 100644
--- a/doc/html/faqe.html
+++ b/doc/html/faqe.html
@@ -1,165 +1,2 @@
-Why ... doesn't work?
-Q: Why does nothing work?
-A: Valid configuration file is required.
-
-Q: Why restrictions (redirections, limits, etc) do not work?
-A: Most probable reasons: 'auth none' or no auth is used. For any ACL based feature one of 'iponly', 'nbname' or 'strong' auths required. Sequence of commands may be invalid. Commands are executed one-by-one and 'proxy', 'tcppm', 'socks' or another service commands must follow valid configuration. Invalid sequence of ACLs. First matching ACL is used (except of internal redirections, see below). If ACL contains at least one records last record is assumed to be 'deny *'.
-
-Q: Why doesn't 3proxy work as service under Windows?
-Possible reasons:
-
-
-Q: Why doesn't internal and external commands work as expected
-A: Check your expectations first.
-Both internal and external IPs are IPs of the host running 3proxy itself.
-This configuration option is usefull in situation 3proxy is running on the
-border host with 2 (or more) connections: e.g. LAN and WAN with different IPs
-
- LAN connection +-------------+ Internet connection
-LAN <-------------->| 3proxy host |<-------------------> INTERNET
- ^+-------------+^
- | |
- Internal IP External IP
-
-If 3proxy is used on the host with single connection, both internal and
-external are usually same IP.
-
Internal should exist and be UP on the moment 3proxy is started and
-should never be disconnected/DOWN. If this interface is periodically
-disconnected (e.g. direct link between 2 hosts), do not specify internal
-address or use 0.0.0.0 instead. In this case, if you have 2 or more
-interfaces you must use firewall (preferably) or 3proxy ACLs to avoid open
-proxy situation.
-
-External IP (if specified) must exist in the momet 3proxy
-serves client request. If external interface is no specified (or 0.0.0.0),
-system select external IP. It may be possible to access resources of internal
-network, to prevent this use ACLs. In addition, SOCKSv5 will not support BIND
-operation, required for incoming connections (this operation is quite rarely
-implemented in SOCKSv5 clients and usually is not required). In case of
-dynamic address, do not specify external or use external 0.0.0.0 or, if
-external address is required, create a script to determine current external
-IP and save it to file, and use external "$path_to_file" with "monitor" command
-to automatically reload configuration on address change.
-
-Q: Why doesn't ODBC loggind work?
-A: Check you use system DSN.
-Check SQL request is valid.
-The best way to check is to make file or stdout logging, get SQL request from log file or console and execute this request manually.
-Under Unix, you may also want to adjust 'stacksize' parameter.
-
-Q: Why doesn't IPv6 work?
-A: Proxy can not access destination directly over IPv6 if client requests IPv4 address.
-To access IPv6 destination, either IPv6 address or hostname must be used in request.
-Best solution is to enable option to resolve hostnames via proxy on client side.
-Q: Why proxy crash on request processing?
-A: default stacksize may be insufficient, if some non-default plugins
- are used (e.g. PAM and ODBC on Linux) or if compiled on some platforms with
- invalid system defined values (few versionds of FreeBSD on amd64).
- Problem can be resolved with 'stacksize' command or '-S' option starting 3proxy 0.8.4.
-
-
-Q: Why doesn't APOP/CRAM-MD5 authentication work with POP3 proxy?
-A: Any Challenge-response authentication require challenge to be transmitted from server. Pop3p doesn't know which server to use before authentication, it makes it impossible to obtain challenge. You can encrypt your POP3 communications with TLS (i.e. stunnel) or IPSec.
-
-Redirection to local proxy
-
-Q: What is it for?
-A: To have control based on request and to have URLs and another protocol specific parameters to be logged.
-
-Q: What are restrictions?
-A: It's hard to redirect services for non-default ports; Internet Explorer supports only SOCKSv4 with no password authentication (Internet Explorer sends username, but not password), for SOCKSv5 only cleartext password authentication is supported.
-
-Q: What are advantages?
-A: You need only to setup SOCKS proxy in browser settings. You can use socksifier, i.e. FreeCAP or SocksCAP with application which is not proxy aware.
-
-Q: How to setup?
-A: You should specify parent proxy with IP of 0.0.0.0 and port 0. Examples:
-
-auth iponly
-allow * * * 80,8080-8088
-parent 1000 http 0.0.0.0 0
-allow * * * 80,8080-8088
-#redirect ports 80 and 8080-8088 to local HTTP proxy
-#Second allow is required, because ACLs are checked
-#twice: first time by socks and second by http proxy.
-
-allow * * * 21,2121
-parent 1000 ftp 0.0.0.0 0
-allow * * * 21,2121
-#redirect ports 21 and 2121 to local
-#ftp proxy
-
-
-allow *
-#allow rest of connections directly
-
-socks
-#now let socks server to start
-
-
-Q: How it affects different ACL rules?
-A: After local redirections rules are applied again to protocol-level request. Redirection rule itself is skipped. It makes it possible to redirect request again on the external proxy depending on request itself.
-
-allow * * * 80,8080-8088
-parent 1000 http 0.0.0.0 0
-#redirect http traffic to internal proxy
-
-allow * * $c:\3proxy\local.nets 80,8080-8088
-#allow direct access to local.nets networks
-allow * * * 80,8080-8088
-parent 1000 http proxy.3proxy.org 3128
-#use parent caching proxy for rest of the networks
-
-allow *
-#allow direct connections for rest of socks
-#requests
-
-
-Can I ...?
-
-Q: Is it possible to resolve names through parent proxy?
-A: Yes, use 'proxy', 'connect+', 'socks4+' or 'socks5+' as parent proxy type.
-3proxy itself requires name resolutions for ACL checks, so, if it's impossible
-to resolve names from 3proxy host, use
-
-fakeresolve
-
-command. Fakeresolve resolves any name to 127.0.0.2.
-
-
-Q: Can I use 3proxy as FTP proxy?
-A: There are two kinds of FTP proxy supported: FTP over HTTP support (known as FTP proxy inside Internet Explorer, Mozilla and another browsers) and real FTP proxy (usable in Far and different FTP clients). Both are supported in 3proxy: first one as a part of HTTP 'proxy' and second one as 'ftppr'.
-
-Q: Can I bind any 3proxy service to non-default port?
-A: proxy -p8080
-
-Why so ...?
-
-Q: Why traffic accounting is incomplete? It differs for what my provider (or another accounting application) shows to me?
-A: 3proxy accounts protocol level traffic. Provider counts channel or IP-level traffic with network and transport headers. In additions, 3proxy doesn't counts DNS resolutions, pings, floods, scans, etc. It makes approx. 10% of difference. That's why you should have 15% reserve if you use 3proxy to limit your traffic. If difference with your provider is significantly above 10% you should look for traffic avoiding proxy server, for example connections through NAT, traffic originated from the host with proxy installed, traffic from server applications, etc.
-
-Q: Why configuration is so difficult and non-intuitive?
-A: Configuration format is created in a way it's easy to parse and matches to internal 3proxy structures. In addition, there are some older things left for compatibility to be cleaned in 3proxy release. And last, I think it's easy and intuitive.
-
-Q: Why the code is so difficult and non-intuitive?
-A: First, I'm not programmer. Second, 3proxy was 'proof of concept' in reply for some conference post. Request was to write proxy server in 100 lines of code. First version of 3proxy had less, with HTTP and SOCKS support and portmappers. Third, there are peoples who want to use 3proxy code in trojans. I don't want to help them. Fourth, the aim is to support different platforms. It's well known - the worse code is, the better it compiles.
-
-Q: Why do you use insecure strcpy, sprintf, etc?
-A: Why not? I try to use insecure function in secure manner. You're welcome to look for vulnerabilities.
+
\ No newline at end of file
diff --git a/doc/html/faqr.html b/doc/html/faqr.html
index f1a2e2fe..e9546af6 100644
--- a/doc/html/faqr.html
+++ b/doc/html/faqr.html
@@ -1,295 +1,2 @@
-
-3APA3A 3proxy tiny proxy server Frequently Asked Questions (FAQ)
-
-
-Почему не работает...
-
- - Q: Почему ничего не работает?
-
- A: Потому что для работы нужен правильный файл конфигурации.
-
- - Q: Почему не работают ограничения доступа (перенаправления, ограничения по скорости,
- трафику и т.д.)?
-
- A: Обычные ошибки - использование auth none (для работы любых
- функций, основанных на ACL, требуется auth iponly, nbname или strong),
- нарушение порядка ввода команд (команды выполняются последовательно,
- запуск сервиса proxy, socks, tcppm и т.д. должен осуществляться после
- того, как указана его конфигурация), неправильный порядок записей в ACL
- (записи просматриваются последовательно до первой, удовлетворяющей
- критериям). Если в ACL имеется хотя бы одна запись, то считается, что
- последняя запись в ACL - это неявная deny *.
-
- - Q: Почему 3proxy не запускается как служба?
-
- A: Наиболее вероятные причины:
-
-
- Q: Почему не получается указать internal и external?
-
- A: Убедитесь, что выправильно понимаете что такое internal и external адреса.
- Оба адреса - это адреса, принадлежищие хосту, на котором установлен 3proxy.
- Эта опция конфигурации необходима в классической ситуации, когда 3proxy
- установлен на граничном компьютере с двумя (или более) подключениями:
-
- LAN connection +-------------+ Internet connection
- LAN <-------------->| 3proxy host |<-------------------> INTERNET
- ^+-------------+^
- | |
- Internal IP External IP
- Если 3proxy работает на хосте с одним интерфейсом, то его адрес будет и
- internal и external.
-
Интерфейс с адресом internal должен существовать и быть рабочим на момент
- запуска 3proxy, и не должен отключаться. Если internal интерфейс
- периодически отключается, то не следует его указывать, или можно указать адрес
- 0.0.0.0. При этом прокси будет принимать запросы на всех интерфейсах, поэтому
- при наличии нескольких интерфейсов для ограничения доступа следует использовать
- фаервол или хотя бы ACL.
-
-
- Интерфейс с адресом external, если он указан, должен быть рабочим на момент
- получения запроса клиента. При отсутствии external или адресе 0.0.0.0 внешний
- адрес будет выбираться системой при установке соединения. При этом, может быть
- возможность доступа через прокси к ресурсам локальной сети, поэтому для
- предотвращения несанкционированного доступа следует использовать ACL. Кроме
- того, могут быть проблемы с приемом входящих соединений через SOCKSv5
- (SOCKSv5 используется в клиентах исключительно редко).
- В случае, если адрес динамический, можно либо не
- указывать external, либо использовать адрес 0.0.0.0, либо, если необходима
- поддержка входящих соединений в SOCKSv5, использовать скрипт,
- который будет получать текущий адрес и сохранять его в файл, который будет
- отслуживаться через команду monitor.
-
- Q: Почему не работает ведение журналов в ODBC?
-
- A: Убедитесь, что используется системный, а не
- пользовательский DSN. Убедитесь, что выполняется правильный SQL запрос. Наиболее
- распространенная проблема связана с отсутствием кавычек или неправильным
- форматом данных. Самый простой способ - сделать ведение журнала в файл или
- на стандартный вывод, просмотреть выдаваемые SQL запросы и попробовать
- дать такой запрос вручную.
-
- Q: Почему не работает IPv6?
-
- A: Прокси не может обращаться напрямую к IPv6 сети если в запросе от клиента
- указан IPv4. В запросе от клиента должен быть IPv6 адрес или имя хоста, чаще
- всего это решается включением опции разрешения имен через прокси-сервер на стороне
- клиента.
-
- Q: Почему не поддерживаются APOP и CRAM-MD5 в POP3 прокси?
-
- A: Любая challenge-response аутентификация, к которым относятся APOP
- и CRAM-MD5, требует, чтобы со стороны сервера был передан уникальный challenge.
- До начала аутентификации POP3 прокси не знает, к какому серверу следует
- подключаться для получения Challenge, поэтому challenge-response в принципе
- невозможен. Защитить соединение можно с помощью TLS (например, stunnel) или
- IPSec.
-
- Q: Почему прокси крэшится при обработке запроса?
-
- A: Возможно, недостаточен размер стека потока по-умолчанию, это может
- быть при использовани каких-либо сторонних плагинов (PAM, ODBC) или на
- некоторых платформах (некоторые версии FreeBSD на amd64). Можно решить
- проблему с помощью опции 'stacksize' или '-S', поддерживаемых в 0.8.4 и выше.
-
-
-
-Перенаправление socks соединений в локальный прокси
-
- - Q: Для чего это надо?
-
- A: Чтобы иметь в логах URL запросов, если пользователь SOCKS пользуется
- Web, FTP или POP3.
-
- - Q: Какие недостатки?
-
- A: Перенапраление невозможно для web-серверов или FTP, висящих на
- нестандартных портах, для SOCKSv4 не поддрживается авторизация с
- паролем (IE поддерживает только SOCKSv4), но при этом IE передает
- имя пользователя по SOCKSv4 (имя, с которым пользователь вошел в систему).
- Для SOCKSv5 не поддерживается NTLM авторизация, пароли передаются в открытом
- тексте.
-
- - Q: Какие преимущества?
-
- A: Достаточно в настройках IE только указать адрес SOCKS прокси. В
- больших сетях можно для этого использовать WPAD (автоматическое
- обнаружение прокси). В 3proxy достаточно запускать только одну службу
- (socks). Если используется только Internet Explorer, то можно
- автоматически получать имя пользователя в логах, не запрашивая
- логин/пароль.
-
- - Q: Как настраивается?
-
- A: Указывается parent http proxy со специальным адресом 0.0.0.0 и портом
- 0. Пример:
-
- allow * * * 80,8080-8088
- parent 1000 http 0.0.0.0 0
- allow * * * 80,8080-8088
- #перенаправить соединения по портам 80 и 8080-8088 в локальный
- #http прокси. Вторая команда allow необходима, т.к. контроль доступа
- #осуществляется 2 раза - на уровне socks и на уровне HTTP прокси
- allow * * * 21,2121
- parent 1000 ftp 0.0.0.0 0
- allow * * * 21,2121
- #перенаправить соединения по портам 21 и 2121 в локальный
- #ftp прокси
- allow *
- #пустить все соединения напрямую
- socks
-
- Q: Как взаимодействует с другими правилами в ACL?
-
- A: После внутреннего перенаправления правила рассматриваются еще раз за
- исключением самого правила с перенаправлением (т.е. обработка правил не
- прекращается). Это позволяет сделать дальнейшие перенаправления на
- внешний прокси. По этой же причине локальное перенаправление не должно
- быть последним правилом (т.е. должно быть еще хотя бы правило allow,
- чтобы разрешить внешние соединения через HTTP прокси).
- Например,
-
- allow * * * 80,8080-8088
- parent 1000 http 0.0.0.0 0
- #перенаправить во внутренний прокси
- allow * * $c:\3proxy\local.nets 80,8080-8088
- #разрешить прямой web-доступ к сетям из local.nets
- allow * * * 80,8080-8088
- parent 1000 http proxy.3proxy.ru 3128
- #все остальные веб-запросы перенаправить на внешний прокси-сервер
- allow *
- #разрешить socks-запросы по другим портам
-
-
-
-А есть ли...
-
- - Q: Можно ли разрешать имена на родительском прокси?
-
- A: Можно. Для этого надо использовать тип родительского прокси http,
- connect+, socks4+ и socks5+. Однако, при это надо помнить, что самому 3proxy
- требуется разрешение имени для управления ACL. Поэтому, если с прокси-хоста
- не работают разрешения имени, необходимо в конфигурации дать команду
-
- fakeresolve
- которая разрешает любое имя в адрес 127.0.0.2.
-
- Q: Существует ли сейчас поддержка FTP прокси в продукте?
-
- Есть поддержка как FTP через HTTP (то, что называется FTP прокси в Internet
- Explorer, Netscape, Opera) так и настоящего FTP прокси (то, что называется
- FTP proxy в FAR и FTP клиентах).
-
- Q: Каким образом можно прибиндить сервисы на свой порт, к примеру, HTTP прокси к 8080, а не 3128 как по-умолчанию?
-
- А:
-
- proxy -p8080
-
- Q: Как ограничить ширину канала?
-
- A: Читайте HowTo https://3proxy.ru/howtor.asp#BANDLIM
-
-
-
-Почему так криво...
-
- - Q: Почему так криво считается трафик? Не совпадает с ...
-
- A: Следует учитывать, что 3proxy считает трафик только на прикладном уровне и
- только проходящий через прокси-сервер. Провайдеры и другие средства учета
- трафика считают трафик на сетевом уровне, что уже дает расхождение порядка 10%
- за счет информации из заголовков пакетов. Кроме того, часть трафика, как
- минимум DNS-разрешения, различный флудовый трафик и т.д. идут мимо прокси.
- Уровень "шумового" трафика в Internet сейчас составляет порядка 50KB/день на
- каждый реальный IP адрес, но может сильно варьироваться в зависимости от сети,
- наличия открытых портов, реакции на ping-запросы и текущего уровня вирусной
- активности. По этим причинам, если 3proxy используется чтобы не "выжрать"
- трафик, выделенный провайдером, всегда следует делать некий запас порядка
- 15%.
-
-
- Если на одной с 3proxy машине имеются какие-либо сервисы или
- работает пользователь, то их трафик не проходит через proxy-сервер и так же
- не будет учтен. Если где-то есть NAT, то клиенты, выходящие через NAT мимо
- прокси, так же останутся неучтенными. Если расхождение с провайдером превышает
- 10% - нужно искать причину именно в этом.
-
- - Q: Почему такая кривая конфигурация и ничерта не понятно?
-
- A: Есть несколько причин. Во-первых, до выхода релиза (т.е. версии 1.0) я буду изо
- всех сил добиваться совместимости конфигурации между версиями. Во-вторых,
- конфигурация сделана так, чтобы ее можно было легко разбирать программно.
- В-третьих, все там понятно. При желании. Если знать как все работает.
-
- - Q: Почему так криво написан код?
-
- A: Есть несколько причин. Во-первых, я не программист. Во-вторых, 3proxy изначально
- писался на коленке (в отет на "слабо" в одной из конференций). Никто
- не мог предположить, что им кто-то реально будет пользоваться. В-третьих, у многих
- возникает желание разобраться в коде 3proxy чтобы внедрить его в какой-нибудь
- троян. Очень не хочется облегчать эту задачу. В-четвертых, мне надо добиться
- компиляции кода в как можно большем числе систем. Замечено, что чем кривее код в
- C, тем он лучше переносится.
-
- - Q: Почему так много strcpy, sprintf и т.д., это ж дыры!
-
-
- A: Есть несколько причин. Во-первых, несмотря на дурной тон использования этих
- функций, они наиболее совместимы между разными системами и компиляторами.
- Во-вторых, само по себе их использование не означает присутствие дыры, если их
- параметры должным образом контролируются. Найдете дыру - обязательно сообщите.
- В третьих, может быть я уберу их перед конечным релизом, чтобы никого не
- пугать.
-
-
+
+
\ No newline at end of file
diff --git a/doc/html/highload.html b/doc/html/highload.html
index a3693cfd..a2dbb906 100644
--- a/doc/html/highload.html
+++ b/doc/html/highload.html
@@ -5,7 +5,7 @@ Optimizing 3proxy for high load
Configuring 'maxconn'
A number of simulatineous connections per service is limited by 'maxconn' option.
-Default maxconn value since 3proxy 0.8 is 500. You may want to set 'maxconn'
+Default maxconn value since 3proxy 0.9.3/10 is 250. You may want to set 'maxconn'
to higher value. Under this configuration:
maxconn 1000
diff --git a/doc/html/howtoe.html b/doc/html/howtoe.html
index 88151299..3263769e 100644
--- a/doc/html/howtoe.html
+++ b/doc/html/howtoe.html
@@ -8,7 +8,6 @@
How to compile 3proxy with Intel C Compiler under Windows
How to compile 3proxy with GCC under Windows
How to compile 3proxy with GCC under Unix/Linux
- How to compile 3proxy with Compaq C Compiler under Unix/Linux
Proxy server installation and removal
Server configuration
-
- How to compile 3proxy with Compaq C Compiler under Unix/Linux
-
-See How to compile 3proxy with GCC under Unix/Linux, use Makefile.ccc instead of Makefile.unix.
@@ -164,6 +168,83 @@
Server configuration
+ - How to make 3proxy start
+
Valid configuration file is required.
+
+
- How to make limitation (access, bandwidth, traffic, connections) work
+
Most probable reasons for non-working limitations: 'auth none' or no auth is used. For any ACL based feature one of 'iponly', 'nbname' or 'strong' auths required. Sequence of commands may be invalid. Commands are executed one-by-one and 'proxy', 'tcppm', 'socks' or another service commands must follow valid configuration. Invalid sequence of ACLs. First matching ACL is used (except of internal redirections, see below). If ACL contains at least one records last record is assumed to be 'deny *'.
+
+
- How to make 3proxy to run as a service
+
Possible reasons for 3proxy starts manually but fails to start as a service:
+
+
+How to understant internal and external
+
+Both internal and external IPs are IPs of the host running 3proxy itself.
+This configuration option is usefull in situation 3proxy is running on the
+border host with 2 (or more) connections: e.g. LAN and WAN with different IPs
+
+ LAN connection +-------------+ Internet connection
+LAN <-------------->| 3proxy host |<-------------------> INTERNET
+ ^+-------------+^
+ | |
+ Internal IP External IP
+
+If 3proxy is used on the host with single connection, both internal and
+external are usually same IP.
+
Internal should exist and be UP on the moment 3proxy is started and
+should never be disconnected/DOWN. If this interface is periodically
+disconnected (e.g. direct link between 2 hosts), do not specify internal
+address or use 0.0.0.0 instead. In this case, if you have 2 or more
+interfaces you must use firewall (preferably) or 3proxy ACLs to avoid open
+proxy situation.
+
+External IP (if specified) must exist in the momet 3proxy
+serves client request. If external interface is no specified (or 0.0.0.0),
+system select external IP. It may be possible to access resources of internal
+network, to prevent this use ACLs. In addition, SOCKSv5 will not support BIND
+operation, required for incoming connections (this operation is quite rarely
+implemented in SOCKSv5 clients and usually is not required). In case of
+dynamic address, do not specify external or use external 0.0.0.0 or, if
+external address is required, create a script to determine current external
+IP and save it to file, and use external "$path_to_file" with "monitor" command
+to automatically reload configuration on address change.
+
+ - How to make ODBC logging work?
+
+Check you use system DSN.
+Check SQL request is valid.
+The best way to check is to make file or stdout logging, get SQL request from log file or console and execute this request manually.
+Under Unix, you may also want to adjust 'stacksize' parameter.
+
+
- How to make IPv6 work
+
Proxy can not access destination directly over IPv6 if client requests IPv4 address.
+To access IPv6 destination, either IPv6 address or hostname must be used in request.
+Best solution is to enable option to resolve hostnames via proxy on client side.
+
+
- How to fix 3proxy crashes
+
default stacksize may be insufficient, if some non-default plugins
+ are used (e.g. PAM and ODBC on Linux) or if compiled on some platforms with
+ invalid system defined values (few versionds of FreeBSD on amd64).
+ Problem can be resolved with 'stacksize' command or '-S' option starting 3proxy 0.8.4.
+
+
- Where to find configuration example
Server configuration example 3proxy.cfg.sample is in any 3proxy distribution.
@@ -382,6 +463,22 @@
proxy -p8080 -i192.168.2.1
+ - How to resolve names through a parent proxy
+
+ A: Use one of http, connect+, socks4+ or socks5+ as a parent type. 3proxy
+ itself still performs a name resolution, it's required e.g. to ACLs matching.
+ So, if no name resolution must be performed by 3proxy itself add a command
+
+ fakeresolve
+ this command resolves any name to 127.0.0.2 address.
+
+ How to setup FTP proxy
+
+ There is FTP over HTTP (what is called FTP proxy in browsers) and FTP over FTP ப
+ (what is called FTP proxy in file managers and FTP clients). For browsers, there is no need to start additional
+ proxy service, 'proxy' supports FTP over HTTP, configure 'proxy' port as an FTP proxy. For ftp clients and file
+ managers use ftppr. FTP proxy supports both active and passive mode with client, but always use passive mode with FTP servers.
+
How to limit service access
First, always specify internal interface to accept incoming connection with
@@ -518,7 +615,7 @@
'flush' command is used to finish with existing ACL and to start new one.
It's required to have different ACLs for different services.
'allow' is used to allow connection and 'deny' to deny connection. 'allow'
-command can be extended by 'parent' command to manage redirections (see How to manage redirections)). If ACL
+command can be extended by 'parent' command to manage redirections (see How to manage redirections)). If ACL
is empty it allow everything. If ACL is not empty, first matching ACL entry
is searched for user request and ACL action (allow or deny) performed. If
no matching record found, connection is denied and user will be asked to
@@ -607,6 +704,60 @@
you want to see and control via ACLs protocol specific parameters, e.g.
filenames requests thorugh FTP while clients are using SOCKS.
+ ࠢ 묨 ७ࠢﬨ
+
+
Q: What is it for?
+A: To have control based on request and to have URLs and another protocol specific parameters to be logged.
+
+Q: What are restrictions?
+A: It's hard to redirect services for non-default ports; Internet Explorer supports only SOCKSv4 with no password authentication (Internet Explorer sends username, but not password), for SOCKSv5 only cleartext password authentication is supported.
+
+Q: What are advantages?
+A: You need only to setup SOCKS proxy in browser settings. You can use socksifier, i.e. FreeCAP or SocksCAP with application which is not proxy aware.
+
+Q: How to setup?
+A: You should specify parent proxy with IP of 0.0.0.0 and port 0. Examples:
+
+auth iponly
+allow * * * 80,8080-8088
+parent 1000 http 0.0.0.0 0
+allow * * * 80,8080-8088
+#redirect ports 80 and 8080-8088 to local HTTP proxy
+#Second allow is required, because ACLs are checked
+#twice: first time by socks and second by http proxy.
+
+allow * * * 21,2121
+parent 1000 ftp 0.0.0.0 0
+allow * * * 21,2121
+#redirect ports 21 and 2121 to local
+#ftp proxy
+
+
+allow *
+#allow rest of connections directly
+
+socks
+#now let socks server to start
+
+
+Q: How it affects different ACL rules
+A: After local redirections rules are applied again to protocol-level request. Redirection rule itself is skipped. It makes it possible to redirect request again on the external proxy depending on request itself.
+
+allow * * * 80,8080-8088
+parent 1000 http 0.0.0.0 0
+#redirect http traffic to internal proxy
+
+allow * * $c:\3proxy\local.nets 80,8080-8088
+#allow direct access to local.nets networks
+allow * * * 80,8080-8088
+parent 1000 http proxy.3proxy.org 3128
+#use parent caching proxy for rest of the networks
+
+allow *
+#allow direct connections for rest of socks
+#requests
+
+
How to balance traffic between few external channgels?
Proxy itself doesn't manage network level routing. The only way to control
@@ -722,30 +873,9 @@
command controls how often text reports are created. amount is amount of
allowed traffic in Megabytes (MB). nocountin allows you to set exclusions.
- How to build network lists
-Networks or users lists are often very huge. 3proxy doesn't currently
-supports user groups, but ones can be created by the means of include files.
-You can store comma-delimited lists of networks or users in the separate
-file and use $ macro to insert this list into 3proxy.cfg.
-3proxy comes with 'dighosts'
-utility. This utility helps to grab the list of the network from HTTP page.
-It may be usefull to e.g. obtain a regullary updated list of local networks
-from ISP's server. A network list can be either in form of NETWORK MASK,
-e.g. 192.168.1.0 255.255.255.0 or NETWORK/LENGTH, e.g. 192.168.1.0/24. You can
-launch dighosts from 3proxy.cfg to be executed on every 3proxy startup or
-configuration reload:
-
-system "dighosts http://provider/network.html local.networks"
-allow * * $local.networks
-allow *
-parent 1000 proxy.provider 3128 *
-proxy
-flush
-
-In this example we obtain list of local networks from provider's page to
-local.networks file, allow direct access to these networks and redirect all
-connection to external networks to provider's proxy.
-
+ How to fix incorrect traffic accounting
+
+ 3proxy accounts protocol level traffic. Provider counts channel or IP-level traffic with network and transport headers. In additions, 3proxy doesn't counts DNS resolutions, pings, floods, scans, etc. It makes approx. 10% of difference. That's why you should have 15% reserve if you use 3proxy to limit your traffic. If difference with your provider is significantly above 10% you should look for traffic avoiding proxy server, for example connections through NAT, traffic originated from the host with proxy installed, traffic from server applications, etc.
How to configure name resolution and DNS caching
For name resolution and caching use commands nserver, nscache / nscache6 and nsrecord.
@@ -874,7 +1004,7 @@
90 - unexpected system error (should not happen)
91 - unexpected poll error (should not happen)
92 - connection terminated by timeout (see timeouts)
- 93 - connection terminated by ratelimit-related timeout
+ 93 - connection terminated by ratelimit-related timeout or due to errors limit
94 - connection termination by server or client with unsent data
95 - dirty connection termination by client (or networking issue)
96 - dirty connection termination by server (or networking issue)
diff --git a/doc/html/howtor.html b/doc/html/howtor.html
index 6a37fcf2..708f3bd5 100644
--- a/doc/html/howtor.html
+++ b/doc/html/howtor.html
@@ -18,25 +18,34 @@
Конфигурация сервера
Конфигурация и настройка клиентов
@@ -172,6 +181,101 @@
- Конфигурация сервера
+ - Как заставить прокси работать
+
+ Для работы требуется корректный файл конфигурации. Если прокси не запускается, значит в конфигурации есть ошибка.
+
+ - Как заставить работать ограничения (контроль доступа, ограничения ширины канала, счетчики и т.п.)
+
+ A: Обычные ошибки - использование auth none (для работы любых
+ функций, основанных на ACL, требуется auth iponly, nbname или strong),
+ нарушение порядка ввода команд (команды выполняются последовательно,
+ запуск сервиса proxy, socks, tcppm и т.д. должен осуществляться после
+ того, как указана его конфигурация), неправильный порядок записей в ACL
+ (записи просматриваются последовательно до первой, удовлетворяющей
+ критериям). Если в ACL имеется хотя бы одна запись, то считается, что
+ последняя запись в ACL - это неявная deny *.
+
+ - Как починить запуск 3proxy службой
+
+ Чаще всего 3proxy не запускается службой (но запускается вручную) по одной из следующих причин:
+
+
+ - Как разобраться с internal и external
+
+ Убедитесь, что выправильно понимаете что такое internal и external адреса.
+ Оба адреса - это адреса, принадлежищие хосту, на котором установлен 3proxy.
+ Эта опция конфигурации необходима в классической ситуации, когда 3proxy
+ установлен на граничном компьютере с двумя (или более) подключениями:
+
+ LAN connection +-------------+ Internet connection
+ LAN <-------------->| 3proxy host |<-------------------> INTERNET
+ ^+-------------+^
+ | |
+ Internal IP External IP
+ Если 3proxy работает на хосте с одним интерфейсом, то его адрес будет и
+ internal и external.
+
Интерфейс с адресом internal должен существовать и быть рабочим на момент
+ запуска 3proxy, и не должен отключаться. Если internal интерфейс
+ периодически отключается, то не следует его указывать, или можно указать адрес
+ 0.0.0.0. При этом прокси будет принимать запросы на всех интерфейсах, поэтому
+ при наличии нескольких интерфейсов для ограничения доступа следует использовать
+ фаервол или хотя бы ACL.
+
+
+ Интерфейс с адресом external, если он указан, должен быть рабочим на момент
+ получения запроса клиента. При отсутствии external или адресе 0.0.0.0 внешний
+ адрес будет выбираться системой при установке соединения. При этом, может быть
+ возможность доступа через прокси к ресурсам локальной сети, поэтому для
+ предотвращения несанкционированного доступа следует использовать ACL. Кроме
+ того, могут быть проблемы с приемом входящих соединений через SOCKSv5
+ (SOCKSv5 используется в клиентах исключительно редко).
+ В случае, если адрес динамический, можно либо не
+ указывать external, либо использовать адрес 0.0.0.0, либо, если необходима
+ поддержка входящих соединений в SOCKSv5, использовать скрипт,
+ который будет получать текущий адрес и сохранять его в файл, который будет
+ отслуживаться через команду monitor.
+
+ Как починить ведение журналов в ODBC
+
+ Убедитесь, что используется системный, а не
+ пользовательский DSN. Убедитесь, что выполняется правильный SQL запрос. Наиболее
+ распространенная проблема связана с отсутствием кавычек или неправильным
+ форматом данных. Самый простой способ - сделать ведение журнала в файл или
+ на стандартный вывод, просмотреть выдаваемые SQL запросы и попробовать
+ дать такой запрос вручную.
+
+ Как починить IPv6
+
+ Прокси не может обращаться напрямую к IPv6 сети если в запросе от клиента
+ указан IPv4. В запросе от клиента должен быть IPv6 адрес или имя хоста, чаще
+ всего это решается включением опции разрешения имен через прокси-сервер на стороне
+ клиента.
+
+ Как починить падения 3proxy
+
+ Возможно, недостаточен размер стека потока по-умолчанию, это может
+ быть при использовани каких-либо сторонних плагинов (PAM, ODBC) или на
+ некоторых платформах (некоторые версии FreeBSD на amd64). Можно решить
+ проблему с помощью опции 'stacksize' или '-S', поддерживаемых в 0.8.4 и выше.
+
Как посмотреть пример файла конфигурации
Пример файла конфигурации 3proxy.cfg.sample поставляется с любым дистрибутивом
@@ -386,6 +490,24 @@
proxy -p8080 -i192.168.1.1
proxy -p8080 -i192.168.2.1
+ Как разрешать имена на родительском прокси?
+
+ A: Для этого надо использовать тип родительского прокси http,
+ connect+, socks4+ и socks5+. Однако, при это надо помнить, что самому 3proxy
+ требуется разрешение имени для управления ACL. Поэтому, если с прокси-хоста
+ не работают разрешения имени, необходимо в конфигурации дать команду
+
+ fakeresolve
+ которая разрешает любое имя в адрес 127.0.0.2.
+
+ Как настроить FTP прокси?
+
+ Есть поддержка как FTP через HTTP (то, что называется FTP прокси в браузерах) так и настоящего FTP прокси (то, что называется
+ FTP proxy в командных оболочках и FTP клиентах). В браузерах в качестве FTP прокси следует прописывать порт службы proxy,
+ т.е. FTP организован
+ через http прокси, дополнительного прокси поднимать не надо. Для FTP-клиентов необходимо поднять ftppr. FTP прокси всегда работает
+ с FTP сервером в пассивном режиме.
+
Как ограничить доступ к службе
Во-первых, для ограничения доступа необходимо указать внутренний интерфейс,
@@ -614,6 +736,74 @@
того, чтобы видеть в логах записи о посещаемых пользвоателем ресурсах и
загружаемых файлах даже в том случае, если он подключается через SOCKS.
+Как управлять локальными перенаправлениями
+
+
+ - Q: Для чего это надо?
+
+ A: Чтобы иметь в логах URL запросов, если пользователь SOCKS пользуется
+ Web, FTP или POP3.
+
+ - Q: Какие недостатки?
+
+ A: Перенапраление невозможно для web-серверов или FTP, висящих на
+ нестандартных портах, для SOCKSv4 не поддрживается авторизация с
+ паролем (IE поддерживает только SOCKSv4), но при этом IE передает
+ имя пользователя по SOCKSv4 (имя, с которым пользователь вошел в систему).
+ Для SOCKSv5 не поддерживается NTLM авторизация, пароли передаются в открытом
+ тексте.
+
+ - Q: Какие преимущества?
+
+ A: Достаточно в настройках IE только указать адрес SOCKS прокси. В
+ больших сетях можно для этого использовать WPAD (автоматическое
+ обнаружение прокси). В 3proxy достаточно запускать только одну службу
+ (socks). Если используется только Internet Explorer, то можно
+ автоматически получать имя пользователя в логах, не запрашивая
+ логин/пароль.
+
+ - Q: Как настраивается?
+
+ A: Указывается parent http proxy со специальным адресом 0.0.0.0 и портом
+ 0. Пример:
+
+ allow * * * 80,8080-8088
+ parent 1000 http 0.0.0.0 0
+ allow * * * 80,8080-8088
+ #перенаправить соединения по портам 80 и 8080-8088 в локальный
+ #http прокси. Вторая команда allow необходима, т.к. контроль доступа
+ #осуществляется 2 раза - на уровне socks и на уровне HTTP прокси
+ allow * * * 21,2121
+ parent 1000 ftp 0.0.0.0 0
+ allow * * * 21,2121
+ #перенаправить соединения по портам 21 и 2121 в локальный
+ #ftp прокси
+ allow *
+ #пустить все соединения напрямую
+ socks
+
+ Q: Как взаимодействует с другими правилами в ACL?
+
+ A: После внутреннего перенаправления правила рассматриваются еще раз за
+ исключением самого правила с перенаправлением (т.е. обработка правил не
+ прекращается). Это позволяет сделать дальнейшие перенаправления на
+ внешний прокси. По этой же причине локальное перенаправление не должно
+ быть последним правилом (т.е. должно быть еще хотя бы правило allow,
+ чтобы разрешить внешние соединения через HTTP прокси).
+ Например,
+
+ allow * * * 80,8080-8088
+ parent 1000 http 0.0.0.0 0
+ #перенаправить во внутренний прокси
+ allow * * $c:\3proxy\local.nets 80,8080-8088
+ #разрешить прямой web-доступ к сетям из local.nets
+ allow * * * 80,8080-8088
+ parent 1000 http proxy.3proxy.ru 3128
+ #все остальные веб-запросы перенаправить на внешний прокси-сервер
+ allow *
+ #разрешить socks-запросы по другим портам
+
+
Как организовать балансировку между несоклькими каналами
Сам по себе прокси не может управлять маршрутизацией пакетов сетевого уровня.
@@ -742,33 +932,26 @@
amount - объем трафика на указанный период в мегабайтах.
- Как строить списки сетей
+ Как пофиксить некорректный подсчет трафика
- Очень часто списки сетей и пользователей бывают достаточно громоздкими.
- 3proxy не поддерживает создание групп, но позволяет включение файлов. Это
- означает, что для удобства администрирования выгодно хранить списки
- пользователей и списки сетей в отдельных файлах и при необходимости дать
- пользователю доступ к тому или иному ресурсу, править файл со списком
- пользователей или сетей вместо того, чтобы править сам файл 3proxy.cfg. В файле
- 3proxy.cfg файл со списком можно включить с помощью макроса $.
- Поскольку в 3proxy есть ограничения на максимальный размер элемента
- конфигурации, большие списки следует разбивать на несколько файлов и
- использовать несколько записей списка контроля доступом.
- В комплекте с 3proxy поставляется утилита dighosts, которая позволяет построить
- список сетей по странице Web. Утилита осуществляет поиск адресов на Web-странице
- в формате АДРЕС МАСКА или АДРЕС/ДЛИНА. Утилиту dighosts можно вызвать во время
- старта 3proxy, используя команду system. Например:
-
- system "dighosts http://provider/network.html local.networks"
- allow * * $local.networks
- allow *
- parent 1000 proxy.provider 3128 *
- proxy
- flush
- В данном случае в файле local.networks генерируется список локальных сетей по
- странице networklist.html. Далее используется список контроля доступа для того,
- чтобы разрешить локальному прокси-серверу доступ к локальным сетям напрямую,
- а все остальные запросы перенаправить на прокси-сервер провайдера.
+ Следует учитывать, что 3proxy считает трафик только на прикладном уровне и
+ только проходящий через прокси-сервер. Провайдеры и другие средства учета
+ трафика считают трафик на сетевом уровне, что уже дает расхождение порядка 10%
+ за счет информации из заголовков пакетов. Кроме того, часть трафика, как
+ минимум DNS-разрешения, различный флудовый трафик и т.д. идут мимо прокси.
+ Уровень "шумового" трафика в Internet сейчас составляет порядка 50KB/день на
+ каждый реальный IP адрес, но может сильно варьироваться в зависимости от сети,
+ наличия открытых портов, реакции на ping-запросы и текущего уровня вирусной
+ активности. По этим причинам, если 3proxy используется чтобы не "выжрать"
+ трафик, выделенный провайдером, всегда следует делать некий запас порядка
+ 15%.
+
+
+ Если на одной с 3proxy машине имеются какие-либо сервисы или
+ работает пользователь, то их трафик не проходит через proxy-сервер и так же
+ не будет учтен. Если где-то есть NAT, то клиенты, выходящие через NAT мимо
+ прокси, так же останутся неучтенными. Если расхождение с провайдером превышает
+ 10% - нужно искать причину именно в этом.
Как управлять разрешением имен и кэшированием DNS
@@ -827,19 +1010,6 @@
tcppm -R0.0.0.0:1234 3128 1.1.1.1 3128
В настройках браузера указывается host.dyndns.example.org:3128.
- Как устанавливать соединение по требованию
-
- Команда dialer задает программу, которая будет запускаться при
- невозможности разрешить имя компьютера, например:
-
- dialer "rasdial PROVIDER"
- (описание rasdial можно найти на сервере поддержки Microsoft).
- Есть два аспекта: невозможность разрешения имени еще не свидетельствует
- об отсутствии соединения (это должна учитывать вызываемая программа),
- при использовании nscache имя может разрешиться при отсутствии
- соединения. В таких случаях полезно запрашивать заведомо несуществующий
- ресурс, например, http://dial.right.now/.
-
Конфигурация клиентов
@@ -1050,7 +1220,7 @@
90 - неожиданная системная ошибка (не должно происходить)
91 - ошибка poll (не должно происходить)
92 - соединение прервано по таймауту на сетевую операцию (см. timeouts)
- 93 - соединение прервано по таймауту связанному с рейтлимитом
+ 93 - соединение прервано по таймауту связанному с рейтлимитом или из-за превышения числа ошибок
94 - клиент или сервер закрыли соединение или произошла сетевая ошибка, остались неотправленные данные
95 - клиент "грязно" закрыл соединение или сетевая ошибка
96 - сервер "грязно" закрыл соединение или сетевая ошибка
diff --git a/doc/html/index.html b/doc/html/index.html
index 13e3e5b0..bf398732 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -3,8 +3,6 @@
Optimizing 3proxy for high loads
How To (English, very incomplete)
How To (Russian)
-FAQ (English)
-FAQ (Russian)
Man pages:
3proxy.8
ftppr.8
diff --git a/man/3proxy.8 b/man/3proxy.8
index 0a26479a..2f09140c 100644
--- a/man/3proxy.8
+++ b/man/3proxy.8
@@ -1,4 +1,4 @@
-.TH 3proxy "8" "January 2019" "3proxy 0.9" "Universal proxy server"
+.TH 3proxy "8" "January 2019" "3proxy 10" "Universal proxy server"
.SH NAME
.B 3proxy
\- 3[APA3A] tiny proxy server, or trivial proxy server, or free proxy
diff --git a/man/3proxy.cfg.3 b/man/3proxy.cfg.3
index 344e176d..9ad85e25 100644
--- a/man/3proxy.cfg.3
+++ b/man/3proxy.cfg.3
@@ -1,4 +1,4 @@
-.TH 3proxy.cfg "8" "January 2019" "3proxy 0.9" "Universal proxy server"
+.TH 3proxy.cfg "8" "January 2019" "3proxy 10" "Universal proxy server"
.SH NAME
.B 3proxy.cfg
3proxy configuration file
@@ -240,6 +240,8 @@ alternate config file. Think twice before using it.
@ (for Unix) use syslog, filename is used as ident name
.br
& use ODBC, filename consists of comma-delimited datasource,username,password (username and password are optional)
+.br
+ radius - use RADIUS for logging
.br
LOGTYPE is one of:
.br
@@ -388,6 +390,28 @@ can use %A as produced archive name and %F as filename.
.br
default timeouts 1 5 30 60 180 1800 15 60 15 5
+.br
+.B radius
+
+.br
+ Configures RADIUS servers to be used for logging and authentication (log and auth types
+must be set to radius). port and local address to use with given server may be specified.
+.br
+ Attributes within request: User-Name, Password: (username and password if presented by client),
+Service Type: Authenticate-Only,
+NAS-Port-Type: NAS-Port-Virtual,
+NAS-Port-ID: (proxy service port, e.g. 1080),
+NAS-IPv6-Address / NAS-IP-Address: (proxy interface accessed by client),
+NAS-Identifier: (text identifing proxy, e.g. PROXY or SOCKSv5),
+Framed-IPv6-Address / Framed-IP-Address: (IP address of the client),
+Called-Station-ID: (requested Hostname, if presents),
+Login-Service: (type of request, e.g. 1001 - SOCKS CONNECT, 1010 - HTTP GET, 1013 - HTTP CONNECT),
+Login-TCP-Port: (requested port),
+Login-IPv6-Host / Login-IP-Host: (requested IP).
+.br
+ Supported reply attributes for authentication:
+Framed-IP-Address / Framed-IPv6-Address (IP to assign to user), Reply-Message.
+Use authcache to speedup authentication. RADIUS feature is currently experimental.
.br
.B nserver
@@ -457,7 +481,7 @@ External or -e can be given twice: once with IPv4 and once with IPv6 address.
.br
sets maximum number of simulationeous connections to each services
-started after this command. Default is 100.
+started after this command. Default is 250.
.br
.B service
@@ -503,6 +527,8 @@ NB: there is no any password check, name may be spoofed.
SOCKSv5, FTP, POP3 and HTTP proxy.
.br
cache - cached authentication, may be used with \'authcache\'.
+.br
+ radius - authentication with RADIUS.
.br
Plugins may add additional authentication types.
@@ -656,14 +682,16 @@ connections. These 2 proxies form 1 group (summarized weight is 1000).
.br
creates chain of 3 proxies: 192.168.10.1, 192.168.20.1 and third
is (192.168.30.1 with probability of 0.3 or 192.168.40.1
-with probability of 0.7) for outgoing web connections.
+with probability of 0.7) for outgoing web connections. Chains are only applied to new connections, pipelined (keep-alive) requests in the same connection use the same chain.
.br
type is one of:
+.br
+ extip does not actully redirect request, it sets external address for this request to . It can be chained with another parent types. It's usefaul to set external IP based on ACL or make it random.
.br
tcp simply redirect connection. TCP is always last in chain. This type of proxy is a simple TCP redirection, it does not support parent authentication.
.br
- http redirect to HTTP proxy. HTTP is always last chain. It should only be used with http (proxy) service,
+ http redirect to HTTP proxy. HTTP is always the last chain. It should only be used with http (proxy) service,
if used with different service, it works as tcp redirection.
.br
pop3 redirect to POP3 proxy (only local redirection is supported, can only be used as a first hop in chaining)
diff --git a/man/ftppr.8 b/man/ftppr.8
index 3f477aa9..9c130ab0 100644
--- a/man/ftppr.8
+++ b/man/ftppr.8
@@ -1,4 +1,4 @@
-.TH ftppr "8" "January 2019" "3proxy 0.9" "Universal proxy server"
+.TH ftppr "8" "January 2019" "3proxy 10" "Universal proxy server"
.SH NAME
.B ftppr
\- FTP proxy gateway service
diff --git a/man/icqpr.8 b/man/icqpr.8
index ccd32604..a82c63bd 100644
--- a/man/icqpr.8
+++ b/man/icqpr.8
@@ -1,4 +1,4 @@
-.TH icqpr "8" "January 2019" "3proxy 0.9" "Universal proxy server"
+.TH icqpr "8" "January 2019" "3proxy 10" "Universal proxy server"
.SH NAME
.B icqpr
\- ICQ (AOL OSCAR) proxy
diff --git a/man/pop3p.8 b/man/pop3p.8
index 338337be..35f1b806 100644
--- a/man/pop3p.8
+++ b/man/pop3p.8
@@ -1,4 +1,4 @@
-.TH pop3p "8" "January 2019" "3proxy 0.9" "Universal proxy server"
+.TH pop3p "8" "January 2019" "3proxy 10" "Universal proxy server"
.SH NAME
.B pop3p
\- POP3 proxy gateway service
diff --git a/man/proxy.8 b/man/proxy.8
index 4ddbf174..b79632f7 100644
--- a/man/proxy.8
+++ b/man/proxy.8
@@ -1,4 +1,4 @@
-.TH proxy "8" "January 2019" "3proxy 0.9" "Universal proxy server"
+.TH proxy "8" "January 2019" "3proxy 10" "Universal proxy server"
.SH NAME
.B proxy
\- HTTP proxy gateway service
diff --git a/man/smtpp.8 b/man/smtpp.8
index 66695092..2a735761 100644
--- a/man/smtpp.8
+++ b/man/smtpp.8
@@ -1,4 +1,4 @@
-.TH smtpp "8" "January 2019" "3proxy 0.9" "Universal proxy server"
+.TH smtpp "8" "January 2019" "3proxy 10" "Universal proxy server"
.SH NAME
.B smtpp
\- SMTP proxy gateway service
diff --git a/man/socks.8 b/man/socks.8
index 8a7960c0..81a63f0c 100644
--- a/man/socks.8
+++ b/man/socks.8
@@ -1,4 +1,4 @@
-.TH socks "8" "January 2019" "3proxy 0.9" "Universal proxy server"
+.TH socks "8" "January 2019" "3proxy 10" "Universal proxy server"
.SH NAME
.B socks
\- SOCKS 4/4.5/5 gateway service
diff --git a/man/tcppm.8 b/man/tcppm.8
index de65ec51..a087e349 100644
--- a/man/tcppm.8
+++ b/man/tcppm.8
@@ -1,4 +1,4 @@
-.TH tcppm "8" "January 2019" "3proxy 0.9" "Universal proxy server"
+.TH tcppm "8" "January 2019" "3proxy 10" "Universal proxy server"
.SH NAME
.B tcppm
\- TCP port mapper
diff --git a/man/udppm.8 b/man/udppm.8
index 9f704c87..dc8b30b9 100644
--- a/man/udppm.8
+++ b/man/udppm.8
@@ -1,4 +1,4 @@
-.TH udppm "8" "January 2019" "3proxy 0.9" "Universal proxy server"
+.TH udppm "8" "January 2019" "3proxy 10" "Universal proxy server"
.SH NAME
.B udppm
\- UDP port mapper
diff --git a/scripts/3proxy-linux-install.sh b/scripts/3proxy-linux-install.sh
deleted file mode 100644
index d352852c..00000000
--- a/scripts/3proxy-linux-install.sh
+++ /dev/null
@@ -1,985 +0,0 @@
-#!/bin/bash
-# 3proxy build and install script for Debian Linux
-# Release 2.0 at 29.12.2016
-# (с) Evgeniy Solovyev
-# mail-to: eugen-soloviov@yandex.ru
-
-ScriptPath=""
-Src3proxyDirPath=""
-ScriptName=""
-ScriptFullName=""
-SourceRoot=""
-
-ResourcesData=""
-
-
-ProxyVersion=""
-LasestProxyVersion=""
-LasestProxyVersionLink=""
-UseSudo=0
-PacketFiles=""
-NeedSourceUpdate=0
-
-
-main()
-{
- local msgNewVersion
- local msgInsertYorN
-
- VarsInit
- LoadResources
- CheckRunConditions
-
- if [ $UseSudo == 1 ]
- then
- sudo bash "${0}"
- exit $?
- fi
-
- CheckLocation
- GetLasestVersionInfo
-
- SourceDownloadOrUpdate
-
- cd "${SourceRoot}"
-
- Build3Proxy
- BinInstall
- ManInstall
- CreateLogDir
- CopyConfig
- SetInit
- Pack3proxyFiles
-}
-
-VarsInit()
-{
- cd `dirname $0`
- ScriptPath="${PWD}"
- ScriptName=`basename $0`
- ScriptFullName="${ScriptPath}/${ScriptName}"
-}
-
-CheckLocation()
-{
- Src3proxyDirPath="${ScriptPath}"
-
- if echo ${ScriptPath} | grep -e "/scripts$"
- then
- if [ -e "../src/version.h" ]
- then
- ProxyVersion=`cat "../src/version.h" | awk '/VERSION/ { gsub("\"", "\n"); print; exit }' | grep "3proxy"`
- cd ../
- SourceRoot="${PWD}"
- cd ../
- Src3proxyDirPath="${PWD}"
- cd "${ScriptPath}"
- fi
- fi
-}
-
-GetLasestVersionInfo()
-{
- local Githublink
- local msg
-
- Githublink=`wget https://github.com/z3APA3A/3proxy/releases/latest -O /dev/stdout |
- awk '/ "${ConfigDir}/3proxy.cfg"
-
- PacketFiles=`echo -e "${PacketFiles}\n${ConfigDir}/3proxy.cfg"`
-}
-
-
-SetInit()
-{
- LoadGlobalResource "InitScript" > "/etc/init.d/3proxy"
- chown root:root "/etc/init.d/3proxy"
- chmod 755 "/etc/init.d/3proxy"
-
- PacketFiles=`echo -e "${PacketFiles}\n/etc/init.d/3proxy"`
- update-rc.d 3proxy defaults
-}
-
-Pack3proxyFiles()
-{
- local CPU_Arc
- CPU_Arc=`uname -m`
- cd ../
- tar -czPpvf "${ProxyVersion}-${CPU_Arc}.tar.gz" $PacketFiles
-}
-
-LoadResources()
-{
- local StartRow
- local EndRow
- local LngLabel
- local msgResourceErr="\aError! Script could not find resources!"
-
- if env | grep -q 'LANG=ru_RU.UTF-8'
- then
- LngLabel="RU"
-#LngLabel="EN"
- else
- LngLabel="EN"
- fi
-
- StartRow=`cat "${ScriptFullName}" | awk "/^#Resources_${LngLabel}/ { print NR; exit}"`
-
- if [ -z "${StartRow}" ]
- then
- echo -e "${msgResourceErr}"
- exit 255
- fi
-
- EndRow=`cat "${ScriptFullName}" | awk "NR > ${StartRow} && /^#Resources_${LngLabel}_end/ { print NR; exit}"`
-
- if [ -z "${EndRow}" ]
- then
- echo -e "${msgResourceErr}"
- exit 255
- fi
-
- ResourcesData=`cat "${ScriptFullName}" | awk -v StartRow="${StartRow}" -v EndRow="${EndRow}" 'NR > StartRow && NR < EndRow { print $0 }'`
-}
-
-
-# $1 - Name of Resource
-GetResource()
-{
- local StartRow
- local EndRow
- local msgResourceErr="\aError! Script could not find resource \"${1}\"!"
-
- StartRow=`echo "${ResourcesData}" | awk "/^#Resource=${1}/ { print NR; exit}"`
-
- if [ -z "${StartRow}" ]
- then
- echo -e "${msgResourceErr}" > /dev/stderr
- exit 255
- fi
-
- EndRow=`echo "${ResourcesData}" | awk "NR > ${StartRow} && /^#endResource=${1}/ { print NR; exit}"`
-
- if [ -z "${EndRow}" ]
- then
- echo -e "${msgResourceErr}" > /dev/stderr
- exit 255
- fi
-
- echo "${ResourcesData}" | awk -v StartRow="${StartRow}" -v EndRow="${EndRow}" 'NR > StartRow && NR < EndRow { print $0 }'
-}
-
-
-# $1 - Name of Resource
-LoadGlobalResource()
-{
- local StartRow
- local EndRow
- local LngLabel
- local msgResourceErr="\aError! Script could not find resource \"${1}\"!"
-
-
- StartRow=`cat "${ScriptFullName}" | awk "/^#Resource=${1}/ { print NR; exit}"`
-
- if [ -z "${StartRow}" ]
- then
- echo -e "${msgResourceErr}" > /dev/stderr
- exit 255
- fi
-
- EndRow=`cat "${ScriptFullName}" | awk "NR > ${StartRow} && /^#endResource=${1}/ { print NR; exit}"`
-
- if [ -z "${EndRow}" ]
- then
- echo -e "${msgResourceErr}" > /dev/stderr
- exit 255
- fi
-
- cat "${ScriptFullName}" | awk -v StartRow="${StartRow}" -v EndRow="${EndRow}" 'NR > StartRow && NR < EndRow { print $0 }'
-}
-
-
-CheckPacketInstall()
-{
- if [ `dpkg -l ${1} 2>&1 | wc -l` -le 1 ]
- then
- echo 0
- return
- fi
- if [ `dpkg -l ${1} | grep -e ^un | wc -l` == 1 ]
- then
- echo 0
- return
- fi
-
- echo 1
-}
-
-main
-exit 0
-
-#Resources_EN
-
-#Resource=msgSudoNotInstalled
-\aThe script is running under the account a non-privileged user.
-"Sudo" package is not installed in the system.
-The script can not continue, as the execution of operations,
-requiring rights "root" - is not possible!
-Please run the script under the account "root",
-or install and configure "sudo" package!
-#endResource=msgSudoNotInstalled
-
-#Resource=msgUserNotMemberOfSudoGroup
-\aThe script is running under account a non-privileged user.
-The account of the current user is not included in the "sudo" group!
-The script can not continue, as the execution of operations,
-requiring rights "root" - is not possible!
-Please run the script under the account "root",
-or configure "sudo" package!
-#endResource=msgUserNotMemberOfSudoGroup
-
-#Resource=msgSystemUseProxy
-\aAttention! The operating system uses proxy-server.
-For correctly work of package manager "apt"
-in the file "/etc/sudoers" should be present line:
-Defaults env_keep = "http_proxy https_proxy"
-#endResource=msgSystemUseProxy
-
-#Resource=msgDoYouWishContinue
-Do you wish to the script continued executing? (y/n):
-#endResource=msgDoYouWishContinue
-
-#Resource=msgPleaseInsertYorN
-\a\nPlease insert "y" or "n"!
-#endResource=msgPleaseInsertYorN
-
-#Resource=msgInternetConnectionError
-\aError downloading "https://github.com/z3APA3A/3proxy/releases/latest"!
-Please check the settings of the Internet connection.
-#endResource=msgInternetConnectionError
-
-#Resource=msgNewVersion
-The new version of "3proxy" detected, do you want download it?
-#endResource=msgNewVersion
-
-#Resource=msgBuildEssentialNotInstalled
-\aPackage "build-essential" was not installed.
-The installation can not be continued!
-#endResource=msgBuildEssentialNotInstalled
-
-#Resources_EN_end
-
-#Resources_RU
-
-#Resource=msgSudoNotInstalled
-\aСкрипт запущен под учётной записью обычного пользователя.
-В системе не установлен пакет "sudo".
-Скрипт не может продолжить работу, так как выполнение операций,
-требующих прав "root" - не представляется возможным!
-Пожалуйста, запустите скрипт под учётной записью "root",
-либо установите и настройте пакет "sudo"!
-#endResource=msgSudoNotInstalled
-
-#Resource=msgUserNotMemberOfSudoGroup
-\aСкрипт запущен под учётной записью обычного пользователя.
-Учётная запись текущего пользователя не включена в группу "sudo"!
-Скрипт не может продолжить работу, так как выполнение операций,
-требующих прав "root" - не представляется возможным!
-Пожалуйста, запустите скрипт под учётной записью "root",
-либо настройте пакет "sudo"!
-#endResource=msgUserNotMemberOfSudoGroup
-
-#Resource=msgSystemUseProxy
-\aВнимание! В системе используется прокси-сервер.
-Чтобы менеджер пакетов "apt" работал корректно,
-в файле "/etc/sudoers" должна присутствовать строка:
-Defaults env_keep = "http_proxy https_proxy"
-#endResource=msgSystemUseProxy
-
-#Resource=msgDoYouWishContinue
-Хотите чтобы скрипт дальше продолжил работу? (y/n):
-#endResource=msgDoYouWishContinue
-
-#Resource=msgPleaseInsertYorN
-\a\nПожалуйста введите "y" или "n"!
-#endResource=msgPleaseInsertYorN
-
-#Resource=msgInternetConnectionError
-\aОшибка закачки "https://github.com/z3APA3A/3proxy/releases/latest"!
-Пожалуйста, проверьте настройки интернет соединения.
-#endResource=msgInternetConnectionError
-
-#Resource=msgNewVersion
-Обнаружена новая версия "3proxy", скачать её (y/n)?
-#endResource=msgNewVersion
-
-#Resource=msgBuildEssentialNotInstalled
-\aПакет "build-essential" не был установлен.
-Дальнейшая установка не может быть продолжена!
-#endResource=msgBuildEssentialNotInstalled
-
-#Resources_RU_end
-
-
-#Resource=ConfigFile
-noconfig
-# If in this file have line "noconfig", then 3proxy not to be runned!
-# For usung this configuration file 3proxy you must to delete
-# or comment out the line with "noconfig".
-
-daemon
-# Parameter "daemon" - means run 3proxy as daemon
-
-
-pidfile /tmp/3proxy.pid
-# PID file location
-# This parameter must have the same value as
-# the variable "PidFile" in the script "/etc/init.d/3proxy"
-
-
-# Configuration file location
-config /etc/3proxy/3proxy.cfg
-
-
-internal 127.0.0.1
-# Internal is address of interface proxy will listen for incoming requests
-# 127.0.0.1 means only localhost will be able to use this proxy. This is
-# address you should specify for clients as proxy IP.
-# You MAY use 0.0.0.0 but you shouldn't, because it's a chance for you to
-# have open proxy in your network in this case.
-
-external 192.168.0.1
-# External is address 3proxy uses for outgoing connections. 0.0.0.0 means any
-# interface. Using 0.0.0.0 is not good because it allows to connect to 127.0.0.1
-
-
-# DNS IP addresses
-nserver 8.8.8.8
-nserver 8.8.4.4
-
-
-# DNS cache size
-nscache 65536
-
-# Timeouts settings
-timeouts 1 5 30 60 180 1800 15 60
-
-
-# log file location
-log /var/log/3proxy/3proxy.log D
-
-# log file format
-logformat "L%C - %U [%d-%o-%Y %H:%M:%S %z] ""%T"" %E %I %O %N/%R:%r"
-
-archiver gz /usr/bin/gzip %F
-# If archiver specified log file will be compressed after closing.
-# you should specify extension, path to archiver and command line, %A will be
-# substituted with archive file name, %f - with original file name.
-# Original file will not be removed, so archiver should care about it.
-
-rotate 30
-# We will keep last 30 log files
-
-proxy -p3128
-# Run http/https proxy on port 3128
-
-auth none
-# No authentication is requires
-
-setgid 65534
-setuid 65534
-# Run 3proxy under account "nobody" with group "nobody"
-#endResource=ConfigFile
-
-
-#Resource=InitScript
-#!/bin/sh
-#
-# 3proxy daemon control script
-#
-### BEGIN INIT INFO
-# Provides: 3proxy
-# Required-Start: $network $remote_fs $syslog
-# Required-Stop: $network $remote_fs $syslog
-# Should-Start: $named
-# Should-Stop: $named
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: 3proxy HTTP Proxy
-### END INIT INFO
-
-
-ScriptName="3proxy"
-ScriptFullName="/etc/init.d/3proxy"
-
-ConfigFile="/etc/3proxy/3proxy.cfg"
-LogDir="/var/log/3proxy"
-PidFile="/tmp/3proxy.pid"
-
-ResourcesData=""
-
-main()
-{
- LoadResources
-
- if [ ! -d "${LogDir}" ]
- then
- mkdir -p "${LogDir}";
- fi
-
- case "$1" in
- start) Start ;;
- stop) Stop ;;
- restart) Stop; Start ;;
- status) Status ;;
- *) ShowHelp;;
- esac
-}
-
-Start()
-{
- local msg
- local ProxyPID
-
- if [ ! -f "${ConfigFile}" ]
- then
- msg=`GetResource "msgConfigFileNotFound"`
- printf "${msg}" "${ConfigFile}"
- return
- fi
-
- if cat "${ConfigFile}" | grep -qe "^noconfig"
- then
- msg=`GetResource "msgNoconfigDetected"`
- printf "${msg}" "${ConfigFile}"
- return
- fi
-
- ProxyPID=`Get3proxyPID`
-
- if [ ! -z "${ProxyPID}" ]
- then
- msg=`GetResource "msg3proxyAlreadyRunning"`
- printf "${msg}" "${ProxyPID}"
- return
- fi
-
- 3proxy "${ConfigFile}"
- sleep 1
-
- ProxyPID=`Get3proxyPID`
-
- if [ ! -f "${PidFile}" ]
- then
- msg=`GetResource "msg3proxyStartProblems"`
- printf "${msg}"
- return
- fi
-
- if [ `cat "${PidFile}"` != "${ProxyPID}" ]
- then
- msg=`GetResource "msg3proxyStartProblems"`
- printf "${msg}"
- return
- fi
-
- msg=`GetResource "msg3proxyStartedSuccessfully"`
- printf "${msg}" `date +%d-%m-%Y" "%H:%M:%S` "${ProxyPID}"
-
-}
-
-Stop()
-{
- local msg
- local ProxyPID
-
- ProxyPID=`Get3proxyPID`
-
- if [ -f "${PidFile}" ]
- then
- if [ `cat "${PidFile}"` = "${ProxyPID}" ]
- then
- kill -9 "${ProxyPID}"
- rm -f "${PidFile}"
-
- msg=`GetResource "msg3proxyStoppedSuccessfully"`
- printf "${msg}" `date +%d-%m-%Y" "%H:%M:%S`
-
- return
- fi
- fi
-
- if [ -z "${ProxyPID}" ]
- then
- msg=`GetResource "msg3proxyProxyNotDetected"`
- printf "${msg}"
-
- return
- fi
-
- pkill -o 3proxy
-
- msg=`GetResource "msg3proxyStoppedByKillall"`
- printf "${msg}" `date +%d-%m-%Y" "%H:%M:%S` "${PidFile}"
-
-}
-
-Status()
-{
- local msg
- local ProxyPID
-
- if [ -f "${PidFile}" ]
- then
- msg=`GetResource "msgPidFileExists"`
- printf "${msg}" "${PidFile}" `cat "${PidFile}"`
- else
- msg=`GetResource "msgPidFileNotExists"`
- printf "${msg}" "${PidFile}"
- fi
-
- ProxyPID=`Get3proxyPID`
-
- if [ ! -z "${ProxyPID}" ]
- then
- msg=`GetResource "msg3proxyProcessDetected"`
- printf "${msg}"
- ps -ef | awk '$8 ~ /^3proxy/ { print "User: " $1 "\tPID: " $2 }'
- else
- msg=`GetResource "msg3proxyProcessNotDetected"`
- printf "${msg}"
- fi
-}
-
-ShowHelp()
-{
- local msg
-
- msg=`GetResource "msg3proxyHelp"`
- printf "${msg}" "${ScriptFullName}" "${ScriptName}"
-}
-
-Get3proxyPID()
-{
- ps -ef | awk '$8 ~ /^3proxy/ { print $2; exit }'
-}
-
-LoadResources()
-{
- local StartRow
- local EndRow
- local LngLabel
- local msgResourceErr="\aError! Script could not find resources!"
-
- if env | grep -q 'LANG=ru_RU.UTF-8'
- then
- LngLabel="RU"
- else
- LngLabel="EN"
- fi
-
- StartRow=`cat "${ScriptFullName}" | awk "/^#Resources_${LngLabel}/ { print NR; exit}"`
-
- if [ -z "${StartRow}" ]
- then
- echo -e "${msgResourceErr}"
- exit 255
- fi
-
- EndRow=`cat "${ScriptFullName}" | awk "NR > ${StartRow} && /^#Resources_${LngLabel}_end/ { print NR; exit}"`
-
- if [ -z "${EndRow}" ]
- then
- echo -e "${msgResourceErr}"
- exit 255
- fi
-
- ResourcesData=`cat "${ScriptFullName}" | awk -v StartRow="${StartRow}" -v EndRow="${EndRow}" 'NR > StartRow && NR < EndRow { print $0 }'`
-}
-
-# $1 - Name of Resource
-GetResource()
-{
- local StartRow
- local EndRow
- local msgResourceErr="\aError! Script could not find resource \"${1}\"!"
-
- StartRow=`echo "${ResourcesData}" | awk "/^#Resource=${1}/ { print NR; exit}"`
-
- if [ -z "${StartRow}" ]
- then
- echo -e "${msgResourceErr}" > /dev/stderr
- exit 255
- fi
-
- EndRow=`echo "${ResourcesData}" | awk "NR > ${StartRow} && /^#endResource=${1}/ { print NR; exit}"`
-
- if [ -z "${EndRow}" ]
- then
- echo -e "${msgResourceErr}" > /dev/stderr
- exit 255
- fi
-
- echo "${ResourcesData}" | awk -v StartRow="${StartRow}" -v EndRow="${EndRow}" 'NR > StartRow && NR < EndRow { print $0 }'
-}
-
-
-main $@
-exit 0;
-
-#Resources_EN
-
-#Resource=msg3proxyHelp
-Usage:
-\t%s {start|stop|restart}
-or
-\tservice %s {start|stop|restart|status}\\n
-#endResource=msg3proxyHelp
-
-#Resource=msgConfigFileNotFound
-\a3proxy configuration file - "%s" is not found!\\n
-#endResource=msgConfigFileNotFound
-
-#Resource=msgNoconfigDetected
-Parameter "noconfig" found in 3proxy configuration file -
-"% s" !
-To run 3proxy this parameter should be disabled.\\n
-#endResource=msgNoconfigDetected
-
-#Resource=msg3proxyAlreadyRunning
-\a3proxy already running PID: %s\\n
-#endResource=msg3proxyAlreadyRunning
-
-#Resource=msg3proxyStartProblems
-With the start of 3proxy, something is wrong!
-Use: service 3proxy status\\n
-#endResource=msg3proxyStartProblems
-
-#Resource=msg3proxyStartedSuccessfully
-[ %s %s ] 3proxy started successfully! PID: %s\\n
-#endResource=msg3proxyStartedSuccessfully
-
-#Resource=msg3proxyStoppedSuccessfully
-[ %s %s ] 3proxy stopped successfully!\\n
-#endResource=msg3proxyStoppedSuccessfully
-
-#Resource=msg3proxyProxyNotDetected
-Process "3proxy" is not detected!\\n
-#endResource=msg3proxyProxyNotDetected
-
-#Resource=msg3proxyStoppedByKillall
-[ %s %s ] Command "pkill -o 3proxy" was executed,
-because process number was not stored in "%s",
-but in fact 3proxy was runned!\\n
-#endResource=msg3proxyStoppedByKillall
-
-#Resource=msgPidFileExists
-File "%s" exists. It contains the PID: %s\\n
-#endResource=msgPidFileExists
-
-#Resource=msgPidFileNotExists
-File "%s" not found, that is, PID 3proxy was not stored!\\n
-#endResource=msgPidFileNotExists
-
-#Resource=msg3proxyProcessDetected
-Process 3proxy detected:\\n
-#endResource=msg3proxyProcessDetected
-
-#Resource=msg3proxyProcessNotDetected
-Processes of 3proxy is not found!\\n
-#endResource=msg3proxyProcessNotDetected
-
-#Resources_EN_end
-
-
-#Resources_RU
-
-#Resource=msg3proxyHelp
-Используйте:
-\t%s {start|stop|restart}
-или
-\tservice %s {start|stop|restart|status}\\n
-#endResource=msg3proxyHelp
-
-#Resource=msgConfigFileNotFound
-\aФайл конфигурации 3proxy - "%s", не найден!\\n
-#endResource=msgConfigFileNotFound
-
-#Resource=msgNoconfigDetected
-\aОбнаружен параметр "noconfig" в файле конфигурации 3proxy -
-"%s" !
-Для запуска 3proxy этот параметр нужно отключить.\\n
-#endResource=msgNoconfigDetected
-
-#Resource=msg3proxyAlreadyRunning
-\a3proxy уже запущен PID: %s\\n
-#endResource=msg3proxyAlreadyRunning
-
-#Resource=msg3proxyStartProblems
-\aСо стартом 3proxy, что-то не так!
-Используйте: service 3proxy status\\n
-#endResource=msg3proxyStartProblems
-
-#Resource=msg3proxyStartedSuccessfully
-[ %s %s ] 3proxy успешно стартовал! PID: %s\\n
-#endResource=msg3proxyStartedSuccessfully
-
-#Resource=msg3proxyStoppedSuccessfully
-[ %s %s ] 3proxy успешно остановлен!\\n
-#endResource=msg3proxyStoppedSuccessfully
-
-#Resource=msg3proxyProxyNotDetected
-Процесс "3proxy" не обнаружен!\\n
-#endResource=msg3proxyProxyNotDetected
-
-#Resource=msg3proxyStoppedByKillall
-[ %s %s ] Выполнена команда "pkill -o 3proxy",
-т.к. номер процесса не записан в "%s",
-но по факту 3proxy рабатал!\\n
-#endResource=msg3proxyStoppedByKillall
-
-#Resource=msgPidFileExists
-Файл "%s" есть. Он содержит PID: %s\\n
-#endResource=msgPidFileExists
-
-#Resource=msgPidFileNotExists
-Файл "%s" не найден, т.е. PID 3proxy не был сохранён!\\n
-#endResource=msgPidFileNotExists
-
-#Resource=msg3proxyProcessDetected
-Обнаружен процесс 3proxy:\\n
-#endResource=msg3proxyProcessDetected
-
-#Resource=msg3proxyProcessNotDetected
-Процессов 3proxy не обнаружено!\\n
-#endResource=msg3proxyProcessNotDetected
-
-#Resources_RU_end
-#endResource=InitScript
diff --git a/scripts/3proxy.cfg b/scripts/3proxy.cfg
index 26b78bf0..30b4024b 100644
--- a/scripts/3proxy.cfg
+++ b/scripts/3proxy.cfg
@@ -9,7 +9,7 @@ log /logs/3proxy-%y%m%d.log D
rotate 60
counter /count/3proxy.3cf
-users $/conf/passwd
+users $/conf/passwd
include /conf/counters
include /conf/bandlimiters
diff --git a/scripts/3proxy.cfg.chroot b/scripts/3proxy.cfg.chroot
index 60836710..ea506828 100644
--- a/scripts/3proxy.cfg.chroot
+++ b/scripts/3proxy.cfg.chroot
@@ -1,5 +1,5 @@
#!/bin/3proxy
-daemon
+#daemon
pidfile /var/run/3proxy/3proxy.pid
chroot /usr/local/3proxy proxy proxy
include /conf/3proxy.cfg
diff --git a/scripts/3proxy.service b/scripts/3proxy.service
new file mode 100644
index 00000000..a31d0fd9
--- /dev/null
+++ b/scripts/3proxy.service
@@ -0,0 +1,18 @@
+[Unit]
+Description=3proxy tiny proxy server
+Documentation=man:3proxy(1)
+After=network.target
+
+[Service]
+Environment=CONFIGFILE=/etc/3proxy/3proxy.cfg
+ExecStart=/bin/3proxy ${CONFIGFILE}
+ExecReload=/bin/kill -SIGUSR1 $MAINPID
+KillMode=process
+Restart=on-failure
+RestartSec=60s
+LimitNOFILE=65536
+LimitNPROC=32768
+
+[Install]
+WantedBy=multi-user.target
+Alias=3proxy.service
\ No newline at end of file
diff --git a/scripts/debian/3proxy.manpages b/scripts/debian/3proxy.manpages
new file mode 100644
index 00000000..f6a505e6
--- /dev/null
+++ b/scripts/debian/3proxy.manpages
@@ -0,0 +1,10 @@
+man/3proxy.8
+man/3proxy.cfg.3
+man/ftppr.8
+man/icqpr.8
+man/pop3p.8
+man/proxy.8
+man/smtpp.8
+man/socks.8
+man/tcppm.8
+man/udppm.8
\ No newline at end of file
diff --git a/scripts/debian/changelog b/scripts/debian/changelog
new file mode 100644
index 00000000..779da373
--- /dev/null
+++ b/scripts/debian/changelog
@@ -0,0 +1,5 @@
+3proxy (10-devel-0) buster; urgency=medium
+
+ *Initial deb devel release
+
+ -- z3APA3A <3apa3a@3proxy.org> Thu, 03 Dec 2020 21:07:14 +0300
diff --git a/scripts/debian/compat b/scripts/debian/compat
new file mode 100644
index 00000000..f11c82a4
--- /dev/null
+++ b/scripts/debian/compat
@@ -0,0 +1 @@
+9
\ No newline at end of file
diff --git a/scripts/debian/conffiles b/scripts/debian/conffiles
new file mode 100644
index 00000000..5511217d
--- /dev/null
+++ b/scripts/debian/conffiles
@@ -0,0 +1,4 @@
+/usr/local/3proxy/conf/3proxy.cfg
+/usr/local/3proxy/conf/add3proxyuser.sh
+/usr/local/3proxy/conf/bandlimiters
+/usr/local/3proxy/conf/counters
diff --git a/scripts/debian/control b/scripts/debian/control
new file mode 100644
index 00000000..30ec490e
--- /dev/null
+++ b/scripts/debian/control
@@ -0,0 +1,18 @@
+Source: 3proxy
+Maintainer: z3APA3A <3apa3a@3proxy.org>
+Section: net
+Priority: optional
+Standards-Version: 4.0.0
+Build-Depends: debhelper (>=10)
+Homepage: https://3proxy.org/
+Vcs-Git: https://github.com/z3APA3A/3proxy
+Vcs-Browser: https://github.com/z3APA3A/3proxy
+
+Package: 3proxy
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: tiny free proxy server
+ 3Proxy tiny free proxy server is really tiny freeware proxy servers set.
+ It includes HTTP proxy with HTTPS and FTP support, SOCKSv4/SOCKSv4.5/SOCKSv5 proxy (socks/socks.exe), POP3 proxy, SMTP proxy, FTP proxy, caching DNS proxy, TCP and UDP portmappers.
+ You can use every proxy as a standalone program (socks, proxy, tcppm, udppm, pop3p) or use combined program (3proxy). Combined proxy additionally supports features like access control, bandwidth limiting, limiting daily/weekly/monthly traffic amount, proxy chaining, log rotation, syslog and ODBC logging, etc.
+ It's created to be small, simple and yet very functional.
\ No newline at end of file
diff --git a/scripts/debian/copyright b/scripts/debian/copyright
new file mode 100644
index 00000000..62c79e03
--- /dev/null
+++ b/scripts/debian/copyright
@@ -0,0 +1,12 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: 3proxy
+Upstream-Contact: 3proxy@3proxy.org
+Source: https://3proxy.org/
+
+Files: *
+Copyright: 2000-2020 3APA3A, Vladimir Dubrovin, 3proxy.org
+License: BSD-3-clause or Apache or GPL-2+ or LGPL-2+
+
+Files: src/libs/md*.*
+Copyright: 1990,1991,1992 RSA Data Security, Inc
+License: public-domain
diff --git a/scripts/debian/postinst b/scripts/debian/postinst
new file mode 100644
index 00000000..dbdbe4be
--- /dev/null
+++ b/scripts/debian/postinst
@@ -0,0 +1,43 @@
+if [ ! -f /usr/local/3proxy/conf/passwd ]; then \
+ touch /usr/local/3proxy/conf/passwd;\
+fi
+chown -R proxy:proxy /usr/local/3proxy
+chmod 550 /usr/local/3proxy/
+chmod 550 /usr/local/3proxy/conf/
+chmod 440 /usr/local/3proxy/conf/*
+if /bin/systemctl >/dev/null 2>&1; then \
+ /usr/sbin/update-rc.d 3proxy disable || true; \
+ /usr/sbin/chkconfig 3proxy off || true; \
+ /bin/systemctl enable 3proxy.service; \
+elif [ -x /usr/sbin/update-rc.d ]; then \
+ /usr/sbin/update-rc.d 3proxy defaults; \
+ /usr/sbin/update-rc.d 3proxy enable; \
+elif [ -x /usr/sbin/chkconfig ]; then \
+ /usr/sbin/chkconfig 3proxy on; \
+fi
+
+echo ""
+echo 3proxy installed.
+if /bin/systemctl >/dev/null 2>&1; then \
+ /bin/systemctl stop 3proxy.service \
+ /bin/systemctl start 3proxy.service \
+ echo use ;\
+ echo " "systemctl start 3proxy.service ;\
+ echo to start proxy ;\
+ echo " "systemctl stop 3proxy.service ;\
+ echo to stop proxy ;\
+elif [ -x /usr/sbin/service ]; then \
+ /usr/sbin/service 3proxy stop || true;\
+ /usr/sbin/service 3proxy start || true;\
+ echo " "service 3proxy start ;\
+ echo to start proxy ;\
+ echo " "service 3proxy stop ;\
+ echo to stop proxy ;\
+fi
+echo " "/usr/local/3proxy/conf/add3proxyuser.sh
+echo to add users
+echo ""
+echo Default config uses Google\'s DNS.
+echo It\'s recommended to use provider supplied DNS or install local recursor, e.g. pdns-recursor.
+echo Configure preferred DNS in /usr/local/3proxy/conf/3proxy.cfg.
+echo run \'/usr/local/3proxy/conf/add3proxyuser.sh admin password\' to configure \'admin\' user
diff --git a/scripts/debian/preinst b/scripts/debian/preinst
new file mode 100644
index 00000000..f000a2e5
--- /dev/null
+++ b/scripts/debian/preinst
@@ -0,0 +1,4 @@
+if [ -x /usr/sbin/useradd ]; then \
+ /usr/bin/getent group proxy >/dev/null || (/usr/sbin/groupadd -f -r proxy || true); \
+ /usr/bin/getent passwd proxy >/dev/null || (/usr/sbin/useradd -Mr -s /bin/false -g proxy -c 3proxy proxy || true); \
+fi
diff --git a/scripts/debian/rules b/scripts/debian/rules
new file mode 100644
index 00000000..dc57dd03
--- /dev/null
+++ b/scripts/debian/rules
@@ -0,0 +1,16 @@
+#!/usr/bin/make -f
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ ln -s Makefile.Linux Makefile || true
+ dh_auto_build
+
+override_dh_auto_clean:
+ find src/ -type f -name "*.o" -delete
+ find src/ -type f -name "Makefile.var" -delete
+ find bin/ -type f -executable -delete
+ rm -f Makefile
+
+override_dh_usrlocal:
diff --git a/scripts/debian/source/format b/scripts/debian/source/format
new file mode 100644
index 00000000..163aaf8d
--- /dev/null
+++ b/scripts/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/scripts/init.d/3proxy.sh b/scripts/init.d/3proxy.sh
index f6b39873..ebedb9cf 100644
--- a/scripts/init.d/3proxy.sh
+++ b/scripts/init.d/3proxy.sh
@@ -18,7 +18,7 @@ case "$1" in
echo Starting 3Proxy
/bin/mkdir -p /var/run/3proxy
- /bin/3proxy /etc/3proxy/3proxy.cfg
+ /bin/3proxy /etc/3proxy/3proxy.cfg &
RETVAL=$?
echo
@@ -29,6 +29,7 @@ case "$1" in
echo Stopping 3Proxy
if [ -f /var/run/3proxy/3proxy.pid ]; then
/bin/kill `cat /var/run/3proxy/3proxy.pid`
+ rm /var/run/3proxy/3proxy.pid
else
/usr/bin/killall 3proxy
fi
@@ -42,6 +43,7 @@ case "$1" in
echo Reloading 3Proxy
if [ -f /var/run/3proxy/3proxy.pid ]; then
/bin/kill -s USR1 `cat /var/run/3proxy/3proxy.pid`
+ rm /var/run/3proxy/3proxy.pid
else
/usr/bin/killall -s USR1 3proxy
fi
diff --git a/scripts/install-unix.sh b/scripts/install-unix.sh
deleted file mode 100644
index a54c91e8..00000000
--- a/scripts/install-unix.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-cd ..
-cp Makefile.unix Makefile
-make
-if [ ! -d /usr/local/etc/3proxy/bin ]; then mkdir -p /usr/local/etc/3proxy/bin/; fi
-install bin/3proxy /usr/local/bin/3proxy
-install bin/mycrypt /usr/local/bin/mycrypt
-install scripts/rc.d/proxy.sh /usr/local/etc/rc.d/proxy.sh
-install scripts/add3proxyuser.sh /usr/local/etc/3proxy/bin/
-if [ -s /usr/local/etc/3proxy/3proxy.cfg ]; then
- echo /usr/local/etc/3proxy/3proxy.cfg already exists
-else
- install scripts/3proxy.cfg /usr/local/etc/3proxy/
- if [ ! -d /var/log/3proxy/ ]; then
- mkdir /var/log/3proxy/
- fi
- touch /usr/local/etc/3proxy/passwd
- touch /usr/local/etc/3proxy/counters
- touch /usr/local/etc/3proxy/bandlimiters
- echo Run /usr/local/etc/3proxy/bin/add3proxyuser.sh to add \'admin\' user
-fi
-
diff --git a/scripts/rh/3proxy.spec b/scripts/rh/3proxy.spec
new file mode 100644
index 00000000..7ded097f
--- /dev/null
+++ b/scripts/rh/3proxy.spec
@@ -0,0 +1,126 @@
+Name: 3proxy
+Version: 10
+Release: %{devel_version}
+Summary: 3proxy tiny proxy server
+License: GPL/LGPL/Apache/BSD
+URL: https://3proxy.org/
+Vendor: 3proxy.org 3proxy@3proxy.org
+Prefix: %{_prefix}
+Packager: z3APA3A
+Source: https://github.com/%{packager}/%{name}/tarball/devel
+
+%description
+3proxy is lightweight yet powerful proxy server
+
+%prep
+%setup -q -n 3proxy-10-devel
+ln -s Makefile.Linux Makefile
+
+%build
+make
+
+%install
+make DESTDIR=%buildroot install
+
+%clean
+make clean
+
+
+%files
+/bin/3proxy
+/bin/ftppr
+/bin/mycrypt
+/bin/pop3p
+/bin/proxy
+/bin/socks
+/bin/tcppm
+/bin/udppm
+%config(noreplace) /etc/3proxy/3proxy.cfg
+/etc/3proxy/conf
+/etc/init.d/3proxy
+/usr/lib/systemd/system/3proxy.service
+%config(noreplace) /usr/local/3proxy/conf/3proxy.cfg
+%config(noreplace) /usr/local/3proxy/conf/add3proxyuser.sh
+%config(noreplace) /usr/local/3proxy/conf/bandlimiters
+%config(noreplace) /usr/local/3proxy/conf/counters
+/usr/local/3proxy/libexec/PCREPlugin.ld.so
+/usr/local/3proxy/libexec/StringsPlugin.ld.so
+/usr/local/3proxy/libexec/TrafficPlugin.ld.so
+/usr/local/3proxy/libexec/TransparentPlugin.ld.so
+%if "%{_arch}" == "arm"
+/usr/share/man/man3/3proxy.cfg.3
+/usr/share/man/man8/3proxy.8
+/usr/share/man/man8/ftppr.8
+/usr/share/man/man8/icqpr.8
+/usr/share/man/man8/pop3p.8
+/usr/share/man/man8/proxy.8
+/usr/share/man/man8/smtpp.8
+/usr/share/man/man8/socks.8
+/usr/share/man/man8/tcppm.8
+/usr/share/man/man8/udppm.8
+%else
+/usr/share/man/man3/3proxy.cfg.3.gz
+/usr/share/man/man8/3proxy.8.gz
+/usr/share/man/man8/ftppr.8.gz
+/usr/share/man/man8/icqpr.8.gz
+/usr/share/man/man8/pop3p.8.gz
+/usr/share/man/man8/proxy.8.gz
+/usr/share/man/man8/smtpp.8.gz
+/usr/share/man/man8/socks.8.gz
+/usr/share/man/man8/tcppm.8.gz
+/usr/share/man/man8/udppm.8.gz
+%endif
+/var/log/3proxy
+
+%doc doc/*
+
+%pre
+if [ -x /usr/sbin/useradd ]; then \
+ /usr/bin/getent group proxy >/dev/null || (/usr/sbin/groupadd -f -r proxy || true); \
+ /usr/bin/getent passwd proxy >/dev/null || (/usr/sbin/useradd -Mr -s /bin/false -g proxy -c 3proxy proxy || true); \
+fi
+
+%post
+if [ ! -f /usr/local/3proxy/conf/passwd ]; then \
+ touch /usr/local/3proxy/conf/passwd;\
+fi
+chown -R proxy:proxy /usr/local/3proxy
+chmod 550 /usr/local/3proxy/
+chmod 550 /usr/local/3proxy/conf/
+chmod 440 /usr/local/3proxy/conf/*
+if /bin/systemctl >/dev/null 2>&1; then \
+ /usr/sbin/update-rc.d 3proxy disable || true; \
+ /usr/sbin/chkconfig 3proxy off || true; \
+ /bin/systemctl enable 3proxy.service; \
+elif [ -x /usr/sbin/update-rc.d ]; then \
+ /usr/sbin/update-rc.d 3proxy defaults; \
+ /usr/sbin/update-rc.d 3proxy enable; \
+elif [ -x /usr/sbin/chkconfig ]; then \
+ /usr/sbin/chkconfig 3proxy on; \
+fi
+
+echo ""
+echo 3proxy installed.
+if /bin/systemctl >/dev/null 2>&1; then \
+ /bin/systemctl stop 3proxy.service \
+ /bin/systemctl start 3proxy.service \
+ echo use ;\
+ echo " "systemctl start 3proxy.service ;\
+ echo to start proxy ;\
+ echo " "systemctl stop 3proxy.service ;\
+ echo to stop proxy ;\
+elif [ -x /usr/sbin/service ]; then \
+ /usr/sbin/service 3proxy stop || true;\
+ /usr/sbin/service 3proxy start || true;\
+ echo " "service 3proxy start ;\
+ echo to start proxy ;\
+ echo " "service 3proxy stop ;\
+ echo to stop proxy ;\
+fi
+echo " "/usr/local/3proxy/conf/add3proxyuser.sh
+echo to add users
+echo ""
+echo Default config uses Google\'s DNS.
+echo It\'s recommended to use provider supplied DNS or install local recursor, e.g. pdns-recursor.
+echo Configure preferred DNS in /usr/local/3proxy/conf/3proxy.cfg.
+echo run \'/usr/local/3proxy/conf/add3proxyuser.sh admin password\' to configure \'admin\' user
diff --git a/src/3proxy.c b/src/3proxy.c
index cef14f76..c99c2856 100644
--- a/src/3proxy.c
+++ b/src/3proxy.c
@@ -19,7 +19,7 @@
#endif
FILE * confopen();
-extern unsigned char *strings[];
+extern char *strings[];
extern FILE *writable;
extern struct counter_header cheader;
extern struct counter_record crecord;
@@ -63,11 +63,6 @@ void __stdcall CommandHandler( DWORD dwCommand )
conf.paused++;
Sleep(2000);
SetStatus( SERVICE_STOPPED, 0, 0 );
-#ifndef NOODBC
- pthread_mutex_lock(&log_mutex);
- close_sql();
- pthread_mutex_unlock(&log_mutex);
-#endif
break;
case SERVICE_CONTROL_PAUSE:
SetStatus( SERVICE_PAUSE_PENDING, 0, 1 );
@@ -84,7 +79,7 @@ void __stdcall CommandHandler( DWORD dwCommand )
}
-void __stdcall ServiceMain(int argc, unsigned char* argv[] )
+void __stdcall ServiceMain(int argc, char* argv[] )
{
hSrv = RegisterServiceCtrlHandler((LPCSTR)conf.stringtable[1], (LPHANDLER_FUNCTION)CommandHandler);
@@ -116,13 +111,7 @@ void mysigpause (int sig){
void mysigterm (int sig){
conf.paused++;
- usleep(999*SLEEPTIME);
- usleep(999*SLEEPTIME);
-#ifndef NOODBC
- pthread_mutex_lock(&log_mutex);
- close_sql();
- pthread_mutex_unlock(&log_mutex);
-#endif
+ usleep(2000*SLEEPTIME);
conf.timetoexit = 1;
}
@@ -192,7 +181,7 @@ void doschedule(void){
void dumpcounters(struct trafcount *tlin, int counterd){
- unsigned char tmpbuf[8192];
+ char tmpbuf[8192];
struct trafcount *tl;
if(counterd >= 0 && tlin) {
@@ -200,11 +189,11 @@ void dumpcounters(struct trafcount *tlin, int counterd){
if(cheader.updated && conf.countertype && timechanged(cheader.updated, conf.time, conf.countertype)){
FILE * cfp;
- cfp = fopen((char *)dologname(tmpbuf, (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w");
+ cfp = fopen((char *)dologname(tmpbuf, sizeof(tmpbuf), (char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w");
if(cfp){
for(tl = tlin; cfp && tl; tl = tl->next){
if(tl->type >= conf.countertype)
- fprintf(cfp, "%05d %020"PRINTF_INT64_MODIFIER"u%s%s\n", tl->number, tl->traf64, tl->comment?" #" : "", tl->comment? tl->comment : "");
+ fprintf(cfp, "%05d %020" PRIu64 "%s%s\n", tl->number, tl->traf64, tl->comment?" #" : "", tl->comment? tl->comment : "");
}
fclose(cfp);
}
@@ -213,7 +202,7 @@ void dumpcounters(struct trafcount *tlin, int counterd){
cheader.updated = conf.time;
lseek(counterd, 0, SEEK_SET);
- write(counterd, &cheader, sizeof(struct counter_header));
+ (void)write(counterd, &cheader, sizeof(struct counter_header));
for(tl=tlin; tl; tl = tl->next){
if(tl->number){
lseek(counterd,
@@ -222,7 +211,7 @@ void dumpcounters(struct trafcount *tlin, int counterd){
crecord.traf64 = tl->traf64;
crecord.cleared = tl->cleared;
crecord.updated = tl->updated;
- write(counterd, &crecord, sizeof(struct counter_record));
+ (void)write(counterd, &crecord, sizeof(struct counter_record));
}
if(tl->type!=NEVER && timechanged(tl->cleared, conf.time, tl->type)){
tl->cleared = conf.time;
@@ -235,12 +224,12 @@ void dumpcounters(struct trafcount *tlin, int counterd){
void cyclestep(void){
struct tm *tm;
time_t minutecounter;
- unsigned char tmpbuf[8192];
minutecounter = time(0);
for(;;){
usleep(SLEEPTIME*999);
+ flushlogs();
conf.time = time(0);
if(conf.needreload) {
doschedule();
@@ -248,7 +237,6 @@ void cyclestep(void){
conf.needreload = 0;
}
doschedule();
- if(conf.stdlog)fflush(conf.stdlog);
if(timechanged(minutecounter, conf.time, MINUTELY)) {
struct filemon *fm;
struct stat sb;
@@ -269,55 +257,6 @@ void cyclestep(void){
tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
basetime = mktime(tm);
}
- if(conf.logname) {
- if(timechanged(conf.logtime, conf.time, conf.logtype)) {
- if(conf.stdlog) conf.stdlog = freopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.time), "a", conf.stdlog);
- else conf.stdlog = fopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.time), "a");
- conf.logtime = conf.time;
- if(conf.logtype != NONE && conf.rotate) {
- int t;
- t = 1;
- switch(conf.logtype){
- case ANNUALLY:
- t = t * 12;
- case MONTHLY:
- t = t * 4;
- case WEEKLY:
- t = t * 7;
- case DAILY:
- t = t * 24;
- case HOURLY:
- t = t * 60;
- case MINUTELY:
- t = t * 60;
- default:
- break;
- }
- dologname (tmpbuf, conf.logname, (conf.archiver)?conf.archiver[1]:NULL, conf.logtype, (conf.logtime - t * conf.rotate));
- remove ((char *) tmpbuf);
- if(conf.archiver) {
- int i;
- *tmpbuf = 0;
- for(i = 2; i < conf.archiverc && strlen((char *)tmpbuf) < 512; i++){
- strcat((char *)tmpbuf, " ");
- if(!strcmp((char *)conf.archiver[i], "%A")){
- strcat((char *)tmpbuf, "\"");
- dologname (tmpbuf + strlen((char *)tmpbuf), conf.logname, conf.archiver[1], conf.logtype, (conf.logtime - t));
- strcat((char *)tmpbuf, "\"");
- }
- else if(!strcmp((char *)conf.archiver[i], "%F")){
- strcat((char *)tmpbuf, "\"");
- dologname (tmpbuf+strlen((char *)tmpbuf), conf.logname, NULL, conf.logtype, (conf.logtime-t));
- strcat((char *)tmpbuf, "\"");
- }
- else
- strcat((char *)tmpbuf, (char *)conf.archiver[i]);
- }
- system((char *)tmpbuf+1);
- }
- }
- }
- }
if(conf.counterd >= 0 && conf.trafcounter) {
if(timechanged(cheader.updated, conf.time, MINUTELY)){
dumpcounters(conf.trafcounter, conf.counterd);
@@ -326,9 +265,7 @@ void cyclestep(void){
if(conf.timetoexit){
conf.paused++;
doschedule();
- usleep(SLEEPTIME*999);
- usleep(SLEEPTIME*999);
- usleep(SLEEPTIME*999);
+ usleep(3*SLEEPTIME*999);
return;
}
@@ -354,9 +291,9 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
FILE * fp = NULL;
#ifdef _WIN32
- unsigned char * arg;
+ char * arg;
WSADATA wd;
- unsigned char tmpbuf[8192];
+ char tmpbuf[8192];
WSAStartup(MAKEWORD( 1, 1 ), &wd);
osv.dwOSVersionInfoSize = sizeof(osv);
@@ -512,11 +449,10 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
pthread_mutex_init(&hash_mutex, NULL);
pthread_mutex_init(&tc_mutex, NULL);
pthread_mutex_init(&pwl_mutex, NULL);
- pthread_mutex_init(&log_mutex, NULL);
#ifndef NORADIUS
pthread_mutex_init(&rad_mutex, NULL);
#endif
-
+ initlog();
freeconf(&conf);
res = readconfig(fp);
conf.version++;
diff --git a/3proxy.ico b/src/3proxy.ico
similarity index 100%
rename from 3proxy.ico
rename to src/3proxy.ico
diff --git a/3proxy.rc b/src/3proxy.rc
similarity index 55%
rename from 3proxy.rc
rename to src/3proxy.rc
index bc117b26..e65242c3 100644
--- a/3proxy.rc
+++ b/src/3proxy.rc
@@ -1,9 +1,8 @@
-#include "src/version.h"
-
+#include "version.h"
1 VERSIONINFO
-FILEVERSION 0,9,0,0
-PRODUCTVERSION 0,9,0,0
+FILEVERSION MAJOR3PROXY,SUBMAJOR3PROXY,MINOR3PROXY,SUBMINOR3PROXY
+PRODUCTVERSION MAJOR3PROXY,SUBMAJOR3PROXY,MINOR3PROXY,SUBMINOR3PROXY
FILETYPE 1
FILESUBTYPE 0x0L
BEGIN
@@ -11,15 +10,15 @@ BEGIN
BEGIN
BLOCK "040904E4"
BEGIN
- VALUE "Comments", "3proxy - tiny proxy server, http://3proxy.org/\0"
+ VALUE "Comments", "3proxy - tiny proxy server, https://3proxy.org/\0"
VALUE "CompanyName", "Vladimir Dubrovin\0"
VALUE "FileDescription", "3proxy - tiny proxy server\0"
- VALUE "FileVersion", "0.9-devel-" BUILDDATE "\0"
+ VALUE "FileVersion", RELEASE3PROXY
VALUE "InternalName", "3proxy\0"
- VALUE "LegalCopyright", "Copyright (C) 2002-2019 Vladimir Dubrovin\0"
+ VALUE "LegalCopyright", "Copyright (C) 2002-" YEAR3PROXY " Vladimir Dubrovin\0"
VALUE "OriginalFilename", "3proxy.exe\0"
VALUE "ProductName", "3proxy\0"
- VALUE "ProductVersion", "0.9-devel-" BUILDDATE "\0"
+ VALUE "ProductVersion", RELEASE3PROXY
END
END
BLOCK "VarFileInfo"
diff --git a/src/Makefile.inc b/src/Makefile.inc
index a22f49a3..c1b957f9 100644
--- a/src/Makefile.inc
+++ b/src/Makefile.inc
@@ -26,50 +26,52 @@ ftp$(OBJSUFFICS): ftp.c proxy.h structures.h
sockgetchar$(OBJSUFFICS): sockgetchar.c proxy.h structures.h
$(CC) $(CFLAGS) sockgetchar.c
-proxy$(OBJSUFFICS): proxy.c proxy.h structures.h proxymain.c
+proxy$(OBJSUFFICS): proxy.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP $(DEFINEOPTION)ANONYMOUS proxy.c
-pop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h proxymain.c
+pop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP pop3p.c
-smtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h proxymain.c
+smtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP smtpp.c
-ftppr$(OBJSUFFICS): ftppr.c proxy.h structures.h proxymain.c
+ftppr$(OBJSUFFICS): ftppr.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP ftppr.c
-tcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h proxymain.c
+tcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP tcppm.c
-socks$(OBJSUFFICS): socks.c proxy.h structures.h proxymain.c
+socks$(OBJSUFFICS): socks.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP socks.c
-udppm$(OBJSUFFICS): udppm.c proxy.h structures.h proxymain.c
+udppm$(OBJSUFFICS): udppm.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP udppm.c
+
+
3proxy$(OBJSUFFICS): 3proxy.c proxy.h structures.h
$(CC) $(CFLAGS) 3proxy.c
-$(BUILDDIR)proxy$(EXESUFFICS): sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS)
- $(LN) $(LNOUT)$(BUILDDIR)proxy$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
+$(BUILDDIR)proxy$(EXESUFFICS): sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS)
+ $(LN) $(LNOUT)$(BUILDDIR)proxy$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
-$(BUILDDIR)pop3p$(EXESUFFICS): sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) $(COMPATLIBS)
- $(LN) $(LNOUT)$(BUILDDIR)pop3p$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
+$(BUILDDIR)pop3p$(EXESUFFICS): sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS)
+ $(LN) $(LNOUT)$(BUILDDIR)pop3p$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
-$(BUILDDIR)smtpp$(EXESUFFICS): sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS)
- $(LN) $(LNOUT)$(BUILDDIR)smtpp$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) base64$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
+$(BUILDDIR)smtpp$(EXESUFFICS): sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS)
+ $(LN) $(LNOUT)$(BUILDDIR)smtpp$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) base64$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
-$(BUILDDIR)ftppr$(EXESUFFICS): sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) ftp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) $(COMPATLIBS)
- $(LN) $(LNOUT)$(BUILDDIR)ftppr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
+$(BUILDDIR)ftppr$(EXESUFFICS): sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) ftp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS)
+ $(LN) $(LNOUT)$(BUILDDIR)ftppr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
-$(BUILDDIR)socks$(EXESUFFICS): sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
- $(LN) $(LNOUT)$(BUILDDIR)socks$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
+$(BUILDDIR)socks$(EXESUFFICS): sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS)
+ $(LN) $(LNOUT)$(BUILDDIR)socks$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
-$(BUILDDIR)tcppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
- $(LN) $(LNOUT)$(BUILDDIR)tcppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
+$(BUILDDIR)tcppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) common$(OBJSUFFICS)
+ $(LN) $(LNOUT)$(BUILDDIR)tcppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
-$(BUILDDIR)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
- $(LN) $(LNOUT)$(BUILDDIR)udppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
+$(BUILDDIR)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS)
+ $(LN) $(LNOUT)$(BUILDDIR)udppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
mainfunc$(OBJSUFFICS): proxy.h structures.h proxymain.c
$(CC) $(COUT)mainfunc$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)MODULEMAINFUNC=mainfunc proxymain.c
@@ -131,20 +133,12 @@ $(BUILDDIR)mycrypt$(EXESUFFICS): md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycryptmain$(
md4$(OBJSUFFICS): libs/md4.h libs/md4.c
$(CC) $(COUT)md4$(OBJSUFFICS) $(CFLAGS) libs/md4.c
-smbdes$(OBJSUFFICS): libs/smbdes.c
- $(CC) $(COUT)smbdes$(OBJSUFFICS) $(CFLAGS) libs/smbdes.c
-
md5$(OBJSUFFICS): libs/md5.h libs/md5.c
$(CC) $(COUT)md5$(OBJSUFFICS) $(CFLAGS) libs/md5.c
-ntlm$(OBJSUFFICS): ntlm.c
- $(CC) $(COUT)ntlm$(OBJSUFFICS) $(CFLAGS) ntlm.c
-
stringtable$(OBJSUFFICS): stringtable.c
$(CC) $(COUT)stringtable$(OBJSUFFICS) $(CFLAGS) stringtable.c
-$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) conf$(OBJSUFFICS) log$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycrypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) smbdes$(OBJSUFFICS) ntlm$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS)
- $(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) mycrypt$(OBJSUFFICS) md5$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) smbdes$(OBJSUFFICS) ntlm$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
+$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) conf$(OBJSUFFICS) log$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycrypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(VERSIONDEP)
+ $(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) mycrypt$(OBJSUFFICS) md5$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
-clean:
- @$(REMOVECOMMAND) *$(OBJSUFFICS) $(COMPFILES)
diff --git a/src/auth.c b/src/auth.c
index b7b3851c..53076e6c 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -9,12 +9,12 @@
#include "proxy.h"
-int clientnegotiate(struct chain * redir, struct clientparam * param, struct sockaddr * addr, unsigned char * hostname){
- unsigned char *buf;
- unsigned char *username;
+int clientnegotiate(struct chain * redir, struct clientparam * param, struct sockaddr * addr, char * hostname){
+ char *buf;
+ char *username;
int res;
int len=0;
- unsigned char * user, *pass;
+ char * user, *pass;
user = redir->extuser;
@@ -56,7 +56,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
":%hu HTTP/1.0\r\nConnection: keep-alive\r\n", ntohs(*SAPORT(addr)));
if(user){
len += sprintf((char *)buf + len, "Proxy-Authorization: Basic ");
- sprintf((char *)username, "%.128s:%.128s", user, pass?pass:(unsigned char *)"");
+ sprintf((char *)username, "%.128s:%.128s", user, pass?pass:(char *)"");
en64(username, buf+len, (int)strlen((char *)username));
len = (int)strlen((char *)buf);
len += sprintf((char *)buf + len, "\r\n");
@@ -87,7 +87,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
buf[7] = 3;
}
else memcpy(buf+4, SAADDR(addr), 4);
- if(!user)user = (unsigned char *)"anonymous";
+ if(!user)user = (char *)"anonymous";
len = (int)strlen((char *)user) + 1;
memcpy(buf+8, user, len);
len += 8;
@@ -138,10 +138,10 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
}
if(buf[1] == 2){
buf[inbuf++] = 1;
- buf[inbuf] = (unsigned char)strlen((char *)user);
+ buf[inbuf] = (char)strlen((char *)user);
memcpy(buf+inbuf+1, user, buf[inbuf]);
inbuf += buf[inbuf] + 1;
- buf[inbuf] = pass?(unsigned char)strlen((char *)pass):0;
+ buf[inbuf] = pass?(char)strlen((char *)pass):0;
if(pass)memcpy(buf+inbuf+1, pass, buf[inbuf]);
inbuf += buf[inbuf] + 1;
if(socksend(param->remsock, buf, inbuf, conf.timeouts[CHAIN_TO]) != inbuf){
@@ -253,6 +253,25 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
if(cur->type == R_EXTIP){
param->sinsl = cur->addr;
if(SAISNULL(¶m->sinsl))param->sinsl = param->sincr;
+#ifndef NOIPV6
+ else if(cur->cidr && *SAFAMILY(¶m->sinsl) == AF_INET6){
+ uint16_t c;
+ int i;
+
+ for(i = 0; i < 8; i++){
+ if(i==4)myrand(¶m->sincr, sizeof(param->sincr));
+ else if(i==6) myrand(¶m->req, sizeof(param->req));
+
+ if(i*16 >= cur->cidr) ((uint16_t *)SAADDR(¶m->sinsl))[i] |= rand();
+ else if ((i+1)*16 > cur->cidr){
+ c = rand();
+ c >>= (cur->cidr - (i*16));
+ c |= ntohs(((uint16_t *)SAADDR(¶m->sinsl))[i]);
+ ((uint16_t *)SAADDR(¶m->sinsl))[i] = htons(c);
+ }
+ }
+ }
+#endif
if(cur->next)continue;
return 0;
}
@@ -260,11 +279,11 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
if(cur->extuser){
if(param->extusername)
myfree(param->extusername);
- param->extusername = (unsigned char *)mystrdup((char *)((*cur->extuser == '*' && param->username)? param->username : cur->extuser));
+ param->extusername = (char *)mystrdup((char *)((*cur->extuser == '*' && param->username)? param->username : cur->extuser));
if(cur->extpass){
if(param->extpassword)
myfree(param->extpassword);
- param->extpassword = (unsigned char *)mystrdup((char *)((*cur->extuser == '*' && param->password)?param->password : cur->extpass));
+ param->extpassword = (char *)mystrdup((char *)((*cur->extuser == '*' && param->password)?param->password : cur->extpass));
}
if(*cur->extuser == '*' && !param->username) return 4;
}
@@ -312,11 +331,11 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
if(*cur -> extuser == '*' && !param->username) return 4;
if(param->extusername)
myfree(param->extusername);
- param->extusername = (unsigned char *)mystrdup((char *)((*cur->extuser == '*' && param->username)? param->username : cur->extuser));
+ param->extusername = (char *)mystrdup((char *)((*cur->extuser == '*' && param->username)? param->username : cur->extuser));
if(cur->extpass){
if(param->extpassword)
myfree(param->extpassword);
- param->extpassword = (unsigned char *)mystrdup((char *)((*cur->extuser == '*' && param->password)?param->password : cur->extpass));
+ param->extpassword = (char *)mystrdup((char *)((*cur->extuser == '*' && param->password)?param->password : cur->extpass));
}
}
return 0;
@@ -330,14 +349,14 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
int IPInentry(struct sockaddr *sa, struct iplist *ipentry){
int addrlen;
- unsigned char *ip, *ipf, *ipt;
+ char *ip, *ipf, *ipt;
if(!sa || ! ipentry || *SAFAMILY(sa) != ipentry->family) return 0;
- ip = (unsigned char *)SAADDR(sa);
- ipf = (unsigned char *)&ipentry->ip_from;
- ipt = (unsigned char *)&ipentry->ip_to;
+ ip = (char *)SAADDR(sa);
+ ipf = (char *)&ipentry->ip_from;
+ ipt = (char *)&ipentry->ip_to;
addrlen = SAADDRLEN(sa);
@@ -352,12 +371,12 @@ int ACLmatches(struct ace* acentry, struct clientparam * param){
struct iplist *ipentry;
struct portlist *portentry;
struct period *periodentry;
- unsigned char * username;
+ char * username;
struct hostname * hstentry=NULL;
int i;
int match = 0;
- username = param->username?param->username:(unsigned char *)"-";
+ username = param->username?param->username:(char *)"-";
if(acentry->src) {
for(ipentry = acentry->src; ipentry; ipentry = ipentry->next)
if(IPInentry((struct sockaddr *)¶m->sincr, ipentry)) {
@@ -393,8 +412,8 @@ int ACLmatches(struct ace* acentry, struct clientparam * param){
break;
case 2:
- lname = strlen((char *)hstentry->name);
- lhost = strlen((char *)param->hostname);
+ lname = (int)strlen((char *)hstentry->name);
+ lhost = (int)strlen((char *)param->hostname);
if(lhost > lname){
if(!strncasecmp((char *)param->hostname + (lhost - lname),
(char *)hstentry->name,
@@ -505,6 +524,11 @@ void stopconnlims (struct clientparam *param){
static void initbandlims (struct clientparam *param){
struct bandlim * be;
int i;
+
+ param->bandlimfunc = NULL;
+ param->bandlims[0] = NULL;
+ param->bandlimsout[0] = NULL;
+ if(!conf.bandlimfunc || (!conf.bandlimiter && !conf.bandlimiterout)) return;
for(i=0, be = conf.bandlimiter; be && inext) {
if(ACLmatches(be->ace, param)){
if(be->ace->action == NOBANDLIM) {
@@ -525,6 +549,7 @@ static void initbandlims (struct clientparam *param){
}
}
if(ibandlimsout[i] = NULL;
+ param->bandlimver = conf.bandlimver;
}
unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nbytesout){
@@ -550,12 +575,7 @@ unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nb
if(!nbytesin && !nbytesout) return 0;
pthread_mutex_lock(&bandlim_mutex);
- if(param->paused != conf.paused && param->bandlimver != conf.paused){
- if(!conf.bandlimfunc){
- param->bandlimfunc = NULL;
- pthread_mutex_unlock(&bandlim_mutex);
- return 0;
- }
+ if(param->bandlimver != conf.bandlimver){
initbandlims(param);
param->bandlimver = conf.paused;
}
@@ -604,30 +624,28 @@ void trafcountfunc(struct clientparam *param){
pthread_mutex_lock(&tc_mutex);
for(tc = conf.trafcounter; tc; tc = tc->next) {
if(ACLmatches(tc->ace, param)){
- time_t t;
- if(tc->ace->action == NOCOUNTIN || tc->ace->action == NOCOUNTALL) {
+
+ if(tc->ace->action == NOCOUNTIN) {
countout = 1;
break;
}
- if(tc->ace->action != COUNTIN) {
+ if(tc->ace->action == NOCOUNTALL) break;
+ if(tc->ace->action != COUNTIN && tc->ace->action != COUNTALL) {
countout = 1;
- if(tc->ace->action != COUNTALL)continue;
+ continue;
}
tc->traf64 += param->statssrv64;
- time(&t);
- tc->updated = t;
+ tc->updated = conf.time;
}
}
if(countout) for(tc = conf.trafcounter; tc; tc = tc->next) {
if(ACLmatches(tc->ace, param)){
- time_t t;
if(tc->ace->action == NOCOUNTOUT || tc->ace->action == NOCOUNTALL) break;
if(tc->ace->action != COUNTOUT && tc->ace->action != COUNTALL ) {
continue;
}
tc->traf64 += param->statscli64;
- time(&t);
- tc->updated = t;
+ tc->updated = conf.time;
}
}
@@ -643,60 +661,83 @@ int alwaysauth(struct clientparam * param){
if(conf.connlimiter && param->remsock == INVALID_SOCKET && startconnlims(param)) return 95;
res = doconnect(param);
if(!res){
- initbandlims(param);
- for(tc = conf.trafcounter; tc; tc = tc->next) {
- if(tc->disabled) continue;
- if(ACLmatches(tc->ace, param)){
- if(tc->ace->action == NOCOUNTIN) break;
- if(tc->ace->action != COUNTIN) {
- countout = 1;
- continue;
+ if(conf.bandlimfunc && conf.bandlimiter){
+ pthread_mutex_lock(&bandlim_mutex);
+ initbandlims(param);
+ pthread_mutex_unlock(&bandlim_mutex);
+ }
+
+ if(conf.trafcountfunc && conf.trafcounter) {
+ pthread_mutex_lock(&tc_mutex);
+ for(tc = conf.trafcounter; tc; tc = tc->next) {
+ if(tc->disabled) continue;
+ if(ACLmatches(tc->ace, param)){
+ if(tc->ace->action == NOCOUNTIN) {
+ countout = 1;
+ break;
+ }
+ if(tc->ace->action == NOCOUNTALL) break;
+ if(tc->ace->action != COUNTIN) {
+ countout = 1;
+ if(tc->ace->action != COUNTALL) continue;
+ }
+ if(tc->traflim64 <= tc->traf64) return 10;
+ param->trafcountfunc = conf.trafcountfunc;
+ param->maxtrafin64 = tc->traflim64 - tc->traf64;
}
-
- if(tc->traflim64 <= tc->traf64) return 10;
- param->trafcountfunc = conf.trafcountfunc;
- param->maxtrafin64 = tc->traflim64 - tc->traf64;
}
- }
- if(countout)for(tc = conf.trafcounter; tc; tc = tc->next) {
- if(tc->disabled) continue;
- if(ACLmatches(tc->ace, param)){
- if(tc->ace->action == NOCOUNTOUT) break;
- if(tc->ace->action != COUNTOUT) {
- continue;
+ if(countout)for(tc = conf.trafcounter; tc; tc = tc->next) {
+ if(tc->disabled) continue;
+ if(ACLmatches(tc->ace, param)){
+ if(tc->ace->action == NOCOUNTOUT || tc->ace->action == NOCOUNTALL) break;
+ if(tc->ace->action != COUNTOUT && tc->ace->action != COUNTALL) {
+ continue;
+ }
+ if(tc->traflim64 <= tc->traf64) return 10;
+ param->trafcountfunc = conf.trafcountfunc;
+ param->maxtrafout64 = tc->traflim64 - tc->traf64;
}
-
- if(tc->traflim64 <= tc->traf64) return 10;
- param->trafcountfunc = conf.trafcountfunc;
- param->maxtrafout64 = tc->traflim64 - tc->traf64;
}
+ pthread_mutex_unlock(&tc_mutex);
}
-
}
return res;
}
-int checkACL(struct clientparam * param){
+int checkACL2(struct clientparam * param, int pre){
struct ace* acentry;
- if(!param->srv->acl) {
+ acentry = pre?param->srv->preacl:param->srv->acl;
+ if(!acentry && !pre) {
return 0;
}
- for(acentry = param->srv->acl; acentry; acentry = acentry->next) {
+ for(; acentry; acentry = acentry->next) {
if(ACLmatches(acentry, param)) {
- param->nolog = acentry->nolog;
- param->weight = acentry->weight;
- if(acentry->action == 2) {
- struct ace dup;
-
- if(param->operation < 256 && !(param->operation & CONNECT)){
- continue;
- }
- if(param->redirected && acentry->chains && SAISNULL(&acentry->chains->addr) && !*SAPORT(&acentry->chains->addr)) {
- continue;
+ if(!pre){
+ param->nolog = acentry->nolog;
+ param->weight = acentry->weight;
+ if(acentry->action == 2) {
+ struct ace dup;
+ int res=60,i=0;
+
+ if(param->operation < 256 && !(param->operation & CONNECT)){
+ continue;
+ }
+ if(param->redirected && acentry->chains && SAISNULL(&acentry->chains->addr) && !*SAPORT(&acentry->chains->addr)) {
+ continue;
+ }
+ if(param->remsock != INVALID_SOCKET) {
+ return 0;
+ }
+ for(; i < conf.parentretries; i++){
+ dup = *acentry;
+ res = handleredirect(param, &dup);
+ if(!res) break;
+ if(param->remsock != INVALID_SOCKET) so._closesocket(param->remsock);
+ param->remsock = INVALID_SOCKET;
+ }
+ return res;
}
- dup = *acentry;
- return handleredirect(param, &dup);
}
return acentry->action;
}
@@ -704,6 +745,19 @@ int checkACL(struct clientparam * param){
return 3;
}
+int checkACL(struct clientparam * param){
+ int res;
+ res = checkACL2(param, 1);
+ if(res < 2) return res;
+ return checkACL2(param, 0);
+}
+
+
+int checkpreACL(struct clientparam * param){
+ return checkACL2(param, 1);
+}
+
+
struct authcache {
char * username;
char * password;
@@ -754,7 +808,7 @@ int cacheauth(struct clientparam * param){
if(param->username){
myfree(param->username);
}
- param->username = (unsigned char *)mystrdup(ac->username);
+ param->username = (char *)mystrdup(ac->username);
pthread_mutex_unlock(&hash_mutex);
return 0;
}
@@ -771,6 +825,16 @@ int cacheauth(struct clientparam * param){
return 4;
}
+int dopreauth(struct clientparam * param){
+ int res = 0;
+
+ if(param->srv && param->srv->authfuncs && param->srv->authfuncs->preauthorize){
+ res = param->srv->authfuncs->preauthorize(param);
+ param->preauthorized = !res;
+ if(res != 1) res = 0;
+ }
+ return res;
+}
int doauth(struct clientparam * param){
int res = 0;
struct auth *authfuncs;
@@ -781,7 +845,8 @@ int doauth(struct clientparam * param){
for(authfuncs=param->srv->authfuncs; authfuncs; authfuncs=authfuncs->next){
res = authfuncs->authenticate?(*authfuncs->authenticate)(param):0;
if(!res) {
- if(authfuncs->authorize &&
+
+ if(!param->preauthorized && authfuncs->authorize &&
(res = (*authfuncs->authorize)(param)))
return res;
if(conf.authcachetype && authfuncs->authenticate && authfuncs->authenticate != cacheauth && param->username && (!(conf.authcachetype&4) || (!param->pwtype && param->password))){
@@ -846,10 +911,12 @@ int doauth(struct clientparam * param){
int ipauth(struct clientparam * param){
int res;
- unsigned char *username;
+ char *username;
+
+ if(param->preauthorized) return (0);
username = param->username;
param->username = NULL;
- res = checkACL(param);
+ res = checkACL2(param,0);
param->username = username;
return res;
}
@@ -869,7 +936,7 @@ int dnsauth(struct clientparam * param){
if(*SAFAMILY(¶m->sincr)!=AF_INET){
char *s = buf;
for(i=15; i>=0; i--){
- unsigned char c=((unsigned char *)SAADDR(¶m->sincr))[i];
+ char c=((char *)SAADDR(¶m->sincr))[i];
*s++ = dig[(c&0xf)];
*s++ = '.';
*s++ = dig[(c>>4)];
@@ -887,7 +954,7 @@ int dnsauth(struct clientparam * param){
((u&0xFF000000)>>24));
}
- if(!udpresolve(*SAFAMILY(¶m->sincr), (unsigned char *)buf, (unsigned char *)addr, NULL, param, 1)) {
+ if(!udpresolve(*SAFAMILY(¶m->sincr), (char *)buf, (char *)addr, NULL, param, 1)) {
return 3;
}
if(memcmp(SAADDR(¶m->sincr), addr, SAADDRLEN(¶m->sincr))) {
@@ -899,7 +966,7 @@ int dnsauth(struct clientparam * param){
int strongauth(struct clientparam * param){
struct passwords * pwl;
- unsigned char buf[256];
+ char buf[256];
if(!param->username) return 4;
@@ -913,15 +980,6 @@ int strongauth(struct clientparam * param){
else if (!param->pwtype && param->password && !strcmp((char *)param->password, (char *)pwl->password)){
break;
}
-#ifndef NOCRYPT
- else if (param->pwtype == 2 && param->password) {
- ntpwdhash(buf, pwl->password, 0);
- mschap(buf, param->password, buf + 16);
- if(!memcmp(buf+16, param->password+8, 24)) {
- break;
- }
- }
-#endif
pthread_mutex_unlock(&pwl_mutex);
return 6;
#ifndef NOCRYPT
@@ -935,13 +993,6 @@ int strongauth(struct clientparam * param){
if(param->password && !param->pwtype && !memcmp(pwl->password, ntpwdhash(buf,param->password, 1), 32)) {
break;
}
- else if (param->pwtype == 2){
- fromhex(pwl->password, buf, 16);
- mschap(buf, param->password, buf + 16);
- if(!memcmp(buf + 16, param->password+8, 24)) {
- break;
- }
- }
pthread_mutex_unlock(&pwl_mutex);
return 8;
#endif
@@ -960,20 +1011,20 @@ int strongauth(struct clientparam * param){
int radauth(struct clientparam * param);
struct auth authfuncs[] = {
- {authfuncs+1, NULL, NULL, ""},
- {authfuncs+2, ipauth, NULL, "iponly"},
- {authfuncs+3, userauth, checkACL, "useronly"},
- {authfuncs+4, dnsauth, checkACL, "dnsname"},
- {authfuncs+5, strongauth, checkACL, "strong"},
- {authfuncs+6, cacheauth, checkACL, "cache"},
+ {authfuncs+1, NULL,NULL, NULL, ""},
+ {authfuncs+2, checkpreACL, ipauth, NULL, "iponly"},
+ {authfuncs+3, checkpreACL, userauth, checkACL, "useronly"},
+ {authfuncs+4, checkpreACL, dnsauth, checkACL, "dnsname"},
+ {authfuncs+5, checkpreACL, strongauth, checkACL, "strong"},
+ {authfuncs+6, checkpreACL, cacheauth, checkACL, "cache"},
#ifndef NORADIUS
#define AUTHOFFSET 1
- {authfuncs+7, radauth, checkACL, "radius"},
+ {authfuncs+7, checkpreACL, radauth, checkACL, "radius"},
#else
#define AUTHOFFSET 0
#endif
- {authfuncs+7+AUTHOFFSET, NULL, NULL, "none"},
- {NULL, NULL, NULL, ""}
+ {authfuncs+7+AUTHOFFSET, NULL, NULL, NULL, "none"},
+ {NULL, NULL, NULL, NULL, ""}
};
@@ -982,7 +1033,7 @@ struct hashtable dns_table = {0, 4, {0,0,0,0}, NULL, NULL, NULL};
struct hashtable dns6_table = {0, 16, {0,0,0,0}, NULL, NULL, NULL};
-void nametohash(const unsigned char * name, unsigned char *hash, unsigned char *rnd){
+void nametohash(const char * name, char *hash, char *rnd){
unsigned i, j, k;
memcpy(hash, rnd, sizeof(unsigned)*4);
for(i=0, j=0, k=0; name[j]; j++){
@@ -994,7 +1045,7 @@ void nametohash(const unsigned char * name, unsigned char *hash, unsigned char *
}
}
-unsigned hashindex(struct hashtable *ht, const unsigned char* hash){
+unsigned hashindex(struct hashtable *ht, const char* hash){
unsigned t1, t2, t3, t4;
t1 = *(unsigned *)hash;
t2 = *(unsigned *)(hash + sizeof(unsigned));
@@ -1073,7 +1124,7 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){
return 0;
}
-void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires){
+void hashadd(struct hashtable *ht, const char* name, char* value, time_t expires){
struct hashentry * hen, *he;
struct hashentry ** hep;
@@ -1086,7 +1137,7 @@ void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* val
}
hen = ht->hashempty;
ht->hashempty = ht->hashempty->next;
- nametohash(name, hen->hash, (unsigned char *)ht->rnd);
+ nametohash(name, hen->hash, (char *)ht->rnd);
memcpy(hen->value, value, ht->recsize);
hen->expires = expires;
hen->next = NULL;
@@ -1106,8 +1157,8 @@ void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* val
pthread_mutex_unlock(&hash_mutex);
}
-unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsigned char* value, unsigned *ttl){
- unsigned char hash[sizeof(unsigned)*4];
+unsigned long hashresolv(struct hashtable *ht, const char* name, char* value, unsigned *ttl){
+ char hash[sizeof(unsigned)*4];
struct hashentry ** hep;
struct hashentry *he;
unsigned index;
@@ -1117,7 +1168,7 @@ unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsign
pthread_mutex_unlock(&hash_mutex);
return 0;
}
- nametohash(name, hash, (unsigned char *)ht->rnd);
+ nametohash(name, hash, (char *)ht->rnd);
index = hashindex(ht, hash);
for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
if(he->expires < conf.time) {
@@ -1142,7 +1193,7 @@ struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0}
struct nserver authnserver;
-unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, unsigned *retttl, struct clientparam* param, int makeauth){
+unsigned long udpresolve(int af, char * name, char * value, unsigned *retttl, struct clientparam* param, int makeauth){
int i,n;
unsigned long retval;
@@ -1156,7 +1207,8 @@ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, un
n = (makeauth && !SAISNULL(&authnserver.addr))? 1 : numservers;
for(i=0; i 255) {
len = 255;
}
- memcpy(buf + 13, name, len);
+ memcpy((char *)buf + 13, name, len);
len += 13;
buf[len] = 0;
for(s2 = buf + 12; (s1 = (unsigned char *)strchr((char *)s2 + 1, '.')); s2 = s1)*s2 = (unsigned char)((s1 - s2) - 1);
@@ -1241,13 +1293,13 @@ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, un
len+=2;
}
- if(socksendto(sock, (struct sockaddr *)sinsr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
+ if(socksendto(sock, (struct sockaddr *)sinsr, (char *)buf, len, conf.timeouts[SINGLEBYTE_L]*1000, param?param->monitorsock:NULL, param?param->monaction:0) != len){
so._shutdown(sock, SHUT_RDWR);
so._closesocket(sock);
continue;
}
if(param) param->statscli64 += len;
- len = sockrecvfrom(sock, (struct sockaddr *)sinsr, buf, 4096, conf.timeouts[DNS_TO]*1000);
+ len = sockrecvfrom(sock, (struct sockaddr *)sinsr, (char *)buf, 4096, conf.timeouts[DNS_TO]*1000, param?param->monitorsock:NULL, param?param->monaction:0);
so._shutdown(sock, SHUT_RDWR);
so._closesocket(sock);
if(len <= 13) {
@@ -1259,7 +1311,7 @@ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, un
us = ntohs(*(unsigned short*)buf);
len-=2;
buf+=2;
- if(us > 4096 || us < len || (us > len && sockrecvfrom(sock, (struct sockaddr *)sinsr, buf+len, us-len, conf.timeouts[DNS_TO]*1000) != us-len)) {
+ if(us > 4096 || us < len || (us > len && sockrecvfrom(sock, (struct sockaddr *)sinsr, (char *)buf+len, us-len, conf.timeouts[DNS_TO]*1000, param?param->monitorsock:NULL, param?param->monaction:0) != us-len)) {
continue;
}
}
@@ -1314,7 +1366,7 @@ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, un
}
*s2 = 0;
if(param->username)myfree(param->username);
- param->username = (unsigned char *)mystrdup ((char *)buf + k + 13);
+ param->username = mystrdup ((char *)buf + k + 13);
return udpresolve(af,param->username, value, NULL, NULL, 2);
}
@@ -1323,11 +1375,11 @@ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, un
return 0;
}
-unsigned long myresolver(int af, unsigned char * name, unsigned char * value){
+unsigned long myresolver(int af, char * name, char * value){
return udpresolve(af, name, value, NULL, NULL, 0);
}
-unsigned long fakeresolver (int af, unsigned char *name, unsigned char * value){
+unsigned long fakeresolver (int af, char *name, char * value){
memset(value, 0, af == AF_INET6? 16 : 4);
if(af == AF_INET6){
memset(value, 0, 16);
@@ -1341,155 +1393,3 @@ unsigned long fakeresolver (int af, unsigned char *name, unsigned char * value){
}
return 1;
}
-
-#ifndef NOODBC
-
-SQLHENV henv = NULL;
-SQLHSTMT hstmt = NULL;
-SQLHDBC hdbc = NULL;
-char * sqlstring = NULL;
-
-
-void close_sql(){
- if(hstmt) {
- SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
- hstmt = NULL;
- }
- if(hdbc){
- SQLDisconnect(hdbc);
- SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
- hdbc = NULL;
- }
- if(henv) {
- SQLFreeHandle(SQL_HANDLE_ENV, henv);
- henv = NULL;
- }
-}
-
-int attempt = 0;
-time_t attempt_time = 0;
-
-int init_sql(char * s){
- SQLRETURN retcode;
- char * datasource;
- char * username;
- char * password;
- char * string;
-
- if(!s) return 0;
- if(!sqlstring || strcmp(sqlstring, s)){
- string = sqlstring;
- sqlstring=mystrdup(s);
- if(string)myfree(string);
- }
-
- if(hstmt || hdbc || henv) close_sql();
- attempt++;
- attempt_time = time(0);
- if(!henv){
- retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
- if (!henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
- henv = NULL;
- return 0;
- }
- retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
-
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
- return 0;
- }
- }
- if(!hdbc){
- retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
- if (!hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
- hdbc = NULL;
- SQLFreeHandle(SQL_HANDLE_ENV, henv);
- henv = NULL;
- return 0;
- }
- SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
- }
- string = mystrdup(sqlstring);
- if(!string) return 0;
- datasource = strtok(string, ",");
- username = strtok(NULL, ",");
- password = strtok(NULL, ",");
-
-
- /* Connect to data source */
- retcode = SQLConnect(hdbc, (SQLCHAR*) datasource, (SQLSMALLINT)strlen(datasource),
- (SQLCHAR*) username, (SQLSMALLINT)((username)?strlen(username):0),
- (SQLCHAR*) password, (SQLSMALLINT)((password)?strlen(password):0));
-
- myfree(string);
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
- SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
- hdbc = NULL;
- SQLFreeHandle(SQL_HANDLE_ENV, henv);
- henv = NULL;
- return 0;
- }
- retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
- close_sql();
- return 0;
- }
- return 1;
-}
-
-void sqlerr (char *buf){
- if(conf.stdlog){
- fprintf(conf.stdlog, "%s\n", buf);
- fflush(conf.stdlog);
- }
- pthread_mutex_unlock(&log_mutex);
-}
-
-unsigned char statbuf[8192];
-
-void logsql(struct clientparam * param, const unsigned char *s) {
- SQLRETURN ret;
- int len;
-
-
- if(param->nolog) return;
- pthread_mutex_lock(&log_mutex);
- len = dobuf(param, statbuf, s, (unsigned char *)"\'");
-
- if(attempt > 5){
- time_t t;
-
- t = time(0);
- if (t - attempt_time < 180){
- sqlerr((char *)statbuf);
- return;
- }
- }
- if(!hstmt){
- if(!init_sql(sqlstring)) {
- sqlerr((char *)statbuf);
- return;
- }
- }
- if(hstmt){
- ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
- if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
- close_sql();
- if(!init_sql(sqlstring)){
- sqlerr((char *)statbuf);
- return;
- }
- if(hstmt) {
- ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
- if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
- sqlerr((char *)statbuf);
- return;
- }
- attempt = 0;
- }
- }
- attempt = 0;
- }
- pthread_mutex_unlock(&log_mutex);
-}
-
-#endif
diff --git a/src/authradius.c b/src/authradius.c
index 652a3177..e0a028c9 100644
--- a/src/authradius.c
+++ b/src/authradius.c
@@ -168,22 +168,7 @@ char radiussecret[64]="";
pthread_mutex_t rad_mutex;
-void md5_calc(unsigned char *output, unsigned char *input,
- unsigned int inputlen);
-
-
-char *strNcpy(char *dest, const char *src, int n)
-{
- if (n > 0)
- strncpy(dest, src, n);
- else
- n = 1;
- dest[n - 1] = 0;
-
- return dest;
-}
-
-void md5_calc(unsigned char *output, unsigned char *input,
+static void md5_calc(unsigned char *output, unsigned char *input,
unsigned int inlen)
{
MD5_CTX context;
@@ -209,7 +194,7 @@ static int calc_replydigest(char *packet, char *original, const char *secret, in
memcpy(calc_vector, packet + 4, AUTH_VECTOR_LEN);
memcpy(packet + 4, original, AUTH_VECTOR_LEN);
- secretlen = strlen(secret);
+ secretlen = (int)strlen(secret);
memcpy(packet + len, secret, secretlen);
md5_calc(calc_digest, (u_char *)packet, len + secretlen);
@@ -220,14 +205,14 @@ static int calc_replydigest(char *packet, char *original, const char *secret, in
}
#define AUTH_PASS_LEN (16)
-int rad_pwencode(char *passwd, int *pwlen, const char *secret, const char *vector)
+static int rad_pwencode(char *passwd, int *pwlen, const char *secret, const char *vector)
{
uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 1];
char digest[AUTH_VECTOR_LEN];
int i, n, secretlen;
int len;
- len = strlen(passwd);
+ len = (int)strlen(passwd);
if (len > 128) len = 128;
*pwlen = len;
if (len % AUTH_PASS_LEN != 0) {
@@ -237,7 +222,7 @@ int rad_pwencode(char *passwd, int *pwlen, const char *secret, const char *vecto
len = *pwlen = i;
}
- secretlen = strlen(secret);
+ secretlen = (int)strlen(secret);
memcpy(buffer, secret, secretlen);
memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
md5_calc((u_char *)digest, buffer, secretlen + AUTH_VECTOR_LEN);
@@ -258,7 +243,7 @@ int rad_pwencode(char *passwd, int *pwlen, const char *secret, const char *vecto
}
-void random_vector(uint8_t *vector, struct clientparam *param)
+static void random_vector(uint8_t *vector, struct clientparam *param)
{
int i;
static int did_random = 0;
@@ -286,21 +271,19 @@ void random_vector(uint8_t *vector, struct clientparam *param)
}
-static float timeout = 5;
-
typedef struct radius_packet_t {
uint8_t code;
uint8_t id;
uint16_t length;
uint8_t vector[AUTH_VECTOR_LEN];
- uint8_t data[4096];
+ uint8_t data[2048];
} radius_packet_t;
#define RETURN(xxx) { res = xxx; goto CLEANRET; }
-int radsend(struct clientparam * param, int auth, int stop){
+#define packet (*((radius_packet_t *)inbuf))
- int loop;
+static int radbuf(struct clientparam * param, unsigned char * inbuf, int auth, int stop){
int id;
int res = 4;
SOCKET sockfd = -1;
@@ -308,29 +291,16 @@ int radsend(struct clientparam * param, int auth, int stop){
int total_length;
int len;
int op;
-#ifdef NOIPV6
- struct sockaddr_in saremote;
-#else
- struct sockaddr_in6 saremote;
-#endif
- struct pollfd fds[1];
char vector[AUTH_VECTOR_LEN];
- radius_packet_t packet, rpacket;
- SASIZETYPE salen;
- int data_len;
- uint8_t *vendor_len;
int count=0;
- uint8_t *attr;
long vendor=0;
- int vendorlen=0;
char buf[64];
-
if(!radiussecret || !nradservers) {
- return 4;
+ return 0;
}
- memset(&packet, 0, sizeof(packet));
+ memset(&packet, 0, sizeof(radius_packet_t));
pthread_mutex_lock(&rad_mutex);
@@ -353,7 +323,7 @@ int radsend(struct clientparam * param, int auth, int stop){
/* Acct-Session-Id */
sprintf(buf, "%u.%u.%u", (unsigned)param->time_start, (unsigned)param->msec_start, (unsigned)param->threadid);
- len = strlen(buf);
+ len = (int)strlen(buf);
*ptr++ = PW_ACCT_SESSION_ID;
*ptr++ = 2+len;
memcpy(ptr, buf, len);
@@ -393,7 +363,7 @@ int radsend(struct clientparam * param, int auth, int stop){
/* NAS-Identifier */
if(conf.stringtable){
*ptr++ = PW_NAS_IDENTIFIER;
- len = strlen(conf.stringtable[SERVICES+param->service]);
+ len = (int)strlen(conf.stringtable[SERVICES+param->service]);
*ptr++ = (2 + len);
memcpy(ptr, conf.stringtable[SERVICES+param->service], len);
ptr += len;
@@ -418,7 +388,7 @@ int radsend(struct clientparam * param, int auth, int stop){
/* Called-Station-ID */
if(param->hostname){
*ptr++ = PW_CALLED_STATION_ID;
- len = strlen(param->hostname);
+ len = (int)strlen(param->hostname);
*ptr++ = (2 + len);
memcpy(ptr, param->hostname, len);
ptr += len;
@@ -460,7 +430,7 @@ int radsend(struct clientparam * param, int auth, int stop){
/* Username */
if(param->username){
- len = strlen(param->username);
+ len = (int)strlen(param->username);
if(len>128)len=128;
*ptr++ = PW_USER_NAME;
*ptr++ = len + 2;
@@ -503,7 +473,7 @@ int radsend(struct clientparam * param, int auth, int stop){
}
if(auth && param->password){
- len = strlen(param->password);
+ len = (int)strlen(param->password);
if(len > 128) len = 128;
*ptr++ = PW_PASSWORD;
ptr++;
@@ -521,11 +491,44 @@ int radsend(struct clientparam * param, int auth, int stop){
packet.length = htons(total_length);
if(!auth){
- len = strlen(radiussecret);
+ len = (int)strlen(radiussecret);
memcpy(ptr,radiussecret,len);
md5_calc(packet.vector, (u_char *)&packet, total_length + len);
}
memcpy(vector, packet.vector, AUTH_VECTOR_LEN);
+ return total_length;
+
+}
+
+
+static int radsend(const unsigned char *inbuf, int total_length, int auth,
+#ifdef NOIPV6
+ struct sockaddr_in* sinsl
+#else
+ struct sockaddr_in6* sinsl
+#endif
+){
+
+ int loop;
+ int res = 4;
+ SOCKET sockfd = -1;
+ int len;
+#ifdef NOIPV6
+ struct sockaddr_in saremote;
+#else
+ struct sockaddr_in6 saremote;
+#endif
+ struct pollfd fds[1];
+ radius_packet_t rpacket;
+ SASIZETYPE salen;
+ int data_len;
+ uint8_t *vendor_len;
+ int count=0;
+ uint8_t *attr;
+ long vendor=0;
+ int vendorlen=0;
+
+
for (loop = 0; loop < nradservers && loop < MAXRADIUS; loop++) {
SOCKET remsock;
@@ -554,6 +557,7 @@ int radsend(struct clientparam * param, int auth, int stop){
}
else remsock = radiuslist[loop].logsock;
*/
+ so._bind(remsock,(struct sockaddr *)&radiuslist[loop].localaddr,SASIZE(&radiuslist[loop].localaddr));
len = so._sendto(remsock, (char *)&packet, total_length, 0,
(struct sockaddr *)&saremote, sizeof(saremote));
if(len != ntohs(packet.length)){
@@ -620,13 +624,13 @@ int radsend(struct clientparam * param, int auth, int stop){
}
if (!vendor && attr[0] == PW_FRAMED_IP_ADDRESS && attr[1] == 6) {
- *SAFAMILY(¶m->sinsl) = AF_INET;
- memcpy(SAADDR(¶m->sinsl), attr+2, 4);
+ *SAFAMILY(sinsl) = AF_INET;
+ memcpy(SAADDR(sinsl), attr+2, 4);
}
else if (!vendor && attr[0] == PW_FRAMED_IPV6_ADDRESS && attr[1] == 18) {
- *SAFAMILY(¶m->sinsl) = AF_INET6;
- memcpy(SAADDR(¶m->sinsl), attr+2, 16);
+ *SAFAMILY(sinsl) = AF_INET6;
+ memcpy(SAADDR(sinsl), attr+2, 16);
}
else if (!vendor && attr[0] == PW_REPLY_MESSAGE && attr[1] >= 3 && isdigit(attr[2])) {
res = 0;
@@ -656,14 +660,20 @@ int radsend(struct clientparam * param, int auth, int stop){
}
int radauth(struct clientparam * param){
+ radius_packet_t ppacket;
+ int len;
/*radsend(param, 0, 0);*/
- return radsend(param, 1, 0);
+ len = radbuf(param, (unsigned char *)&ppacket, 1, 0);
+ return len?radsend((unsigned char *)&ppacket, len, 1, ¶m->sinsl):4;
+}
+
+
+int raddobuf(struct clientparam * param, char * buf, const unsigned char *s){
+ return radbuf(param, (unsigned char *)buf, 0, 1);
}
-void logradius(struct clientparam * param, const unsigned char *s) {
- radsend(param, 0, 1);
- if(param->trafcountfunc)(*param->trafcountfunc)(param);
- clearstat(param);
+void logradius(const char *buf, int len, struct LOGGER *logger){
+ if(len)radsend((unsigned char *)buf, len, 0, NULL);
}
diff --git a/src/base64.c b/src/base64.c
index e6d0295a..d7b7b8cb 100644
--- a/src/base64.c
+++ b/src/base64.c
@@ -7,11 +7,11 @@
#include
-static const unsigned char base64digits[] =
+static const char base64digits[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-#define BAD 255
-static const unsigned char base64val[] = {
+#define BAD -1
+static const char base64val[] = {
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
@@ -23,7 +23,7 @@ static const unsigned char base64val[] = {
};
#define DECODE64(c) ((c > 32 && c<127)? base64val[(int)c] : BAD)
-unsigned char* en64 (const unsigned char *in, unsigned char *out, int inlen)
+char* en64 (const char *in, char *out, int inlen)
{
for (; inlen > 0; inlen -= 3, in+=3)
{
@@ -40,7 +40,7 @@ unsigned char* en64 (const unsigned char *in, unsigned char *out, int inlen)
int de64 (const char *in, char *out, int maxlen)
{
int len = 0;
- register unsigned char digit1, digit2, digit3, digit4;
+ register char digit1, digit2, digit3, digit4;
if (in[0] == '+' && in[1] == ' ')
in += 2;
@@ -79,9 +79,9 @@ int de64 (const char *in, char *out, int maxlen)
return (len);
}
-unsigned char hex[] = "0123456789ABCDEF";
+char hex[] = "0123456789ABCDEF";
-void tohex(unsigned char *in, unsigned char *out, int len){
+void tohex(char *in, char *out, int len){
int i;
for (i=0; i 0; len--) {
c1 = strchr((char *)hex, *in++);
c2 = strchr((char *)hex, *in++);
if(c1 && c2){
- *out++ = ((unsigned char)((unsigned char *)c1 - hex) << 4) + (unsigned char)((unsigned char *)c2 - hex);
+ *out++ = (char)(unsigned char)(((c1 - hex) << 4) + (c2 - hex));
}
}
}
diff --git a/src/common.c b/src/common.c
index 1bdf5d45..5153adfe 100644
--- a/src/common.c
+++ b/src/common.c
@@ -31,7 +31,7 @@ int randomizer = 1;
#endif
-unsigned char **stringtable = NULL;
+char **stringtable = NULL;
#ifdef WITH_LINUX_FUTEX
int sys_futex(void *addr1, int op, int val1, struct timespec *timeout, void *addr2, int val3)
@@ -93,42 +93,46 @@ char *rotations[] = {
struct extparam conf = {
- {1, 5, 30, 60, 180, 1800, 15, 60, 15, 5, 0, 0},
- NULL,
- NULL,
- NULL, NULL,
- NULL,
- NULL,
- NULL,
- 0,
- 0, -1, 0, 0, 0, 0,
- 0, 500, 0, 0, 0, 0,
- 6, 600,
- 1048576,
- NULL, NULL,
- NONE, NONE,
- NULL,
+ {1, 5, 30, 60, 180, 1800, 15, 60, 15, 5, 0, 0}, /* int timeouts[12]; */
+ NULL, /*struct ace * acl; */
+ NULL, /* char * conffile; */
+ NULL, NULL, /* struct bandlim * bandlimiter, *bandlimiterout; */
+ NULL, /* struct connlim * connlimiter; */
+ NULL, /* struct trafcount * trafcounter; */
+ NULL, /* struct srvparam *services; */
+ 0, /* int stacksize, */
+ 0, -1, 0, 0, 0, 0, /* threadinit, counterd, haveerror, rotate, paused, archiverc, */
+ 0, 250, 0, 0, 0, 0, 0, 2, /* demon, maxchild, needreload, timetoexit, version, noforce, bandlimver, parenretries; */
+ 6, 600, /* int authcachetype, authcachetime; */
+ 1048576, /* int filtermaxsize; */
+ NULL, /* **archiver; */
+ NONE, NONE, /* ROTATION logtype, countertype; */
+ NULL, /* char * counterfile; */
#ifndef NOIPV6
- {AF_INET},{AF_INET6},{AF_INET},
+ {AF_INET},{AF_INET6},{AF_INET}, /* struct sockaddr_in6 intsa;
+ struct sockaddr_in6 extsa6;
+ struct sockaddr_in6 extsa; */
+
#else
- {AF_INET},{AF_INET},
+ {AF_INET},{AF_INET}, /* struct sockaddr_in intsa;
+ struct sockaddr_in extsa; */
+
#endif
- NULL,
- NULL,
- doconnect,
- lognone,
- NULL,
- NULL,
- NULL, NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- (time_t)0, (time_t)0,
- 0,0,
- '@',
+ NULL, /* struct passwords *pwl; */
+ NULL, /* struct auth * authenticate; */
+ doconnect, /* AUTHFUNC authfunc; */
+ NULL, /* BANDLIMFUNC bandlimfunc; */
+ NULL, /* TRAFCOUNTFUNC trafcountfunc; */
+ NULL, /* void (*prelog)(struct clientparam * param); */
+ NULL, NULL, /* char *logtarget, *logformat; */
+ NULL, /* struct filemon * fmon; */
+ NULL, /* struct filter * filters; */
+ NULL, /* struct auth *authfuncs; */
+ NULL, /* char* demanddialprog; */
+ NULL, /* char **stringtable; */
+ (time_t)0, /* time_t time; */
+ 0,0, /* unsigned logdumpsrv, logdumpcli; */
+ '@', /* char delimchar; */
};
int numservers=0;
@@ -137,13 +141,13 @@ char* NULLADDR="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
int myrand(void * entropy, int len){
int i;
- unsigned short init;
+ uint16_t init;
init = randomizer;
for(i=0; i < len/2; i++){
- init ^= ((unsigned short *)entropy)[i];
+ init ^= ((uint16_t *)entropy)[i];
}
- srand(init);
+ srand(rand()+init);
randomizer = rand();
return rand();
@@ -266,7 +270,7 @@ int ceparseargs(const char *str){
#endif
-int parsehost(int family, unsigned char *host, struct sockaddr *sa){
+int parsehost(int family, char *host, struct sockaddr *sa){
char *sp=NULL,*se=NULL;
unsigned short port=0;
int ret = 0;
@@ -293,13 +297,16 @@ int parsehostname(char *hostname, struct clientparam *param, unsigned short port
if(!hostname || !*hostname)return 2;
if(*hostname == '[') se=strchr(hostname, ']');
- if ( (sp = strchr(se?se:hostname, ':')) && !strchr(sp+1, ':')) *sp = 0;
+ if ((sp = strchr(se?se:hostname, ':'))) {
+ if(strchr(sp+1, ':'))sp = NULL;
+ else *sp = 0;
+ }
if(se){
*se = 0;
}
if(hostname != (char *)param->hostname){
if(param->hostname) myfree(param->hostname);
- param->hostname = (unsigned char *)mystrdup(hostname + (se!=0));
+ param->hostname = (char *)mystrdup(hostname + (se!=0));
}
if(sp){
port = atoi(sp+1);
@@ -322,11 +329,11 @@ int parseusername(char *username, struct clientparam *param, int extpasswd){
if(sp) *sp = 0;
if(*(sb+1)) {
if(param->password) myfree(param->password);
- param->password = (unsigned char *)mystrdup(sb+1);
+ param->password = (char *)mystrdup(sb+1);
}
if(*username) {
if(param->username) myfree(param->username);
- param->username = (unsigned char *)mystrdup(username);
+ param->username = (char *)mystrdup(username);
}
username = se+1;
}
@@ -335,11 +342,11 @@ int parseusername(char *username, struct clientparam *param, int extpasswd){
if(sp){
*sp = 0;
if(param->extpassword) myfree(param->extpassword);
- param->extpassword = (unsigned char *) mystrdup(sp+1);
+ param->extpassword = (char *) mystrdup(sp+1);
}
}
if(param->extusername) myfree(param->extusername);
- param->extusername = (unsigned char *)mystrdup(username);
+ param->extusername = (char *)mystrdup(username);
if(sb) *sb = ':';
if(se) *se = ':';
if(sp) *sp = ':';
@@ -395,7 +402,7 @@ int doconnect(struct clientparam * param){
return 0;
if (param->remsock != INVALID_SOCKET){
size = sizeof(param->sinsr);
- if(so._getpeername(param->remsock, (struct sockaddr *)¶m->sinsr, &size)==-1) {return (15);}
+ if(so._getpeername(param->remsock, (struct sockaddr *)¶m->sinsr, &size)==-1) {return (14);}
}
else {
struct linger lg = {1,conf.timeouts[SINGLEBYTE_S]};
@@ -422,7 +429,7 @@ int doconnect(struct clientparam * param){
#endif
#ifdef SO_REUSEPORT
opt = 1;
- so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
+ so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
#endif
}
#endif
@@ -455,7 +462,7 @@ int doconnect(struct clientparam * param){
return 0;
}
-int scanaddr(const unsigned char *s, unsigned long * ip, unsigned long * mask) {
+int scanaddr(const char *s, unsigned long * ip, unsigned long * mask) {
unsigned d1, d2, d3, d4, m;
int res;
if ((res = sscanf((char *)s, "%u.%u.%u.%u/%u", &d1, &d2, &d3, &d4, &m)) < 4) return 0;
@@ -488,7 +495,7 @@ struct hostent * my_gethostbyname(char *name, char *buf, struct hostent *hp){
#endif
#ifdef NOIPV6
-unsigned long getip(unsigned char *name){
+unsigned long getip(char *name){
unsigned long retval;
int i;
int ndots = 0;
@@ -515,9 +522,8 @@ unsigned long getip(unsigned char *name){
}
}
if((tmpresolv=resolvfunc)){
- if((*tmpresolv)(AF_INET, name, (unsigned char *)&retval)) return retval;
- if(conf.demanddialprog) system(conf.demanddialprog);
- return (*tmpresolv)(AF_INET, name, (unsigned char *)&retval)?retval:0;
+ if((*tmpresolv)(AF_INET, name, (char *)&retval)) return retval;
+ return (*tmpresolv)(AF_INET, name, (char *)&retval)?retval:0;
}
#if !defined(_WIN32) && !defined(GETHOSTBYNAME_R)
if(!ghbn_init){
@@ -542,7 +548,7 @@ unsigned long getip(unsigned char *name){
}
#endif
-int afdetect(unsigned char *name){
+int afdetect(char *name){
int ndots=0, ncols=0, nhex=0;
int i;
@@ -574,7 +580,7 @@ int afdetect(unsigned char *name){
}
-unsigned long getip46(int family, unsigned char *name, struct sockaddr *sa){
+unsigned long getip46(int family, char *name, struct sockaddr *sa){
#ifndef NOIPV6
int detect;
struct addrinfo *ai, hint;
diff --git a/src/conf.c b/src/conf.c
index 01b56645..050308a2 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -101,49 +101,6 @@ int getrotate(char c){
}
-unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t) {
- struct tm *ts;
-
- ts = localtime(&t);
- if(strchr((char *)name, '%')){
- struct clientparam fakecli;
-
- memset(&fakecli, 0, sizeof(fakecli));
- dobuf2(&fakecli, buf, NULL, NULL, ts, (char *)name);
- }
- else switch(lt){
- case NONE:
- sprintf((char *)buf, "%s", name);
- break;
- case ANNUALLY:
- sprintf((char *)buf, "%s.%04d", name, ts->tm_year+1900);
- break;
- case MONTHLY:
- sprintf((char *)buf, "%s.%04d.%02d", name, ts->tm_year+1900, ts->tm_mon+1);
- break;
- case WEEKLY:
- t = t - (ts->tm_wday * (60*60*24));
- ts = localtime(&t);
- sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
- break;
- case DAILY:
- sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
- break;
- case HOURLY:
- sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour);
- break;
- case MINUTELY:
- sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour, ts->tm_min);
- break;
- default:
- break;
- }
- if(ext){
- strcat((char *)buf, ".");
- strcat((char *)buf, (char *)ext);
- }
- return buf;
-}
int start_proxy_thread(struct child * chp){
pthread_t thread;
@@ -168,13 +125,13 @@ int start_proxy_thread(struct child * chp){
#endif
while(conf.threadinit)usleep(SLEEPTIME);
if(haveerror) {
- fprintf(stderr, "Service not started on line: %d\n", linenum);
+ fprintf(stderr, "Service not started on line: %d%s\n", linenum, haveerror == 2? ": insufficient memory":"");
return(40);
}
return 0;
}
-static int h_proxy(int argc, unsigned char ** argv){
+static int h_proxy(int argc, char ** argv){
struct child ch;
ch.argc = argc;
@@ -259,12 +216,12 @@ static int h_proxy(int argc, unsigned char ** argv){
return start_proxy_thread(&ch);
}
-static int h_internal(int argc, unsigned char ** argv){
+static int h_internal(int argc, char ** argv){
getip46(46, argv[1], (struct sockaddr *)&conf.intsa);
return 0;
}
-static int h_external(int argc, unsigned char ** argv){
+static int h_external(int argc, char ** argv){
int res;
#ifndef NOIPV6
struct sockaddr_in6 sa6;
@@ -280,102 +237,50 @@ static int h_external(int argc, unsigned char ** argv){
}
-static int h_log(int argc, unsigned char ** argv){
- unsigned char tmpbuf[8192];
- int notchanged = 0;
-
-
- havelog = 1;
- if(argc > 1 && conf.logtarget && !strcmp((char *)conf.logtarget, (char *)argv[1])) {
- notchanged = 1;
- }
- if(!notchanged && conf.logtarget){
- myfree(conf.logtarget);
- conf.logtarget = NULL;
- }
- if(argc > 1) {
- if(!strcmp((char *) argv[1], "/dev/null")) {
- conf.logfunc = lognone;
- return 0;
- }
- if(!notchanged) conf.logtarget = (unsigned char *)mystrdup((char *)argv[1]);
- if(*argv[1]=='@'){
-#ifndef _WIN32
- conf.logfunc = logsyslog;
- if(notchanged) return 0;
- openlog((char *)conf.logtarget+1, LOG_PID, LOG_DAEMON);
-#endif
- }
-#ifndef NOODBC
- else if(*argv[1]=='&'){
- if(notchanged) return 0;
- conf.logfunc = logsql;
- pthread_mutex_lock(&log_mutex);
- close_sql();
- init_sql((char *)argv[1]+1);
- pthread_mutex_unlock(&log_mutex);
- }
-#endif
-#ifndef NORADIUS
- else if(!strcmp(argv[1],"radius")){
- conf.logfunc = logradius;
- }
-#endif
- else {
- if(argc > 2) {
- conf.logtype = getrotate(*argv[2]);
- }
- conf.logfunc = logstdout;
- if(notchanged) return 0;
- conf.logtime = time(0);
- if(conf.logname)myfree(conf.logname);
- conf.logname = (unsigned char *)mystrdup((char *)argv[1]);
- if(conf.stdlog) conf.stdlog = freopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.logtime), "a", conf.stdlog);
- else conf.stdlog = fopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.logtime), "a");
- if(!conf.stdlog){
- perror((char *)tmpbuf);
- return 1;
- }
-
- }
+static int h_log(int argc, char ** argv){
+ myfree(conf.logtarget);
+ if(argc < 2) conf.logtarget = (char *)mystrdup("");
+ else conf.logtarget = (char *)mystrdup((char *)argv[1]);
+ if(argc > 2) {
+ conf.logtype = getrotate(*argv[2]);
}
- else conf.logfunc = logstdout;
return 0;
}
-static int h_stacksize(int argc, unsigned char **argv){
+static int h_stacksize(int argc, char **argv){
conf.stacksize = atoi((char *)argv[1]);
return 0;
}
-static int h_force(int argc, unsigned char **argv){
+static int h_force(int argc, char **argv){
conf.noforce = 0;
return 0;
}
-static int h_noforce(int argc, unsigned char **argv){
+static int h_noforce(int argc, char **argv){
conf.noforce = 1;
return 0;
}
-static int h_service(int argc, unsigned char **argv){
+static int h_service(int argc, char **argv){
return 0;
}
-static int h_daemon(int argc, unsigned char **argv){
+static int h_daemon(int argc, char **argv){
if(!conf.demon)daemonize();
conf.demon = 1;
return 0;
}
-static int h_config(int argc, unsigned char **argv){
+static int h_config(int argc, char **argv){
if(conf.conffile)myfree(conf.conffile);
conf.conffile = mystrdup((char *)argv[1]);
+ if(!conf.conffile) return 21;
return 0;
}
-static int h_include(int argc, unsigned char **argv){
+static int h_include(int argc, char **argv){
int res;
FILE *fp1;
@@ -389,21 +294,20 @@ static int h_include(int argc, unsigned char **argv){
return res;
}
-static int h_archiver(int argc, unsigned char **argv){
+static int h_archiver(int argc, char **argv){
int j;
conf.archiver = myalloc(argc * sizeof(char *));
if(conf.archiver) {
conf.archiverc = argc;
- for(j = 0; j < conf.archiverc; j++) conf.archiver[j] = (unsigned char *)mystrdup((char *)argv[j]);
+ for(j = 0; j < conf.archiverc; j++) conf.archiver[j] = (char *)mystrdup((char *)argv[j]);
}
return 0;
}
-static int h_counter(int argc, unsigned char **argv){
+static int h_counter(int argc, char **argv){
struct counter_header ch1;
if(conf.counterd >=0)close(conf.counterd);
- if(!conf.trafcountfunc) conf.trafcountfunc = trafcountfunc;
conf.counterd = open((char *)argv[1], O_BINARY|O_RDWR|O_CREAT, 0660);
if(conf.counterd<0){
fprintf(stderr, "Unable to open counter file %s, line %d\n", argv[1], linenum);
@@ -440,19 +344,19 @@ static int h_counter(int argc, unsigned char **argv){
return 0;
}
-static int h_rotate(int argc, unsigned char **argv){
+static int h_rotate(int argc, char **argv){
conf.rotate = atoi((char *)argv[1]);
return 0;
}
-static int h_logformat(int argc, unsigned char **argv){
- unsigned char * old = conf.logformat;
- conf.logformat = (unsigned char *)mystrdup((char *)argv[1]);
+static int h_logformat(int argc, char **argv){
+ char * old = conf.logformat;
+ conf.logformat = (char *)mystrdup((char *)argv[1]);
if(old) myfree(old);
return 0;
}
-static int h_timeouts(int argc, unsigned char **argv){
+static int h_timeouts(int argc, char **argv){
int j;
for(j = 0; conf.timeouts[j] && j + 1 < argc; j++) {
@@ -464,11 +368,11 @@ static int h_timeouts(int argc, unsigned char **argv){
return 0;
}
-static int h_noop(int argc, unsigned char **argv){
+static int h_noop(int argc, char **argv){
return 0;
}
-static int h_auth(int argc, unsigned char **argv){
+static int h_auth(int argc, char **argv){
struct auth *au, * newau;
freeauth(conf.authfuncs);
@@ -478,9 +382,13 @@ static int h_auth(int argc, unsigned char **argv){
for(au = authfuncs; au; au=au->next){
if(!strcmp((char *)argv[argc], au->desc)){
newau = myalloc(sizeof(struct auth));
+ if(!newau) {
+ return 21;
+ }
newau->next = conf.authfuncs;
conf.authfuncs = newau;
conf.authfuncs->desc = au->desc;
+ conf.authfuncs->preauthorize = au->preauthorize;
conf.authfuncs->authenticate = au->authenticate;
conf.authfuncs->authorize = au->authorize;
break;
@@ -492,37 +400,38 @@ static int h_auth(int argc, unsigned char **argv){
return 0;
}
-static int h_users(int argc, unsigned char **argv){
+static int h_users(int argc, char **argv){
int j;
- unsigned char *arg;
+ char *arg;
struct passwords *pwl = NULL;
for (j = 1; juser = (unsigned char *)mystrdup((char *)argv[j]);
+ pwl->user = mystrdup((char *)argv[j]);
pwl->pwtype = SYS;
}
else {
*arg = 0;
- pwl->user = (unsigned char *)mystrdup((char *)argv[j]);
+ pwl->user = mystrdup((char *)argv[j]);
if((arg[1] == 'C' && arg[2] == 'L' && (pwl->pwtype = CL)) ||
(arg[1] == 'C' && arg[2] == 'R' && (pwl->pwtype = CR)) ||
(arg[1] == 'N' && arg[2] == 'T' && (pwl->pwtype = NT)) ||
(arg[1] == 'L' && arg[2] == 'M' && (pwl->pwtype = LM))){
- pwl->password = (unsigned char *)mystrdup((char *)arg+4);
+ pwl->password = mystrdup((char *)arg+4);
}
else {
- pwl->password = (unsigned char *) mystrdup((char *)arg + 1);
+ pwl->password = mystrdup((char *)arg + 1);
pwl->pwtype = UN;
}
+ if(!pwl->password) return 3;
}
+ if(!pwl->user) return 21;
pthread_mutex_lock(&pwl_mutex);
pwl->next = conf.pwl;
conf.pwl = pwl;
@@ -533,7 +442,7 @@ static int h_users(int argc, unsigned char **argv){
return 0;
}
-static int h_maxconn(int argc, unsigned char **argv){
+static int h_maxconn(int argc, char **argv){
conf.maxchild = atoi((char *)argv[1]);
if(!conf.maxchild) {
return(1);
@@ -553,21 +462,21 @@ static int h_maxconn(int argc, unsigned char **argv){
return 0;
}
-static int h_flush(int argc, unsigned char **argv){
+static int h_flush(int argc, char **argv){
freeacl(conf.acl);
conf.acl = NULL;
return 0;
}
/*
-static int h_flushusers(int argc, unsigned char **argv){
+static int h_flushusers(int argc, char **argv){
freepwl(conf.pwl);
conf.pwl = NULL;
return 0;
}
*/
-static int h_nserver(int argc, unsigned char **argv){
+static int h_nserver(int argc, char **argv){
char *str;
if(numservers < MAXNSERVERS) {
@@ -586,7 +495,7 @@ static int h_nserver(int argc, unsigned char **argv){
return 0;
}
-static int h_authnserver(int argc, unsigned char **argv){
+static int h_authnserver(int argc, char **argv){
char *str;
if((str = strchr((char *)argv[1], '/')))
@@ -600,12 +509,12 @@ static int h_authnserver(int argc, unsigned char **argv){
return 0;
}
-static int h_fakeresolve(int argc, unsigned char **argv){
+static int h_fakeresolve(int argc, char **argv){
resolvfunc = fakeresolver;
return 0;
}
-static int h_nscache(int argc, unsigned char **argv){
+static int h_nscache(int argc, char **argv){
int res;
res = atoi((char *)argv[1]);
@@ -619,7 +528,16 @@ static int h_nscache(int argc, unsigned char **argv){
}
return 0;
}
-static int h_nscache6(int argc, unsigned char **argv){
+
+static int h_parentretries(int argc, char **argv){
+ int res;
+
+ res = atoi((char *)argv[1]);
+ if(res > 0) conf.parentretries = res;
+ return 0;
+}
+
+static int h_nscache6(int argc, char **argv){
int res;
res = atoi((char *)argv[1]);
@@ -634,7 +552,7 @@ static int h_nscache6(int argc, unsigned char **argv){
return 0;
}
-static int h_nsrecord(int argc, unsigned char **argv){
+static int h_nsrecord(int argc, char **argv){
#ifndef NOIPV6
struct sockaddr_in6 sa;
#else
@@ -647,13 +565,7 @@ static int h_nsrecord(int argc, unsigned char **argv){
return 0;
}
-static int h_dialer(int argc, unsigned char **argv){
- if(conf.demanddialprog) myfree(conf.demanddialprog);
- conf.demanddialprog = mystrdup((char *)argv[1]);
- return 0;
-}
-
-static int h_system(int argc, unsigned char **argv){
+static int h_system(int argc, char **argv){
int res;
if((res = system((char *)argv[1])) == -1){
@@ -663,7 +575,7 @@ static int h_system(int argc, unsigned char **argv){
return 0;
}
-static int h_pidfile(int argc, unsigned char **argv){
+static int h_pidfile(int argc, char **argv){
FILE *pidf;
if(!(pidf = fopen((char *)argv[1], "w"))){
@@ -675,25 +587,28 @@ static int h_pidfile(int argc, unsigned char **argv){
return 0;
}
-static int h_monitor(int argc, unsigned char **argv){
+static int h_monitor(int argc, char **argv){
struct filemon * fm;
fm = myalloc(sizeof (struct filemon));
+ if(!fm) return 21;
if(stat((char *)argv[1], &fm->sb)){
myfree(fm);
fprintf(stderr, "Warning: file %s doesn't exist on line %d\n", argv[1], linenum);
}
else {
fm->path = mystrdup((char *)argv[1]);
+ if(!fm->path) return 21;
fm->next = conf.fmon;
conf.fmon = fm;
}
return 0;
}
-static int h_parent(int argc, unsigned char **argv){
+static int h_parent(int argc, char **argv){
struct ace *acl = NULL;
struct chain *chains;
+ char * cidr;
acl = conf.acl;
while(acl && acl->next) acl = acl->next;
@@ -705,8 +620,7 @@ static int h_parent(int argc, unsigned char **argv){
chains = myalloc(sizeof(struct chain));
if(!chains){
- fprintf(stderr, "Chainig error: unable to allocate memory for chain\n");
- return(2);
+ return(21);
}
memset(chains, 0, sizeof(struct chain));
chains->weight = (unsigned)atoi((char *)argv[1]);
@@ -733,15 +647,19 @@ static int h_parent(int argc, unsigned char **argv){
fprintf(stderr, "Chaining error: bad chain type (%s)\n", argv[2]);
return(4);
}
-#ifndef NOIPV6
- if(!getip46(46, argv[3], (struct sockaddr *)&chains->addr)) return 5;
-#else
+ cidr = strchr(argv[3], '/');
+ if(cidr) *cidr = 0;
getip46(46, argv[3], (struct sockaddr *)&chains->addr);
-#endif
+ chains->exthost = mystrdup((char *)argv[3]);
chains->exthost = (unsigned char *)mystrdup((char *)argv[3]);
+ if(!chains->exthost) return 21;
+ if(cidr){
+ *cidr = '/';
+ chains->cidr = atoi(cidr + 1);
+ }
*SAPORT(&chains->addr) = htons((unsigned short)atoi((char *)argv[4]));
- if(argc > 5) chains->extuser = (unsigned char *)mystrdup((char *)argv[5]);
- if(argc > 6) chains->extpass = (unsigned char *)mystrdup((char *)argv[6]);
+ if(argc > 5) chains->extuser = mystrdup((char *)argv[5]);
+ if(argc > 6) chains->extpass = mystrdup((char *)argv[6]);
if(!acl->chains) {
acl->chains = chains;
}
@@ -755,7 +673,7 @@ static int h_parent(int argc, unsigned char **argv){
}
-static int h_nolog(int argc, unsigned char **argv){
+static int h_nolog(int argc, char **argv){
struct ace *acl = NULL;
acl = conf.acl;
@@ -769,7 +687,7 @@ static int h_nolog(int argc, unsigned char **argv){
return 0;
}
-int scanipl(unsigned char *arg, struct iplist *dst){
+int scanipl(char *arg, struct iplist *dst){
#ifndef NOIPV6
struct sockaddr_in6 sa;
#else
@@ -777,23 +695,31 @@ int scanipl(unsigned char *arg, struct iplist *dst){
#endif
char * slash, *dash;
int masklen, addrlen;
+ int res;
if((slash = strchr((char *)arg, '/'))) *slash = 0;
if((dash = strchr((char *)arg,'-'))) *dash = 0;
- if(afdetect(arg) == -1) return 1;
- if(!getip46(46, arg, (struct sockaddr *)&sa)) return 1;
+ if(afdetect(arg) == -1) {
+ if(slash)*slash = '/';
+ if(dash)*dash = '-';
+ return 1;
+ }
+ res = getip46(46, arg, (struct sockaddr *)&sa);
+ if(dash)*dash = '-';
+ if(!res) return 1;
memcpy(&dst->ip_from, SAADDR(&sa), SAADDRLEN(&sa));
dst->family = *SAFAMILY(&sa);
if(dash){
if(afdetect(dash+1) == -1) return 1;
- if(!getip46(46, (unsigned char *)dash+1, (struct sockaddr *)&sa)) return 2;
+ if(!getip46(46, (char *)dash+1, (struct sockaddr *)&sa)) return 2;
memcpy(&dst->ip_to, SAADDR(&sa), SAADDRLEN(&sa));
if(*SAFAMILY(&sa) != dst->family || memcmp(&dst->ip_to, &dst->ip_from, SAADDRLEN(&sa)) < 0) return 3;
return 0;
}
memcpy(&dst->ip_to, &dst->ip_from, SAADDRLEN(&sa));
if(slash){
+ *slash = '/';
addrlen = SAADDRLEN(&sa);
masklen = atoi(slash+1);
if(masklen < 0 || masklen > (addrlen*8)) return 4;
@@ -801,12 +727,12 @@ int scanipl(unsigned char *arg, struct iplist *dst){
int i, nbytes = masklen / 8, nbits = (8 - (masklen % 8)) % 8;
for(i = addrlen; i>(nbytes + (nbits > 0)); i--){
- ((unsigned char *)&dst->ip_from)[i-1] = 0x00;
- ((unsigned char *)&dst->ip_to)[i-1] = 0xff;
+ ((char *)&dst->ip_from)[i-1] = 0x00;
+ ((char *)&dst->ip_to)[i-1] = (char)(unsigned char)0xff;
}
for(;nbits;nbits--){
- ((unsigned char *)&dst->ip_from)[nbytes] &= ~(0x01<<(nbits-1));
- ((unsigned char *)&dst->ip_to)[nbytes] |= (0x01<<(nbits-1));
+ ((char *)&dst->ip_from)[nbytes] &= ~(0x01<<(nbits-1));
+ ((char *)&dst->ip_to)[nbytes] |= (0x01<<(nbits-1));
}
return 0;
}
@@ -814,9 +740,9 @@ int scanipl(unsigned char *arg, struct iplist *dst){
return 0;
}
-struct ace * make_ace (int argc, unsigned char ** argv){
+struct ace * make_ace (int argc, char ** argv){
struct ace * acl;
- unsigned char *arg;
+ char *arg;
struct iplist *ipl=NULL;
struct portlist *portl=NULL;
struct userlist *userl=NULL;
@@ -828,7 +754,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
memset(acl, 0, sizeof(struct ace));
if(argc > 0 && strcmp("*", (char *)argv[0])) {
arg = argv[0];
- arg = (unsigned char *)strtok((char *)arg, ",");
+ arg = (char *)strtok((char *)arg, ",");
do {
if(!acl->users) {
acl->users = userl = myalloc(sizeof(struct userlist));
@@ -842,11 +768,12 @@ struct ace * make_ace (int argc, unsigned char ** argv){
return(NULL);
}
memset(userl, 0, sizeof(struct userlist));
- userl->user=(unsigned char*)mystrdup((char *)arg);
- } while((arg = (unsigned char *)strtok((char *)NULL, ",")));
+ userl->user=mystrdup((char *)arg);
+ if(!userl->user) return NULL;
+ } while((arg = strtok((char *)NULL, ",")));
}
if(argc > 1 && strcmp("*", (char *)argv[1])) {
- arg = (unsigned char *)strtok((char *)argv[1], ",");
+ arg = (char *)strtok((char *)argv[1], ",");
do {
if(!acl->src) {
acl->src = ipl = myalloc(sizeof(struct iplist));
@@ -864,13 +791,13 @@ struct ace * make_ace (int argc, unsigned char ** argv){
fprintf(stderr, "Invalid IP, IP range or CIDR, line %d\n", linenum);
return(NULL);
}
- } while((arg = (unsigned char *)strtok((char *)NULL, ",")));
+ } while((arg = (char *)strtok((char *)NULL, ",")));
}
if(argc > 2 && strcmp("*", (char *)argv[2])) {
- arg = (unsigned char *)strtok((char *)argv[2], ",");
+ arg = (char *)strtok((char *)argv[2], ",");
do {
int arglen;
- unsigned char *pattern;
+ char *pattern;
struct iplist tmpip={NULL};
arglen = (int)strlen((char *)arg);
@@ -900,7 +827,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
arglen--;
hostnamel->matchtype ^= MATCHBEGIN;
}
- hostnamel->name = (unsigned char *) mystrdup( (char *)pattern);
+ hostnamel->name = (char *) mystrdup( (char *)pattern);
if(!hostnamel->name) {
fprintf(stderr, "No memory for ACL entry, line %d\n", linenum);
return(NULL);
@@ -921,10 +848,10 @@ struct ace * make_ace (int argc, unsigned char ** argv){
}
*ipl = tmpip;
}
- }while((arg = (unsigned char *)strtok((char *)NULL, ",")));
+ }while((arg = (char *)strtok((char *)NULL, ",")));
}
if(argc > 3 && strcmp("*", (char *)argv[3])) {
- arg = (unsigned char *)strtok((char *)argv[3], ",");
+ arg = (char *)strtok((char *)argv[3], ",");
do {
if(!acl->ports) {
acl->ports = portl = myalloc(sizeof(struct portlist));
@@ -944,10 +871,10 @@ struct ace * make_ace (int argc, unsigned char ** argv){
return(NULL);
}
if (res == 1) portl->endport = portl->startport;
- } while((arg = (unsigned char *)strtok((char *)NULL, ",")));
+ } while((arg = (char *)strtok((char *)NULL, ",")));
}
if(argc > 4 && strcmp("*", (char *)argv[4])) {
- arg = (unsigned char *)strtok((char *)argv[4], ",");
+ arg = (char *)strtok((char *)argv[4], ",");
do {
if(!strcmp((char *)arg, "CONNECT")){
acl->operation |= CONNECT;
@@ -1010,7 +937,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
fprintf(stderr, "Unknown operation type: %s line %d\n", arg, linenum);
return(NULL);
}
- } while((arg = (unsigned char *)strtok((char *)NULL, ",")));
+ } while((arg = (char *)strtok((char *)NULL, ",")));
}
if(argc > 5){
for(arg = argv[5]; *arg;){
@@ -1074,7 +1001,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
}
-static int h_ace(int argc, unsigned char **argv){
+static int h_ace(int argc, char **argv){
int res = 0;
int offset = 0;
struct ace *acl = NULL;
@@ -1136,11 +1063,11 @@ static int h_ace(int argc, unsigned char **argv){
switch(acl->action){
case REDIRECT:
acl->chains = myalloc(sizeof(struct chain));
- memset(acl->chains, 0, sizeof(struct chain));
if(!acl->chains) {
- fprintf(stderr, "No memory for ACL entry, line %d\n", linenum);
- return(2);
+ freeacl(acl);
+ return(21);
}
+ memset(acl->chains, 0, sizeof(struct chain));
acl->chains->type = R_HTTP;
if(!getip46(46, argv[1], (struct sockaddr *)&acl->chains->addr)) return 5;
*SAPORT(&acl->chains->addr) = htons((unsigned short)atoi((char *)argv[2]));
@@ -1161,8 +1088,8 @@ static int h_ace(int argc, unsigned char **argv){
case NOCONNLIM:
ncl = myalloc(sizeof(struct connlim));
if(!ncl) {
- fprintf(stderr, "No memory to create connection limit filter\n");
- return(3);
+ freeacl(acl);
+ return(21);
}
memset(ncl, 0, sizeof(struct connlim));
ncl->ace = acl;
@@ -1188,14 +1115,16 @@ static int h_ace(int argc, unsigned char **argv){
nbl = myalloc(sizeof(struct bandlim));
if(!nbl) {
- fprintf(stderr, "No memory to create band limit filter\n");
- return(3);
+ freeacl(acl);
+ return(21);
}
memset(nbl, 0, sizeof(struct bandlim));
nbl->ace = acl;
if(acl->action == BANDLIM) {
sscanf((char *)argv[1], "%u", &nbl->rate);
if(nbl->rate < 300) {
+ myfree(nbl);
+ freeacl(acl);
fprintf(stderr, "Wrong bandwidth specified, line %d\n", linenum);
return(4);
}
@@ -1223,7 +1152,7 @@ static int h_ace(int argc, unsigned char **argv){
bli->next = nbl;
}
}
-
+ conf.bandlimver++;
pthread_mutex_unlock(&bandlim_mutex);
break;
@@ -1233,10 +1162,11 @@ static int h_ace(int argc, unsigned char **argv){
case NOCOUNTOUT:
case COUNTALL:
case NOCOUNTALL:
+ if(!conf.trafcountfunc) conf.trafcountfunc = trafcountfunc;
tl = myalloc(sizeof(struct trafcount));
if(!tl) {
- fprintf(stderr, "No memory to create traffic limit filter\n");
- return(5);
+ freeacl(acl);
+ return(21);
}
memset(tl, 0, sizeof(struct trafcount));
tl->ace = acl;
@@ -1254,6 +1184,8 @@ static int h_ace(int argc, unsigned char **argv){
tl->type = getrotate(*argv[2]);
tl->traflim64 = ((uint64_t)lim)*(1024*1024);
if(!tl->traflim64) {
+ myfree(tl);
+ freeacl(acl);
fprintf(stderr, "Wrong traffic limit specified, line %d\n", linenum);
return(6);
}
@@ -1262,7 +1194,7 @@ static int h_ace(int argc, unsigned char **argv){
sizeof(struct counter_header) + (tl->number - 1) * sizeof(struct counter_record),
SEEK_SET);
memset(&crecord, 0, sizeof(struct counter_record));
- read(conf.counterd, &crecord, sizeof(struct counter_record));
+ (void)read(conf.counterd, &crecord, sizeof(struct counter_record));
tl->traf64 = crecord.traf64;
tl->cleared = crecord.cleared;
tl->updated = crecord.updated;
@@ -1288,26 +1220,26 @@ static int h_ace(int argc, unsigned char **argv){
return 0;
}
-static int h_logdump(int argc, unsigned char **argv){
+static int h_logdump(int argc, char **argv){
conf.logdumpsrv = (unsigned) atoi((char *) *(argv + 1));
if(argc > 2) conf.logdumpcli = (unsigned) atoi((char *) *(argv + 2));
return 0;
}
-static int h_filtermaxsize(int argc, unsigned char **argv){
+static int h_filtermaxsize(int argc, char **argv){
conf.filtermaxsize = atoi((char *) *(argv + 1));
return 0;
}
-static int h_delimchar(int argc, unsigned char **argv){
+static int h_delimchar(int argc, char **argv){
conf.delimchar = *argv[1];
return 0;
}
#ifndef NORADIUS
-static int h_radius(int argc, unsigned char **argv){
+static int h_radius(int argc, char **argv){
unsigned short port;
/*
@@ -1329,13 +1261,19 @@ static int h_radius(int argc, unsigned char **argv){
if(strlen(argv[1]) > 63) argv[1][63] = 0;
strcpy(radiussecret, argv[1]);
for( nradservers=0; nradservers < MAXRADIUS && nradservers < argc -2; nradservers++){
+ char *s = 0;
+ if((s=strchr(argv[nradservers + 2], '/'))){
+ *s = 0;
+ s++;
+ }
if( !getip46(46, argv[nradservers + 2], (struct sockaddr *)&radiuslist[nradservers].authaddr)) return 1;
+ if( s && !getip46(46, s+1, (struct sockaddr *)&radiuslist[nradservers].localaddr)) return 2;
if(!*SAPORT(&radiuslist[nradservers].authaddr))*SAPORT(&radiuslist[nradservers].authaddr) = htons(1812);
port = ntohs(*SAPORT(&radiuslist[nradservers].authaddr));
radiuslist[nradservers].logaddr = radiuslist[nradservers].authaddr;
*SAPORT(&radiuslist[nradservers].logaddr) = htons(port+1);
/*
- bindaddr = conf.intsa;
+ bindaddr = radiuslist[nradservers].localaddr;
if ((radiuslist[nradservers].logsock = so._socket(SASOCK(&radiuslist[nradservers].logaddr), SOCK_DGRAM, 0)) < 0) return 2;
if (so._bind(radiuslist[nradservers].logsock, (struct sockaddr *)&bindaddr, SASIZE(&bindaddr))) return 3;
*/
@@ -1343,7 +1281,7 @@ static int h_radius(int argc, unsigned char **argv){
return 0;
}
#endif
-static int h_authcache(int argc, unsigned char **argv){
+static int h_authcache(int argc, char **argv){
conf.authcachetype = 0;
if(strstr((char *) *(argv + 1), "ip")) conf.authcachetype |= 1;
if(strstr((char *) *(argv + 1), "user")) conf.authcachetype |= 2;
@@ -1357,7 +1295,7 @@ static int h_authcache(int argc, unsigned char **argv){
return 0;
}
-static int h_plugin(int argc, unsigned char **argv){
+static int h_plugin(int argc, char **argv){
#ifdef NOPLUGINS
return 999;
#else
@@ -1397,7 +1335,7 @@ static int h_plugin(int argc, unsigned char **argv){
#ifndef _WIN32
-uid_t strtouid(unsigned char *str){
+uid_t strtouid(char *str){
uid_t res = 0;
if(!isnumber(*(char *)str)){
@@ -1410,7 +1348,7 @@ uid_t strtouid(unsigned char *str){
}
-static int h_setuid(int argc, unsigned char **argv){
+static int h_setuid(int argc, char **argv){
uid_t res = 0;
res = strtouid(argv[1]);
if(!res || setreuid(res,res)) {
@@ -1420,7 +1358,7 @@ static int h_setuid(int argc, unsigned char **argv){
return 0;
}
-gid_t strtogid(unsigned char *str){
+gid_t strtogid(char *str){
gid_t res = 0;
if(!isnumber(*(char *)str)){
@@ -1432,7 +1370,7 @@ gid_t strtogid(unsigned char *str){
return res;
}
-static int h_setgid(int argc, unsigned char **argv){
+static int h_setgid(int argc, char **argv){
gid_t res = 0;
res = strtogid(argv[1]);
@@ -1444,7 +1382,7 @@ static int h_setgid(int argc, unsigned char **argv){
}
-static int h_chroot(int argc, unsigned char **argv){
+static int h_chroot(int argc, char **argv){
uid_t uid = 0;
gid_t gid = 0;
if(argc > 2) {
@@ -1473,16 +1411,20 @@ static int h_chroot(int argc, unsigned char **argv){
*p = 0;
}
chrootp = mystrdup((char *)argv[1]);
+ if(!chrootp) return 21;
}
- if (gid && setregid(gid,gid)) {
+ if(gid && setregid(gid,gid)) {
fprintf(stderr, "Unable to set gid %d", (int)gid);
return(4);
}
- if (uid && setreuid(uid,uid)) {
+ if(uid && setreuid(uid,uid)) {
fprintf(stderr, "Unable to set uid %d", (int)uid);
return(5);
}
- chdir("/");
+ if(chdir("/")){
+ fprintf(stderr, "Unable to chdir to /");
+ return(5);
+ }
return 0;
}
#endif
@@ -1520,7 +1462,7 @@ struct commands commandhandlers[]={
{commandhandlers+20, "logformat", h_logformat, 2, 2},
{commandhandlers+21, "timeouts", h_timeouts, 2, 0},
{commandhandlers+22, "auth", h_auth, 2, 0},
- {commandhandlers+23, "users", h_users, 2, 0},
+ {commandhandlers+23, "users", h_users, 1, 0},
{commandhandlers+24, "maxconn", h_maxconn, 2, 2},
{commandhandlers+25, "flush", h_flush, 1, 1},
{commandhandlers+26, "nserver", h_nserver, 2, 2},
@@ -1528,51 +1470,53 @@ struct commands commandhandlers[]={
{commandhandlers+28, "nscache", h_nscache, 2, 2},
{commandhandlers+29, "nscache6", h_nscache6, 2, 2},
{commandhandlers+30, "nsrecord", h_nsrecord, 3, 3},
- {commandhandlers+31, "dialer", h_dialer, 2, 2},
- {commandhandlers+32, "system", h_system, 2, 2},
- {commandhandlers+33, "pidfile", h_pidfile, 2, 2},
- {commandhandlers+34, "monitor", h_monitor, 2, 2},
- {commandhandlers+35, "parent", h_parent, 5, 0},
- {commandhandlers+36, "allow", h_ace, 1, 0},
- {commandhandlers+37, "deny", h_ace, 1, 0},
- {commandhandlers+38, "redirect", h_ace, 3, 0},
- {commandhandlers+39, "bandlimin", h_ace, 2, 0},
- {commandhandlers+40, "bandlimout", h_ace, 2, 0},
- {commandhandlers+41, "nobandlimin", h_ace, 1, 0},
- {commandhandlers+42, "nobandlimout", h_ace, 1, 0},
- {commandhandlers+43, "countin", h_ace, 4, 0},
- {commandhandlers+44, "nocountin", h_ace, 1, 0},
- {commandhandlers+45, "countout", h_ace, 4, 0},
- {commandhandlers+46, "nocountout", h_ace, 1, 0},
- {commandhandlers+47, "connlim", h_ace, 4, 0},
- {commandhandlers+48, "noconnlim", h_ace, 1, 0},
- {commandhandlers+49, "plugin", h_plugin, 3, 0},
- {commandhandlers+50, "logdump", h_logdump, 2, 3},
- {commandhandlers+51, "filtermaxsize", h_filtermaxsize, 2, 2},
- {commandhandlers+52, "nolog", h_nolog, 1, 1},
- {commandhandlers+53, "weight", h_nolog, 2, 2},
- {commandhandlers+54, "authcache", h_authcache, 2, 3},
- {commandhandlers+55, "smtpp", h_proxy, 1, 0},
- {commandhandlers+56, "delimchar",h_delimchar, 2, 2},
- {commandhandlers+57, "authnserver", h_authnserver, 2, 2},
- {commandhandlers+58, "stacksize", h_stacksize, 2, 2},
- {commandhandlers+59, "force", h_force, 1, 1},
- {commandhandlers+60, "noforce", h_noforce, 1, 1},
+ {commandhandlers+31, "system", h_system, 2, 2},
+ {commandhandlers+32, "pidfile", h_pidfile, 2, 2},
+ {commandhandlers+33, "monitor", h_monitor, 2, 2},
+ {commandhandlers+34, "parent", h_parent, 5, 0},
+ {commandhandlers+35, "allow", h_ace, 1, 0},
+ {commandhandlers+36, "deny", h_ace, 1, 0},
+ {commandhandlers+37, "redirect", h_ace, 3, 0},
+ {commandhandlers+38, "bandlimin", h_ace, 2, 0},
+ {commandhandlers+39, "bandlimout", h_ace, 2, 0},
+ {commandhandlers+40, "nobandlimin", h_ace, 1, 0},
+ {commandhandlers+41, "nobandlimout", h_ace, 1, 0},
+ {commandhandlers+42, "countin", h_ace, 4, 0},
+ {commandhandlers+43, "nocountin", h_ace, 1, 0},
+ {commandhandlers+44, "countout", h_ace, 4, 0},
+ {commandhandlers+45, "nocountout", h_ace, 1, 0},
+ {commandhandlers+46, "countall", h_ace, 4, 0},
+ {commandhandlers+47, "nocountall", h_ace, 1, 0},
+ {commandhandlers+48, "connlim", h_ace, 4, 0},
+ {commandhandlers+49, "noconnlim", h_ace, 1, 0},
+ {commandhandlers+50, "plugin", h_plugin, 3, 0},
+ {commandhandlers+51, "logdump", h_logdump, 2, 3},
+ {commandhandlers+52, "filtermaxsize", h_filtermaxsize, 2, 2},
+ {commandhandlers+53, "nolog", h_nolog, 1, 1},
+ {commandhandlers+54, "weight", h_nolog, 2, 2},
+ {commandhandlers+55, "authcache", h_authcache, 2, 3},
+ {commandhandlers+56, "smtpp", h_proxy, 1, 0},
+ {commandhandlers+57, "delimchar",h_delimchar, 2, 2},
+ {commandhandlers+58, "authnserver", h_authnserver, 2, 2},
+ {commandhandlers+59, "stacksize", h_stacksize, 2, 2},
+ {commandhandlers+60, "force", h_force, 1, 1},
+ {commandhandlers+61, "noforce", h_noforce, 1, 1},
+ {commandhandlers+62, "parentretries", h_parentretries, 2, 2},
#ifndef NORADIUS
- {commandhandlers+61, "radius", h_radius, 3, 0},
+ {commandhandlers+63, "radius", h_radius, 3, 0},
#endif
{specificcommands, "", h_noop, 1, 0}
};
-int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned char ** buff, int *inbuf, int *bufsize){
+int parsestr (char *str, char **argm, int nitems, char ** buff, int *inbuf, int *bufsize){
#define buf (*buff)
int argc = 0;
int space = 1;
int comment = 0;
- unsigned char * incbegin = 0;
+ char * incbegin = 0;
int fd;
int res, len;
- unsigned char *str1;
+ char *str1;
for(;;str++){
if(*str == '\"'){
@@ -1662,15 +1606,15 @@ int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned cha
int readconfig(FILE * fp){
- unsigned char ** argv = NULL;
- unsigned char * buf = NULL;
+ char ** argv = NULL;
+ char * buf = NULL;
int bufsize = STRINGBUF*2;
int inbuf = 0;
int argc;
struct commands * cm;
int res = 0;
- if( !(buf = myalloc(bufsize)) || ! (argv = myalloc((NPARAMS + 1) * sizeof(unsigned char *))) ) {
+ if( !(buf = myalloc(bufsize)) || ! (argv = myalloc((NPARAMS + 1) * sizeof(char *))) ) {
fprintf(stderr, "No memory for configuration");
return(10);
}
@@ -1681,7 +1625,7 @@ int readconfig(FILE * fp){
argc = parsestr (buf, argv, NPARAMS-1, &buf, &inbuf, &bufsize);
if(argc < 1) {
fprintf(stderr, "Parse error line %d\n", linenum);
- return(21);
+ return(11);
}
argv[argc] = NULL;
if(!strcmp((char *)argv[0], "end") && argc == 1) {
@@ -1738,9 +1682,9 @@ void freeconf(struct extparam *confp){
struct ace *acl;
struct filemon *fm;
int counterd, archiverc;
- unsigned char *logname, *logtarget;
- unsigned char **archiver;
- unsigned char * logformat;
+ char *logtarget;
+ char **archiver;
+ char * logformat;
int i;
@@ -1762,6 +1706,7 @@ void freeconf(struct extparam *confp){
confp->bandlimiter = NULL;
confp->bandlimiterout = NULL;
confp->bandlimfunc = NULL;
+ confp->bandlimver++;
pthread_mutex_unlock(&bandlim_mutex);
pthread_mutex_lock(&connlim_mutex);
cl = confp->connlimiter;
@@ -1774,18 +1719,13 @@ void freeconf(struct extparam *confp){
pthread_mutex_unlock(&pwl_mutex);
-/*
logtarget = confp->logtarget;
confp->logtarget = NULL;
- logname = confp->logname;
- confp->logname = NULL;
-*/
- confp->logfunc = lognone;
logformat = confp->logformat;
confp->logformat = NULL;
confp->rotate = 0;
confp->logtype = NONE;
- confp->logtime = confp->time = 0;
+ confp->time = 0;
archiverc = confp->archiverc;
confp->archiverc = 0;
@@ -1812,7 +1752,7 @@ void freeconf(struct extparam *confp){
{
char * args[] = {"auth", "iponly", NULL};
- h_auth(2, (unsigned char **)args);
+ h_auth(2, (char **)args);
}
if(tc)dumpcounters(tc,counterd);
for(; tc; tc = (struct trafcount *) itfree(tc, tc->next)){
@@ -1833,22 +1773,12 @@ void freeconf(struct extparam *confp){
for(; fm; fm = (struct filemon *)itfree(fm, fm->next)){
if(fm->path) myfree(fm->path);
}
-/*
- if(logtarget) {
- myfree(logtarget);
- }
- if(logname) {
- myfree(logname);
- }
-*/
- if(logformat) {
- myfree(logformat);
- }
+ myfree(logtarget);
+ myfree(logformat);
if(archiver) {
for(i = 0; i < archiverc; i++) myfree(archiver[i]);
myfree(archiver);
}
- havelog = 0;
}
int reload (void){
diff --git a/src/datatypes.c b/src/datatypes.c
index 66132997..af7ded1b 100644
--- a/src/datatypes.c
+++ b/src/datatypes.c
@@ -9,7 +9,7 @@
static void pr_unsigned64(struct node *node, CBFUNC cbf, void*cb){
char buf[32];
- if(node->value)(*cbf)(cb, buf, sprintf(buf, "%"PRINTF_INT64_MODIFIER"u", *(uint64_t *)node->value));
+ if(node->value)(*cbf)(cb, buf, sprintf(buf, "%"PRIu64, *(uint64_t *)node->value));
}
static void pr_integer(struct node *node, CBFUNC cbf, void*cb){
@@ -77,7 +77,7 @@ static void pr_sa(struct node *node, CBFUNC cbf, void*cb){
buf[1] = 0;
inet_ntop(*SAFAMILY(node->value), SAADDR(node->value), buf+1, sizeof(buf)-10);
sprintf(buf + strlen(buf), "]:%hu", (unsigned short)*SAPORT(node->value));
- if(node->value)(*cbf)(cb, buf, strlen(buf));
+ if(node->value)(*cbf)(cb, buf, (int)strlen(buf));
#endif
}
@@ -365,32 +365,11 @@ static void * ef_ace_next(struct node * node){
return ((struct ace *)node->value) -> next;
}
+
+char * aceaction (int action);
+
static void * ef_ace_type(struct node * node){
- switch (((struct ace *)node->value) -> action) {
- case ALLOW:
- case REDIRECT:
- return "allow";
- case DENY:
- return "deny";
- case BANDLIM:
- return "bandlim";
- case NOBANDLIM:
- return "nobandlim";
- case COUNTIN:
- return "countin";
- case NOCOUNTIN:
- return "nocountin";
- case COUNTOUT:
- return "countout";
- case NOCOUNTOUT:
- return "nocountout";
- case COUNTALL:
- return "countall";
- case NOCOUNTALL:
- return "nocountall";
- default:
- return "unknown";
- }
+ return aceaction(((struct ace *)node->value) -> action);
}
@@ -523,19 +502,8 @@ static void * ef_server_childcount(struct node * node){
}
static void * ef_server_log(struct node * node){
- if(((struct srvparam *)node->value) -> logfunc == lognone) return "none";
-#ifndef NORADIUS
- else if(((struct srvparam *)node->value) -> logfunc == logradius) return "radius";
-#endif
- else if(((struct srvparam *)node->value) -> logfunc == logstdout)
- return (((struct srvparam *)node->value) -> logtarget)?"file":"stdout";
-#ifndef _WIN32
- else if(((struct srvparam *)node->value) -> logfunc == logsyslog) return "syslog";
-#endif
-#ifndef NOODBC
- else if(((struct srvparam *)node->value) -> logfunc == logsql) return "odbc";
-#endif
- return NULL;
+ if(((struct srvparam *)node->value) -> log == NULL) return "none";
+ return ((struct srvparam *)node->value) -> log -> selector;
}
static void * ef_server_logformat(struct node * node){
@@ -551,11 +519,6 @@ static void * ef_server_replacement(struct node * node){
return NULL;
}
-static void * ef_server_logtarget(struct node * node){
- return ((struct srvparam *)node->value) -> logtarget;
-}
-
-
static void * ef_server_target(struct node * node){
return ((struct srvparam *)node->value) -> target;
}
@@ -763,18 +726,17 @@ static struct property prop_server[] = {
{prop_server + 7, "singlepacket", ef_server_singlepacket, TYPE_INTEGER, "is single packet redirection"},
{prop_server + 8, "usentlm", ef_server_usentlm, TYPE_INTEGER, "allow NTLM authentication"},
{prop_server + 9, "log", ef_server_log, TYPE_STRING, "type of logging"},
- {prop_server + 10, "logtarget", ef_server_logtarget, TYPE_STRING, "log target options"},
- {prop_server + 11, "logformat", ef_server_logformat, TYPE_STRING, "logging format string"},
- {prop_server + 12, "nonprintable", ef_server_nonprintable, TYPE_STRING, "non printable characters"},
- {prop_server + 13, "replacement", ef_server_replacement, TYPE_CHAR, "replacement character"},
- {prop_server + 14, "childcount", ef_server_childcount, TYPE_INTEGER, "number of servers connected"},
- {prop_server + 15, "intsa", ef_server_intsa, TYPE_SA, "ip address of internal interface"},
- {prop_server + 16, "extsa", ef_server_extsa, TYPE_SA, "ip address of external interface"},
+ {prop_server + 10, "logformat", ef_server_logformat, TYPE_STRING, "logging format string"},
+ {prop_server + 11, "nonprintable", ef_server_nonprintable, TYPE_STRING, "non printable characters"},
+ {prop_server + 12, "replacement", ef_server_replacement, TYPE_CHAR, "replacement character"},
+ {prop_server + 13, "childcount", ef_server_childcount, TYPE_INTEGER, "number of servers connected"},
+ {prop_server + 14, "intsa", ef_server_intsa, TYPE_SA, "ip address of internal interface"},
+ {prop_server + 15, "extsa", ef_server_extsa, TYPE_SA, "ip address of external interface"},
#ifndef NOIPV6
- {prop_server + 17, "extsa6", ef_server_extsa6, TYPE_SA, "ipv6 address of external interface"},
- {prop_server + 18, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
-#else
+ {prop_server + 16, "extsa6", ef_server_extsa6, TYPE_SA, "ipv6 address of external interface"},
{prop_server + 17, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
+#else
+ {prop_server + 16, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
#endif
{NULL, "next", ef_server_next, TYPE_SERVER, "next"}
};
diff --git a/src/dnspr.c b/src/dnspr.c
index bdf2e614..6a7ef073 100644
--- a/src/dnspr.c
+++ b/src/dnspr.c
@@ -27,7 +27,7 @@ void * dnsprchild(struct clientparam* param) {
int len;
unsigned type=0;
unsigned ttl;
- unsigned char addr[16];
+ char addr[16];
#ifdef _WIN32
unsigned long ul = 1;
#endif
@@ -83,7 +83,7 @@ void * dnsprchild(struct clientparam* param) {
type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2];
if((type==0x01 || type==0x1c) && !param->srv->singlepacket){
- ip = udpresolve((type==0x1c)?AF_INET6:AF_INET, (unsigned char *)host, addr, &ttl, param, 0);
+ ip = udpresolve((type==0x1c)?AF_INET6:AF_INET, host, addr, &ttl, param, 0);
}
len+=5;
@@ -153,12 +153,12 @@ void * dnsprchild(struct clientparam* param) {
#endif
}
- if(socksendto(param->remsock, (struct sockaddr *)¶m->sinsr, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){
+ if(socksendto(param->remsock, (struct sockaddr *)¶m->sinsr, (char *)buf, i, conf.timeouts[SINGLEBYTE_L]*1000, NULL, 0) != i){
RETURN(820);
}
param->statscli64 += i;
param->nwrites++;
- len = sockrecvfrom(param->remsock, (struct sockaddr *)¶m->sinsr, buf, BUFSIZE, conf.timeouts[DNS_TO]*1000);
+ len = sockrecvfrom(param->remsock, (struct sockaddr *)¶m->sinsr, (char *)buf, BUFSIZE, conf.timeouts[DNS_TO]*1000, NULL, 0);
if(len <= 13) {
RETURN(821);
}
@@ -170,11 +170,11 @@ void * dnsprchild(struct clientparam* param) {
if(us > 4096) RETURN(833);
buf += 2;
len -= 2;
- if(len < us) len += sockgetlinebuf(param, SERVER, buf+len, us - len, 0, conf.timeouts[SINGLEBYTE_L]);
+ if(len < us) len += sockgetlinebuf(param, SERVER, (char *)buf+len, us - len, 0, conf.timeouts[SINGLEBYTE_L]);
if(len != us) RETURN(832);
}
if(buf[6] || buf[7]){
- if(socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
+ if(socksendto(param->clisock, (struct sockaddr *)¶m->sincr, (char *)buf, len, conf.timeouts[SINGLEBYTE_L]*1000, NULL, 0) != len){
RETURN(822);
}
RETURN(0);
@@ -185,7 +185,7 @@ void * dnsprchild(struct clientparam* param) {
buf[2] = 0x85;
buf[3] = 0x83;
}
- res = socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000);
+ res = socksendto(param->clisock, (struct sockaddr *)¶m->sincr, (char *)buf, len, conf.timeouts[SINGLEBYTE_L]*1000, NULL, 0);
if(res != len){RETURN(819);}
if(!ip) {RETURN(888);}
@@ -198,7 +198,7 @@ void * dnsprchild(struct clientparam* param) {
if((ip && type == 0x01) || type == 0x1c){
myinet_ntop(type == 0x01? AF_INET:AF_INET6, addr, (char *)buf+strlen((char *)buf), 64);
}
- dolog(param, buf);
+ dolog(param, (char *)buf);
}
if(bbuf)myfree(bbuf);
if(host)myfree(host);
diff --git a/src/ftp.c b/src/ftp.c
index 6f6931c0..b964c7d2 100644
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -20,7 +20,7 @@ int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) {
if(innbuf)*innbuf = 0;
if(len < 140) return 707;
- while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
+ while((i = sockgetlinebuf(param, SERVER, (char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
if(i < 3) return 706;
buf[i] = 0;
@@ -28,13 +28,13 @@ int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) {
*innbuf = i;
return 702;
}
- sprintf(buf, "USER %.128s\r\n", param->extusername?param->extusername:(unsigned char *)"anonymous");
- if((int)socksend(param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
+ sprintf(buf, "USER %.128s\r\n", param->extusername?param->extusername:(char *)"anonymous");
+ if((int)socksend(param->remsock, (char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
return 703;
}
param->statscli64 += (int)strlen(buf);
param->nwrites++;
- while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
+ while((i = sockgetlinebuf(param, SERVER, (char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
if(i < 3) return 704;
buf[i] = 0;
@@ -43,15 +43,15 @@ int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) {
sprintf(buf, "PASS %.128s\r\n",
param->extusername?
(param->extpassword?
- param->extpassword:(unsigned char *)"")
- :(unsigned char *)"3proxy@");
+ param->extpassword:(char *)"")
+ :(char *)"3proxy@");
res = (int)strlen(buf);
- if((int)socksend(param->remsock, (unsigned char *)buf, res, conf.timeouts[STRING_S]) != (int)strlen(buf)){
+ if((int)socksend(param->remsock, (char *)buf, res, conf.timeouts[STRING_S]) != (int)strlen(buf)){
return 705;
}
param->statscli64 += res;
param->nwrites++;
- while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0){
+ while((i = sockgetlinebuf(param, SERVER, (char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0){
buf[i] = 0;
res = (i>3 && buf[3] != '-')? atoi(buf)/100 : 0;
if(res || (nbuf && (len-i) > 256 && i > 3)) {
@@ -71,18 +71,18 @@ int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) {
return 0;
}
-int ftpcd(struct clientparam *param, unsigned char* path, char *nbuf, int *innbuf){
+int ftpcd(struct clientparam *param, char* path, char *nbuf, int *innbuf){
char buf[1024];
int i;
int inbuf = 0;
sprintf(buf, "CWD %.512s\r\n", path);
- if((int)socksend(param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
+ if((int)socksend(param->remsock, (char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
return 711;
}
param->statscli64 += (int)strlen(buf);
param->nwrites++;
- while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
+ while((i = sockgetlinebuf(param, SERVER, (char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
if(nbuf && innbuf && inbuf + i < *innbuf && i > 6) {
memcpy(nbuf + inbuf, buf, i);
inbuf += i;
@@ -95,7 +95,7 @@ int ftpcd(struct clientparam *param, unsigned char* path, char *nbuf, int *innbu
return 0;
}
-int ftpres(struct clientparam *param, unsigned char * buf, int l){
+int ftpres(struct clientparam *param, char * buf, int l){
int i;
if (l < 16) return 755;
@@ -107,10 +107,10 @@ int ftpres(struct clientparam *param, unsigned char * buf, int l){
return 0;
}
-int ftpsyst(struct clientparam *param, unsigned char *buf, unsigned len){
+int ftpsyst(struct clientparam *param, char *buf, unsigned len){
int i;
- if(socksend(param->remsock, (unsigned char *)"SYST\r\n", 6, conf.timeouts[STRING_S]) != 6){
+ if(socksend(param->remsock, (char *)"SYST\r\n", 6, conf.timeouts[STRING_S]) != 6){
return 721;
}
param->statscli64 += 6;
@@ -125,11 +125,11 @@ int ftpsyst(struct clientparam *param, unsigned char *buf, unsigned len){
return 0;
}
-int ftppwd(struct clientparam *param, unsigned char *buf, unsigned len){
+int ftppwd(struct clientparam *param, char *buf, unsigned len){
int i;
char *b, *e;
- if(socksend(param->remsock, (unsigned char *)"PWD\r\n", 5, conf.timeouts[STRING_S]) != 5){
+ if(socksend(param->remsock, (char *)"PWD\r\n", 5, conf.timeouts[STRING_S]) != 5){
return 731;
}
param->statscli64 += 5;
@@ -149,17 +149,17 @@ int ftppwd(struct clientparam *param, unsigned char *buf, unsigned len){
return 0;
}
-int ftptype(struct clientparam *param, unsigned char* f_type){
+int ftptype(struct clientparam *param, char* f_type){
char buf[1024];
int i;
sprintf(buf, "TYPE %.512s\r\n", f_type);
- if((int)socksend(param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
+ if((int)socksend(param->remsock, (char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
return 741;
}
param->statscli64 += (int)strlen(buf);
param->nwrites++;
- while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
+ while((i = sockgetlinebuf(param, SERVER, (char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
if(i < 3) return 742;
if(buf[0] != '2') return 740;
@@ -176,12 +176,12 @@ SOCKET ftpdata(struct clientparam *param){
unsigned short b5, b6;
SASIZETYPE sasize;
- if(socksend(param->remsock, (unsigned char *)"PASV\r\n", 6, conf.timeouts[STRING_S]) != 6){
+ if(socksend(param->remsock, (char *)"PASV\r\n", 6, conf.timeouts[STRING_S]) != 6){
return INVALID_SOCKET;
}
param->statscli64 += 6;
param->nwrites++;
- while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
+ while((i = sockgetlinebuf(param, SERVER, (char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
if(i < 7) return INVALID_SOCKET;
if(buf[0] != '2') return INVALID_SOCKET;
@@ -216,7 +216,7 @@ SOCKET ftpdata(struct clientparam *param){
return s;
}
-SOCKET ftpcommand(struct clientparam *param, unsigned char * command, unsigned char *arg) {
+SOCKET ftpcommand(struct clientparam *param, char * command, char *arg) {
char buf[1024];
int i;
SOCKET s;
@@ -225,15 +225,15 @@ SOCKET ftpcommand(struct clientparam *param, unsigned char * command, unsigned c
s = ftpdata(param);
if(s==INVALID_SOCKET) return INVALID_SOCKET;
sprintf(buf, "%.15s%s%.512s\r\n", command, arg?
- (unsigned char *)" ":(unsigned char *)"",
- arg?arg:(unsigned char *)"");
- if((int)socksend(param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
+ " ":"",
+ arg?arg:"");
+ if((int)socksend(param->remsock, buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
so._closesocket(s);
return INVALID_SOCKET;
}
param->statscli64 += (int)strlen(buf);
param->nwrites++;
- while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
+ while((i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
if(i < 3) {
so._closesocket(s);
diff --git a/src/ftppr.c b/src/ftppr.c
index 71eb8cc6..7a804f16 100644
--- a/src/ftppr.c
+++ b/src/ftppr.c
@@ -13,8 +13,8 @@
void * ftpprchild(struct clientparam* param) {
int i=0, res;
- unsigned char *buf;
- unsigned char *se;
+ char *buf;
+ char *se;
int status = 0;
int inbuf;
int pasv = 0;
@@ -29,7 +29,7 @@ void * ftpprchild(struct clientparam* param) {
param->operation = CONNECT;
lg.l_onoff = 1;
lg.l_linger = conf.timeouts[STRING_L];;
- if(socksend(param->ctrlsock, (unsigned char *)"220 Ready\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (801);}
+ if(socksend(param->ctrlsock, (char *)"220 Ready\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (801);}
for(;;){
i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 10, '\n', conf.timeouts[CONNECTION_S]);
if(!i) {
@@ -37,7 +37,7 @@ void * ftpprchild(struct clientparam* param) {
}
if(i<4) {RETURN(802);}
buf[i] = 0;
- if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0;
+ if ((se=(char *)strchr((char *)buf, '\r'))) *se = 0;
if (req) myfree (req);
req = NULL;
@@ -50,7 +50,7 @@ void * ftpprchild(struct clientparam* param) {
}
if((res = (*param->srv->authfunc)(param))) {RETURN(res);}
param->ctrlsocksrv = param->remsock;
- if(socksend(param->ctrlsock, (unsigned char *)"220 Ready\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (801);}
+ if(socksend(param->ctrlsock, (char *)"220 Ready\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (801);}
status = 1;
}
else if (!strncasecmp((char *)buf, "USER ", 5)){
@@ -59,12 +59,12 @@ void * ftpprchild(struct clientparam* param) {
if((res = (*param->srv->authfunc)(param))) {RETURN(res);}
param->ctrlsocksrv = param->remsock;
}
- if(socksend(param->ctrlsock, (unsigned char *)"331 ok\r\n", 8, conf.timeouts[STRING_S])!=8) {RETURN (807);}
+ if(socksend(param->ctrlsock, (char *)"331 ok\r\n", 8, conf.timeouts[STRING_S])!=8) {RETURN (807);}
status = 2;
}
else if (!strncasecmp((char *)buf, "PASS ", 5)){
- param->extpassword = (unsigned char *)mystrdup((char *)buf+5);
+ param->extpassword = (char *)mystrdup((char *)buf+5);
inbuf = BUFSIZE;
res = ftplogin(param, (char *)buf, &inbuf);
param->res = res;
@@ -129,16 +129,16 @@ void * ftpprchild(struct clientparam* param) {
if(pasv == 1){
if(*SAFAMILY(¶m->sincl) == AF_INET)
sprintf((char *)buf, "227 OK (%u,%u,%u,%u,%u,%u)\r\n",
- (unsigned)(((unsigned char *)(SAADDR(¶m->sincl)))[0]),
- (unsigned)(((unsigned char *)(SAADDR(¶m->sincl)))[1]),
- (unsigned)(((unsigned char *)(SAADDR(¶m->sincl)))[2]),
- (unsigned)(((unsigned char *)(SAADDR(¶m->sincl)))[3]),
- (unsigned)(((unsigned char *)(SAPORT(¶m->sincl)))[0]),
- (unsigned)(((unsigned char *)(SAPORT(¶m->sincl)))[1])
+ (unsigned)(((char *)(SAADDR(¶m->sincl)))[0]),
+ (unsigned)(((char *)(SAADDR(¶m->sincl)))[1]),
+ (unsigned)(((char *)(SAADDR(¶m->sincl)))[2]),
+ (unsigned)(((char *)(SAADDR(¶m->sincl)))[3]),
+ (unsigned)(((char *)(SAPORT(¶m->sincl)))[0]),
+ (unsigned)(((char *)(SAPORT(¶m->sincl)))[1])
);
else sprintf((char *)buf, "227 OK (127,0,0,1,%u,%u)\r\n",
- (unsigned)(((unsigned char *)(SAPORT(¶m->sincl)))[0]),
- (unsigned)(((unsigned char *)(SAPORT(¶m->sincl)))[1])
+ (unsigned)(((char *)(SAPORT(¶m->sincl)))[0]),
+ (unsigned)(((char *)(SAPORT(¶m->sincl)))[1])
);
}
else {
@@ -230,11 +230,11 @@ void * ftpprchild(struct clientparam* param) {
so._closesocket(clidatasock);
clidatasock = INVALID_SOCKET;
- if(socksend(param->ctrlsock, (unsigned char *)"550 err\r\n", 9, conf.timeouts[STRING_S])!=9) {RETURN (831);}
+ if(socksend(param->ctrlsock, (char *)"550 err\r\n", 9, conf.timeouts[STRING_S])!=9) {RETURN (831);}
continue;
}
- if(socksend(param->ctrlsock, (unsigned char *)"125 data\r\n", 10, conf.timeouts[STRING_S]) != 10) {
+ if(socksend(param->ctrlsock, (char *)"125 data\r\n", 10, conf.timeouts[STRING_S]) != 10) {
param->remsock = INVALID_SOCKET;
RETURN (832);
}
@@ -250,7 +250,10 @@ void * ftpprchild(struct clientparam* param) {
so._setsockopt(param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
so._setsockopt(clidatasock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
param->clisock = clidatasock;
+ param->monitorsock = ¶m->ctrlsock;
+ param->monaction = 0;
res = mapsocket(param, conf.timeouts[CONNECTION_S]);
+ param->monitorsock = NULL;
if(param->remsock != INVALID_SOCKET) {
so._shutdown (param->remsock, SHUT_RDWR);
so._closesocket(param->remsock);
@@ -274,7 +277,7 @@ void * ftpprchild(struct clientparam* param) {
}
else {
if(status < 3) {
- if(socksend(param->remsock, (unsigned char *)"530 login\r\n", 11, conf.timeouts[STRING_S])!=1) {RETURN (810);}
+ if(socksend(param->remsock, (char *)"530 login\r\n", 11, conf.timeouts[STRING_S])!=1) {RETURN (810);}
continue;
}
if(!strncasecmp((char *)buf, "QUIT", 4)) status = 5;
@@ -295,7 +298,7 @@ void * ftpprchild(struct clientparam* param) {
sasize = sizeof(param->sincr);
if(so._getpeername(param->ctrlsock, (struct sockaddr *)¶m->sincr, &sasize)){RETURN(819);}
if(req && (param->statscli64 || param->statssrv64)){
- dolog(param, (unsigned char *)req);
+ dolog(param, (char *)req);
}
}
@@ -316,7 +319,7 @@ void * ftpprchild(struct clientparam* param) {
sasize = sizeof(param->sincr);
so._getpeername(param->ctrlsock, (struct sockaddr *)¶m->sincr, &sasize);
if(param->res != 0 || param->statscli64 || param->statssrv64 ){
- dolog(param, (unsigned char *)((req && (param->res > 802))? req:NULL));
+ dolog(param, (req && (param->res > 802))? req:NULL);
}
if(req) myfree(req);
if(buf) myfree(buf);
@@ -333,4 +336,5 @@ struct proxydef childdef = {
" -hdefault_host[:port] - use this host and port as default if no host specified\n"
};
#include "proxymain.c"
+#include "log.c"
#endif
diff --git a/src/libs/regex.c b/src/libs/regex.c
deleted file mode 100644
index 82ae70a0..00000000
--- a/src/libs/regex.c
+++ /dev/null
@@ -1,3821 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "regex.h"
-
-/* utility definitions */
-#ifdef _POSIX2_RE_DUP_MAX
-#define DUPMAX _POSIX2_RE_DUP_MAX
-#else
-#define DUPMAX 255
-#endif
-#define INFINITY (DUPMAX + 1)
-#define NC (CHAR_MAX - CHAR_MIN + 1)
-typedef unsigned char uch;
-
-/* for old systems with bcopy() but no memmove() */
-#ifdef USEBCOPY
-#define memmove(d, s, c) bcopy(s, d, c)
-#endif
-
-#define MAGIC1 ((('r'^0200)<<8) | 'e')
-
-/*
- * The internal representation is a *strip*, a sequence of
- * operators ending with an endmarker. (Some terminology etc. is a
- * historical relic of earlier versions which used multiple strips.)
- * Certain oddities in the representation are there to permit running
- * the machinery backwards; in particular, any deviation from sequential
- * flow must be marked at both its source and its destination. Some
- * fine points:
- *
- * - OPLUS_ and O_PLUS are *inside* the loop they create.
- * - OQUEST_ and O_QUEST are *outside* the bypass they create.
- * - OCH_ and O_CH are *outside* the multi-way branch they create, while
- * OOR1 and OOR2 are respectively the end and the beginning of one of
- * the branches. Note that there is an implicit OOR2 following OCH_
- * and an implicit OOR1 preceding O_CH.
- *
- * In state representations, an operator's bit is on to signify a state
- * immediately *preceding* "execution" of that operator.
- */
-typedef long sop; /* strip operator */
-typedef long sopno;
-#define OPRMASK 0x7c000000
-#define OPDMASK 0x03ffffff
-#define OPSHIFT (26)
-#define OP(n) ((n)&OPRMASK)
-#define OPND(n) ((n)&OPDMASK)
-#define SOP(op, opnd) ((op)|(opnd))
-/* operators meaning operand */
-/* (back, fwd are offsets) */
-#define OEND (1< uch [csetsize] */
- uch mask; /* bit within array */
- uch hash; /* hash code */
- size_t smultis;
- char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */
-} cset;
-/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */
-#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c))
-#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c))
-#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask)
-#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* regcomp() internal fns */
-
-/* stuff for character categories */
-typedef unsigned char cat_t;
-
-/*
- * main compiled-expression structure
- */
-struct re_guts {
- int magic;
-# define MAGIC2 ((('R'^0200)<<8)|'E')
- sop *strip; /* malloced area for strip */
- int csetsize; /* number of bits in a cset vector */
- int ncsets; /* number of csets in use */
- cset *sets; /* -> cset [ncsets] */
- uch *setbits; /* -> uch[csetsize][ncsets/CHAR_BIT] */
- int cflags; /* copy of regcomp() cflags argument */
- sopno nstates; /* = number of sops */
- sopno firststate; /* the initial OEND (normally 0) */
- sopno laststate; /* the final OEND */
- int iflags; /* internal flags */
-# define USEBOL 01 /* used ^ */
-# define USEEOL 02 /* used $ */
-# define BAD 04 /* something wrong */
- int nbol; /* number of ^ used */
- int neol; /* number of $ used */
- int ncategories; /* how many character categories */
- cat_t *categories; /* ->catspace[-CHAR_MIN] */
- char *must; /* match must contain this string */
- int mlen; /* length of must */
- size_t nsub; /* copy of re_nsub */
- int backrefs; /* does it use back references? */
- sopno nplus; /* how deep does it nest +s? */
- /* catspace must be last */
- cat_t catspace[1]; /* actually [NC] */
-};
-
-/* misc utilities */
-#define OUT (CHAR_MAX+1) /* a non-character value */
-#define ISWORD(c) (isalnum(c) || (c) == '_')
-
-
-/* character-class table */
-static struct cclass {
- char *name;
- char *chars;
- char *multis;
-} cclasses[] = {
- {"alnum","ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",""},
- {"alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", ""},
- {"blank"," \t", ""},
- {"cntrl","\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\177",""},
- {"digit","0123456789",""},
- {"graph","ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",""},
- {"lower","abcdefghijklmnopqrstuvwxyz",""},
- {"print","ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",""},
- {"punct","!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",""},
- {"space","\t\n\v\f\r ", ""},
- {"upper","ABCDEFGHIJKLMNOPQRSTUVWXYZ",""},
- {"xdigit","0123456789ABCDEFabcdef",""},
- {NULL,NULL,""}
-};
-
-/* character-name table */
-static struct cname {
- char *name;
- char code;
-} cnames[] = {
- {"NUL", '\0'},
- {"SOH", '\001'},
- {"STX", '\002'},
- {"ETX", '\003'},
- {"EOT", '\004'},
- {"ENQ", '\005'},
- {"ACK", '\006'},
- {"BEL", '\007'},
- {"alert", '\007'},
- {"BS", '\010'},
- {"backspace", '\b'},
- {"HT", '\011'},
- {"tab", '\t'},
- {"LF", '\012'},
- {"newline", '\n'},
- {"VT", '\013'},
- {"vertical-tab", '\v'},
- {"FF", '\014'},
- {"form-feed", '\f'},
- {"CR", '\015'},
- {"carriage-return", '\r'},
- {"SO", '\016'},
- {"SI", '\017'},
- {"DLE", '\020'},
- {"DC1", '\021'},
- {"DC2", '\022'},
- {"DC3", '\023'},
- {"DC4", '\024'},
- {"NAK", '\025'},
- {"SYN", '\026'},
- {"ETB", '\027'},
- {"CAN", '\030'},
- {"EM", '\031'},
- {"SUB", '\032'},
- {"ESC", '\033'},
- {"IS4", '\034'},
- {"FS", '\034'},
- {"IS3", '\035'},
- {"GS", '\035'},
- {"IS2", '\036'},
- {"RS", '\036'},
- {"IS1", '\037'},
- {"US", '\037'},
- {"space", ' '},
- {"exclamation-mark", '!'},
- {"quotation-mark", '"'},
- {"number-sign", '#'},
- {"dollar-sign", '$'},
- {"percent-sign", '%'},
- {"ampersand", '&'},
- {"apostrophe", '\''},
- {"left-parenthesis", '('},
- {"right-parenthesis", ')'},
- {"asterisk", '*'},
- {"plus-sign", '+'},
- {"comma", ','},
- {"hyphen", '-'},
- {"hyphen-minus", '-'},
- {"period", '.'},
- {"full-stop", '.'},
- {"slash", '/'},
- {"solidus", '/'},
- {"zero", '0'},
- {"one", '1'},
- {"two", '2'},
- {"three", '3'},
- {"four", '4'},
- {"five", '5'},
- {"six", '6'},
- {"seven", '7'},
- {"eight", '8'},
- {"nine", '9'},
- {"colon", ':'},
- {"semicolon", ';'},
- {"less-than-sign", '<'},
- {"equals-sign", '='},
- {"greater-than-sign", '>'},
- {"question-mark", '?'},
- {"commercial-at", '@'},
- {"left-square-bracket", '['},
- {"backslash", '\\'},
- {"reverse-solidus", '\\'},
- {"right-square-bracket", ']'},
- {"circumflex", '^'},
- {"circumflex-accent", '^'},
- {"underscore", '_'},
- {"low-line", '_'},
- {"grave-accent", '`'},
- {"left-brace", '{'},
- {"left-curly-bracket", '{'},
- {"vertical-line", '|'},
- {"right-brace", '}'},
- {"right-curly-bracket", '}'},
- {"tilde", '~'},
- {"DEL", '\177'},
- {NULL, 0}
-};
-
-
-/*
- * parse structure, passed up and down to avoid global variables and
- * other clumsinesses
- */
-struct parse {
- char *next; /* next character in RE */
- char *end; /* end of string (-> NUL normally) */
- int error; /* has an error been seen? */
- sop *strip; /* malloced strip */
- sopno ssize; /* malloced strip size (allocated) */
- sopno slen; /* malloced strip length (used) */
- int ncsalloc; /* number of csets allocated */
- struct re_guts *g;
-# define NPAREN 10 /* we need to remember () 1-9 for back refs */
- sopno pbegin[NPAREN]; /* -> ( ([0] unused) */
- sopno pend[NPAREN]; /* -> ) ([0] unused) */
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-static void p_ere(register struct parse *p, int stop);
-static void p_ere_exp(register struct parse *p);
-static void p_str(register struct parse *p);
-static void p_bre(register struct parse *p, register int end1, register int end2);
-static int p_simp_re(register struct parse *p, int starordinary);
-static int p_count(register struct parse *p);
-static void p_bracket(register struct parse *p);
-static void p_b_term(register struct parse *p, register cset *cs);
-static void p_b_cclass(register struct parse *p, register cset *cs);
-static void p_b_eclass(register struct parse *p, register cset *cs);
-static char p_b_symbol(register struct parse *p);
-static char p_b_coll_elem(register struct parse *p, int endc);
-static char othercase(int ch);
-static void bothcases(register struct parse *p, int ch);
-static void ordinary(register struct parse *p, register int ch);
-static void nonnewline(register struct parse *p);
-static void repeat(register struct parse *p, sopno start, int from, int to);
-static int seterr(register struct parse *p, int e);
-static cset *allocset(register struct parse *p);
-static void freeset(register struct parse *p, register cset *cs);
-static int freezeset(register struct parse *p, register cset *cs);
-static int firstch(register struct parse *p, register cset *cs);
-static int nch(register struct parse *p, register cset *cs);
-static void mcadd(register struct parse *p, register cset *cs, register char *cp);
-static void mcinvert(register struct parse *p, register cset *cs);
-static void mccase(register struct parse *p, register cset *cs);
-static int isinsets(register struct re_guts *g, int c);
-static int samesets(register struct re_guts *g, int c1, int c2);
-static void categorize(struct parse *p, register struct re_guts *g);
-static sopno dupl(register struct parse *p, sopno start, sopno finish);
-static void doemit(register struct parse *p, sop op, size_t opnd);
-static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos);
-static void dofwd(register struct parse *p, sopno pos, sop value);
-static void enlarge(register struct parse *p, sopno size);
-static void stripsnug(register struct parse *p, register struct re_guts *g);
-static void findmust(register struct parse *p, register struct re_guts *g);
-static sopno pluscount(register struct parse *p, register struct re_guts *g);
-
-#ifdef __cplusplus
-}
-#endif
-
-static char nuls[10]; /* place to point scanner in event of error */
-
-/*
- * macros for use with parse structure
- * BEWARE: these know that the parse structure is named `p' !!!
- */
-#define PEEK() (*p->next)
-#define PEEK2() (*(p->next+1))
-#define MORE() (p->next < p->end)
-#define MORE2() (p->next+1 < p->end)
-#define SEE(c) (MORE() && PEEK() == (c))
-#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b))
-#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0)
-#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
-#define NEXT() (p->next++)
-#define NEXT2() (p->next += 2)
-#define NEXTn(n) (p->next += (n))
-#define GETNEXT() (*p->next++)
-#define SETERROR(e) seterr(p, (e))
-#define REQUIRE(co, e) ((co) || SETERROR(e))
-#define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e))
-#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e))
-#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e))
-#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
-#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
-#define AHEAD(pos) dofwd(p, pos, HERE()-(pos))
-#define ASTERN(sop, pos) EMIT(sop, HERE()-pos)
-#define HERE() (p->slen)
-#define THERE() (p->slen - 1)
-#define THERETHERE() (p->slen - 2)
-#define DROP(n) (p->slen -= (n))
-
-#define never 0 /* some s have bugs too */
-
-int /* 0 success, otherwise REG_something */
-regcomp(preg, pattern, cflags)
-regex_t *preg;
-const char *pattern;
-int cflags;
-{
- struct parse pa;
- register struct re_guts *g;
- register struct parse *p = &pa;
- register int i;
- register size_t len;
-#define GOODFLAGS(f) ((f)&~REG_DUMP)
-
- cflags = GOODFLAGS(cflags);
- if ((cflags®_EXTENDED) && (cflags®_NOSPEC))
- return(REG_INVARG);
-
- if (cflags®_PEND) {
- if (preg->re_endp < pattern)
- return(REG_INVARG);
- len = preg->re_endp - pattern;
- } else
- len = strlen((char *)pattern);
-
- /* do the mallocs early so failure handling is easy */
- g = (struct re_guts *)malloc(sizeof(struct re_guts) +
- (NC-1)*sizeof(cat_t));
- if (g == NULL)
- return(REG_ESPACE);
- p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
- p->strip = (sop *)malloc(p->ssize * sizeof(sop));
- p->slen = 0;
- if (p->strip == NULL) {
- free((char *)g);
- return(REG_ESPACE);
- }
-
- /* set things up */
- p->g = g;
- p->next = (char *)pattern; /* convenience; we do not modify it */
- p->end = p->next + len;
- p->error = 0;
- p->ncsalloc = 0;
- for (i = 0; i < NPAREN; i++) {
- p->pbegin[i] = 0;
- p->pend[i] = 0;
- }
- g->csetsize = NC;
- g->sets = NULL;
- g->setbits = NULL;
- g->ncsets = 0;
- g->cflags = cflags;
- g->iflags = 0;
- g->nbol = 0;
- g->neol = 0;
- g->must = NULL;
- g->mlen = 0;
- g->nsub = 0;
- g->ncategories = 1; /* category 0 is "everything else" */
- g->categories = &g->catspace[-(CHAR_MIN)];
- (void) memset((char *)g->catspace, 0, NC*sizeof(cat_t));
- g->backrefs = 0;
-
- /* do it */
- EMIT(OEND, 0);
- g->firststate = THERE();
- if (cflags®_EXTENDED)
- p_ere(p, OUT);
- else if (cflags®_NOSPEC)
- p_str(p);
- else
- p_bre(p, OUT, OUT);
- EMIT(OEND, 0);
- g->laststate = THERE();
-
- /* tidy up loose ends and fill things in */
- categorize(p, g);
- stripsnug(p, g);
- findmust(p, g);
- g->nplus = pluscount(p, g);
- g->magic = MAGIC2;
- preg->re_nsub = g->nsub;
- preg->re_g = g;
- preg->re_magic = MAGIC1;
- /* not debugging, so can't rely on the assert() in regexec() */
- if (g->iflags&BAD)
- SETERROR(REG_ASSERT);
-
- /* win or lose, we're done */
- if (p->error != 0) /* lose */
- regfree(preg);
- return(p->error);
-#undef GOODFLAGS
-}
-
-/*
- - p_ere - ERE parser top level, concatenation and alternation
- == static void p_ere(register struct parse *p, int stop);
- */
-static void
-p_ere(p, stop)
-register struct parse *p;
-int stop; /* character this ERE should end at */
-{
- register char c;
- register sopno prevback;
- register sopno prevfwd;
- register sopno conc;
- register int first = 1; /* is this the first alternative? */
-
- for (;;) {
- /* do a bunch of concatenated expressions */
- conc = HERE();
- while (MORE() && (c = PEEK()) != '|' && c != stop)
- p_ere_exp(p);
- REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */
-
- if (!EAT('|'))
- break; /* NOTE BREAK OUT */
-
- if (first) {
- INSERT(OCH_, conc); /* offset is wrong */
- prevfwd = conc;
- prevback = conc;
- first = 0;
- }
- ASTERN(OOR1, prevback);
- prevback = THERE();
- AHEAD(prevfwd); /* fix previous offset */
- prevfwd = HERE();
- EMIT(OOR2, 0); /* offset is very wrong */
- }
-
- if (!first) { /* tail-end fixups */
- AHEAD(prevfwd);
- ASTERN(O_CH, prevback);
- }
-
- assert(!MORE() || SEE(stop));
-}
-
-/*
- - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
- == static void p_ere_exp(register struct parse *p);
- */
-static void
-p_ere_exp(p)
-register struct parse *p;
-{
- register char c;
- register sopno pos;
- register int count;
- register int count2;
- register sopno subno;
- int wascaret = 0;
-
- assert(MORE()); /* caller should have ensured this */
- c = GETNEXT();
-
- pos = HERE();
- switch (c) {
- case '(':
- REQUIRE(MORE(), REG_EPAREN);
- p->g->nsub++;
- subno = p->g->nsub;
- if (subno < NPAREN)
- p->pbegin[subno] = HERE();
- EMIT(OLPAREN, subno);
- if (!SEE(')'))
- p_ere(p, ')');
- if (subno < NPAREN) {
- p->pend[subno] = HERE();
- assert(p->pend[subno] != 0);
- }
- EMIT(ORPAREN, subno);
- MUSTEAT(')', REG_EPAREN);
- break;
- case '^':
- EMIT(OBOL, 0);
- p->g->iflags |= USEBOL;
- p->g->nbol++;
- wascaret = 1;
- break;
- case '$':
- EMIT(OEOL, 0);
- p->g->iflags |= USEEOL;
- p->g->neol++;
- break;
- case '|':
- SETERROR(REG_EMPTY);
- break;
- case '*':
- case '+':
- case '?':
- SETERROR(REG_BADRPT);
- break;
- case '.':
- if (p->g->cflags®_NEWLINE)
- nonnewline(p);
- else
- EMIT(OANY, 0);
- break;
- case '[':
- p_bracket(p);
- break;
- case '\\':
- REQUIRE(MORE(), REG_EESCAPE);
- c = GETNEXT();
- ordinary(p, c);
- break;
- case '{': /* okay as ordinary except if digit follows */
- REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT);
- /* FALLTHROUGH */
- default:
- ordinary(p, c);
- break;
- }
-
- if (!MORE())
- return;
- c = PEEK();
- /* we call { a repetition if followed by a digit */
- if (!( c == '*' || c == '+' || c == '?' ||
- (c == '{' && MORE2() && isdigit(PEEK2())) ))
- return; /* no repetition, we're done */
- NEXT();
-
- REQUIRE(!wascaret, REG_BADRPT);
- switch (c) {
- case '*': /* implemented as +? */
- /* this case does not require the (y|) trick, noKLUDGE */
- INSERT(OPLUS_, pos);
- ASTERN(O_PLUS, pos);
- INSERT(OQUEST_, pos);
- ASTERN(O_QUEST, pos);
- break;
- case '+':
- INSERT(OPLUS_, pos);
- ASTERN(O_PLUS, pos);
- break;
- case '?':
- /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
- INSERT(OCH_, pos); /* offset slightly wrong */
- ASTERN(OOR1, pos); /* this one's right */
- AHEAD(pos); /* fix the OCH_ */
- EMIT(OOR2, 0); /* offset very wrong... */
- AHEAD(THERE()); /* ...so fix it */
- ASTERN(O_CH, THERETHERE());
- break;
- case '{':
- count = p_count(p);
- if (EAT(',')) {
- if (isdigit(PEEK())) {
- count2 = p_count(p);
- REQUIRE(count <= count2, REG_BADBR);
- } else /* single number with comma */
- count2 = INFINITY;
- } else /* just a single number */
- count2 = count;
- repeat(p, pos, count, count2);
- if (!EAT('}')) { /* error heuristics */
- while (MORE() && PEEK() != '}')
- NEXT();
- REQUIRE(MORE(), REG_EBRACE);
- SETERROR(REG_BADBR);
- }
- break;
- }
-
- if (!MORE())
- return;
- c = PEEK();
- if (!( c == '*' || c == '+' || c == '?' ||
- (c == '{' && MORE2() && isdigit(PEEK2())) ) )
- return;
- SETERROR(REG_BADRPT);
-}
-
-/*
- - p_str - string (no metacharacters) "parser"
- == static void p_str(register struct parse *p);
- */
-static void
-p_str(p)
-register struct parse *p;
-{
- REQUIRE(MORE(), REG_EMPTY);
- while (MORE())
- ordinary(p, GETNEXT());
-}
-
-/*
- - p_bre - BRE parser top level, anchoring and concatenation
- == static void p_bre(register struct parse *p, register int end1, \
- == register int end2);
- * Giving end1 as OUT essentially eliminates the end1/end2 check.
- *
- * This implementation is a bit of a kludge, in that a trailing $ is first
- * taken as an ordinary character and then revised to be an anchor. The
- * only undesirable side effect is that '$' gets included as a character
- * category in such cases. This is fairly harmless; not worth fixing.
- * The amount of lookahead needed to avoid this kludge is excessive.
- */
-static void
-p_bre(p, end1, end2)
-register struct parse *p;
-register int end1; /* first terminating character */
-register int end2; /* second terminating character */
-{
- register sopno start = HERE();
- register int first = 1; /* first subexpression? */
- register int wasdollar = 0;
-
- if (EAT('^')) {
- EMIT(OBOL, 0);
- p->g->iflags |= USEBOL;
- p->g->nbol++;
- }
- while (MORE() && !SEETWO(end1, end2)) {
- wasdollar = p_simp_re(p, first);
- first = 0;
- }
- if (wasdollar) { /* oops, that was a trailing anchor */
- DROP(1);
- EMIT(OEOL, 0);
- p->g->iflags |= USEEOL;
- p->g->neol++;
- }
-
- REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */
-}
-
-/*
- - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
- == static int p_simp_re(register struct parse *p, int starordinary);
- */
-static int /* was the simple RE an unbackslashed $? */
-p_simp_re(p, starordinary)
-register struct parse *p;
-int starordinary; /* is a leading * an ordinary character? */
-{
- register int c;
- register int count;
- register int count2;
- register sopno pos;
- register int i;
- register sopno subno;
-# define BACKSL (1<g->cflags®_NEWLINE)
- nonnewline(p);
- else
- EMIT(OANY, 0);
- break;
- case '[':
- p_bracket(p);
- break;
- case BACKSL|'{':
- SETERROR(REG_BADRPT);
- break;
- case BACKSL|'(':
- p->g->nsub++;
- subno = p->g->nsub;
- if (subno < NPAREN)
- p->pbegin[subno] = HERE();
- EMIT(OLPAREN, subno);
- /* the MORE here is an error heuristic */
- if (MORE() && !SEETWO('\\', ')'))
- p_bre(p, '\\', ')');
- if (subno < NPAREN) {
- p->pend[subno] = HERE();
- assert(p->pend[subno] != 0);
- }
- EMIT(ORPAREN, subno);
- REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
- break;
- case BACKSL|')': /* should not get here -- must be user */
- case BACKSL|'}':
- SETERROR(REG_EPAREN);
- break;
- case BACKSL|'1':
- case BACKSL|'2':
- case BACKSL|'3':
- case BACKSL|'4':
- case BACKSL|'5':
- case BACKSL|'6':
- case BACKSL|'7':
- case BACKSL|'8':
- case BACKSL|'9':
- i = (c&~BACKSL) - '0';
- assert(i < NPAREN);
- if (p->pend[i] != 0) {
- assert(i <= p->g->nsub);
- EMIT(OBACK_, i);
- assert(p->pbegin[i] != 0);
- assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
- assert(OP(p->strip[p->pend[i]]) == ORPAREN);
- (void) dupl(p, p->pbegin[i]+1, p->pend[i]);
- EMIT(O_BACK, i);
- } else
- SETERROR(REG_ESUBREG);
- p->g->backrefs = 1;
- break;
- case '*':
- REQUIRE(starordinary, REG_BADRPT);
- /* FALLTHROUGH */
- default:
- ordinary(p, (char)c); /* takes off BACKSL, if any */
- break;
- }
-
- if (EAT('*')) { /* implemented as +? */
- /* this case does not require the (y|) trick, noKLUDGE */
- INSERT(OPLUS_, pos);
- ASTERN(O_PLUS, pos);
- INSERT(OQUEST_, pos);
- ASTERN(O_QUEST, pos);
- } else if (EATTWO('\\', '{')) {
- count = p_count(p);
- if (EAT(',')) {
- if (MORE() && isdigit(PEEK())) {
- count2 = p_count(p);
- REQUIRE(count <= count2, REG_BADBR);
- } else /* single number with comma */
- count2 = INFINITY;
- } else /* just a single number */
- count2 = count;
- repeat(p, pos, count, count2);
- if (!EATTWO('\\', '}')) { /* error heuristics */
- while (MORE() && !SEETWO('\\', '}'))
- NEXT();
- REQUIRE(MORE(), REG_EBRACE);
- SETERROR(REG_BADBR);
- }
- } else if (c == (unsigned char)'$') /* $ (but not \$) ends it */
- return(1);
-
- return(0);
-}
-
-/*
- - p_count - parse a repetition count
- == static int p_count(register struct parse *p);
- */
-static int /* the value */
-p_count(p)
-register struct parse *p;
-{
- register int count = 0;
- register int ndigits = 0;
-
- while (MORE() && isdigit(PEEK()) && count <= DUPMAX) {
- count = count*10 + (GETNEXT() - '0');
- ndigits++;
- }
-
- REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
- return(count);
-}
-
-/*
- - p_bracket - parse a bracketed character list
- == static void p_bracket(register struct parse *p);
- *
- * Note a significant property of this code: if the allocset() did SETERROR,
- * no set operations are done.
- */
-static void
-p_bracket(p)
-register struct parse *p;
-{
- register cset *cs = allocset(p);
- register int invert = 0;
-
- /* Dept of Truly Sickening Special-Case Kludges */
- if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
- EMIT(OBOW, 0);
- NEXTn(6);
- return;
- }
- if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) {
- EMIT(OEOW, 0);
- NEXTn(6);
- return;
- }
-
- if (EAT('^'))
- invert++; /* make note to invert set at end */
- if (EAT(']'))
- CHadd(cs, ']');
- else if (EAT('-'))
- CHadd(cs, '-');
- while (MORE() && PEEK() != ']' && !SEETWO('-', ']'))
- p_b_term(p, cs);
- if (EAT('-'))
- CHadd(cs, '-');
- MUSTEAT(']', REG_EBRACK);
-
- if (p->error != 0) /* don't mess things up further */
- return;
-
- if (p->g->cflags®_ICASE) {
- register int i;
- register int ci;
-
- for (i = p->g->csetsize - 1; i >= 0; i--)
- if (CHIN(cs, i) && isalpha(i)) {
- ci = othercase(i);
- if (ci != i)
- CHadd(cs, ci);
- }
- if (cs->multis != NULL)
- mccase(p, cs);
- }
- if (invert) {
- register int i;
-
- for (i = p->g->csetsize - 1; i >= 0; i--)
- if (CHIN(cs, i))
- CHsub(cs, i);
- else
- CHadd(cs, i);
- if (p->g->cflags®_NEWLINE)
- CHsub(cs, '\n');
- if (cs->multis != NULL)
- mcinvert(p, cs);
- }
-
- assert(cs->multis == NULL); /* xxx */
-
- if (nch(p, cs) == 1) { /* optimize singleton sets */
- ordinary(p, firstch(p, cs));
- freeset(p, cs);
- } else
- EMIT(OANYOF, freezeset(p, cs));
-}
-
-/*
- - p_b_term - parse one term of a bracketed character list
- == static void p_b_term(register struct parse *p, register cset *cs);
- */
-static void
-p_b_term(p, cs)
-register struct parse *p;
-register cset *cs;
-{
- register char c;
- register char start, finish;
- register int i;
-
- /* classify what we've got */
- switch ((MORE()) ? PEEK() : '\0') {
- case '[':
- c = (MORE2()) ? PEEK2() : '\0';
- break;
- case '-':
- SETERROR(REG_ERANGE);
- return; /* NOTE RETURN */
- break;
- default:
- c = '\0';
- break;
- }
-
- switch (c) {
- case ':': /* character class */
- NEXT2();
- REQUIRE(MORE(), REG_EBRACK);
- c = PEEK();
- REQUIRE(c != '-' && c != ']', REG_ECTYPE);
- p_b_cclass(p, cs);
- REQUIRE(MORE(), REG_EBRACK);
- REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
- break;
- case '=': /* equivalence class */
- NEXT2();
- REQUIRE(MORE(), REG_EBRACK);
- c = PEEK();
- REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
- p_b_eclass(p, cs);
- REQUIRE(MORE(), REG_EBRACK);
- REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
- break;
- default: /* symbol, ordinary character, or range */
-/* xxx revision needed for multichar stuff */
- start = p_b_symbol(p);
- if (SEE('-') && MORE2() && PEEK2() != ']') {
- /* range */
- NEXT();
- if (EAT('-'))
- finish = '-';
- else
- finish = p_b_symbol(p);
- } else
- finish = start;
-/* xxx what about signed chars here... */
- REQUIRE(start <= finish, REG_ERANGE);
- for (i = start; i <= finish; i++)
- CHadd(cs, i);
- break;
- }
-}
-
-/*
- - p_b_cclass - parse a character-class name and deal with it
- == static void p_b_cclass(register struct parse *p, register cset *cs);
- */
-static void
-p_b_cclass(p, cs)
-register struct parse *p;
-register cset *cs;
-{
- register char *sp = p->next;
- register struct cclass *cp;
- register size_t len;
- register char *u;
- register char c;
-
- while (MORE() && isalpha(PEEK()))
- NEXT();
- len = p->next - sp;
- for (cp = cclasses; cp->name != NULL; cp++)
- if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
- break;
- if (cp->name == NULL) {
- /* oops, didn't find it */
- SETERROR(REG_ECTYPE);
- return;
- }
-
- u = cp->chars;
- while ((c = *u++) != '\0')
- CHadd(cs, c);
- for (u = cp->multis; *u != '\0'; u += strlen(u) + 1)
- MCadd(p, cs, u);
-}
-
-/*
- - p_b_eclass - parse an equivalence-class name and deal with it
- == static void p_b_eclass(register struct parse *p, register cset *cs);
- *
- * This implementation is incomplete. xxx
- */
-static void
-p_b_eclass(p, cs)
-register struct parse *p;
-register cset *cs;
-{
- register char c;
-
- c = p_b_coll_elem(p, '=');
- CHadd(cs, c);
-}
-
-/*
- - p_b_symbol - parse a character or [..]ed multicharacter collating symbol
- == static char p_b_symbol(register struct parse *p);
- */
-static char /* value of symbol */
-p_b_symbol(p)
-register struct parse *p;
-{
- register char value;
-
- REQUIRE(MORE(), REG_EBRACK);
- if (!EATTWO('[', '.'))
- return(GETNEXT());
-
- /* collating symbol */
- value = p_b_coll_elem(p, '.');
- REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
- return(value);
-}
-
-/*
- - p_b_coll_elem - parse a collating-element name and look it up
- == static char p_b_coll_elem(register struct parse *p, int endc);
- */
-static char /* value of collating element */
-p_b_coll_elem(p, endc)
-register struct parse *p;
-int endc; /* name ended by endc,']' */
-{
- register char *sp = p->next;
- register struct cname *cp;
- register int len;
-
- while (MORE() && !SEETWO(endc, ']'))
- NEXT();
- if (!MORE()) {
- SETERROR(REG_EBRACK);
- return(0);
- }
- len = p->next - sp;
- for (cp = cnames; cp->name != NULL; cp++)
- if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
- return(cp->code); /* known name */
- if (len == 1)
- return(*sp); /* single character */
- SETERROR(REG_ECOLLATE); /* neither */
- return(0);
-}
-
-/*
- - othercase - return the case counterpart of an alphabetic
- == static char othercase(int ch);
- */
-static char /* if no counterpart, return ch */
-othercase(ch)
-int ch;
-{
- assert(isalpha(ch));
- if (isupper(ch))
- return(tolower(ch));
- else if (islower(ch))
- return(toupper(ch));
- else /* peculiar, but could happen */
- return(ch);
-}
-
-/*
- - bothcases - emit a dualcase version of a two-case character
- == static void bothcases(register struct parse *p, int ch);
- *
- * Boy, is this implementation ever a kludge...
- */
-static void
-bothcases(p, ch)
-register struct parse *p;
-int ch;
-{
- register char *oldnext = p->next;
- register char *oldend = p->end;
- char bracket[3];
-
- assert(othercase(ch) != ch); /* p_bracket() would recurse */
- p->next = bracket;
- p->end = bracket+2;
- bracket[0] = ch;
- bracket[1] = ']';
- bracket[2] = '\0';
- p_bracket(p);
- assert(p->next == bracket+2);
- p->next = oldnext;
- p->end = oldend;
-}
-
-/*
- - ordinary - emit an ordinary character
- == static void ordinary(register struct parse *p, register int ch);
- */
-static void
-ordinary(p, ch)
-register struct parse *p;
-register int ch;
-{
- register cat_t *cap = p->g->categories;
-
- if ((p->g->cflags®_ICASE) && isalpha(ch) && othercase(ch) != ch)
- bothcases(p, ch);
- else {
- EMIT(OCHAR, (unsigned char)ch);
- if (cap[ch] == 0)
- cap[ch] = p->g->ncategories++;
- }
-}
-
-/*
- - nonnewline - emit REG_NEWLINE version of OANY
- == static void nonnewline(register struct parse *p);
- *
- * Boy, is this implementation ever a kludge...
- */
-static void
-nonnewline(p)
-register struct parse *p;
-{
- register char *oldnext = p->next;
- register char *oldend = p->end;
- char bracket[4];
-
- p->next = bracket;
- p->end = bracket+3;
- bracket[0] = '^';
- bracket[1] = '\n';
- bracket[2] = ']';
- bracket[3] = '\0';
- p_bracket(p);
- assert(p->next == bracket+3);
- p->next = oldnext;
- p->end = oldend;
-}
-
-/*
- - repeat - generate code for a bounded repetition, recursively if needed
- == static void repeat(register struct parse *p, sopno start, int from, int to);
- */
-static void
-repeat(p, start, from, to)
-register struct parse *p;
-sopno start; /* operand from here to end of strip */
-int from; /* repeated from this number */
-int to; /* to this number of times (maybe INFINITY) */
-{
- register sopno finish = HERE();
-# define N 2
-# define INF 3
-# define REP(f, t) ((f)*8 + (t))
-# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
- register sopno copy;
-
- if (p->error != 0) /* head off possible runaway recursion */
- return;
-
- assert(from <= to);
-
- switch (REP(MAP(from), MAP(to))) {
- case REP(0, 0): /* must be user doing this */
- DROP(finish-start); /* drop the operand */
- break;
- case REP(0, 1): /* as x{1,1}? */
- case REP(0, N): /* as x{1,n}? */
- case REP(0, INF): /* as x{1,}? */
- /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
- INSERT(OCH_, start); /* offset is wrong... */
- repeat(p, start+1, 1, to);
- ASTERN(OOR1, start);
- AHEAD(start); /* ... fix it */
- EMIT(OOR2, 0);
- AHEAD(THERE());
- ASTERN(O_CH, THERETHERE());
- break;
- case REP(1, 1): /* trivial case */
- /* done */
- break;
- case REP(1, N): /* as x?x{1,n-1} */
- /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
- INSERT(OCH_, start);
- ASTERN(OOR1, start);
- AHEAD(start);
- EMIT(OOR2, 0); /* offset very wrong... */
- AHEAD(THERE()); /* ...so fix it */
- ASTERN(O_CH, THERETHERE());
- copy = dupl(p, start+1, finish+1);
- assert(copy == finish+4);
- repeat(p, copy, 1, to-1);
- break;
- case REP(1, INF): /* as x+ */
- INSERT(OPLUS_, start);
- ASTERN(O_PLUS, start);
- break;
- case REP(N, N): /* as xx{m-1,n-1} */
- copy = dupl(p, start, finish);
- repeat(p, copy, from-1, to-1);
- break;
- case REP(N, INF): /* as xx{n-1,INF} */
- copy = dupl(p, start, finish);
- repeat(p, copy, from-1, to);
- break;
- default: /* "can't happen" */
- SETERROR(REG_ASSERT); /* just in case */
- break;
- }
-}
-
-/*
- - seterr - set an error condition
- == static int seterr(register struct parse *p, int e);
- */
-static int /* useless but makes type checking happy */
-seterr(p, e)
-register struct parse *p;
-int e;
-{
- if (p->error == 0) /* keep earliest error condition */
- p->error = e;
- p->next = nuls; /* try to bring things to a halt */
- p->end = nuls;
- return(0); /* make the return value well-defined */
-}
-
-/*
- - allocset - allocate a set of characters for []
- == static cset *allocset(register struct parse *p);
- */
-static cset *
-allocset(p)
-register struct parse *p;
-{
- register int no = p->g->ncsets++;
- register size_t nc;
- register size_t nbytes;
- register cset *cs;
- register size_t css = (size_t)p->g->csetsize;
- register int i;
-
- if (no >= p->ncsalloc) { /* need another column of space */
- p->ncsalloc += CHAR_BIT;
- nc = p->ncsalloc;
- assert(nc % CHAR_BIT == 0);
- nbytes = nc / CHAR_BIT * css;
- if (p->g->sets == NULL)
- p->g->sets = (cset *)malloc(nc * sizeof(cset));
- else
- p->g->sets = (cset *)realloc((char *)p->g->sets,
- nc * sizeof(cset));
- if (p->g->setbits == NULL)
- p->g->setbits = (uch *)malloc(nbytes);
- else {
- p->g->setbits = (uch *)realloc((char *)p->g->setbits,
- nbytes);
- /* xxx this isn't right if setbits is now NULL */
- for (i = 0; i < no; i++)
- p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);
- }
- if (p->g->sets != NULL && p->g->setbits != NULL)
- (void) memset((char *)p->g->setbits + (nbytes - css),
- 0, css);
- else {
- no = 0;
- SETERROR(REG_ESPACE);
- /* caller's responsibility not to do set ops */
- }
- }
-
- assert(p->g->sets != NULL); /* xxx */
- cs = &p->g->sets[no];
- cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);
- cs->mask = 1 << ((no) % CHAR_BIT);
- cs->hash = 0;
- cs->smultis = 0;
- cs->multis = NULL;
-
- return(cs);
-}
-
-/*
- - freeset - free a now-unused set
- == static void freeset(register struct parse *p, register cset *cs);
- */
-static void
-freeset(p, cs)
-register struct parse *p;
-register cset *cs;
-{
- register int i;
- register cset *top = &p->g->sets[p->g->ncsets];
- register size_t css = (size_t)p->g->csetsize;
-
- for (i = 0; i < css; i++)
- CHsub(cs, i);
- if (cs == top-1) /* recover only the easy case */
- p->g->ncsets--;
-}
-
-/*
- - freezeset - final processing on a set of characters
- == static int freezeset(register struct parse *p, register cset *cs);
- *
- * The main task here is merging identical sets. This is usually a waste
- * of time (although the hash code minimizes the overhead), but can win
- * big if REG_ICASE is being used. REG_ICASE, by the way, is why the hash
- * is done using addition rather than xor -- all ASCII [aA] sets xor to
- * the same value!
- */
-static int /* set number */
-freezeset(p, cs)
-register struct parse *p;
-register cset *cs;
-{
- register uch h = cs->hash;
- register int i;
- register cset *top = &p->g->sets[p->g->ncsets];
- register cset *cs2;
- register size_t css = (size_t)p->g->csetsize;
-
- /* look for an earlier one which is the same */
- for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
- if (cs2->hash == h && cs2 != cs) {
- /* maybe */
- for (i = 0; i < css; i++)
- if (!!CHIN(cs2, i) != !!CHIN(cs, i))
- break; /* no */
- if (i == css)
- break; /* yes */
- }
-
- if (cs2 < top) { /* found one */
- freeset(p, cs);
- cs = cs2;
- }
-
- return((int)(cs - p->g->sets));
-}
-
-/*
- - firstch - return first character in a set (which must have at least one)
- == static int firstch(register struct parse *p, register cset *cs);
- */
-static int /* character; there is no "none" value */
-firstch(p, cs)
-register struct parse *p;
-register cset *cs;
-{
- register int i;
- register size_t css = (size_t)p->g->csetsize;
-
- for (i = 0; i < css; i++)
- if (CHIN(cs, i))
- return((char)i);
- assert(never);
- return(0); /* arbitrary */
-}
-
-/*
- - nch - number of characters in a set
- == static int nch(register struct parse *p, register cset *cs);
- */
-static int
-nch(p, cs)
-register struct parse *p;
-register cset *cs;
-{
- register int i;
- register size_t css = (size_t)p->g->csetsize;
- register int n = 0;
-
- for (i = 0; i < css; i++)
- if (CHIN(cs, i))
- n++;
- return(n);
-}
-
-/*
- - mcadd - add a collating element to a cset
- == static void mcadd(register struct parse *p, register cset *cs, \
- == register char *cp);
- */
-static void
-mcadd(p, cs, cp)
-register struct parse *p;
-register cset *cs;
-register char *cp;
-{
- register size_t oldend = cs->smultis;
-
- cs->smultis += strlen(cp) + 1;
- if (cs->multis == NULL)
- cs->multis = malloc(cs->smultis);
- else
- cs->multis = realloc(cs->multis, cs->smultis);
- if (cs->multis == NULL) {
- SETERROR(REG_ESPACE);
- return;
- }
-
- (void) strcpy(cs->multis + oldend - 1, cp);
- cs->multis[cs->smultis - 1] = '\0';
-}
-
-/*
- - mcinvert - invert the list of collating elements in a cset
- == static void mcinvert(register struct parse *p, register cset *cs);
- *
- * This would have to know the set of possibilities. Implementation
- * is deferred.
- */
-static void
-mcinvert(p, cs)
-register struct parse *p;
-register cset *cs;
-{
- assert(cs->multis == NULL); /* xxx */
-}
-
-/*
- - mccase - add case counterparts of the list of collating elements in a cset
- == static void mccase(register struct parse *p, register cset *cs);
- *
- * This would have to know the set of possibilities. Implementation
- * is deferred.
- */
-static void
-mccase(p, cs)
-register struct parse *p;
-register cset *cs;
-{
- assert(cs->multis == NULL); /* xxx */
-}
-
-/*
- - isinsets - is this character in any sets?
- == static int isinsets(register struct re_guts *g, int c);
- */
-static int /* predicate */
-isinsets(g, c)
-register struct re_guts *g;
-int c;
-{
- register uch *col;
- register int i;
- register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
- register unsigned uc = (unsigned char)c;
-
- for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
- if (col[uc] != 0)
- return(1);
- return(0);
-}
-
-/*
- - samesets - are these two characters in exactly the same sets?
- == static int samesets(register struct re_guts *g, int c1, int c2);
- */
-static int /* predicate */
-samesets(g, c1, c2)
-register struct re_guts *g;
-int c1;
-int c2;
-{
- register uch *col;
- register int i;
- register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
- register unsigned uc1 = (unsigned char)c1;
- register unsigned uc2 = (unsigned char)c2;
-
- for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
- if (col[uc1] != col[uc2])
- return(0);
- return(1);
-}
-
-/*
- - categorize - sort out character categories
- == static void categorize(struct parse *p, register struct re_guts *g);
- */
-static void
-categorize(p, g)
-struct parse *p;
-register struct re_guts *g;
-{
- register cat_t *cats = g->categories;
- register int c;
- register int c2;
- register cat_t cat;
-
- /* avoid making error situations worse */
- if (p->error != 0)
- return;
-
- for (c = CHAR_MIN; c <= CHAR_MAX; c++)
- if (cats[c] == 0 && isinsets(g, c)) {
- cat = g->ncategories++;
- cats[c] = cat;
- for (c2 = c+1; c2 <= CHAR_MAX; c2++)
- if (cats[c2] == 0 && samesets(g, c, c2))
- cats[c2] = cat;
- }
-}
-
-/*
- - dupl - emit a duplicate of a bunch of sops
- == static sopno dupl(register struct parse *p, sopno start, sopno finish);
- */
-static sopno /* start of duplicate */
-dupl(p, start, finish)
-register struct parse *p;
-sopno start; /* from here */
-sopno finish; /* to this less one */
-{
- register sopno ret = HERE();
- register sopno len = finish - start;
-
- assert(finish >= start);
- if (len == 0)
- return(ret);
- enlarge(p, p->ssize + len); /* this many unexpected additions */
- assert(p->ssize >= p->slen + len);
- (void) memcpy((char *)(p->strip + p->slen),
- (char *)(p->strip + start), (size_t)len*sizeof(sop));
- p->slen += len;
- return(ret);
-}
-
-/*
- - doemit - emit a strip operator
- == static void doemit(register struct parse *p, sop op, size_t opnd);
- *
- * It might seem better to implement this as a macro with a function as
- * hard-case backup, but it's just too big and messy unless there are
- * some changes to the data structures. Maybe later.
- */
-static void
-doemit(p, op, opnd)
-register struct parse *p;
-sop op;
-size_t opnd;
-{
- /* avoid making error situations worse */
- if (p->error != 0)
- return;
-
- /* deal with oversize operands ("can't happen", more or less) */
- assert(opnd < 1<slen >= p->ssize)
- enlarge(p, (p->ssize+1) / 2 * 3); /* +50% */
- assert(p->slen < p->ssize);
-
- /* finally, it's all reduced to the easy case */
- p->strip[p->slen++] = SOP(op, opnd);
-}
-
-/*
- - doinsert - insert a sop into the strip
- == static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos);
- */
-static void
-doinsert(p, op, opnd, pos)
-register struct parse *p;
-sop op;
-size_t opnd;
-sopno pos;
-{
- register sopno sn;
- register sop s;
- register int i;
-
- /* avoid making error situations worse */
- if (p->error != 0)
- return;
-
- sn = HERE();
- EMIT(op, opnd); /* do checks, ensure space */
- assert(HERE() == sn+1);
- s = p->strip[sn];
-
- /* adjust paren pointers */
- assert(pos > 0);
- for (i = 1; i < NPAREN; i++) {
- if (p->pbegin[i] >= pos) {
- p->pbegin[i]++;
- }
- if (p->pend[i] >= pos) {
- p->pend[i]++;
- }
- }
-
- memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos],
- (HERE()-pos-1)*sizeof(sop));
- p->strip[pos] = s;
-}
-
-/*
- - dofwd - complete a forward reference
- == static void dofwd(register struct parse *p, sopno pos, sop value);
- */
-static void
-dofwd(p, pos, value)
-register struct parse *p;
-register sopno pos;
-sop value;
-{
- /* avoid making error situations worse */
- if (p->error != 0)
- return;
-
- assert(value < 1<strip[pos] = OP(p->strip[pos]) | value;
-}
-
-/*
- - enlarge - enlarge the strip
- == static void enlarge(register struct parse *p, sopno size);
- */
-static void
-enlarge(p, size)
-register struct parse *p;
-register sopno size;
-{
- register sop *sp;
-
- if (p->ssize >= size)
- return;
-
- sp = (sop *)realloc(p->strip, size*sizeof(sop));
- if (sp == NULL) {
- SETERROR(REG_ESPACE);
- return;
- }
- p->strip = sp;
- p->ssize = size;
-}
-
-/*
- - stripsnug - compact the strip
- == static void stripsnug(register struct parse *p, register struct re_guts *g);
- */
-static void
-stripsnug(p, g)
-register struct parse *p;
-register struct re_guts *g;
-{
- g->nstates = p->slen;
- g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
- if (g->strip == NULL) {
- SETERROR(REG_ESPACE);
- g->strip = p->strip;
- }
-}
-
-/*
- - findmust - fill in must and mlen with longest mandatory literal string
- == static void findmust(register struct parse *p, register struct re_guts *g);
- *
- * This algorithm could do fancy things like analyzing the operands of |
- * for common subsequences. Someday. This code is simple and finds most
- * of the interesting cases.
- *
- * Note that must and mlen got initialized during setup.
- */
-static void
-findmust(p, g)
-struct parse *p;
-register struct re_guts *g;
-{
- register sop *scan;
- sop *start;
- register sop *newstart;
- register sopno newlen;
- register sop s;
- register char *cp;
- register sopno i;
-
- /* avoid making error situations worse */
- if (p->error != 0)
- return;
-
- /* find the longest OCHAR sequence in strip */
- newlen = 0;
- scan = g->strip + 1;
- do {
- s = *scan++;
- switch (OP(s)) {
- case OCHAR: /* sequence member */
- if (newlen == 0) /* new sequence */
- newstart = scan - 1;
- newlen++;
- break;
- case OPLUS_: /* things that don't break one */
- case OLPAREN:
- case ORPAREN:
- break;
- case OQUEST_: /* things that must be skipped */
- case OCH_:
- scan--;
- do {
- scan += OPND(s);
- s = *scan;
- /* assert() interferes w debug printouts */
- if (OP(s) != O_QUEST && OP(s) != O_CH &&
- OP(s) != OOR2) {
- g->iflags |= BAD;
- return;
- }
- } while (OP(s) != O_QUEST && OP(s) != O_CH);
- /* fallthrough */
- default: /* things that break a sequence */
- if (newlen > g->mlen) { /* ends one */
- start = newstart;
- g->mlen = newlen;
- }
- newlen = 0;
- break;
- }
- } while (OP(s) != OEND);
-
- if (g->mlen == 0) /* there isn't one */
- return;
-
- /* turn it into a character string */
- g->must = malloc((size_t)g->mlen + 1);
- if (g->must == NULL) { /* argh; just forget it */
- g->mlen = 0;
- return;
- }
- cp = g->must;
- scan = start;
- for (i = g->mlen; i > 0; i--) {
- while (OP(s = *scan++) != OCHAR)
- continue;
- assert(cp < g->must + g->mlen);
- *cp++ = (char)OPND(s);
- }
- assert(cp == g->must + g->mlen);
- *cp++ = '\0'; /* just on general principles */
-}
-
-/*
- - pluscount - count + nesting
- == static sopno pluscount(register struct parse *p, register struct re_guts *g);
- */
-static sopno /* nesting depth */
-pluscount(p, g)
-struct parse *p;
-register struct re_guts *g;
-{
- register sop *scan;
- register sop s;
- register sopno plusnest = 0;
- register sopno maxnest = 0;
-
- if (p->error != 0)
- return(0); /* there may not be an OEND */
-
- scan = g->strip + 1;
- do {
- s = *scan++;
- switch (OP(s)) {
- case OPLUS_:
- plusnest++;
- break;
- case O_PLUS:
- if (plusnest > maxnest)
- maxnest = plusnest;
- plusnest--;
- break;
- }
- } while (OP(s) != OEND);
- if (plusnest != 0)
- g->iflags |= BAD;
- return(maxnest);
-}
-
-static int nope = 0; /* for use in asserts; shuts lint up */
-
-/* macros for manipulating states, small version */
-#define states unsigned
-#define states1 unsigned /* for later use in regexec() decision */
-#define CLEAR(v) ((v) = 0)
-#define SET0(v, n) ((v) &= ~((unsigned)1 << (n)))
-#define SET1(v, n) ((v) |= (unsigned)1 << (n))
-#define ISSET(v, n) ((v) & ((unsigned)1 << (n)))
-#define ASSIGN(d, s) ((d) = (s))
-#define EQ(a, b) ((a) == (b))
-#define STATEVARS int dummy /* dummy version */
-#define STATESETUP(m, n) /* nothing */
-#define STATETEARDOWN(m) /* nothing */
-#define SETUP(v) ((v) = 0)
-#define onestate unsigned
-#define INIT(o, n) ((o) = (unsigned)1 << (n))
-#define INC(o) ((o) <<= 1)
-#define ISSTATEIN(v, o) ((v) & (o))
-/* some abbreviations; note that some of these know variable names! */
-/* do "if I'm here, I can also be there" etc without branches */
-#define FWD(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) << (n))
-#define BACK(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) >> (n))
-#define ISSETBACK(v, n) ((v) & ((unsigned)here >> (n)))
-/* function names */
-#define SNAMES /* engine.c looks after details */
-
-/*
- * The matching engine and friends. This file is #included by regexec.c
- * after suitable #defines of a variety of macros used herein, so that
- * different state representations can be used without duplicating masses
- * of code.
- */
-
-#ifdef SNAMES
-#define matcher smatcher
-#define fast sfast
-#define slow sslow
-#define dissect sdissect
-#define backref sbackref
-#define step sstep
-#define print sprint
-#define at sat
-#define match smat
-#endif
-#ifdef LNAMES
-#define matcher lmatcher
-#define fast lfast
-#define slow lslow
-#define dissect ldissect
-#define backref lbackref
-#define step lstep
-#define print lprint
-#define at lat
-#define match lmat
-#endif
-
-/* another structure passed up and down to avoid zillions of parameters */
-struct match {
- struct re_guts *g;
- int eflags;
- regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
- char *offp; /* offsets work from here */
- char *beginp; /* start of string -- virtual NUL precedes */
- char *endp; /* end of string -- virtual NUL here */
- char *coldp; /* can be no match starting before here */
- char **lastpos; /* [nplus+1] */
- STATEVARS;
- states st; /* current states */
- states fresh; /* states for a fresh start */
- states tmp; /* temporary */
- states empty; /* empty set of states */
-};
-
-static int matcher(register struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
-static char *dissect(register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
-static char *backref(register struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev);
-static char *fast(register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
-static char *slow(register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
-static states step(register struct re_guts *g, sopno start, sopno stop, register states bef, int ch, register states aft);
-#define BOL (OUT+1)
-#define EOL (BOL+1)
-#define BOLEOL (BOL+2)
-#define NOTHING (BOL+3)
-#define BOW (BOL+4)
-#define EOW (BOL+5)
-#define CODEMAX (BOL+5) /* highest code used */
-#define NONCHAR(c) ((c) > CHAR_MAX)
-#define NNONCHAR (CODEMAX-CHAR_MAX)
-#define SP(t, s, c) /* nothing */
-#define AT(t, p1, p2, s1, s2) /* nothing */
-#define NOTE(s) /* nothing */
-
-/*
- - matcher - the actual matching engine
- == static int matcher(register struct re_guts *g, char *string, \
- == size_t nmatch, regmatch_t pmatch[], int eflags);
- */
-static int /* 0 success, REG_NOMATCH failure */
-matcher(g, string, nmatch, pmatch, eflags)
-register struct re_guts *g;
-char *string;
-size_t nmatch;
-regmatch_t pmatch[];
-int eflags;
-{
- register char *endp;
- register int i;
- struct match mv;
- register struct match *m = &mv;
- register char *dp;
- const register sopno gf = g->firststate+1; /* +1 for OEND */
- const register sopno gl = g->laststate;
- char *start;
- char *stop;
-
- /* simplify the situation where possible */
- if (g->cflags®_NOSUB)
- nmatch = 0;
- if (eflags®_STARTEND) {
- start = string + pmatch[0].rm_so;
- stop = string + pmatch[0].rm_eo;
- } else {
- start = string;
- stop = start + strlen(start);
- }
- if (stop < start)
- return(REG_INVARG);
-
- /* prescreening; this does wonders for this rather slow code */
- if (g->must != NULL) {
- for (dp = start; dp < stop; dp++)
- if (*dp == g->must[0] && stop - dp >= g->mlen &&
- memcmp(dp, g->must, (size_t)g->mlen) == 0)
- break;
- if (dp == stop) /* we didn't find g->must */
- return(REG_NOMATCH);
- }
-
- /* match struct setup */
- m->g = g;
- m->eflags = eflags;
- m->pmatch = NULL;
- m->lastpos = NULL;
- m->offp = string;
- m->beginp = start;
- m->endp = stop;
- STATESETUP(m, 4);
- SETUP(m->st);
- SETUP(m->fresh);
- SETUP(m->tmp);
- SETUP(m->empty);
- CLEAR(m->empty);
-
- /* this loop does only one repetition except for backrefs */
- for (;;) {
- endp = fast(m, start, stop, gf, gl);
- if (endp == NULL) { /* a miss */
- STATETEARDOWN(m);
- return(REG_NOMATCH);
- }
- if (nmatch == 0 && !g->backrefs)
- break; /* no further info needed */
-
- /* where? */
- assert(m->coldp != NULL);
- for (;;) {
- NOTE("finding start");
- endp = slow(m, m->coldp, stop, gf, gl);
- if (endp != NULL)
- break;
- assert(m->coldp < m->endp);
- m->coldp++;
- }
- if (nmatch == 1 && !g->backrefs)
- break; /* no further info needed */
-
- /* oh my, he wants the subexpressions... */
- if (m->pmatch == NULL)
- m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) *
- sizeof(regmatch_t));
- if (m->pmatch == NULL) {
- STATETEARDOWN(m);
- return(REG_ESPACE);
- }
- for (i = 1; i <= m->g->nsub; i++)
- m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1;
- if (!g->backrefs && !(m->eflags®_BACKR)) {
- NOTE("dissecting");
- dp = dissect(m, m->coldp, endp, gf, gl);
- } else {
- if (g->nplus > 0 && m->lastpos == NULL)
- m->lastpos = (char **)malloc((g->nplus+1) *
- sizeof(char *));
- if (g->nplus > 0 && m->lastpos == NULL) {
- free(m->pmatch);
- STATETEARDOWN(m);
- return(REG_ESPACE);
- }
- NOTE("backref dissect");
- dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
- }
- if (dp != NULL)
- break;
-
- /* uh-oh... we couldn't find a subexpression-level match */
- assert(g->backrefs); /* must be back references doing it */
- assert(g->nplus == 0 || m->lastpos != NULL);
- for (;;) {
- if (dp != NULL || endp <= m->coldp)
- break; /* defeat */
- NOTE("backoff");
- endp = slow(m, m->coldp, endp-1, gf, gl);
- if (endp == NULL)
- break; /* defeat */
- /* try it on a shorter possibility */
- NOTE("backoff dissect");
- dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
- }
- assert(dp == NULL || dp == endp);
- if (dp != NULL) /* found a shorter one */
- break;
-
- /* despite initial appearances, there is no match here */
- NOTE("false alarm");
- start = m->coldp + 1; /* recycle starting later */
- assert(start <= stop);
- }
-
- /* fill in the details if requested */
- if (nmatch > 0) {
- pmatch[0].rm_so = m->coldp - m->offp;
- pmatch[0].rm_eo = endp - m->offp;
- }
- if (nmatch > 1) {
- assert(m->pmatch != NULL);
- for (i = 1; i < nmatch; i++)
- if (i <= m->g->nsub)
- pmatch[i] = m->pmatch[i];
- else {
- pmatch[i].rm_so = -1;
- pmatch[i].rm_eo = -1;
- }
- }
-
- if (m->pmatch != NULL)
- free((char *)m->pmatch);
- if (m->lastpos != NULL)
- free((char *)m->lastpos);
- STATETEARDOWN(m);
- return(0);
-}
-
-/*
- - dissect - figure out what matched what, no back references
- == static char *dissect(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst);
- */
-static char * /* == stop (success) always */
-dissect(m, start, stop, startst, stopst)
-register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
-{
- register int i;
- register sopno ss; /* start sop of current subRE */
- register sopno es; /* end sop of current subRE */
- register char *sp; /* start of string matched by it */
- register char *stp; /* string matched by it cannot pass here */
- register char *rest; /* start of rest of string */
- register char *tail; /* string unmatched by rest of RE */
- register sopno ssub; /* start sop of subsubRE */
- register sopno esub; /* end sop of subsubRE */
- register char *ssp; /* start of string matched by subsubRE */
- register char *sep; /* end of string matched by subsubRE */
- register char *oldssp; /* previous ssp */
- register char *dp;
-
- AT("diss", start, stop, startst, stopst);
- sp = start;
- for (ss = startst; ss < stopst; ss = es) {
- /* identify end of subRE */
- es = ss;
- switch (OP(m->g->strip[es])) {
- case OPLUS_:
- case OQUEST_:
- es += OPND(m->g->strip[es]);
- break;
- case OCH_:
- while (OP(m->g->strip[es]) != O_CH)
- es += OPND(m->g->strip[es]);
- break;
- }
- es++;
-
- /* figure out what it matched */
- switch (OP(m->g->strip[ss])) {
- case OEND:
- assert(nope);
- break;
- case OCHAR:
- sp++;
- break;
- case OBOL:
- case OEOL:
- case OBOW:
- case OEOW:
- break;
- case OANY:
- case OANYOF:
- sp++;
- break;
- case OBACK_:
- case O_BACK:
- assert(nope);
- break;
- /* cases where length of match is hard to find */
- case OQUEST_:
- stp = stop;
- for (;;) {
- /* how long could this one be? */
- rest = slow(m, sp, stp, ss, es);
- assert(rest != NULL); /* it did match */
- /* could the rest match the rest? */
- tail = slow(m, rest, stop, es, stopst);
- if (tail == stop)
- break; /* yes! */
- /* no -- try a shorter match for this one */
- stp = rest - 1;
- assert(stp >= sp); /* it did work */
- }
- ssub = ss + 1;
- esub = es - 1;
- /* did innards match? */
- if (slow(m, sp, rest, ssub, esub) != NULL) {
- dp = dissect(m, sp, rest, ssub, esub);
- assert(dp == rest);
- } else /* no */
- assert(sp == rest);
- sp = rest;
- break;
- case OPLUS_:
- stp = stop;
- for (;;) {
- /* how long could this one be? */
- rest = slow(m, sp, stp, ss, es);
- assert(rest != NULL); /* it did match */
- /* could the rest match the rest? */
- tail = slow(m, rest, stop, es, stopst);
- if (tail == stop)
- break; /* yes! */
- /* no -- try a shorter match for this one */
- stp = rest - 1;
- assert(stp >= sp); /* it did work */
- }
- ssub = ss + 1;
- esub = es - 1;
- ssp = sp;
- oldssp = ssp;
- for (;;) { /* find last match of innards */
- sep = slow(m, ssp, rest, ssub, esub);
- if (sep == NULL || sep == ssp)
- break; /* failed or matched null */
- oldssp = ssp; /* on to next try */
- ssp = sep;
- }
- if (sep == NULL) {
- /* last successful match */
- sep = ssp;
- ssp = oldssp;
- }
- assert(sep == rest); /* must exhaust substring */
- assert(slow(m, ssp, sep, ssub, esub) == rest);
- dp = dissect(m, ssp, sep, ssub, esub);
- assert(dp == sep);
- sp = rest;
- break;
- case OCH_:
- stp = stop;
- for (;;) {
- /* how long could this one be? */
- rest = slow(m, sp, stp, ss, es);
- assert(rest != NULL); /* it did match */
- /* could the rest match the rest? */
- tail = slow(m, rest, stop, es, stopst);
- if (tail == stop)
- break; /* yes! */
- /* no -- try a shorter match for this one */
- stp = rest - 1;
- assert(stp >= sp); /* it did work */
- }
- ssub = ss + 1;
- esub = ss + OPND(m->g->strip[ss]) - 1;
- assert(OP(m->g->strip[esub]) == OOR1);
- for (;;) { /* find first matching branch */
- if (slow(m, sp, rest, ssub, esub) == rest)
- break; /* it matched all of it */
- /* that one missed, try next one */
- assert(OP(m->g->strip[esub]) == OOR1);
- esub++;
- assert(OP(m->g->strip[esub]) == OOR2);
- ssub = esub + 1;
- esub += OPND(m->g->strip[esub]);
- if (OP(m->g->strip[esub]) == OOR2)
- esub--;
- else
- assert(OP(m->g->strip[esub]) == O_CH);
- }
- dp = dissect(m, sp, rest, ssub, esub);
- assert(dp == rest);
- sp = rest;
- break;
- case O_PLUS:
- case O_QUEST:
- case OOR1:
- case OOR2:
- case O_CH:
- assert(nope);
- break;
- case OLPAREN:
- i = OPND(m->g->strip[ss]);
- assert(0 < i && i <= m->g->nsub);
- m->pmatch[i].rm_so = sp - m->offp;
- break;
- case ORPAREN:
- i = OPND(m->g->strip[ss]);
- assert(0 < i && i <= m->g->nsub);
- m->pmatch[i].rm_eo = sp - m->offp;
- break;
- default: /* uh oh */
- assert(nope);
- break;
- }
- }
-
- assert(sp == stop);
- return(sp);
-}
-
-/*
- - backref - figure out what matched what, figuring in back references
- == static char *backref(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst, sopno lev);
- */
-static char * /* == stop (success) or NULL (failure) */
-backref(m, start, stop, startst, stopst, lev)
-register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
-sopno lev; /* PLUS nesting level */
-{
- register int i;
- register sopno ss; /* start sop of current subRE */
- register char *sp; /* start of string matched by it */
- register sopno ssub; /* start sop of subsubRE */
- register sopno esub; /* end sop of subsubRE */
- register char *ssp; /* start of string matched by subsubRE */
- register char *dp;
- register size_t len;
- register int hard;
- register sop s;
- register regoff_t offsave;
- register cset *cs;
-
- AT("back", start, stop, startst, stopst);
- sp = start;
-
- /* get as far as we can with easy stuff */
- hard = 0;
- for (ss = startst; !hard && ss < stopst; ss++)
- switch (OP(s = m->g->strip[ss])) {
- case OCHAR:
- if (sp == stop || *sp++ != (char)OPND(s))
- return(NULL);
- break;
- case OANY:
- if (sp == stop)
- return(NULL);
- sp++;
- break;
- case OANYOF:
- cs = &m->g->sets[OPND(s)];
- if (sp == stop || !CHIN(cs, *sp++))
- return(NULL);
- break;
- case OBOL:
- if ( (sp == m->beginp && !(m->eflags®_NOTBOL)) ||
- (sp < m->endp && *(sp-1) == '\n' &&
- (m->g->cflags®_NEWLINE)) )
- { /* yes */ }
- else
- return(NULL);
- break;
- case OEOL:
- if ( (sp == m->endp && !(m->eflags®_NOTEOL)) ||
- (sp < m->endp && *sp == '\n' &&
- (m->g->cflags®_NEWLINE)) )
- { /* yes */ }
- else
- return(NULL);
- break;
- case OBOW:
- if (( (sp == m->beginp && !(m->eflags®_NOTBOL)) ||
- (sp < m->endp && *(sp-1) == '\n' &&
- (m->g->cflags®_NEWLINE)) ||
- (sp > m->beginp &&
- !ISWORD(*(sp-1))) ) &&
- (sp < m->endp && ISWORD(*sp)) )
- { /* yes */ }
- else
- return(NULL);
- break;
- case OEOW:
- if (( (sp == m->endp && !(m->eflags®_NOTEOL)) ||
- (sp < m->endp && *sp == '\n' &&
- (m->g->cflags®_NEWLINE)) ||
- (sp < m->endp && !ISWORD(*sp)) ) &&
- (sp > m->beginp && ISWORD(*(sp-1))) )
- { /* yes */ }
- else
- return(NULL);
- break;
- case O_QUEST:
- break;
- case OOR1: /* matches null but needs to skip */
- ss++;
- s = m->g->strip[ss];
- do {
- assert(OP(s) == OOR2);
- ss += OPND(s);
- } while (OP(s = m->g->strip[ss]) != O_CH);
- /* note that the ss++ gets us past the O_CH */
- break;
- default: /* have to make a choice */
- hard = 1;
- break;
- }
- if (!hard) { /* that was it! */
- if (sp != stop)
- return(NULL);
- return(sp);
- }
- ss--; /* adjust for the for's final increment */
-
- /* the hard stuff */
- AT("hard", sp, stop, ss, stopst);
- s = m->g->strip[ss];
- switch (OP(s)) {
- case OBACK_: /* the vilest depths */
- i = OPND(s);
- assert(0 < i && i <= m->g->nsub);
- if (m->pmatch[i].rm_eo == -1)
- return(NULL);
- assert(m->pmatch[i].rm_so != -1);
- len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so;
- assert(stop - m->beginp >= len);
- if (sp > stop - len)
- return(NULL); /* not enough left to match */
- ssp = m->offp + m->pmatch[i].rm_so;
- if (memcmp(sp, ssp, len) != 0)
- return(NULL);
- while (m->g->strip[ss] != SOP(O_BACK, i))
- ss++;
- return(backref(m, sp+len, stop, ss+1, stopst, lev));
- break;
- case OQUEST_: /* to null or not */
- dp = backref(m, sp, stop, ss+1, stopst, lev);
- if (dp != NULL)
- return(dp); /* not */
- return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev));
- break;
- case OPLUS_:
- assert(m->lastpos != NULL);
- assert(lev+1 <= m->g->nplus);
- m->lastpos[lev+1] = sp;
- return(backref(m, sp, stop, ss+1, stopst, lev+1));
- break;
- case O_PLUS:
- if (sp == m->lastpos[lev]) /* last pass matched null */
- return(backref(m, sp, stop, ss+1, stopst, lev-1));
- /* try another pass */
- m->lastpos[lev] = sp;
- dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev);
- if (dp == NULL)
- return(backref(m, sp, stop, ss+1, stopst, lev-1));
- else
- return(dp);
- break;
- case OCH_: /* find the right one, if any */
- ssub = ss + 1;
- esub = ss + OPND(s) - 1;
- assert(OP(m->g->strip[esub]) == OOR1);
- for (;;) { /* find first matching branch */
- dp = backref(m, sp, stop, ssub, esub, lev);
- if (dp != NULL)
- return(dp);
- /* that one missed, try next one */
- if (OP(m->g->strip[esub]) == O_CH)
- return(NULL); /* there is none */
- esub++;
- assert(OP(m->g->strip[esub]) == OOR2);
- ssub = esub + 1;
- esub += OPND(m->g->strip[esub]);
- if (OP(m->g->strip[esub]) == OOR2)
- esub--;
- else
- assert(OP(m->g->strip[esub]) == O_CH);
- }
- break;
- case OLPAREN: /* must undo assignment if rest fails */
- i = OPND(s);
- assert(0 < i && i <= m->g->nsub);
- offsave = m->pmatch[i].rm_so;
- m->pmatch[i].rm_so = sp - m->offp;
- dp = backref(m, sp, stop, ss+1, stopst, lev);
- if (dp != NULL)
- return(dp);
- m->pmatch[i].rm_so = offsave;
- return(NULL);
- break;
- case ORPAREN: /* must undo assignment if rest fails */
- i = OPND(s);
- assert(0 < i && i <= m->g->nsub);
- offsave = m->pmatch[i].rm_eo;
- m->pmatch[i].rm_eo = sp - m->offp;
- dp = backref(m, sp, stop, ss+1, stopst, lev);
- if (dp != NULL)
- return(dp);
- m->pmatch[i].rm_eo = offsave;
- return(NULL);
- break;
- default: /* uh oh */
- assert(nope);
- break;
- }
-
- /* "can't happen" */
- assert(nope);
- /* NOTREACHED */
- return((char *)NULL); /* dummy */
-}
-
-/*
- - fast - step through the string at top speed
- == static char *fast(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst);
- */
-static char * /* where tentative match ended, or NULL */
-fast(m, start, stop, startst, stopst)
-register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
-{
- register states st = m->st;
- register states fresh = m->fresh;
- register states tmp = m->tmp;
- register char *p = start;
- register int c = (start == m->beginp) ? OUT : *(start-1);
- register int lastc; /* previous c */
- register int flagch;
- register int i;
- register char *coldp; /* last p after which no match was underway */
-
- CLEAR(st);
- SET1(st, startst);
- st = step(m->g, startst, stopst, st, NOTHING, st);
- ASSIGN(fresh, st);
- SP("start", st, *p);
- coldp = NULL;
- for (;;) {
- /* next character */
- lastc = c;
- c = (p == m->endp) ? OUT : *p;
- if (EQ(st, fresh))
- coldp = p;
-
- /* is there an EOL and/or BOL between lastc and c? */
- flagch = '\0';
- i = 0;
- if ( (lastc == '\n' && m->g->cflags®_NEWLINE) ||
- (lastc == OUT && !(m->eflags®_NOTBOL)) ) {
- flagch = BOL;
- i = m->g->nbol;
- }
- if ( (c == '\n' && m->g->cflags®_NEWLINE) ||
- (c == OUT && !(m->eflags®_NOTEOL)) ) {
- flagch = (flagch == BOL) ? BOLEOL : EOL;
- i += m->g->neol;
- }
- if (i != 0) {
- for (; i > 0; i--)
- st = step(m->g, startst, stopst, st, flagch, st);
- SP("boleol", st, c);
- }
-
- /* how about a word boundary? */
- if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
- (c != OUT && ISWORD(c)) ) {
- flagch = BOW;
- }
- if ( (lastc != OUT && ISWORD(lastc)) &&
- (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
- flagch = EOW;
- }
- if (flagch == BOW || flagch == EOW) {
- st = step(m->g, startst, stopst, st, flagch, st);
- SP("boweow", st, c);
- }
-
- /* are we done? */
- if (ISSET(st, stopst) || p == stop)
- break; /* NOTE BREAK OUT */
-
- /* no, we must deal with this character */
- ASSIGN(tmp, st);
- ASSIGN(st, fresh);
- assert(c != OUT);
- st = step(m->g, startst, stopst, tmp, c, st);
- SP("aft", st, c);
- assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
- p++;
- }
-
- assert(coldp != NULL);
- m->coldp = coldp;
- if (ISSET(st, stopst))
- return(p+1);
- else
- return(NULL);
-}
-
-/*
- - slow - step through the string more deliberately
- == static char *slow(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst);
- */
-static char * /* where it ended */
-slow(m, start, stop, startst, stopst)
-register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
-{
- register states st = m->st;
- register states empty = m->empty;
- register states tmp = m->tmp;
- register char *p = start;
- register int c = (start == m->beginp) ? OUT : *(start-1);
- register int lastc; /* previous c */
- register int flagch;
- register int i;
- register char *matchp; /* last p at which a match ended */
-
- AT("slow", start, stop, startst, stopst);
- CLEAR(st);
- SET1(st, startst);
- SP("sstart", st, *p);
- st = step(m->g, startst, stopst, st, NOTHING, st);
- matchp = NULL;
- for (;;) {
- /* next character */
- lastc = c;
- c = (p == m->endp) ? OUT : *p;
-
- /* is there an EOL and/or BOL between lastc and c? */
- flagch = '\0';
- i = 0;
- if ( (lastc == '\n' && m->g->cflags®_NEWLINE) ||
- (lastc == OUT && !(m->eflags®_NOTBOL)) ) {
- flagch = BOL;
- i = m->g->nbol;
- }
- if ( (c == '\n' && m->g->cflags®_NEWLINE) ||
- (c == OUT && !(m->eflags®_NOTEOL)) ) {
- flagch = (flagch == BOL) ? BOLEOL : EOL;
- i += m->g->neol;
- }
- if (i != 0) {
- for (; i > 0; i--)
- st = step(m->g, startst, stopst, st, flagch, st);
- SP("sboleol", st, c);
- }
-
- /* how about a word boundary? */
- if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
- (c != OUT && ISWORD(c)) ) {
- flagch = BOW;
- }
- if ( (lastc != OUT && ISWORD(lastc)) &&
- (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
- flagch = EOW;
- }
- if (flagch == BOW || flagch == EOW) {
- st = step(m->g, startst, stopst, st, flagch, st);
- SP("sboweow", st, c);
- }
-
- /* are we done? */
- if (ISSET(st, stopst))
- matchp = p;
- if (EQ(st, empty) || p == stop)
- break; /* NOTE BREAK OUT */
-
- /* no, we must deal with this character */
- ASSIGN(tmp, st);
- ASSIGN(st, empty);
- assert(c != OUT);
- st = step(m->g, startst, stopst, tmp, c, st);
- SP("saft", st, c);
- assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
- p++;
- }
-
- return(matchp);
-}
-
-
-/*
- - step - map set of states reachable before char to set reachable after
- == static states step(register struct re_guts *g, sopno start, sopno stop, \
- == register states bef, int ch, register states aft);
- == #define BOL (OUT+1)
- == #define EOL (BOL+1)
- == #define BOLEOL (BOL+2)
- == #define NOTHING (BOL+3)
- == #define BOW (BOL+4)
- == #define EOW (BOL+5)
- == #define CODEMAX (BOL+5) // highest code used
- == #define NONCHAR(c) ((c) > CHAR_MAX)
- == #define NNONCHAR (CODEMAX-CHAR_MAX)
- */
-static states
-step(g, start, stop, bef, ch, aft)
-register struct re_guts *g;
-sopno start; /* start state within strip */
-sopno stop; /* state after stop state within strip */
-register states bef; /* states reachable before */
-int ch; /* character or NONCHAR code */
-register states aft; /* states already known reachable after */
-{
- register cset *cs;
- register sop s;
- register sopno pc;
- register onestate here; /* note, macros know this name */
- register sopno look;
- register long i;
-
- for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) {
- s = g->strip[pc];
- switch (OP(s)) {
- case OEND:
- assert(pc == stop-1);
- break;
- case OCHAR:
- /* only characters can match */
- assert(!NONCHAR(ch) || ch != (char)OPND(s));
- if (ch == (char)OPND(s))
- FWD(aft, bef, 1);
- break;
- case OBOL:
- if (ch == BOL || ch == BOLEOL)
- FWD(aft, bef, 1);
- break;
- case OEOL:
- if (ch == EOL || ch == BOLEOL)
- FWD(aft, bef, 1);
- break;
- case OBOW:
- if (ch == BOW)
- FWD(aft, bef, 1);
- break;
- case OEOW:
- if (ch == EOW)
- FWD(aft, bef, 1);
- break;
- case OANY:
- if (!NONCHAR(ch))
- FWD(aft, bef, 1);
- break;
- case OANYOF:
- cs = &g->sets[OPND(s)];
- if (!NONCHAR(ch) && CHIN(cs, ch))
- FWD(aft, bef, 1);
- break;
- case OBACK_: /* ignored here */
- case O_BACK:
- FWD(aft, aft, 1);
- break;
- case OPLUS_: /* forward, this is just an empty */
- FWD(aft, aft, 1);
- break;
- case O_PLUS: /* both forward and back */
- FWD(aft, aft, 1);
- i = ISSETBACK(aft, OPND(s));
- BACK(aft, aft, OPND(s));
- if (!i && ISSETBACK(aft, OPND(s))) {
- /* oho, must reconsider loop body */
- pc -= OPND(s) + 1;
- INIT(here, pc);
- }
- break;
- case OQUEST_: /* two branches, both forward */
- FWD(aft, aft, 1);
- FWD(aft, aft, OPND(s));
- break;
- case O_QUEST: /* just an empty */
- FWD(aft, aft, 1);
- break;
- case OLPAREN: /* not significant here */
- case ORPAREN:
- FWD(aft, aft, 1);
- break;
- case OCH_: /* mark the first two branches */
- FWD(aft, aft, 1);
- assert(OP(g->strip[pc+OPND(s)]) == OOR2);
- FWD(aft, aft, OPND(s));
- break;
- case OOR1: /* done a branch, find the O_CH */
- if (ISSTATEIN(aft, here)) {
- for (look = 1;
- OP(s = g->strip[pc+look]) != O_CH;
- look += OPND(s))
- assert(OP(s) == OOR2);
- FWD(aft, aft, look);
- }
- break;
- case OOR2: /* propagate OCH_'s marking */
- FWD(aft, aft, 1);
- if (OP(g->strip[pc+OPND(s)]) != O_CH) {
- assert(OP(g->strip[pc+OPND(s)]) == OOR2);
- FWD(aft, aft, OPND(s));
- }
- break;
- case O_CH: /* just empty */
- FWD(aft, aft, 1);
- break;
- default: /* ooooops... */
- assert(nope);
- break;
- }
- }
-
- return(aft);
-}
-
-#undef matcher
-#undef fast
-#undef slow
-#undef dissect
-#undef backref
-#undef step
-#undef print
-#undef at
-#undef match
-
-/* now undo things */
-#undef states
-#undef CLEAR
-#undef SET0
-#undef SET1
-#undef ISSET
-#undef ASSIGN
-#undef EQ
-#undef STATEVARS
-#undef STATESETUP
-#undef STATETEARDOWN
-#undef SETUP
-#undef onestate
-#undef INIT
-#undef INC
-#undef ISSTATEIN
-#undef FWD
-#undef BACK
-#undef ISSETBACK
-#undef SNAMES
-
-/* macros for manipulating states, large version */
-#define states char *
-#define CLEAR(v) memset(v, 0, m->g->nstates)
-#define SET0(v, n) ((v)[n] = 0)
-#define SET1(v, n) ((v)[n] = 1)
-#define ISSET(v, n) ((v)[n])
-#define ASSIGN(d, s) memcpy(d, s, m->g->nstates)
-#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
-#define STATEVARS int vn; char *space
-#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \
- if ((m)->space == NULL) return(REG_ESPACE); \
- (m)->vn = 0; }
-#define STATETEARDOWN(m) { free((m)->space); }
-#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
-#define onestate int
-#define INIT(o, n) ((o) = (n))
-#define INC(o) ((o)++)
-#define ISSTATEIN(v, o) ((v)[o])
-/* some abbreviations; note that some of these know variable names! */
-/* do "if I'm here, I can also be there" etc without branches */
-#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here])
-#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here])
-#define ISSETBACK(v, n) ((v)[here - (n)])
-/* function names */
-#define LNAMES /* flag */
-
-/*
- * The matching engine and friends. This file is #included by regexec.c
- * after suitable #defines of a variety of macros used herein, so that
- * different state representations can be used without duplicating masses
- * of code.
- */
-
-#ifdef SNAMES
-#define matcher smatcher
-#define fast sfast
-#define slow sslow
-#define dissect sdissect
-#define backref sbackref
-#define step sstep
-#define print sprint
-#define at sat
-#define match smat
-#endif
-#ifdef LNAMES
-#define matcher lmatcher
-#define fast lfast
-#define slow lslow
-#define dissect ldissect
-#define backref lbackref
-#define step lstep
-#define print lprint
-#define at lat
-#define match lmat
-#endif
-
-/* another structure passed up and down to avoid zillions of parameters */
-struct match {
- struct re_guts *g;
- int eflags;
- regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
- char *offp; /* offsets work from here */
- char *beginp; /* start of string -- virtual NUL precedes */
- char *endp; /* end of string -- virtual NUL here */
- char *coldp; /* can be no match starting before here */
- char **lastpos; /* [nplus+1] */
- STATEVARS;
- states st; /* current states */
- states fresh; /* states for a fresh start */
- states tmp; /* temporary */
- states empty; /* empty set of states */
-};
-
-static int matcher(register struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
-static char *dissect(register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
-static char *backref(register struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev);
-static char *fast(register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
-static char *slow(register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
-static states step(register struct re_guts *g, sopno start, sopno stop, register states bef, int ch, register states aft);
-#define BOL (OUT+1)
-#define EOL (BOL+1)
-#define BOLEOL (BOL+2)
-#define NOTHING (BOL+3)
-#define BOW (BOL+4)
-#define EOW (BOL+5)
-#define CODEMAX (BOL+5) /* highest code used */
-#define NONCHAR(c) ((c) > CHAR_MAX)
-#define NNONCHAR (CODEMAX-CHAR_MAX)
-#define SP(t, s, c) /* nothing */
-#define AT(t, p1, p2, s1, s2) /* nothing */
-#define NOTE(s) /* nothing */
-
-/*
- - matcher - the actual matching engine
- == static int matcher(register struct re_guts *g, char *string, \
- == size_t nmatch, regmatch_t pmatch[], int eflags);
- */
-static int /* 0 success, REG_NOMATCH failure */
-matcher(g, string, nmatch, pmatch, eflags)
-register struct re_guts *g;
-char *string;
-size_t nmatch;
-regmatch_t pmatch[];
-int eflags;
-{
- register char *endp;
- register int i;
- struct match mv;
- register struct match *m = &mv;
- register char *dp;
- const register sopno gf = g->firststate+1; /* +1 for OEND */
- const register sopno gl = g->laststate;
- char *start;
- char *stop;
-
- /* simplify the situation where possible */
- if (g->cflags®_NOSUB)
- nmatch = 0;
- if (eflags®_STARTEND) {
- start = string + pmatch[0].rm_so;
- stop = string + pmatch[0].rm_eo;
- } else {
- start = string;
- stop = start + strlen(start);
- }
- if (stop < start)
- return(REG_INVARG);
-
- /* prescreening; this does wonders for this rather slow code */
- if (g->must != NULL) {
- for (dp = start; dp < stop; dp++)
- if (*dp == g->must[0] && stop - dp >= g->mlen &&
- memcmp(dp, g->must, (size_t)g->mlen) == 0)
- break;
- if (dp == stop) /* we didn't find g->must */
- return(REG_NOMATCH);
- }
-
- /* match struct setup */
- m->g = g;
- m->eflags = eflags;
- m->pmatch = NULL;
- m->lastpos = NULL;
- m->offp = string;
- m->beginp = start;
- m->endp = stop;
- STATESETUP(m, 4);
- SETUP(m->st);
- SETUP(m->fresh);
- SETUP(m->tmp);
- SETUP(m->empty);
- CLEAR(m->empty);
-
- /* this loop does only one repetition except for backrefs */
- for (;;) {
- endp = fast(m, start, stop, gf, gl);
- if (endp == NULL) { /* a miss */
- STATETEARDOWN(m);
- return(REG_NOMATCH);
- }
- if (nmatch == 0 && !g->backrefs)
- break; /* no further info needed */
-
- /* where? */
- assert(m->coldp != NULL);
- for (;;) {
- NOTE("finding start");
- endp = slow(m, m->coldp, stop, gf, gl);
- if (endp != NULL)
- break;
- assert(m->coldp < m->endp);
- m->coldp++;
- }
- if (nmatch == 1 && !g->backrefs)
- break; /* no further info needed */
-
- /* oh my, he wants the subexpressions... */
- if (m->pmatch == NULL)
- m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) *
- sizeof(regmatch_t));
- if (m->pmatch == NULL) {
- STATETEARDOWN(m);
- return(REG_ESPACE);
- }
- for (i = 1; i <= m->g->nsub; i++)
- m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1;
- if (!g->backrefs && !(m->eflags®_BACKR)) {
- NOTE("dissecting");
- dp = dissect(m, m->coldp, endp, gf, gl);
- } else {
- if (g->nplus > 0 && m->lastpos == NULL)
- m->lastpos = (char **)malloc((g->nplus+1) *
- sizeof(char *));
- if (g->nplus > 0 && m->lastpos == NULL) {
- free(m->pmatch);
- STATETEARDOWN(m);
- return(REG_ESPACE);
- }
- NOTE("backref dissect");
- dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
- }
- if (dp != NULL)
- break;
-
- /* uh-oh... we couldn't find a subexpression-level match */
- assert(g->backrefs); /* must be back references doing it */
- assert(g->nplus == 0 || m->lastpos != NULL);
- for (;;) {
- if (dp != NULL || endp <= m->coldp)
- break; /* defeat */
- NOTE("backoff");
- endp = slow(m, m->coldp, endp-1, gf, gl);
- if (endp == NULL)
- break; /* defeat */
- /* try it on a shorter possibility */
- NOTE("backoff dissect");
- dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
- }
- assert(dp == NULL || dp == endp);
- if (dp != NULL) /* found a shorter one */
- break;
-
- /* despite initial appearances, there is no match here */
- NOTE("false alarm");
- start = m->coldp + 1; /* recycle starting later */
- assert(start <= stop);
- }
-
- /* fill in the details if requested */
- if (nmatch > 0) {
- pmatch[0].rm_so = m->coldp - m->offp;
- pmatch[0].rm_eo = endp - m->offp;
- }
- if (nmatch > 1) {
- assert(m->pmatch != NULL);
- for (i = 1; i < nmatch; i++)
- if (i <= m->g->nsub)
- pmatch[i] = m->pmatch[i];
- else {
- pmatch[i].rm_so = -1;
- pmatch[i].rm_eo = -1;
- }
- }
-
- if (m->pmatch != NULL)
- free((char *)m->pmatch);
- if (m->lastpos != NULL)
- free((char *)m->lastpos);
- STATETEARDOWN(m);
- return(0);
-}
-
-/*
- - dissect - figure out what matched what, no back references
- == static char *dissect(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst);
- */
-static char * /* == stop (success) always */
-dissect(m, start, stop, startst, stopst)
-register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
-{
- register int i;
- register sopno ss; /* start sop of current subRE */
- register sopno es; /* end sop of current subRE */
- register char *sp; /* start of string matched by it */
- register char *stp; /* string matched by it cannot pass here */
- register char *rest; /* start of rest of string */
- register char *tail; /* string unmatched by rest of RE */
- register sopno ssub; /* start sop of subsubRE */
- register sopno esub; /* end sop of subsubRE */
- register char *ssp; /* start of string matched by subsubRE */
- register char *sep; /* end of string matched by subsubRE */
- register char *oldssp; /* previous ssp */
- register char *dp;
-
- AT("diss", start, stop, startst, stopst);
- sp = start;
- for (ss = startst; ss < stopst; ss = es) {
- /* identify end of subRE */
- es = ss;
- switch (OP(m->g->strip[es])) {
- case OPLUS_:
- case OQUEST_:
- es += OPND(m->g->strip[es]);
- break;
- case OCH_:
- while (OP(m->g->strip[es]) != O_CH)
- es += OPND(m->g->strip[es]);
- break;
- }
- es++;
-
- /* figure out what it matched */
- switch (OP(m->g->strip[ss])) {
- case OEND:
- assert(nope);
- break;
- case OCHAR:
- sp++;
- break;
- case OBOL:
- case OEOL:
- case OBOW:
- case OEOW:
- break;
- case OANY:
- case OANYOF:
- sp++;
- break;
- case OBACK_:
- case O_BACK:
- assert(nope);
- break;
- /* cases where length of match is hard to find */
- case OQUEST_:
- stp = stop;
- for (;;) {
- /* how long could this one be? */
- rest = slow(m, sp, stp, ss, es);
- assert(rest != NULL); /* it did match */
- /* could the rest match the rest? */
- tail = slow(m, rest, stop, es, stopst);
- if (tail == stop)
- break; /* yes! */
- /* no -- try a shorter match for this one */
- stp = rest - 1;
- assert(stp >= sp); /* it did work */
- }
- ssub = ss + 1;
- esub = es - 1;
- /* did innards match? */
- if (slow(m, sp, rest, ssub, esub) != NULL) {
- dp = dissect(m, sp, rest, ssub, esub);
- assert(dp == rest);
- } else /* no */
- assert(sp == rest);
- sp = rest;
- break;
- case OPLUS_:
- stp = stop;
- for (;;) {
- /* how long could this one be? */
- rest = slow(m, sp, stp, ss, es);
- assert(rest != NULL); /* it did match */
- /* could the rest match the rest? */
- tail = slow(m, rest, stop, es, stopst);
- if (tail == stop)
- break; /* yes! */
- /* no -- try a shorter match for this one */
- stp = rest - 1;
- assert(stp >= sp); /* it did work */
- }
- ssub = ss + 1;
- esub = es - 1;
- ssp = sp;
- oldssp = ssp;
- for (;;) { /* find last match of innards */
- sep = slow(m, ssp, rest, ssub, esub);
- if (sep == NULL || sep == ssp)
- break; /* failed or matched null */
- oldssp = ssp; /* on to next try */
- ssp = sep;
- }
- if (sep == NULL) {
- /* last successful match */
- sep = ssp;
- ssp = oldssp;
- }
- assert(sep == rest); /* must exhaust substring */
- assert(slow(m, ssp, sep, ssub, esub) == rest);
- dp = dissect(m, ssp, sep, ssub, esub);
- assert(dp == sep);
- sp = rest;
- break;
- case OCH_:
- stp = stop;
- for (;;) {
- /* how long could this one be? */
- rest = slow(m, sp, stp, ss, es);
- assert(rest != NULL); /* it did match */
- /* could the rest match the rest? */
- tail = slow(m, rest, stop, es, stopst);
- if (tail == stop)
- break; /* yes! */
- /* no -- try a shorter match for this one */
- stp = rest - 1;
- assert(stp >= sp); /* it did work */
- }
- ssub = ss + 1;
- esub = ss + OPND(m->g->strip[ss]) - 1;
- assert(OP(m->g->strip[esub]) == OOR1);
- for (;;) { /* find first matching branch */
- if (slow(m, sp, rest, ssub, esub) == rest)
- break; /* it matched all of it */
- /* that one missed, try next one */
- assert(OP(m->g->strip[esub]) == OOR1);
- esub++;
- assert(OP(m->g->strip[esub]) == OOR2);
- ssub = esub + 1;
- esub += OPND(m->g->strip[esub]);
- if (OP(m->g->strip[esub]) == OOR2)
- esub--;
- else
- assert(OP(m->g->strip[esub]) == O_CH);
- }
- dp = dissect(m, sp, rest, ssub, esub);
- assert(dp == rest);
- sp = rest;
- break;
- case O_PLUS:
- case O_QUEST:
- case OOR1:
- case OOR2:
- case O_CH:
- assert(nope);
- break;
- case OLPAREN:
- i = OPND(m->g->strip[ss]);
- assert(0 < i && i <= m->g->nsub);
- m->pmatch[i].rm_so = sp - m->offp;
- break;
- case ORPAREN:
- i = OPND(m->g->strip[ss]);
- assert(0 < i && i <= m->g->nsub);
- m->pmatch[i].rm_eo = sp - m->offp;
- break;
- default: /* uh oh */
- assert(nope);
- break;
- }
- }
-
- assert(sp == stop);
- return(sp);
-}
-
-/*
- - backref - figure out what matched what, figuring in back references
- == static char *backref(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst, sopno lev);
- */
-static char * /* == stop (success) or NULL (failure) */
-backref(m, start, stop, startst, stopst, lev)
-register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
-sopno lev; /* PLUS nesting level */
-{
- register int i;
- register sopno ss; /* start sop of current subRE */
- register char *sp; /* start of string matched by it */
- register sopno ssub; /* start sop of subsubRE */
- register sopno esub; /* end sop of subsubRE */
- register char *ssp; /* start of string matched by subsubRE */
- register char *dp;
- register size_t len;
- register int hard;
- register sop s;
- register regoff_t offsave;
- register cset *cs;
-
- AT("back", start, stop, startst, stopst);
- sp = start;
-
- /* get as far as we can with easy stuff */
- hard = 0;
- for (ss = startst; !hard && ss < stopst; ss++)
- switch (OP(s = m->g->strip[ss])) {
- case OCHAR:
- if (sp == stop || *sp++ != (char)OPND(s))
- return(NULL);
- break;
- case OANY:
- if (sp == stop)
- return(NULL);
- sp++;
- break;
- case OANYOF:
- cs = &m->g->sets[OPND(s)];
- if (sp == stop || !CHIN(cs, *sp++))
- return(NULL);
- break;
- case OBOL:
- if ( (sp == m->beginp && !(m->eflags®_NOTBOL)) ||
- (sp < m->endp && *(sp-1) == '\n' &&
- (m->g->cflags®_NEWLINE)) )
- { /* yes */ }
- else
- return(NULL);
- break;
- case OEOL:
- if ( (sp == m->endp && !(m->eflags®_NOTEOL)) ||
- (sp < m->endp && *sp == '\n' &&
- (m->g->cflags®_NEWLINE)) )
- { /* yes */ }
- else
- return(NULL);
- break;
- case OBOW:
- if (( (sp == m->beginp && !(m->eflags®_NOTBOL)) ||
- (sp < m->endp && *(sp-1) == '\n' &&
- (m->g->cflags®_NEWLINE)) ||
- (sp > m->beginp &&
- !ISWORD(*(sp-1))) ) &&
- (sp < m->endp && ISWORD(*sp)) )
- { /* yes */ }
- else
- return(NULL);
- break;
- case OEOW:
- if (( (sp == m->endp && !(m->eflags®_NOTEOL)) ||
- (sp < m->endp && *sp == '\n' &&
- (m->g->cflags®_NEWLINE)) ||
- (sp < m->endp && !ISWORD(*sp)) ) &&
- (sp > m->beginp && ISWORD(*(sp-1))) )
- { /* yes */ }
- else
- return(NULL);
- break;
- case O_QUEST:
- break;
- case OOR1: /* matches null but needs to skip */
- ss++;
- s = m->g->strip[ss];
- do {
- assert(OP(s) == OOR2);
- ss += OPND(s);
- } while (OP(s = m->g->strip[ss]) != O_CH);
- /* note that the ss++ gets us past the O_CH */
- break;
- default: /* have to make a choice */
- hard = 1;
- break;
- }
- if (!hard) { /* that was it! */
- if (sp != stop)
- return(NULL);
- return(sp);
- }
- ss--; /* adjust for the for's final increment */
-
- /* the hard stuff */
- AT("hard", sp, stop, ss, stopst);
- s = m->g->strip[ss];
- switch (OP(s)) {
- case OBACK_: /* the vilest depths */
- i = OPND(s);
- assert(0 < i && i <= m->g->nsub);
- if (m->pmatch[i].rm_eo == -1)
- return(NULL);
- assert(m->pmatch[i].rm_so != -1);
- len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so;
- assert(stop - m->beginp >= len);
- if (sp > stop - len)
- return(NULL); /* not enough left to match */
- ssp = m->offp + m->pmatch[i].rm_so;
- if (memcmp(sp, ssp, len) != 0)
- return(NULL);
- while (m->g->strip[ss] != SOP(O_BACK, i))
- ss++;
- return(backref(m, sp+len, stop, ss+1, stopst, lev));
- break;
- case OQUEST_: /* to null or not */
- dp = backref(m, sp, stop, ss+1, stopst, lev);
- if (dp != NULL)
- return(dp); /* not */
- return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev));
- break;
- case OPLUS_:
- assert(m->lastpos != NULL);
- assert(lev+1 <= m->g->nplus);
- m->lastpos[lev+1] = sp;
- return(backref(m, sp, stop, ss+1, stopst, lev+1));
- break;
- case O_PLUS:
- if (sp == m->lastpos[lev]) /* last pass matched null */
- return(backref(m, sp, stop, ss+1, stopst, lev-1));
- /* try another pass */
- m->lastpos[lev] = sp;
- dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev);
- if (dp == NULL)
- return(backref(m, sp, stop, ss+1, stopst, lev-1));
- else
- return(dp);
- break;
- case OCH_: /* find the right one, if any */
- ssub = ss + 1;
- esub = ss + OPND(s) - 1;
- assert(OP(m->g->strip[esub]) == OOR1);
- for (;;) { /* find first matching branch */
- dp = backref(m, sp, stop, ssub, esub, lev);
- if (dp != NULL)
- return(dp);
- /* that one missed, try next one */
- if (OP(m->g->strip[esub]) == O_CH)
- return(NULL); /* there is none */
- esub++;
- assert(OP(m->g->strip[esub]) == OOR2);
- ssub = esub + 1;
- esub += OPND(m->g->strip[esub]);
- if (OP(m->g->strip[esub]) == OOR2)
- esub--;
- else
- assert(OP(m->g->strip[esub]) == O_CH);
- }
- break;
- case OLPAREN: /* must undo assignment if rest fails */
- i = OPND(s);
- assert(0 < i && i <= m->g->nsub);
- offsave = m->pmatch[i].rm_so;
- m->pmatch[i].rm_so = sp - m->offp;
- dp = backref(m, sp, stop, ss+1, stopst, lev);
- if (dp != NULL)
- return(dp);
- m->pmatch[i].rm_so = offsave;
- return(NULL);
- break;
- case ORPAREN: /* must undo assignment if rest fails */
- i = OPND(s);
- assert(0 < i && i <= m->g->nsub);
- offsave = m->pmatch[i].rm_eo;
- m->pmatch[i].rm_eo = sp - m->offp;
- dp = backref(m, sp, stop, ss+1, stopst, lev);
- if (dp != NULL)
- return(dp);
- m->pmatch[i].rm_eo = offsave;
- return(NULL);
- break;
- default: /* uh oh */
- assert(nope);
- break;
- }
-
- /* "can't happen" */
- assert(nope);
- /* NOTREACHED */
- return((char *)NULL); /* dummy */
-}
-
-/*
- - fast - step through the string at top speed
- == static char *fast(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst);
- */
-static char * /* where tentative match ended, or NULL */
-fast(m, start, stop, startst, stopst)
-register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
-{
- register states st = m->st;
- register states fresh = m->fresh;
- register states tmp = m->tmp;
- register char *p = start;
- register int c = (start == m->beginp) ? OUT : *(start-1);
- register int lastc; /* previous c */
- register int flagch;
- register int i;
- register char *coldp; /* last p after which no match was underway */
-
- CLEAR(st);
- SET1(st, startst);
- st = step(m->g, startst, stopst, st, NOTHING, st);
- ASSIGN(fresh, st);
- SP("start", st, *p);
- coldp = NULL;
- for (;;) {
- /* next character */
- lastc = c;
- c = (p == m->endp) ? OUT : *p;
- if (EQ(st, fresh))
- coldp = p;
-
- /* is there an EOL and/or BOL between lastc and c? */
- flagch = '\0';
- i = 0;
- if ( (lastc == '\n' && m->g->cflags®_NEWLINE) ||
- (lastc == OUT && !(m->eflags®_NOTBOL)) ) {
- flagch = BOL;
- i = m->g->nbol;
- }
- if ( (c == '\n' && m->g->cflags®_NEWLINE) ||
- (c == OUT && !(m->eflags®_NOTEOL)) ) {
- flagch = (flagch == BOL) ? BOLEOL : EOL;
- i += m->g->neol;
- }
- if (i != 0) {
- for (; i > 0; i--)
- st = step(m->g, startst, stopst, st, flagch, st);
- SP("boleol", st, c);
- }
-
- /* how about a word boundary? */
- if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
- (c != OUT && ISWORD(c)) ) {
- flagch = BOW;
- }
- if ( (lastc != OUT && ISWORD(lastc)) &&
- (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
- flagch = EOW;
- }
- if (flagch == BOW || flagch == EOW) {
- st = step(m->g, startst, stopst, st, flagch, st);
- SP("boweow", st, c);
- }
-
- /* are we done? */
- if (ISSET(st, stopst) || p == stop)
- break; /* NOTE BREAK OUT */
-
- /* no, we must deal with this character */
- ASSIGN(tmp, st);
- ASSIGN(st, fresh);
- assert(c != OUT);
- st = step(m->g, startst, stopst, tmp, c, st);
- SP("aft", st, c);
- assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
- p++;
- }
-
- assert(coldp != NULL);
- m->coldp = coldp;
- if (ISSET(st, stopst))
- return(p+1);
- else
- return(NULL);
-}
-
-/*
- - slow - step through the string more deliberately
- == static char *slow(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst);
- */
-static char * /* where it ended */
-slow(m, start, stop, startst, stopst)
-register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
-{
- register states st = m->st;
- register states empty = m->empty;
- register states tmp = m->tmp;
- register char *p = start;
- register int c = (start == m->beginp) ? OUT : *(start-1);
- register int lastc; /* previous c */
- register int flagch;
- register int i;
- register char *matchp; /* last p at which a match ended */
-
- AT("slow", start, stop, startst, stopst);
- CLEAR(st);
- SET1(st, startst);
- SP("sstart", st, *p);
- st = step(m->g, startst, stopst, st, NOTHING, st);
- matchp = NULL;
- for (;;) {
- /* next character */
- lastc = c;
- c = (p == m->endp) ? OUT : *p;
-
- /* is there an EOL and/or BOL between lastc and c? */
- flagch = '\0';
- i = 0;
- if ( (lastc == '\n' && m->g->cflags®_NEWLINE) ||
- (lastc == OUT && !(m->eflags®_NOTBOL)) ) {
- flagch = BOL;
- i = m->g->nbol;
- }
- if ( (c == '\n' && m->g->cflags®_NEWLINE) ||
- (c == OUT && !(m->eflags®_NOTEOL)) ) {
- flagch = (flagch == BOL) ? BOLEOL : EOL;
- i += m->g->neol;
- }
- if (i != 0) {
- for (; i > 0; i--)
- st = step(m->g, startst, stopst, st, flagch, st);
- SP("sboleol", st, c);
- }
-
- /* how about a word boundary? */
- if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
- (c != OUT && ISWORD(c)) ) {
- flagch = BOW;
- }
- if ( (lastc != OUT && ISWORD(lastc)) &&
- (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
- flagch = EOW;
- }
- if (flagch == BOW || flagch == EOW) {
- st = step(m->g, startst, stopst, st, flagch, st);
- SP("sboweow", st, c);
- }
-
- /* are we done? */
- if (ISSET(st, stopst))
- matchp = p;
- if (EQ(st, empty) || p == stop)
- break; /* NOTE BREAK OUT */
-
- /* no, we must deal with this character */
- ASSIGN(tmp, st);
- ASSIGN(st, empty);
- assert(c != OUT);
- st = step(m->g, startst, stopst, tmp, c, st);
- SP("saft", st, c);
- assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
- p++;
- }
-
- return(matchp);
-}
-
-
-static states
-step(g, start, stop, bef, ch, aft)
-register struct re_guts *g;
-sopno start; /* start state within strip */
-sopno stop; /* state after stop state within strip */
-register states bef; /* states reachable before */
-int ch; /* character or NONCHAR code */
-register states aft; /* states already known reachable after */
-{
- register cset *cs;
- register sop s;
- register sopno pc;
- register onestate here; /* note, macros know this name */
- register sopno look;
- register long i;
-
- for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) {
- s = g->strip[pc];
- switch (OP(s)) {
- case OEND:
- assert(pc == stop-1);
- break;
- case OCHAR:
- /* only characters can match */
- assert(!NONCHAR(ch) || ch != (char)OPND(s));
- if (ch == (char)OPND(s))
- FWD(aft, bef, 1);
- break;
- case OBOL:
- if (ch == BOL || ch == BOLEOL)
- FWD(aft, bef, 1);
- break;
- case OEOL:
- if (ch == EOL || ch == BOLEOL)
- FWD(aft, bef, 1);
- break;
- case OBOW:
- if (ch == BOW)
- FWD(aft, bef, 1);
- break;
- case OEOW:
- if (ch == EOW)
- FWD(aft, bef, 1);
- break;
- case OANY:
- if (!NONCHAR(ch))
- FWD(aft, bef, 1);
- break;
- case OANYOF:
- cs = &g->sets[OPND(s)];
- if (!NONCHAR(ch) && CHIN(cs, ch))
- FWD(aft, bef, 1);
- break;
- case OBACK_: /* ignored here */
- case O_BACK:
- FWD(aft, aft, 1);
- break;
- case OPLUS_: /* forward, this is just an empty */
- FWD(aft, aft, 1);
- break;
- case O_PLUS: /* both forward and back */
- FWD(aft, aft, 1);
- i = ISSETBACK(aft, OPND(s));
- BACK(aft, aft, OPND(s));
- if (!i && ISSETBACK(aft, OPND(s))) {
- /* oho, must reconsider loop body */
- pc -= OPND(s) + 1;
- INIT(here, pc);
- }
- break;
- case OQUEST_: /* two branches, both forward */
- FWD(aft, aft, 1);
- FWD(aft, aft, OPND(s));
- break;
- case O_QUEST: /* just an empty */
- FWD(aft, aft, 1);
- break;
- case OLPAREN: /* not significant here */
- case ORPAREN:
- FWD(aft, aft, 1);
- break;
- case OCH_: /* mark the first two branches */
- FWD(aft, aft, 1);
- assert(OP(g->strip[pc+OPND(s)]) == OOR2);
- FWD(aft, aft, OPND(s));
- break;
- case OOR1: /* done a branch, find the O_CH */
- if (ISSTATEIN(aft, here)) {
- for (look = 1;
- OP(s = g->strip[pc+look]) != O_CH;
- look += OPND(s))
- assert(OP(s) == OOR2);
- FWD(aft, aft, look);
- }
- break;
- case OOR2: /* propagate OCH_'s marking */
- FWD(aft, aft, 1);
- if (OP(g->strip[pc+OPND(s)]) != O_CH) {
- assert(OP(g->strip[pc+OPND(s)]) == OOR2);
- FWD(aft, aft, OPND(s));
- }
- break;
- case O_CH: /* just empty */
- FWD(aft, aft, 1);
- break;
- default: /* ooooops... */
- assert(nope);
- break;
- }
- }
-
- return(aft);
-}
-
-#undef matcher
-#undef fast
-#undef slow
-#undef dissect
-#undef backref
-#undef step
-#undef print
-#undef at
-#undef match
-
-int /* 0 success, REG_NOMATCH failure */
-regexec(preg, string, nmatch, pmatch, eflags)
-const regex_t *preg;
-const char *string;
-size_t nmatch;
-regmatch_t pmatch[];
-int eflags;
-{
- register struct re_guts *g = preg->re_g;
-#define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
-
- if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
- return(REG_BADPAT);
- assert(!(g->iflags&BAD));
- if (g->iflags&BAD) /* backstop for no-debug case */
- return(REG_BADPAT);
- eflags = GOODFLAGS(eflags);
-
- if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags®_LARGE))
- return(smatcher(g, (char *)string, nmatch, pmatch, eflags));
- else
- return(lmatcher(g, (char *)string, nmatch, pmatch, eflags));
-#undef GOODFLAGS
-}
-/*
- - regfree - free everything
- = extern void regfree(regex_t *);
- */
-void
-regfree(preg)
-regex_t *preg;
-{
- register struct re_guts *g;
-
- if (preg->re_magic != MAGIC1) /* oops */
- return; /* nice to complain, but hard */
-
- g = preg->re_g;
- if (g == NULL || g->magic != MAGIC2) /* oops again */
- return;
- preg->re_magic = 0; /* mark it invalid */
- g->magic = 0; /* mark it invalid */
-
- if (g->strip != NULL)
- free((char *)g->strip);
- if (g->sets != NULL)
- free((char *)g->sets);
- if (g->setbits != NULL)
- free((char *)g->setbits);
- if (g->must != NULL)
- free(g->must);
- free((char *)g);
-}
-
-#ifdef WITH_MAIN
-int main(int argc, char* argv[]){
- regex_t preg;
- int i, s;
- if(argc<2) return 1;
- if (regcomp(&preg, argv[1], REG_NOSUB)) {
- fprintf(stderr, "Failed to compile regex\n");
- return 2;
- }
- for (i = 2; i
-#include
-
-
-#define uchar unsigned char
-
-static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9,
- 1, 58, 50, 42, 34, 26, 18,
- 10, 2, 59, 51, 43, 35, 27,
- 19, 11, 3, 60, 52, 44, 36,
- 63, 55, 47, 39, 31, 23, 15,
- 7, 62, 54, 46, 38, 30, 22,
- 14, 6, 61, 53, 45, 37, 29,
- 21, 13, 5, 28, 20, 12, 4};
-
-static const uchar perm2[48] = {14, 17, 11, 24, 1, 5,
- 3, 28, 15, 6, 21, 10,
- 23, 19, 12, 4, 26, 8,
- 16, 7, 27, 20, 13, 2,
- 41, 52, 31, 37, 47, 55,
- 30, 40, 51, 45, 33, 48,
- 44, 49, 39, 56, 34, 53,
- 46, 42, 50, 36, 29, 32};
-
-static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2,
- 60, 52, 44, 36, 28, 20, 12, 4,
- 62, 54, 46, 38, 30, 22, 14, 6,
- 64, 56, 48, 40, 32, 24, 16, 8,
- 57, 49, 41, 33, 25, 17, 9, 1,
- 59, 51, 43, 35, 27, 19, 11, 3,
- 61, 53, 45, 37, 29, 21, 13, 5,
- 63, 55, 47, 39, 31, 23, 15, 7};
-
-static const uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
- 4, 5, 6, 7, 8, 9,
- 8, 9, 10, 11, 12, 13,
- 12, 13, 14, 15, 16, 17,
- 16, 17, 18, 19, 20, 21,
- 20, 21, 22, 23, 24, 25,
- 24, 25, 26, 27, 28, 29,
- 28, 29, 30, 31, 32, 1};
-
-static const uchar perm5[32] = { 16, 7, 20, 21,
- 29, 12, 28, 17,
- 1, 15, 23, 26,
- 5, 18, 31, 10,
- 2, 8, 24, 14,
- 32, 27, 3, 9,
- 19, 13, 30, 6,
- 22, 11, 4, 25};
-
-
-static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
- 39, 7, 47, 15, 55, 23, 63, 31,
- 38, 6, 46, 14, 54, 22, 62, 30,
- 37, 5, 45, 13, 53, 21, 61, 29,
- 36, 4, 44, 12, 52, 20, 60, 28,
- 35, 3, 43, 11, 51, 19, 59, 27,
- 34, 2, 42, 10, 50, 18, 58, 26,
- 33, 1, 41, 9, 49, 17, 57, 25};
-
-
-static const uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
-
-static const uchar sbox[8][4][16] = {
- {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
- {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
- {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
- {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
-
- {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
- {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
- {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
- {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
-
- {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
- {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
- {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
- {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
-
- {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
- {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
- {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
- {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
-
- {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
- {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
- {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
- {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
-
- {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
- {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
- {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
- {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
-
- {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
- {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
- {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
- {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
-
- {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
- {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
- {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
- {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}};
-
-static void permute(char *out, const char *in, const uchar *p, int n)
-{
- int i;
- for (i=0;i>1;
- key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
- key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
- key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
- key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
- key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
- key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
- key[7] = str[6]&0x7F;
- for (i=0;i<8;i++) {
- key[i] = (key[i]<<1);
- }
-}
-
-
-static void smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
-{
- int i;
- char outb[64];
- char inb[64];
- char keyb[64];
- unsigned char key2[8];
-
- str_to_key(key, key2);
-
- for (i=0;i<64;i++) {
- inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
- keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
- outb[i] = 0;
- }
-
- dohash(outb, inb, keyb);
-
- for (i=0;i<8;i++) {
- out[i] = 0;
- }
-
- for (i=0;i<64;i++) {
- if (outb[i])
- out[i/8] |= (1<<(7-(i%8)));
- }
-}
-
-/*
- * Converts the password to uppercase, and creates the LM
- * password hash.
- */
-void lmpwdhash(const unsigned char *password,unsigned char *lmhash)
-{
- int i;
- unsigned char p14[14];
- static unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
-
- memset(p14, 0, sizeof(p14));
- for (i = 0; i < 14 && password[i]; i++) {
- p14[i] = toupper((int) password[i]);
- }
-
- smbhash(lmhash, sp8, p14);
- smbhash(lmhash+8, sp8, p14+7);
-}
-
-/*
- * Take the NT or LM password, and return the MSCHAP response
- *
- * The win_password MUST be exactly 16 bytes long.
- */
-void mschap(const unsigned char *win_password,
- const unsigned char *challenge, unsigned char *response)
-{
- unsigned char p21[21];
-
- memset(p21, 0, sizeof(p21));
- memcpy(p21, win_password, 16);
-
- smbhash(response, challenge, p21);
- smbhash(response+8, challenge, p21+7);
- smbhash(response+16, challenge, p21+14);
-}
diff --git a/src/log.c b/src/log.c
index 7572565e..9cf51be0 100644
--- a/src/log.c
+++ b/src/log.c
@@ -6,33 +6,485 @@
*/
-
-
-
#include "proxy.h"
pthread_mutex_t log_mutex;
-int havelog = 0;
+#ifdef _WIN32
+HANDLE log_sem;
+#else
+sem_t log_sem;
+#endif
+#define MAXLOG 1024
+#define EVENTSIZE (4096 - sizeof(void *))
+#define LOGBUFSIZE (EVENTSIZE - sizeof(struct logevent))
+#define MAX_SEM_COUNT 256
+typedef enum {
+ REGISTER,
+ UNREGISTER,
+ LOG,
+ FLUSH,
+ FREEPARAM
+} EVENTTYPE;
+
+static int loginit = 0;
struct clientparam logparam;
struct srvparam logsrv;
+struct LOGGER;
+struct logevent {
+ struct logevent *next;
+ struct LOGGER *log;
+ EVENTTYPE event;
+ int inbuf;
+ struct clientparam *param;
+ char * logstring;
+ char buf[1];
+} *logtail=NULL, *loghead=NULL;
-void dolog(struct clientparam * param, const unsigned char *s){
- static int init = 0;
- if(param)param->srv->logfunc(param, s);
+
+static void delayflushlogs(void);
+static void delayunregisterlog (struct LOGGER * log);
+static void delayregisterlog (struct LOGGER * log);
+static void delaydolog(struct logevent *evt);
+static void delayfreeparam(struct clientparam *param);
+
+static void initlog2(void);
+
+void logpush(struct logevent *evt);
+
+#ifdef WITHMAIN
+#define HAVERADIUS 0
+#define HAVESQL 0
+#else
+#ifndef NORADIUS
+int raddobuf(struct clientparam * param, char * buf, int bufsize, const char *s);
+void logradius(const char * buf, int len, struct LOGGER *logger);
+#define HAVERADIUS 1
+#else
+#define HAVERADIUS 0
+#endif
+#ifndef NOODBC
+#define HAVESQL 1
+static int sqlinit(struct LOGGER *logger);
+static int sqldobuf(struct clientparam * param, char * buf, int bufsize, const char *s);
+static void sqllog(const char * buf, int len, struct LOGGER *logger);
+static void sqlrotate(struct LOGGER *logger);
+static void sqlclose(struct LOGGER *logger);
+#else
+#define HAVESQL 0
+#endif
+#endif
+
+#ifdef _WIN32
+#define HAVESYSLOG 0
+#else
+#define HAVESYSLOG 1
+static int sysloginit(struct LOGGER *logger);
+static void logsyslog(const char * buf, int len, struct LOGGER *logger);
+static void syslogrotate(struct LOGGER *logger);
+static void syslogclose(struct LOGGER *logger);
+#endif
+
+static int stdloginit(struct LOGGER *logger);
+static int stddobuf(struct clientparam * param, char * buf, int bufsize, const char *s);
+static void stdlog(const char * buf, int len, struct LOGGER *logger);
+static void stdlogrotate(struct LOGGER *logger);
+static void stdlogclose(struct LOGGER *logger);
+static void stdlogflush(struct LOGGER *logger);
+
+
+struct LOGFUNC stdlogfuncs[] = {
+#if HAVESYSLOG > 0
+ {stdlogfuncs+1, sysloginit, stddobuf, logsyslog, syslogrotate, NULL, syslogclose, "@"},
+#endif
+#if HAVERADIUS > 0
+ {stdlogfuncs+1+HAVESYSLOG, NULL, raddobuf, logradius, NULL, NULL, NULL, "radius"},
+#endif
+#if HAVESQL > 0
+ {stdlogfuncs+1+HAVESYSLOG+HAVERADIUS, sqlinit, sqldobuf, sqllog, sqlrotate, NULL, sqlclose, "&"},
+#endif
+ {NULL, stdloginit, stddobuf, stdlog, stdlogrotate, stdlogflush, stdlogclose, ""}
+ };
+
+struct LOGFUNC *logfuncs = stdlogfuncs;
+
+struct stdlogdata{
+ FILE *fp;
+} errld;
+
+struct LOGGER errlogger = {NULL, NULL, "stderr", &errld, stdlogfuncs+1+HAVESYSLOG+HAVERADIUS+HAVESQL, 0, 0, 1};
+
+struct LOGGER *loggers = &errlogger;
+
+
+
+static void delayflushlogs(void){
+ struct LOGGER *log;
+ for(log = loggers; log; log=log->next){
+ if(log->logfunc && log->logfunc->flush)log->logfunc->flush(log);
+#ifndef WITHMAIN
+ if(log->rotate && log->logfunc && log->logfunc->rotate && timechanged(log->rotated, conf.time, log->rotate)){
+ log->logfunc->rotate(log);
+ log->rotated = conf.time;
+ }
+#endif
+ }
+}
+
+
+
+void flushlogs(void){
+ if(loginit){
+ struct logevent * evt;
+ evt = malloc(sizeof(struct logevent));
+ evt->event = FLUSH;
+ logpush(evt);
+ }
+}
+
+
+void delayregisterlog(struct LOGGER *log){
+ struct LOGFUNC *funcs;
+
+
+ if(log->logfunc) return;
+ for(funcs = logfuncs; funcs; funcs=funcs->next){
+ if(!strncmp(log->selector, funcs->prefix, strlen(funcs->prefix))){
+ if(funcs->init && funcs->init(log)) break;
+ log->logfunc = funcs;
+ log->rotated = conf.time;
+ return;
+ }
+ }
+}
+
+
+struct LOGGER * registerlog(const char * logstring, int logtype){
+ struct LOGGER *log;
+
+ if(!logstring || !strcmp(logstring, "NUL") || !strcmp(logstring, "/dev/null")) return NULL;
+ pthread_mutex_lock(&log_mutex);
+ if(!loginit){
+ initlog2();
+ loginit = 1;
+ }
+ for(log = loggers; log; log=log->next){
+ if(!strcmp(logstring, log->selector)){
+ if(logtype >= 0) log->rotate = logtype;
+ log->registered++;
+ pthread_mutex_unlock(&log_mutex);
+ return log;
+ }
+ }
+ log = malloc(sizeof(struct LOGGER));
+ if(!log) {
+ pthread_mutex_unlock(&log_mutex);
+ return NULL;
+ }
+ memset (log, 0, sizeof(struct LOGGER));
+ log->selector = mystrdup(logstring);
+ if(log->selector){
+ struct logevent *evt;
+ if(logtype)log->rotate = logtype;
+ log->registered++;
+ log->next = loggers;
+ if (log->next)log->next->prev = log;
+ loggers = log;
+ pthread_mutex_unlock(&log_mutex);
+
+ evt = malloc(sizeof(struct logevent));
+ evt->event = REGISTER;
+ evt->log = log;
+ logpush(evt);
+ return log;
+ }
+ pthread_mutex_unlock(&log_mutex);
+ myfree(log);
+ return NULL;
+}
+
+static void delayunregisterlog (struct LOGGER * log){
+ if(log){
+ pthread_mutex_lock(&log_mutex);
+ log->registered--;
+ if(!log->registered){
+ if(log->prev)log->prev->next = log->next;
+ else loggers = log->next;
+ if(log->next)log->next->prev = log->prev;
+ pthread_mutex_unlock(&log_mutex);
+
+ if(log->logfunc){
+ if(log->logfunc->flush) log->logfunc->flush(log);
+ if(log->logfunc->close) log->logfunc->close(log);
+ }
+ myfree(log->selector);
+ myfree(log);
+ }
+ else pthread_mutex_unlock(&log_mutex);
+
+ }
+}
+
+void unregisterlog (struct LOGGER * log){
+ struct logevent *evt;
+
+ if(!log) return;
+ evt = malloc(sizeof(struct logevent));
+ evt->event = UNREGISTER;
+ evt->log = log;
+ logpush(evt);
+}
+
+#ifdef _WIN32
+DWORD WINAPI logthreadfunc(LPVOID p) {
+#else
+void * logthreadfunc (void *p) {
+#endif
+
+ for(;;){
+ struct logevent *evt;
+#ifdef _WIN32
+ WaitForSingleObject(log_sem, INFINITE);
+#else
+ sem_wait(&log_sem);
+#endif
+
+ while(loghead){
+ pthread_mutex_lock(&log_mutex);
+ evt = loghead;
+ loghead = evt->next;
+ if(!loghead)logtail = NULL;
+ pthread_mutex_unlock(&log_mutex);
+ switch(evt->event){
+ case REGISTER:
+ delayregisterlog(evt->log);
+ break;
+ case UNREGISTER:
+ delayunregisterlog(evt->log);
+ break;
+ case FLUSH:
+ delayflushlogs();
+ break;
+ case LOG:
+ delaydolog(evt);
+ break;
+ case FREEPARAM:
+ delayfreeparam(evt->param);
+ break;
+
+ default:
+ break;
+ }
+ myfree(evt);
+ }
+
+
+
+ }
+
+ return 0;
+}
+
+
+
+void logpush(struct logevent *evt){
+ pthread_mutex_lock(&log_mutex);
+ if(!loginit){
+ if(evt->event == FREEPARAM){
+ delayfreeparam(evt->param);
+ }
+ myfree(evt);
+ pthread_mutex_unlock(&log_mutex);
+ return;
+ }
+ if(logtail) logtail->next = evt;
+ logtail = evt;
+ evt->next = NULL;
+ if(!loghead)loghead = evt;
+
+ pthread_mutex_unlock(&log_mutex);
+#ifdef _WIN32
+ ReleaseSemaphore(log_sem, 1, NULL);
+#else
+ sem_post(&log_sem);
+#endif
+}
+
+static void initlog2(void){
+ pthread_t thread;
+
+#ifdef _WIN32
+ HANDLE h;
+ if(!(log_sem = CreateSemaphore(NULL, 0, MAX_SEM_COUNT, NULL))) exit(11);
+#ifndef _WINCE
+ h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, 65536, (void *)logthreadfunc, NULL, 0, &thread);
+#else
+ h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, 65536, (void *)logthreadfunc, NULL, 0, &thread);
+#endif
+ if (h) {
+ CloseHandle(h);
+ }
else {
- if(!init){
- srvinit(&logsrv, &logparam);
- init = 1;
+ exit(10);
+ }
+#else
+ pthread_attr_t pa;
+ pthread_attr_init(&pa);
+
+ pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + 1024*256);
+ pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
+
+ if(sem_init(&log_sem, 0, 0)) exit(11);
+ if(pthread_create(&thread, &pa, logthreadfunc, NULL)) exit(10);
+#endif
+}
+
+void initlog(void){
+ srvinit(&logsrv, &logparam);
+ pthread_mutex_init(&log_mutex, NULL);
+ errld.fp = stdout;
+}
+
+static void delaydolog(struct logevent *evt){
+
+ if(!evt->log->logfunc || !evt->log->logfunc->log) return;
+ if(evt->inbuf){
+ evt->log->logfunc->log(evt->buf, evt->inbuf, evt->log);
+ }
+ else if(evt->param && evt->log->logfunc->dobuf){
+ char buf[LOGBUFSIZE];
+
+ evt->log->logfunc->log(buf, evt->log->logfunc->dobuf(evt->param, buf, LOGBUFSIZE, evt->logstring), evt->log);
+ }
+}
+
+void dolog(struct clientparam * param, const char *s){
+ static int init = 0;
+
+ if(!param || !param->srv){
+ stdlog(s, (int)strlen(s), &errlogger);
+ return;
+ }
+ if(conf.prelog)conf.prelog(param);
+ if(!param->nolog && param->srv->log) {
+ struct logevent *evt;
+
+ if(!param->srv->log->logfunc) {
+ int slen =0, hlen=0, ulen=0;
+
+ slen = s?(int)strlen(s)+1 : 0;
+ hlen = param->hostname? (int)strlen(param->hostname)+1 : 0;
+ ulen = param->username? (int)strlen(param->username)+1 : 0;
+ if(!(evt = malloc(sizeof(struct logevent) + slen + ulen + hlen))) return;
+ evt->inbuf = 0;
+ evt->param=param;
+ evt->logstring = NULL;
+ if(slen){
+ memcpy(evt->buf,s, slen);
+ evt->logstring = evt->buf;
+ }
+ if(hlen){
+ memcpy(evt->buf+slen,param->hostname, hlen);
+ param->hostname = evt->buf + slen;
+ }
+ if(ulen){
+ memcpy(evt->buf+slen+hlen,param->username, ulen);
+ param->username = evt->buf + slen + hlen;
+ }
+ evt->event = LOG;
+ evt->log = param->srv->log;
+ logpush(evt);
+ }
+ else if (param->srv->log->logfunc->log){
+
+ if(!(evt = malloc(param->srv->log->logfunc->dobuf?EVENTSIZE:sizeof(struct logevent)))) return;
+ evt->inbuf = 0;
+ evt->param = NULL;
+ evt->logstring = NULL;
+
+ if(param->srv->log->logfunc->dobuf){
+ evt->inbuf = param->srv->log->logfunc->dobuf(param, evt->buf, LOGBUFSIZE, s);
+ }
+ evt->event = LOG;
+ evt->log = param->srv->log;
+ logpush(evt);
}
- logstdout(&logparam, s);
}
+ if(param->trafcountfunc)(*param->trafcountfunc)(param);
+ clearstat(param);
}
+static void delayfreeparam(struct clientparam * param) {
+ if(param->res == 2) return;
+ if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) {
+ so._shutdown(param->ctrlsocksrv, SHUT_RDWR);
+ so._closesocket(param->ctrlsocksrv);
+ }
+ if(param->ctrlsock != INVALID_SOCKET && param->ctrlsock != param->clisock) {
+ so._shutdown(param->ctrlsock, SHUT_RDWR);
+ so._closesocket(param->ctrlsock);
+ }
+ if(param->remsock != INVALID_SOCKET) {
+ so._shutdown(param->remsock, SHUT_RDWR);
+ so._closesocket(param->remsock);
+ }
+ if(param->clisock != INVALID_SOCKET) {
+ so._shutdown(param->clisock, SHUT_RDWR);
+ so._closesocket(param->clisock);
+ }
+ myfree(param->clibuf);
+ myfree(param->srvbuf);
+ if(param->datfilterssrv) myfree(param->datfilterssrv);
+#ifndef STDMAIN
+ if(param->reqfilters) myfree(param->reqfilters);
+ if(param->hdrfilterscli) myfree(param->hdrfilterscli);
+ if(param->hdrfilterssrv) myfree(param->hdrfilterssrv);
+ if(param->predatfilters) myfree(param->predatfilters);
+ if(param->datfilterscli) myfree(param->datfilterscli);
+ if(param->filters){
+ if(param->nfilters)while(param->nfilters--){
+ if(param->filters[param->nfilters].filter->filter_clear)
+ (*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data);
+ }
+ myfree(param->filters);
+ }
+ if(conf.connlimiter && (param->res != 95 || param->remsock != INVALID_SOCKET)) stopconnlims(param);
+#endif
+ if(param->srv){
+ pthread_mutex_lock(¶m->srv->counter_mutex);
+ if(param->prev){
+ param->prev->next = param->next;
+ }
+ else
+ param->srv->child = param->next;
+ if(param->next){
+ param->next->prev = param->prev;
+ }
+ (param->srv->childcount)--;
+ if(param->srv->service == S_ZOMBIE && !param->srv->child)srvpostfree(param->srv);
+ pthread_mutex_unlock(¶m->srv->counter_mutex);
+ }
+ if(param->hostname) myfree(param->hostname);
+ if(param->username) myfree(param->username);
+ if(param->password) myfree(param->password);
+ if(param->extusername) myfree(param->extusername);
+ if(param->extpassword) myfree(param->extpassword);
+ myfree(param);
+}
+
+void freeparam(struct clientparam * param) {
+ struct logevent *evt;
+
+ evt = malloc(sizeof(struct logevent));
+ evt->event = FREEPARAM;
+ evt->param = param;
+ logpush(evt);
+}
+
void clearstat(struct clientparam * param) {
#ifdef _WIN32
@@ -60,8 +512,48 @@ char months[12][4] = {
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
+char * dologname (char *buf, int bufsize, char *name, const char *ext, ROTATION lt, time_t t) {
+ struct tm *ts;
+
+ ts = localtime(&t);
+ if(strchr((char *)name, '%')){
+ dobuf2(&logparam, buf, bufsize - (ext?(int)strlen(ext):0), NULL, NULL, ts, (char *)name);
+ }
+ else switch(lt){
+ case NONE:
+ sprintf((char *)buf, "%s", name);
+ break;
+ case ANNUALLY:
+ sprintf((char *)buf, "%s.%04d", name, ts->tm_year+1900);
+ break;
+ case MONTHLY:
+ sprintf((char *)buf, "%s.%04d.%02d", name, ts->tm_year+1900, ts->tm_mon+1);
+ break;
+ case WEEKLY:
+ t = t - (ts->tm_wday * (60*60*24));
+ ts = localtime(&t);
+ sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
+ break;
+ case DAILY:
+ sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
+ break;
+ case HOURLY:
+ sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour);
+ break;
+ case MINUTELY:
+ sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour, ts->tm_min);
+ break;
+ default:
+ break;
+ }
+ if(ext){
+ strcat((char *)buf, ".");
+ strcat((char *)buf, (char *)ext);
+ }
+ return buf;
+}
-int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format){
+int dobuf2(struct clientparam * param, char * buf, int bufsize, const char *s, const char * doublec, struct tm* tm, char * format){
int i, j;
int len;
time_t sec;
@@ -96,7 +588,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
delay = param->time_start?((unsigned) ((sec - param->time_start))*1000 + msec) - param->msec_start : 0;
*buf = 0;
- for(i=0, j=0; format[j] && i < 4040; j++){
+ for(i=0, j=0; format[j] && i < (bufsize-70); j++){
if(format[j] == '%' && format[j+1]){
j++;
switch(format[j]){
@@ -158,7 +650,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
break;
case 'U':
if(param->username && *param->username){
- for(len = 0; i< 4000 && param->username[len]; len++){
+ for(len = 0; i< (bufsize - 3) && param->username[len]; len++){
buf[i] = param->username[len];
if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
if(doublec && strchr((char *)doublec, buf[i])) {
@@ -174,7 +666,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
break;
case 'n':
len = param->hostname? (int)strlen((char *)param->hostname) : 0;
- if (len > 0 && !strchr((char *)param->hostname, ':')) for(len = 0; param->hostname[len] && i < 256; len++, i++){
+ if (len > 0 && !strchr((char *)param->hostname, ':')) for(len = 0; param->hostname[len] && i < (bufsize-3); len++, i++){
buf[i] = param->hostname[len];
if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
if(doublec && strchr((char *)doublec, buf[i])) {
@@ -193,7 +685,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
if(param->service < 15) {
len = (conf.stringtable)? (int)strlen((char *)conf.stringtable[SERVICES + param->service]) : 0;
if(len > 20) len = 20;
- memcpy(buf+i, (len)?conf.stringtable[SERVICES + param->service]:(unsigned char*)"-", (len)?len:1);
+ memcpy(buf+i, (len)?conf.stringtable[SERVICES + param->service]:(char*)"-", (len)?len:1);
i += (len)?len:1;
}
break;
@@ -203,7 +695,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
break;
case 'T':
if(s){
- for(len = 0; i<4000 && s[len]; len++){
+ for(len = 0; i < (bufsize-3) && s[len]; len++){
buf[i] = s[len];
if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
if(doublec && strchr((char *)doublec, buf[i])) {
@@ -246,15 +738,15 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
i += (int)strlen((char *)buf+i);
break;
case 'L':
- sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->cycles);
+ sprintf((char *)buf+i, "%"PRIu64, param->cycles);
i += (int)strlen((char *)buf+i);
break;
case 'I':
- sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->statssrv64);
+ sprintf((char *)buf+i, "%"PRIu64, param->statssrv64);
i += (int)strlen((char *)buf+i);
break;
case 'O':
- sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->statscli64);
+ sprintf((char *)buf+i, "%"PRIu64, param->statscli64);
i += (int)strlen((char *)buf+i);
break;
case 'h':
@@ -281,13 +773,13 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
j = k;
}
if(!s || format[k]!='T') break;
- for(k = 0, len = 0; s[len] && i < 4000; len++){
+ for(k = 0, len = 0; s[len]; len++){
if(isspace(s[len])){
k++;
while(isspace(s[len+1]))len++;
if(k == pmin) continue;
}
- if(k>=pmin && k<=pmax) {
+ if(k>=pmin && k<=pmax && i < (bufsize-3)) {
buf[i] = s[len];
if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
if(doublec && strchr((char *)doublec, buf[i])) {
@@ -310,7 +802,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
return i;
}
-int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec){
+int dobuf(struct clientparam * param, char * buf, int bufsize, const char *s, const char * doublec){
struct tm* tm;
int i;
char * format;
@@ -318,37 +810,297 @@ int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *
time(&t);
if(!param) return 0;
- if(param->trafcountfunc)(*param->trafcountfunc)(param);
format = param->srv->logformat?(char *)param->srv->logformat : DEFLOGFORMAT;
tm = (*format == 'G' || *format == 'g')?
gmtime(&t) : localtime(&t);
- i = dobuf2(param, buf, s, doublec, tm, format + 1);
- clearstat(param);
+ i = dobuf2(param, buf, bufsize, s, doublec, tm, format + 1);
return i;
}
-void lognone(struct clientparam * param, const unsigned char *s) {
- if(param->trafcountfunc)(*param->trafcountfunc)(param);
- clearstat(param);
+
+static int stdloginit(struct LOGGER *logger){
+ char tmpbuf[1024];
+ struct stdlogdata *lp;
+
+ lp = myalloc(sizeof(struct stdlogdata));
+ if(!lp) return 1;
+ logger->data = lp;
+ if(!*logger->selector || !strcmp(logger->selector, "stdout")){
+ logger->rotate = NONE;
+ lp->fp = stdout;
+ }
+ else if(!strcmp(logger->selector,"stderr")){
+ logger->rotate = NONE;
+ lp->fp = stderr;
+ }
+ else {
+ lp->fp = fopen((char *)dologname (tmpbuf, sizeof(tmpbuf) - 1, logger->selector, NULL, logger->rotate, time(NULL)), "a");
+ if(!lp->fp){
+ myfree(lp);
+ return(2);
+ }
+ }
+ return 0;
}
-void logstdout(struct clientparam * param, const unsigned char *s) {
- FILE *log;
- unsigned char tmpbuf[8192];
+static int stddobuf(struct clientparam * param, char * buf, int bufsize, const char *s){
+ return dobuf(param, buf, bufsize, s, NULL);
+}
- dobuf(param, tmpbuf, s, NULL);
- log = param->srv->stdlog?param->srv->stdlog:conf.stdlog?conf.stdlog:stdout;
- if(!param->nolog)if(fprintf(log, "%s\n", tmpbuf) < 0) {
- perror("printf()");
- };
- if(log != conf.stdlog)fflush(log);
+static void stdlog(const char * buf, int len, struct LOGGER *logger) {
+ FILE *log = ((struct stdlogdata *)logger->data)->fp;
+
+ fprintf(log, "%s\n", buf);
+#ifdef WITHMAIN
+ fflush(log);
+#endif
}
-#ifndef _WIN32
-void logsyslog(struct clientparam * param, const unsigned char *s) {
- unsigned char tmpbuf[8192];
- dobuf(param, tmpbuf, s, NULL);
- if(!param->nolog)syslog(LOG_INFO, "%s", tmpbuf);
+static void stdlogrotate(struct LOGGER *logger){
+#ifndef WITHMAIN
+ char tmpbuf[1024];
+ struct stdlogdata *lp = (struct stdlogdata *)logger->data;
+ if(lp->fp) lp->fp = freopen((char *)dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, NULL, logger->rotate, conf.time), "a", lp->fp);
+ else lp->fp = fopen((char *)dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, NULL, logger->rotate, conf.time), "a");
+ logger->rotated = conf.time;
+ if(logger->rotate) {
+ int t;
+ t = 1;
+ switch(logger->rotate){
+ case ANNUALLY:
+ t = t * 12;
+ case MONTHLY:
+ t = t * 4;
+ case WEEKLY:
+ t = t * 7;
+ case DAILY:
+ t = t * 24;
+ case HOURLY:
+ t = t * 60;
+ case MINUTELY:
+ t = t * 60;
+ default:
+ break;
+ }
+/*
+ FIXME: move archiver to thread
+*/
+ dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, (conf.archiver)?conf.archiver[1]:NULL, logger->rotate, (logger->rotated - t * conf.rotate));
+ remove ((char *) tmpbuf);
+ if(conf.archiver) {
+ int i;
+ *tmpbuf = 0;
+ for(i = 2; i < conf.archiverc && strlen((char *)tmpbuf) < 512; i++){
+ strcat((char *)tmpbuf, " ");
+ if(!strcmp((char *)conf.archiver[i], "%A")){
+ strcat((char *)tmpbuf, "\"");
+ dologname (tmpbuf + strlen((char *)tmpbuf), (int)(sizeof(tmpbuf) - (strlen((char *)tmpbuf) + 1)), logger->selector, conf.archiver[1], logger->rotate, (logger->rotated - t));
+ strcat((char *)tmpbuf, "\"");
+ }
+ else if(!strcmp((char *)conf.archiver[i], "%F")){
+ strcat((char *)tmpbuf, "\"");
+ dologname (tmpbuf+strlen((char *)tmpbuf), (int)(sizeof(tmpbuf) - (strlen((char *)tmpbuf) + 1)), logger->selector, NULL, logger->rotate, (logger->rotated-t));
+ strcat((char *)tmpbuf, "\"");
+ }
+ else
+ strcat((char *)tmpbuf, (char *)conf.archiver[i]);
+ }
+ (void)system((char *)tmpbuf+1);
+ }
+ }
+#endif
+}
+
+static void stdlogflush(struct LOGGER *logger){
+ fflush(((struct stdlogdata *)logger->data)->fp);
}
+
+static void stdlogclose(struct LOGGER *logger){
+ if(((struct stdlogdata *)logger->data)->fp != stdout && ((struct stdlogdata *)logger->data)->fp != stderr)
+ fclose(((struct stdlogdata *)logger->data)->fp);
+ myfree(logger->data);
+}
+
+#if HAVESYSLOG > 0
+
+static int sysloginit(struct LOGGER *logger){
+ openlog(logger->selector, LOG_PID, LOG_DAEMON);
+ return 0;
+}
+
+static void logsyslog(const char * buf, int len, struct LOGGER *logger) {
+ syslog(LOG_INFO, "%s", buf);
+}
+
+static void syslogrotate(struct LOGGER *logger){
+#ifndef WITHMAIN
+ closelog();
+ openlog(logger->selector+1, LOG_PID, LOG_DAEMON);
+#endif
+}
+
+static void syslogclose(struct LOGGER *logger){
+ closelog();
+}
+
+
#endif
+#if HAVESQL > 0
+
+struct sqldata {
+ SQLHENV henv;
+ SQLHSTMT hstmt;
+ SQLHDBC hdbc;
+ int attempt;
+ time_t attempt_time;
+};
+
+
+
+
+static int sqlinit2(struct sqldata * sd, char * source){
+ SQLRETURN retcode;
+ char * datasource;
+ char * username;
+ char * password;
+ char * string;
+ int ret = 0;
+
+ retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sd->henv);
+ if (!sd->henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
+ return 1;
+ }
+ retcode = SQLSetEnvAttr(sd->henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
+ ret = 2;
+ goto CLOSEENV;
+ }
+ retcode = SQLAllocHandle(SQL_HANDLE_DBC, sd->henv, &sd->hdbc);
+ if (!sd->hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
+ ret = 3;
+ goto CLOSEENV;
+ }
+ SQLSetConnectAttr(sd->hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
+
+ string = mystrdup(source);
+ if(!string) goto CLOSEHDBC;
+ datasource = strtok(string, ",");
+ username = strtok(NULL, ",");
+ password = strtok(NULL, ",");
+
+
+ /* Connect to data source */
+ retcode = SQLConnect(sd->hdbc, (SQLCHAR*) datasource, (SQLSMALLINT)strlen(datasource),
+ (SQLCHAR*) username, (SQLSMALLINT)((username)?strlen(username):0),
+ (SQLCHAR*) password, (SQLSMALLINT)((password)?strlen(password):0));
+
+ myfree(string);
+
+
+
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
+ ret = 4;
+ goto CLOSEHDBC;
+ }
+
+ retcode = SQLAllocHandle(SQL_HANDLE_STMT, sd->hdbc, &sd->hstmt);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
+ sd->hstmt = 0;
+ ret = 5;
+ goto CLOSEHDBC;
+ }
+
+ return 0;
+
+CLOSEHDBC:
+ SQLFreeHandle(SQL_HANDLE_DBC, sd->hdbc);
+ sd->hdbc = 0;
+CLOSEENV:
+ SQLFreeHandle(SQL_HANDLE_ENV, sd->henv);
+ sd->henv = 0;
+ return ret;
+}
+
+static int sqlinit(struct LOGGER *logger){
+ struct sqldata *sd;
+ int res;
+
+ sd = (struct sqldata *)myalloc(sizeof(struct sqldata));
+ memset(sd, 0, sizeof(struct sqldata));
+ logger->data = sd;
+ if((res = sqlinit2(sd, logger->selector))) {
+ myfree(sd);
+ return res;
+ }
+ return 0;
+}
+
+static int sqldobuf(struct clientparam * param, char * buf, int bufsize, const char *s){
+ return dobuf(param, buf, bufsize, s, "\'");
+}
+
+
+static void sqllog(const char * buf, int len, struct LOGGER *logger){
+ SQLRETURN ret;
+ struct sqldata *sd = (struct sqldata *)logger->data;
+
+
+ if(sd->attempt > 5){
+ if (conf.time - sd->attempt_time < 180){
+ return;
+ }
+ }
+ if(sd->attempt){
+ sd->attempt++;
+ sqlrotate(logger);
+
+ if(!sd->hstmt){
+ sd->attempt_time=conf.time;
+ return;
+ }
+ }
+ ret = SQLExecDirect(sd->hstmt, (SQLCHAR *)buf, (SQLINTEGER)len);
+ if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
+ sqlrotate(logger);
+ if(sd->hstmt) {
+ ret = SQLExecDirect(sd->hstmt, (SQLCHAR *)buf, (SQLINTEGER)len);
+ if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
+ sd->attempt++;
+ sd->attempt_time=conf.time;
+ return;
+ }
+ }
+ }
+ sd->attempt=0;
+}
+
+static void sqlrotate(struct LOGGER *logger){
+ struct sqldata * sd;
+ sqlclose(logger);
+ sd = (struct sqldata *)myalloc(sizeof(struct sqldata));
+ memset(sd, 0, sizeof(struct sqldata));
+ logger->data = sd;
+ sqlinit2(sd, logger->selector+1);
+}
+
+static void sqlclose(struct LOGGER *logger){
+ struct sqldata *sd = (struct sqldata *)logger->data;
+ if(sd->hstmt) {
+ SQLFreeHandle(SQL_HANDLE_STMT, sd->hstmt);
+ sd->hstmt = NULL;
+ }
+ if(sd->hdbc){
+ SQLDisconnect(sd->hdbc);
+ SQLFreeHandle(SQL_HANDLE_DBC, sd->hdbc);
+ sd->hdbc = NULL;
+ }
+ if(sd->henv) {
+ SQLFreeHandle(SQL_HANDLE_ENV, sd->henv);
+ sd->henv = NULL;
+ }
+ myfree(sd);
+}
+
+
+#endif
diff --git a/src/mycrypt.c b/src/mycrypt.c
index c07725fa..5bc5c94d 100644
--- a/src/mycrypt.c
+++ b/src/mycrypt.c
@@ -16,13 +16,13 @@
#endif
-void tohex(unsigned char *in, unsigned char *out, int len);
+void tohex(char *in, char *out, int len);
-static unsigned char itoa64[] =
+static char itoa64[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
void
-_crypt_to64(unsigned char *s, unsigned long v, int n)
+_crypt_to64(char *s, unsigned long v, int n)
{
while (--n >= 0) {
*s++ = itoa64[v&0x3f];
@@ -31,9 +31,9 @@ _crypt_to64(unsigned char *s, unsigned long v, int n)
}
-unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPassword, int ctohex)
+char * ntpwdhash (char *szHash, const char *szPassword, int ctohex)
{
- unsigned char szUnicodePass[513];
+ char szUnicodePass[513];
unsigned int nPasswordLen;
MD4_CTX ctx;
unsigned int i;
@@ -42,7 +42,7 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
* NT passwords are unicode. Convert plain text password
* to unicode by inserting a zero every other byte
*/
- nPasswordLen = (int)strlen((char *)szPassword);
+ nPasswordLen = (int)strlen(szPassword);
if(nPasswordLen > 255)nPasswordLen = 255;
for (i = 0; i < nPasswordLen; i++) {
szUnicodePass[i << 1] = szPassword[i];
@@ -51,8 +51,8 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
/* Encrypt Unicode password to a 16-byte MD4 hash */
MD4Init(&ctx);
- MD4Update(&ctx, szUnicodePass, (nPasswordLen<<1));
- MD4Final(szUnicodePass, &ctx);
+ MD4Update(&ctx, (unsigned char*)szUnicodePass, (nPasswordLen<<1));
+ MD4Final((unsigned char*)szUnicodePass, &ctx);
if (ctohex){
tohex(szUnicodePass, szHash, 16);
}
@@ -61,14 +61,14 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
}
-unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsigned char *passwd){
+char * mycrypt(const char *pw, const char *salt, char *passwd){
- const unsigned char *ep;
- if(salt[0] == '$' && salt[1] == '1' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) {
- static unsigned char *magic = (unsigned char *)"$1$";
- unsigned char *p;
- const unsigned char *sp;
- unsigned char final[MD5_SIZE];
+ const char *ep;
+ if(salt[0] == '$' && salt[1] == '1' && salt[2] == '$' && (ep = strchr(salt+3, '$'))) {
+ static char *magic = "$1$";
+ char *p;
+ const char *sp;
+ char final[MD5_SIZE];
int sl,pl,i;
MD5_CTX ctx,ctx1;
unsigned long l;
@@ -82,39 +82,39 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
MD5Init(&ctx);
/* The password first, since that is what is most unknown */
- MD5Update(&ctx,pw,strlen((char *)pw));
+ MD5Update(&ctx,(unsigned char*)pw,strlen(pw));
/* Then our magic string */
- MD5Update(&ctx,magic,strlen((char *)magic));
+ MD5Update(&ctx,(unsigned char*)magic,strlen(magic));
/* Then the raw salt */
- MD5Update(&ctx,sp,sl);
+ MD5Update(&ctx,(unsigned char*)sp,sl);
- /* Then just as many unsigned characters of the MD5(pw,salt,pw) */
+ /* Then just as many characters of the MD5(pw,salt,pw) */
MD5Init(&ctx1);
- MD5Update(&ctx1,pw,strlen((char *)pw));
- MD5Update(&ctx1,sp,sl);
- MD5Update(&ctx1,pw,strlen((char *)pw));
- MD5Final(final,&ctx1);
- for(pl = (int)strlen((char *)pw); pl > 0; pl -= MD5_SIZE)
- MD5Update(&ctx,final,pl>MD5_SIZE ? MD5_SIZE : pl);
+ MD5Update(&ctx1,(unsigned char*)pw,strlen(pw));
+ MD5Update(&ctx1,(unsigned char*)sp,sl);
+ MD5Update(&ctx1,(unsigned char*)pw,strlen(pw));
+ MD5Final((unsigned char*)final,&ctx1);
+ for(pl = (int)strlen(pw); pl > 0; pl -= MD5_SIZE)
+ MD5Update(&ctx,(unsigned char*)final,pl>MD5_SIZE ? MD5_SIZE : pl);
/* Don't leave anything around in vm they could use. */
memset(final,0,sizeof final);
/* Then something really weird... */
- for (i = (int)strlen((char *)pw); i ; i >>= 1)
+ for (i = (int)strlen(pw); i ; i >>= 1)
if(i&1)
- MD5Update(&ctx, final, 1);
+ MD5Update(&ctx, (unsigned char*)final, 1);
else
- MD5Update(&ctx, pw, 1);
+ MD5Update(&ctx, (unsigned char*)pw, 1);
/* Now make the output string */
- strcpy((char *)passwd,(char *)magic);
- strncat((char *)passwd,(char *)sp,sl);
- strcat((char *)passwd,"$");
+ strcpy(passwd,magic);
+ strncat(passwd,sp,sl);
+ strcat(passwd,"$");
- MD5Final(final,&ctx);
+ MD5Final((unsigned char*)final,&ctx);
/*
* and now, just to make sure things don't run too fast
@@ -124,24 +124,24 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
for(i=0;i<1000;i++) {
MD5Init(&ctx1);
if(i & 1)
- MD5Update(&ctx1,pw,strlen((char *)pw));
+ MD5Update(&ctx1,(unsigned char*)pw,strlen(pw));
else
- MD5Update(&ctx1,final,MD5_SIZE);
+ MD5Update(&ctx1,(unsigned char*)final,MD5_SIZE);
if(i % 3)
- MD5Update(&ctx1,sp,sl);
+ MD5Update(&ctx1,(unsigned char*)sp,sl);
if(i % 7)
- MD5Update(&ctx1,pw,strlen((char *)pw));
+ MD5Update(&ctx1,(unsigned char*)pw,strlen(pw));
if(i & 1)
- MD5Update(&ctx1,final,MD5_SIZE);
+ MD5Update(&ctx1,(unsigned char*)final,MD5_SIZE);
else
- MD5Update(&ctx1,pw,strlen((char *)pw));
- MD5Final(final,&ctx1);
+ MD5Update(&ctx1,(unsigned char*)pw,strlen(pw));
+ MD5Final((unsigned char*)final,&ctx1);
}
- p = passwd + strlen((char *)passwd);
+ p = passwd + strlen(passwd);
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
_crypt_to64(p,l,4); p += 4;
@@ -170,7 +170,7 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
#include
int main(int argc, char* argv[]){
- unsigned char buf[1024];
+ char buf[1024];
unsigned i;
if(argc < 2 || argc > 3) {
fprintf(stderr, "usage: \n"
@@ -185,13 +185,13 @@ int main(int argc, char* argv[]){
return 1;
}
if(argc == 2) {
- printf("NT:%s\n", ntpwdhash(buf, (unsigned char *)argv[1], 1));
+ printf("NT:%s\n", ntpwdhash(buf, argv[1], 1));
}
else {
- i = (int)strlen((char *)argv[1]);
+ i = (int)strlen(argv[1]);
if (i > 64) argv[1][64] = 0;
- sprintf((char *)buf, "$1$%s$", argv[1]);
- printf("CR:%s\n", mycrypt((unsigned char *)argv[2], buf, buf+256));
+ sprintf(buf, "$1$%s$", argv[1]);
+ printf("CR:%s\n", mycrypt(argv[2], buf, buf+256));
}
return 0;
}
diff --git a/src/ntlm.c b/src/ntlm.c
deleted file mode 100644
index 21bd0da9..00000000
--- a/src/ntlm.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- 3APA3A simpliest proxy server
- (c) 2002-2016 by Vladimir Dubrovin <3proxy@3proxy.ru>
-
- please read License Agreement
-
-*/
-
-#include "proxy.h"
-struct ntlmchal {
- unsigned char sig[8];
- unsigned char messtype[4];
- unsigned char dom_len[2];
- unsigned char dom_max_len[2];
- unsigned char dom_offset[4];
- unsigned char flags[4];
- unsigned char challenge[8];
- unsigned char reserved[8];
- unsigned char addr_len[2];
- unsigned char addr_max_len[2];
- unsigned char addr_offset[4];
- unsigned char data[1];
-};
-
-struct ntlmreq {
- unsigned char sig[8];
- unsigned char messtype[4];
- unsigned char flags[4];
- unsigned char dom_len[2];
- unsigned char dom_max_len[2];
- unsigned char dom_offset[4];
- unsigned char pad1[2];
- unsigned char host_len[2];
- unsigned char host_max_len[2];
- unsigned char host_offset[4];
- unsigned char pad2[2];
- unsigned char data[1];
-};
-
-int text2unicode(const char * text, char * buf, int buflen){
- int count = 0;
- buflen = ((buflen>>1)<<1);
- if(!text || !buflen) return 0;
- do {
- buf[count++] = toupper(*text++);
- buf[count++] = '\0';
- } while (*text && count < buflen);
- return count;
-}
-
-void unicode2text(const char *unicode, char * buf, int len){
- int i;
- if(!unicode || !len) return;
- for(i=0; isig, "NTLMSSP", 8);
- chal->messtype[0] = 2;
- gethostname(hostname, 128);
- hostname[15] = 0;
- len = (((int)strlen(hostname)) << 1);
- chal->dom_len[0] = len;
- chal->dom_max_len[0] = len;
- chal->dom_offset[0] = (unsigned char)((unsigned char *)chal->data - (unsigned char *)chal);
- chal->flags[0] = 0x03;
- chal->flags[1] = 0x82;
- chal->flags[2] = 0x81;
- chal->flags[3] = 0xA0;
- text2unicode(hostname, (char *)chal->data, 64);
- time((time_t *)challenge);
- memcpy(challenge+4, SAADDR(¶m->sincr), 4);
- challenge[1]^=*SAPORT(¶m->sincr);
- for(i = 0; i < 8; i++) challenge[i] ^= myrand(challenge, 8);
- memcpy(chal->challenge, challenge, 8);
- en64((unsigned char *)tmpbuf, (unsigned char *)buf, (int)((unsigned char *)chal->data - (unsigned char *)chal) + len);
-}
diff --git a/src/plugins.c b/src/plugins.c
index a0681df7..b01e438e 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -11,11 +11,11 @@
unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nbytesout);
void trafcountfunc(struct clientparam *param);
int checkACL(struct clientparam * param);
-void nametohash(const unsigned char * name, unsigned char *hash);
-unsigned hashindex(const unsigned char* hash);
-void decodeurl(unsigned char *s, int allowcr);
-int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned char ** buff, int *inbuf, int *bufsize);
-struct ace * make_ace (int argc, unsigned char ** argv);
+void nametohash(const char * name, char *hash);
+unsigned hashindex(const char* hash);
+void decodeurl(char *s, int allowcr);
+int parsestr (char *str, char **argm, int nitems, char ** buff, int *inbuf, int *bufsize);
+struct ace * make_ace (int argc, char ** argv);
extern char * proxy_stringtable[];
extern char * admin_stringtable[];
extern struct schedule * schedule;
@@ -74,6 +74,9 @@ struct symbol symbols[] = {
{symbols+47, "parsestr", (void *) parsestr},
{symbols+48, "make_ace", (void *) make_ace},
{symbols+49, "freeacl", (void *) freeacl},
+ {symbols+50, "checkpreACL", (void *) checkpreACL},
+ {symbols+51, "dolog", (void *) dolog},
+ {symbols+52, "logfuncs", (void *) &logfuncs},
{NULL, "", NULL}
};
@@ -108,6 +111,7 @@ struct pluginlink pluginlink = {
ACLmatches,
alwaysauth,
checkACL,
+ checkpreACL,
nametohash,
hashindex,
en64,
diff --git a/src/plugins/FilePlugin/FilePlugin.c b/src/plugins/FilePlugin/FilePlugin.c
index ad9dbbe8..66ba113e 100644
--- a/src/plugins/FilePlugin/FilePlugin.c
+++ b/src/plugins/FilePlugin/FilePlugin.c
@@ -577,7 +577,7 @@ static int WINAPI fp_sendto(SOCKET s, const void *msg, int len, int flags, const
case GOT_FTP_CLIDATA:
case GOT_FTP_SRVDATA:
case GOT_HTTP_CLIDATA:
- if((!fps->what & FP_CLIDATA)) break;
+ if(!(fps->what & FP_CLIDATA)) break;
#ifdef _WIN32
if(SetFilePointer(fps->fpd.h_cli, fps->clientwritten + fps->clihdrwritten, 0, FILE_BEGIN) != (fps->clientwritten + fps->clihdrwritten)){
return -1;
@@ -760,7 +760,7 @@ static FILTER_ACTION fp_client(void *fo, struct clientparam * param, void** fc){
return CONTINUE;
}
-static FILTER_ACTION fp_request(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
+static FILTER_ACTION fp_request(void *fc, struct clientparam * param, char ** buf_p, int * bufsize_p, int offset, int * length_p){
if(fc && (param->service == S_PROXY)){
if(FC->state) {
closefiles(FC);
@@ -776,7 +776,7 @@ static FILTER_ACTION fp_request(void *fc, struct clientparam * param, unsigned c
return CONTINUE;
}
-static FILTER_ACTION fp_hcli(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
+static FILTER_ACTION fp_hcli(void *fc, struct clientparam * param, char ** buf_p, int * bufsize_p, int offset, int * length_p){
if(fc && param->service == S_SMTPP) {
processcallbacks(FC, FP_CALLONREQUEST, *buf_p + offset, *length_p - offset);
if(FC->what & FP_REJECT) return REJECT;
@@ -792,7 +792,7 @@ static FILTER_ACTION fp_hcli(void *fc, struct clientparam * param, unsigned char
return CONTINUE;
}
-static FILTER_ACTION fp_hsrv(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
+static FILTER_ACTION fp_hsrv(void *fc, struct clientparam * param, char ** buf_p, int * bufsize_p, int offset, int * length_p){
if(fc && param->service == S_PROXY && (FC->state == GOT_HTTP_REQUEST || FC->state == GOT_HTTP_CLI_HDR || FC->state == GOT_HTTP_CLIDATA)){
if(FC->what & FP_SRVHEADER) initserverfile(FC);
FC->state = GOT_HTTP_SRV_HDR;
@@ -801,7 +801,7 @@ static FILTER_ACTION fp_hsrv(void *fc, struct clientparam * param, unsigned char
return CONTINUE;
}
-static FILTER_ACTION fp_dcli(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
+static FILTER_ACTION fp_dcli(void *fc, struct clientparam * param, char ** buf_p, int * bufsize_p, int offset, int * length_p){
if(fc && FC->state == GOT_HTTP_REQUEST){
FC->state = GOT_HTTP_CLI_HDR2;
}
@@ -809,7 +809,7 @@ static FILTER_ACTION fp_dcli(void *fc, struct clientparam * param, unsigned char
}
-static FILTER_ACTION fp_dsrv(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
+static FILTER_ACTION fp_dsrv(void *fc, struct clientparam * param, char ** buf_p, int * bufsize_p, int offset, int * length_p){
if(fc && (FC->state == GOT_HTTP_REQUEST || FC->state == GOT_HTTP_CLI_HDR || FC->state == GOT_HTTP_CLIDATA || FC->state == GOT_HTTP_CLIDATA || FC->state == GOT_HTTP_SRV_HDR)){
FC->state = GOT_HTTP_SRV_HDR2;
}
@@ -846,7 +846,7 @@ static struct symbol fp_symbols[] = {
{NULL, "fp_stringtable", (void*) fp_stringtable}
};
-static int h_cachedir(int argc, unsigned char **argv){
+static int h_cachedir(int argc, char **argv){
char * dirp;
size_t len;
@@ -866,7 +866,7 @@ static int h_cachedir(int argc, unsigned char **argv){
return 0;
}
-static int h_preview(int argc, unsigned char **argv){
+static int h_preview(int argc, char **argv){
preview = atoi(argv[1]);
return 0;
}
diff --git a/src/plugins/LdapPlugin/getldapuser.c b/src/plugins/LdapPlugin/getldapuser.c
index e5e09044..a509e8a5 100644
--- a/src/plugins/LdapPlugin/getldapuser.c
+++ b/src/plugins/LdapPlugin/getldapuser.c
@@ -27,7 +27,7 @@ main(int argc, char *argv[])
char *attrs[] = { NULL, NULL };
int i, rc = -1;
int lderrno;
- unsigned char tmpbuf[1000];
+ char tmpbuf[1000];
if ( argc < 6 )
{
diff --git a/src/plugins/LdapPlugin/ldapauth.c b/src/plugins/LdapPlugin/ldapauth.c
index 1572b4d8..15ec985e 100644
--- a/src/plugins/LdapPlugin/ldapauth.c
+++ b/src/plugins/LdapPlugin/ldapauth.c
@@ -22,6 +22,9 @@ static struct commands ldap_trafgroup_handler;
static struct commands ldap_attrsgroup_handler;
static struct commands ldap_dircount_handler;
+static void (*ldolog)(struct clientparam * param, const char *s);
+
+
static char *attrs[] = { NULL, NULL};
static char *ldap_group_attr;
static char *ldap_access;
@@ -58,7 +61,7 @@ int savecounters(void)
struct trafcount *tcd;
struct counter_record wcounter;
FILE *f;
- unsigned char *tmpbuf,pat_file[]="%s%s.lc";
+ char *tmpbuf,pat_file[]="%s%s.lc";
/* timetoexit !=0 - .*/
@@ -109,7 +112,7 @@ static int ldapfunc(struct clientparam *param)
ld = ldap_init( ldap_serv, 389 );
if ( ld == NULL )
{
- param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
+ ldolog(param,"Error ldap_init: No init lib ldap");
/*ldap_perror( ld, "Error ldap_init" ); */
return 7;
}
@@ -133,7 +136,7 @@ static int ldapfunc(struct clientparam *param)
if ( rc != LDAP_SUCCESS )
{
- param->srv->logfunc(param,"Error ldap_bind: No connect ldap catalog");
+ ldolog(param,"Error ldap_bind: No connect ldap catalog");
ldap_unbind_s(ld);
return 7;
}
@@ -144,7 +147,7 @@ static int ldapfunc(struct clientparam *param)
if ( ld == NULL )
{
- param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
+ ldolog(param,"Error ldap_init: No init lib ldap");
/*ldap_perror( ld, "Error ldap_init" ); */
return 7;
}
@@ -153,7 +156,7 @@ static int ldapfunc(struct clientparam *param)
if ( rc != LDAP_SUCCESS )
{
- param->srv->logfunc(param, "Error ldap_bind: Not authorize in ldap\
+ ldolog(param, "Error ldap_bind: Not authorize in ldap\
catalog, checked option \'ldapconnect\' ");
ldap_unbind_s(ld);
return 7;
@@ -184,7 +187,7 @@ static int ldapfunc(struct clientparam *param)
/* --------------------------------------------------------------------------
handle command ldapserv */
-int h_ldapconnect(int argc, unsigned char ** argv)
+int h_ldapconnect(int argc, char ** argv)
{
LDAP *ld = NULL;
@@ -213,7 +216,7 @@ int h_ldapconnect(int argc, unsigned char ** argv)
}
/* --------------------------------------------------------------------------
handle command ldapaccess */
-int h_access(int argc, unsigned char ** argv)
+int h_access(int argc, char ** argv)
{
if (argc < 1)
{
@@ -226,7 +229,7 @@ int h_access(int argc, unsigned char ** argv)
/* --------------------------------------------------------------------------
handle command ldapsbase
searching base */
-int h_sbase(int argc, unsigned char ** argv)
+int h_sbase(int argc, char ** argv)
{
if (argc < 1)
{
@@ -238,7 +241,7 @@ int h_sbase(int argc, unsigned char ** argv)
}
/* --------------------------------------------------------------------------
handle command ldapuserenv */
-int h_userenv(int argc, unsigned char ** argv)
+int h_userenv(int argc, char ** argv)
{
if (argc < 1)
{
@@ -250,7 +253,7 @@ int h_userenv(int argc, unsigned char ** argv)
}
/* --------------------------------------------------------------------------
handle command ldaptrafgroup */
-int h_trafgroup(int argc, unsigned char ** argv)
+int h_trafgroup(int argc, char ** argv)
{
struct trafcount *newtrafcount;
struct bandlim *newbandlim;
@@ -415,7 +418,7 @@ int h_trafgroup(int argc, unsigned char ** argv)
}
/* --------------------------------------------------------------------------
handle command ldapattrsgroup */
-int h_attrsgroup(int argc, unsigned char ** argv)
+int h_attrsgroup(int argc, char ** argv)
{
if (argc < 1)
{
@@ -432,7 +435,7 @@ int h_attrsgroup(int argc, unsigned char ** argv)
}
/* --------------------------------------------------------------------------
handle command ldapdircount */
-int h_dircount(int argc, unsigned char ** argv)
+int h_dircount(int argc, char ** argv)
{
if (argc < 1)
{
@@ -472,6 +475,9 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink,
return (0);
}
+
+ ldolog=pluginlink->findbyname("dolog");
+
already_loaded = 1;
mypluginlink=pluginlink;
@@ -488,6 +494,7 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink,
+ myalwaysauth.preauthorize = pluginlink->checkpreACL;
myalwaysauth.authenticate = ldapfunc;
myalwaysauth.authorize = pluginlink->checkACL;
myalwaysauth.desc = "ldap";
diff --git a/src/plugins/PCREPlugin/pcre_plugin.c b/src/plugins/PCREPlugin/pcre_plugin.c
index 65a63aaa..aa456e58 100644
--- a/src/plugins/PCREPlugin/pcre_plugin.c
+++ b/src/plugins/PCREPlugin/pcre_plugin.c
@@ -123,7 +123,7 @@ static FILTER_ACTION pcre_filter_client(void *fo, struct clientparam * param, vo
return (res)? CONTINUE:PASS;
}
-static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
+static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, char ** buf_p, int * bufsize_p, int offset, int * length_p){
int ovector[48];
int count = 0;
struct ace *acl;
@@ -195,7 +195,7 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
}
memcpy(newbuf, *buf_p, ovector[0]);
pl->freefunc(*buf_p);
- *buf_p = (unsigned char *)newbuf;
+ *buf_p = (char *)newbuf;
*bufsize_p = ovector[0] + replen + 1;
}
memcpy(*buf_p + ovector[0], tmpbuf, replen);
@@ -219,7 +219,7 @@ static void pcre_filter_close(void *fo){
pcre_data_free((struct pcre_filter_data *)fo);
}
-static int h_pcre(int argc, unsigned char **argv){
+static int h_pcre(int argc, char **argv){
int action = 0;
pcre *re = NULL;
struct ace *acl;
@@ -317,7 +317,7 @@ static int h_pcre(int argc, unsigned char **argv){
return 0;
}
-static int h_pcre_extend(int argc, unsigned char **argv){
+static int h_pcre_extend(int argc, char **argv){
struct ace *acl;
if(!pcre_last_filter || !pcre_last_filter->data) return 1;
acl = ((struct pcre_filter_data *)pcre_last_filter->data)->acl;
@@ -328,7 +328,7 @@ static int h_pcre_extend(int argc, unsigned char **argv){
return 0;
}
-static int h_pcre_options(int argc, unsigned char **argv){
+static int h_pcre_options(int argc, char **argv){
int i,j;
pcre_options = 0;
@@ -351,7 +351,7 @@ static struct commands pcre_commandhandlers[] = {
static struct symbol regexp_symbols[] = {
{regexp_symbols+1, "pcre_compile", (void*) pcre_compile},
{regexp_symbols+2, "pcre_exec", (void*) pcre_exec},
- {NULL, "pcre_free", NULL},
+ {NULL, "pcre_options", (void *)&pcre_options},
};
#ifdef WATCOM
@@ -371,8 +371,7 @@ PLUGINAPI int PLUGINCALL pcre_plugin (struct pluginlink * pluginlink,
pcre_free = pl->freefunc;
pcre_loaded = 1;
pthread_mutex_init(&pcre_mutex, NULL);
- regexp_symbols[6].value = pl->freefunc;
- regexp_symbols[6].next = pl->symbols.next;
+ regexp_symbols[2].next = pl->symbols.next;
pl->symbols.next = regexp_symbols;
pcre_commandhandlers[3].next = pl->commandhandlers->next;
pl->commandhandlers->next = pcre_commandhandlers;
diff --git a/src/plugins/PamAuth/pamauth.c b/src/plugins/PamAuth/pamauth.c
index da65ee91..22c127bb 100644
--- a/src/plugins/PamAuth/pamauth.c
+++ b/src/plugins/PamAuth/pamauth.c
@@ -20,7 +20,7 @@ static struct auth pamauth;
#ifdef USERCASE
static int usercaselow = 0;
#endif
-static unsigned char *service=NULL;
+static char *service=NULL;
static struct pluginlink * pl;
@@ -125,7 +125,7 @@ static int pamfunc(struct clientparam *param)
/*------------------------------- MAIN --------------------------------------
start plugin init */
-PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, unsigned char** argv)
+PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char** argv)
{
@@ -139,6 +139,7 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, unsigne
already_loaded = 1;
pthread_mutex_init(&pam_mutex, NULL);
+ pamauth.preauthorize = pluginlink->checkpreACL;
pamauth.authenticate = pamfunc;
pamauth.authorize = pluginlink->checkACL;
pamauth.desc = "pam";
diff --git a/src/plugins/SSLPlugin/my_ssl.c b/src/plugins/SSLPlugin/my_ssl.c
index a82eff14..7382b8d6 100644
--- a/src/plugins/SSLPlugin/my_ssl.c
+++ b/src/plugins/SSLPlugin/my_ssl.c
@@ -47,19 +47,19 @@ static char hexMap[] = {
static BIO *bio_err=NULL;
-static size_t bin2hex (const unsigned char* bin, size_t bin_length, char* str, size_t str_length)
+static size_t bin2hex (const char* bin, size_t bin_length, char* str, size_t str_length)
{
char *p;
size_t i;
- if ( str_length < ( bin_length+1) )
+ if ( str_length < ( (bin_length*2)+1) )
return 0;
p = str;
for ( i=0; i < bin_length; ++i )
{
- *p++ = hexMap[*bin >> 4];
- *p++ = hexMap[*bin & 0xf];
+ *p++ = hexMap[(*(unsigned char *)bin) >> 4];
+ *p++ = hexMap[(*(unsigned char *)bin) & 0xf];
++bin;
}
@@ -111,14 +111,22 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert)
EVP_PKEY *pk = NULL;
RSA *rsa = NULL;
- unsigned char p1[] = "RU";
- unsigned char p2[] = "3proxy";
- unsigned char p3[] = "3proxy CA";
+ char p1[] = "RU";
+ char p2[] = "3proxy";
+ char p3[] = "3proxy CA";
- char hash_name_sha1[sizeof(src_cert->sha1_hash)*2 + 1];
- char cache_name[200];
+ int hash_size = 20;
+ char hash_sha1[20];
+ char hash_name_sha1[(20*2) + 1];
+ char cache_name[256];
- bin2hex(src_cert->sha1_hash, sizeof(src_cert->sha1_hash), hash_name_sha1, sizeof(hash_name_sha1));
+ err = X509_digest(src_cert, EVP_sha1(), hash_sha1, NULL);
+ if(!err){
+ X509_free(dst_cert);
+ return NULL;
+ }
+
+ bin2hex(hash_sha1, 20, hash_name_sha1, sizeof(hash_name_sha1));
sprintf(cache_name, "%s%s.pem", cert_path, hash_name_sha1);
/* check if certificate is already cached */
fcache = fopen(cache_name, "rb");
@@ -153,19 +161,11 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert)
}
- /* Its self signed so set the issuer name to be the same as the
- * subject.
- */
err = X509_set_issuer_name(dst_cert, name);
if(!err){
X509_free(dst_cert);
return NULL;
}
- err = X509_digest(dst_cert, EVP_sha1(), dst_cert->sha1_hash, NULL);
- if(!err){
- X509_free(dst_cert);
- return NULL;
- }
err = X509_sign(dst_cert, CA_key, EVP_sha256());
if(!err){
X509_free(dst_cert);
diff --git a/src/plugins/SSLPlugin/ssl_plugin.c b/src/plugins/SSLPlugin/ssl_plugin.c
index afd494e0..3a9dac77 100644
--- a/src/plugins/SSLPlugin/ssl_plugin.c
+++ b/src/plugins/SSLPlugin/ssl_plugin.c
@@ -28,6 +28,7 @@ extern "C" {
#endif
PROXYFUNC tcppmfunc, proxyfunc, smtppfunc, ftpprfunc;
+static void (*pdolog)(struct clientparam * param, const char *s);
static struct pluginlink * pl;
@@ -56,6 +57,7 @@ struct SSLqueue {
*/
static struct SSLqueue *searchSSL(SOCKET s){
struct SSLqueue *sslq = NULL;
+
pthread_mutex_lock(&ssl_mutex);
for(sslq = SSLq; sslq; sslq = sslq->next)
if(sslq->s == s) break;
@@ -65,19 +67,21 @@ static struct SSLqueue *searchSSL(SOCKET s){
static void addSSL(SOCKET s, SSL_CERT cert, SSL_CONN conn, struct clientparam* param){
struct SSLqueue *sslq;
+
sslq = (struct SSLqueue *) malloc(sizeof(struct SSLqueue));
sslq->s = s;
sslq->cert = cert;
sslq->conn = conn;
+ sslq->param = param;
pthread_mutex_lock(&ssl_mutex);
sslq->next = SSLq;
- sslq->param = param;
SSLq = sslq;
pthread_mutex_unlock(&ssl_mutex);
}
int delSSL(SOCKET s){
struct SSLqueue *sqi, *sqt = NULL;
+
if(!SSLq) return 0;
pthread_mutex_lock(&ssl_mutex);
if(SSLq){
@@ -113,13 +117,15 @@ static int ssl_send(SOCKET s, const void *msg, size_t len, int flags){
struct SSLqueue *sslq;
if ((sslq = searchSSL(s))){
- int i=0, res, err;
- do {
- if((res = ssl_write(sslq->conn, (void *)msg, len)) < 0) {
- err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
- usleep(10*SLEEPTIME);
+ int res, err;
+ if((res = ssl_write(sslq->conn, (void *)msg, len)) <= 0){
+ err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
+ if (err == SSL_ERROR_WANT_WRITE){
+ seterrno3(EAGAIN);
+ return -1;
}
- } while (res < 0 && (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) && ++i < 100);
+ else seterrno3(err);
+ }
return res;
}
@@ -135,13 +141,15 @@ static int ssl_sendto(SOCKET s, const void *msg, size_t len, int flags, const st
struct SSLqueue *sslq;
if ((sslq = searchSSL(s))){
- int i=0, res, err;
- do {
- if((res = ssl_write(sslq->conn, (void *)msg, len)) < 0) {
- err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
- usleep(10*SLEEPTIME);
+ int res, err;
+ if((res = ssl_write(sslq->conn, (void *)msg, len)) <= 0) {
+ err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
+ if (err == SSL_ERROR_WANT_WRITE){
+ seterrno3(EAGAIN);
+ return -1;
}
- } while (res < 0 && (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) && ++i < 100);
+ else seterrno3(err);
+ }
return res;
}
@@ -156,16 +164,17 @@ static int ssl_recvfrom(SOCKET s, void *msg, size_t len, int flags, struct socka
struct SSLqueue *sslq;
if ((sslq = searchSSL(s))){
- int i=0, res, err;
- do {
- if((res = ssl_read(sslq->conn, (void *)msg, len)) < 0) {
- err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
- usleep(10*SLEEPTIME);
+ int res, err;
+ if((res = ssl_read(sslq->conn, (void *)msg, len)) <= 0) {
+ err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
+ if (err == SSL_ERROR_WANT_READ) {
+ seterrno3(EAGAIN);
+ return -1;
}
- } while (res < 0 && (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) && ++i < 100);
+ else seterrno3(err);
+ }
return res;
}
-
return sso._recvfrom(s, msg, len, flags, from, fromlen);
}
@@ -177,13 +186,15 @@ static int WINAPI ssl_recv(SOCKET s, void *msg, size_t len, int flags){
struct SSLqueue *sslq;
if ((sslq = searchSSL(s))){
- int i=0, res, err;
- do {
- if((res = ssl_read(sslq->conn, (void *)msg, len)) < 0) {
- err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
- usleep(10*SLEEPTIME);
+ int res, err;
+ if((res = ssl_read(sslq->conn, (void *)msg, len)) <= 0) {
+ err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
+ if (err == SSL_ERROR_WANT_READ) {
+ seterrno3(EAGAIN);
+ return -1;
}
- } while (res < 0 && (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) && ++i < 100);
+ else seterrno3(err);
+ }
return res;
}
@@ -238,25 +249,25 @@ int dossl(struct clientparam* param, SSL_CONN* ServerConnp, SSL_CONN* ClientConn
ServerConn = ssl_handshake_to_server(param->remsock, (char *)param->hostname, &ServerCert, &errSSL);
if ( ServerConn == NULL || ServerCert == NULL ) {
param->res = 8011;
- param->srv->logfunc(param, (unsigned char *)"SSL handshake to server failed");
- if(ServerConn == NULL) param->srv->logfunc(param, (unsigned char *)"ServerConn is NULL");
- if(ServerCert == NULL) param->srv->logfunc(param, (unsigned char *)"ServerCert is NULL");
- if(errSSL)param->srv->logfunc(param, (unsigned char *)errSSL);
+ pdolog(param, (char *)"SSL handshake to server failed");
+ if(ServerConn == NULL) pdolog(param, (char *)"ServerConn is NULL");
+ if(ServerCert == NULL) pdolog(param, (char *)"ServerCert is NULL");
+ if(errSSL)pdolog(param, (char *)errSSL);
return 1;
}
FakeCert = ssl_copy_cert(ServerCert);
if ( FakeCert == NULL ) {
param->res = 8012;
_ssl_cert_free(ServerCert);
- param->srv->logfunc(param, (unsigned char *)"Failed to create certificate copy");
+ pdolog(param, (char *)"Failed to create certificate copy");
ssl_conn_free(ServerConn);
return 2;
}
ClientConn = ssl_handshake_to_client(param->clisock, FakeCert, &errSSL);
if ( ClientConn == NULL ) {
param->res = 8012;
- param->srv->logfunc(param, (unsigned char *)"Handshake to client failed");
- if(errSSL)param->srv->logfunc(param, (unsigned char *)errSSL);
+ pdolog(param, (char *)"Handshake to client failed");
+ if(errSSL)pdolog(param, (char *)errSSL);
_ssl_cert_free(ServerCert);
_ssl_cert_free(FakeCert);
ssl_conn_free(ServerConn);
@@ -328,7 +339,7 @@ static struct filter ssl_filter = {
int mitm = 0;
int ssl_inited = 0;
-static int h_mitm(int argc, unsigned char **argv){
+static int h_mitm(int argc, char **argv){
if(!ssl_inited) {
ssl_init();
ssl_inited = 1;
@@ -341,7 +352,7 @@ static int h_mitm(int argc, unsigned char **argv){
return 0;
}
-static int h_nomitm(int argc, unsigned char **argv){
+static int h_nomitm(int argc, char **argv){
struct filter * sf;
if(!(mitm&1)) return 1;
if(mitm) usleep(100*SLEEPTIME);
@@ -356,7 +367,7 @@ static int h_nomitm(int argc, unsigned char **argv){
return 0;
}
-static int h_certpath(int argc, unsigned char **argv){
+static int h_certpath(int argc, char **argv){
size_t len;
len = strlen(argv[1]);
if(!len || (argv[1][len - 1] != '/' && argv[1][len - 1] != '\\')) return 1;
@@ -382,6 +393,8 @@ PLUGINAPI int PLUGINCALL ssl_plugin (struct pluginlink * pluginlink,
int argc, char** argv){
pl = pluginlink;
+ pdolog=pluginlink->findbyname("dolog");
+
if(!ssl_loaded){
ssl_loaded = 1;
pthread_mutex_init(&ssl_mutex, NULL);
diff --git a/src/plugins/TrafficPlugin/Makefile.inc b/src/plugins/TrafficPlugin/Makefile.inc
index 4aed3dbe..9c4d1ebb 100644
--- a/src/plugins/TrafficPlugin/Makefile.inc
+++ b/src/plugins/TrafficPlugin/Makefile.inc
@@ -4,4 +4,4 @@ TrafficPlugin$(OBJSUFFICS): TrafficPlugin.c
$(CC) $(DCFLAGS) $(CFLAGS) TrafficPlugin.c
$(BUILDDIR)TrafficPlugin$(DLSUFFICS): TrafficPlugin$(OBJSUFFICS)
- $(LN) $(LNOUT)../../$(BUILDDIR)TrafficPlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) TrafficPlugin$(OBJSUFFICS)
+ $(LN) $(LNOUT)../../$(BUILDDIR)TrafficPlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) TrafficPlugin$(OBJSUFFICS) $(LIBS)
diff --git a/src/plugins/TrafficPlugin/TrafficPlugin.c b/src/plugins/TrafficPlugin/TrafficPlugin.c
index b7219931..a0877769 100644
--- a/src/plugins/TrafficPlugin/TrafficPlugin.c
+++ b/src/plugins/TrafficPlugin/TrafficPlugin.c
@@ -26,10 +26,10 @@ extern "C" {
int DBGLEVEL = 0;
int already_loaded = 0;
-typedef int (* handler)(int argc, unsigned char ** argv);
+typedef int (* handler)(int argc, char ** argv);
-struct extparam * conf;
-struct commands * commandhandlers;
+struct extparam * sconfp;
+struct commands * scommandhandlers;
struct pluginlink * pl;
typedef enum {
@@ -79,7 +79,7 @@ static void killtrafcorrect() {
}
struct commands trafcorrect_handler;
-int h_trafcorrect(int argc, unsigned char ** argv) {
+int h_trafcorrect(int argc, char ** argv) {
if (argc < 2) {
if(DBGLEVEL == 1)fprintf(stdout, "See documentation of traffic correct plugin.\n");
return 1;
@@ -169,12 +169,9 @@ int h_trafcorrect(int argc, unsigned char ** argv) {
return 1;
}
-static unsigned short myhtons(unsigned short port) {
- return (port << 8) | (port >> 8);
-}
+void(*origprelog)(struct clientparam * param) = NULL;
-LOGFUNC origlogfunc;
-void mylogfunc(struct clientparam * param, const unsigned char * pz) {
+void mylogfunc(struct clientparam * param) {
PROXYSERVICE g_s = S_NOSERVICE;
int port;
int rule = 0;
@@ -189,7 +186,7 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
port = starttrafcorrect->port;
g_s = starttrafcorrect->p_service;
if (starttrafcorrect->p_service == S_NOSERVICE) g_s = param->service;
- if (starttrafcorrect->port <= 0) port = myhtons(*SAPORT(¶m->sinsr));
+ if (starttrafcorrect->port <= 0) port = htons(*SAPORT(¶m->sinsr));
#ifndef NOPSTDINT
statssrv_before = param->statssrv64;
@@ -199,7 +196,7 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
statscli_before = param->statscli;
#endif
rule++;
- if (((g_s == param->service) && (port == myhtons(*SAPORT(¶m->sinsr)))) ||
+ if (((g_s == param->service) && (port == htons(*SAPORT(¶m->sinsr)))) ||
( ((starttrafcorrect->type == UDP) &&
((param->operation == UDPASSOC)||
(param->operation == DNSRESOLVE)||
@@ -240,9 +237,9 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
}
if (DBGLEVEL == 1) {
#ifndef NOPSTDINT
- fprintf(stdout, "Port=%hd; Before: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; After: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(*SAPORT(¶m->sinsr)), statssrv_before, statscli_before, param->statssrv64, param->statscli64,param->nreads,param->nwrites,rule);
+ fprintf(stdout, "Port=%hd; Before: srv=%"PRIu64", cli=%"PRIu64"; After: srv=%"PRIu64", cli=%"PRIu64"; nreads=%ld; nwrites=%ld; Rule=%d\n",htons(*SAPORT(¶m->sinsr)), statssrv_before, statscli_before, param->statssrv64, param->statscli64,param->nreads,param->nwrites,rule);
#else
- fprintf(stdout, "Port=%hd; Before: srv=%lu, cli=%lu; After: srv=%lu, cli=%lu; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(param->sins.sin_port), statssrv_before, statscli_before, param->statssrv, param->statscli,param->nreads,param->nwrites,rule);
+ fprintf(stdout, "Port=%hd; Before: srv=%lu, cli=%lu; After: srv=%lu, cli=%lu; nreads=%ld; nwrites=%ld; Rule=%d\n",htons(*SAPORT(¶m->sins)), statssrv_before, statscli_before, param->statssrv, param->statscli,param->nreads,param->nwrites,rule);
#endif
}
ok = 1;
@@ -252,7 +249,7 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
if ((!ok) && (DBGLEVEL == 1)) {
fprintf(stdout, "No rules specifed: service=%d, port=%d, operation=%d", param->service, *SAPORT(¶m->sinsr),param->operation);
}
- origlogfunc(param, pz);
+ if(origprelog)origprelog(param);
}
#ifdef _WIN32
@@ -277,8 +274,8 @@ BOOL WINAPI DllMain( HINSTANCE hModule,
PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char** argv) {
struct commands * starthandler;
- conf = pluginlink->conf;
- commandhandlers = pluginlink->commandhandlers;
+ sconfp = pluginlink->conf;
+ scommandhandlers = pluginlink->commandhandlers;
pl = pluginlink;
if (argc>1) {
@@ -295,7 +292,7 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char**
}
already_loaded = 1;
/* "trafcorrect" */
- starthandler = commandhandlers;
+ starthandler = scommandhandlers;
for ( ; starthandler->next; starthandler = starthandler->next);
trafcorrect_handler.next = NULL;
trafcorrect_handler.minargs = 1;
@@ -305,8 +302,8 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char**
starthandler->next = &trafcorrect_handler;
/* conf->logfunc, */
- origlogfunc = conf->logfunc;
- conf->logfunc = mylogfunc;
+ origprelog = sconfp->prelog;
+ sconfp->prelog = mylogfunc;
return 0;
}
diff --git a/src/plugins/TransparentPlugin/transparent_plugin.c b/src/plugins/TransparentPlugin/transparent_plugin.c
index 0619bac4..6ae871e8 100644
--- a/src/plugins/TransparentPlugin/transparent_plugin.c
+++ b/src/plugins/TransparentPlugin/transparent_plugin.c
@@ -54,7 +54,6 @@ static FILTER_ACTION transparent_filter_client(void *fo, struct clientparam * pa
}
#else
#error No SO_ORIGINAL_DST defined
- param->srv->logfunc(param, (unsigned char *)"transparent_plugin: No SO_ORIGINAL_DST defined");
return REJECT;
#endif
#else
@@ -86,12 +85,12 @@ static struct filter transparent_filter = {
transparent_filter_close
};
-static int h_transparent(int argc, unsigned char **argv){
+static int h_transparent(int argc, char **argv){
transparent_filter.filter_open = transparent_filter_open;
return 0;
}
-static int h_notransparent(int argc, unsigned char **argv){
+static int h_notransparent(int argc, char **argv){
transparent_filter.filter_open = NULL;
return 0;
}
diff --git a/src/plugins/WindowsAuthentication/WindowsAuthentication.c b/src/plugins/WindowsAuthentication/WindowsAuthentication.c
index 818237e7..46e53244 100644
--- a/src/plugins/WindowsAuthentication/WindowsAuthentication.c
+++ b/src/plugins/WindowsAuthentication/WindowsAuthentication.c
@@ -78,6 +78,7 @@ PLUGINAPI int PLUGINCALL WindowsAuthentication(struct pluginlink * pluginlink, i
(LPTSTR) tmpbuf, &dlen, &snu)) return 100000 + (int)GetLastError();
if(snu != SidTypeGroup && snu != SidTypeAlias && snu != SidTypeWellKnownGroup) return 12;
if(!loaded){
+ alwaysauth.preauthorize = pluginlink->checkpreACL;
alwaysauth.authenticate = windowsfunc;
alwaysauth.authorize = pluginlink->checkACL;
alwaysauth.desc = "windows";
diff --git a/src/plugins/utf8tocp1251/utf8tocp1251.c b/src/plugins/utf8tocp1251/utf8tocp1251.c
index 412c927a..f47df774 100644
--- a/src/plugins/utf8tocp1251/utf8tocp1251.c
+++ b/src/plugins/utf8tocp1251/utf8tocp1251.c
@@ -22,17 +22,17 @@ static struct auth alwaysauth;
extern "C" {
#endif
-unsigned char * conv_utf8_to_cp1251(unsigned char *s){
- int i, j=0, n=(int)strlen((char *)s);
- int byte2 = 0;
- int c1, new_c1, new_c2, new_i;
+char * conv_utf8_to_cp1251(char *s){
+ unsigned i, j=0, n=(int)strlen((char *)s);
+ unsigned byte2 = 0;
+ unsigned c1, new_c1, new_c2, new_i;
for(i = 0; i < n; i++){
- if(byte2 && s[i]>=128 && s[i]<=192){
+ if(byte2 && ((unsigned)s[i])>=128 && ((unsigned)s[i])<=192){
new_c2=(c1&3)*64+(s[i]&63);
new_c1=(c1>>2)&5;
new_i=(new_c1*256)+new_c2;
- if(new_i == 1025) s[j++] = 168;
- else if (new_i==1105) s[j++] = 184;
+ if(new_i == 1025) s[j++] = (char)(unsigned char)168;
+ else if (new_i==1105) s[j++] = (char)(unsigned char)184;
else if (new_i < (192 + 848) || new_i > (255 + 848)){
return s;
}
@@ -46,7 +46,7 @@ unsigned char * conv_utf8_to_cp1251(unsigned char *s){
c1 = s[i];
byte2 = 1;
}
- else if(s[i] < 128) s[j++] = s[i];
+ else if(((unsigned)s[i]) < 128) s[j++] = s[i];
else return s;
}
s[j] = 0;
diff --git a/src/pop3p.c b/src/pop3p.c
index b433998a..71a3c34c 100644
--- a/src/pop3p.c
+++ b/src/pop3p.c
@@ -12,23 +12,23 @@
void * pop3pchild(struct clientparam* param) {
int i=0, res;
- unsigned char buf[320];
- unsigned char *se;
+ char buf[320];
+ char *se;
- if(socksend(param->clisock, (unsigned char *)"+OK Proxy\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (611);}
+ if(socksend(param->clisock, (char *)"+OK Proxy\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (611);}
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
while(i > 4 && strncasecmp((char *)buf, "USER", 4)){
if(!strncasecmp((char *)buf, "QUIT", 4)){
- socksend(param->clisock, (unsigned char *)"+OK\r\n", 5,conf.timeouts[STRING_S]);
+ socksend(param->clisock, (char *)"+OK\r\n", 5,conf.timeouts[STRING_S]);
RETURN(0);
}
- socksend(param->clisock, (unsigned char *)"-ERR need USER first\r\n", 22, conf.timeouts[STRING_S]);
+ socksend(param->clisock, (char *)"-ERR need USER first\r\n", 22, conf.timeouts[STRING_S]);
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
}
if(i<6) {RETURN(612);}
buf[i] = 0;
- if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0;
+ if ((se=(char *)strchr((char *)buf, '\r'))) *se = 0;
if (strncasecmp((char *)buf, "USER ", 5)){RETURN (614);}
if(parseconnusername((char *)buf +5, param, 0, 110)){RETURN(615);}
param->operation = CONNECT;
@@ -38,9 +38,9 @@ void * pop3pchild(struct clientparam* param) {
if( i < 3 ) {RETURN(621);}
buf[i] = 0;
if(strncasecmp((char *)buf, "+OK", 3)||!strncasecmp((char *)buf+4, "PROXY", 5)){RETURN(622);}
- if( socksend(param->remsock, (unsigned char *)"USER ", 5, conf.timeouts[STRING_S])!= 5 ||
+ if( socksend(param->remsock, (char *)"USER ", 5, conf.timeouts[STRING_S])!= 5 ||
socksend(param->remsock, param->extusername, (int)strlen((char *)param->extusername), conf.timeouts[STRING_S]) <= 0 ||
- socksend(param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2)
+ socksend(param->remsock, (char *)"\r\n", 2, conf.timeouts[STRING_S])!=2)
{RETURN(623);}
param->statscli64 += (uint64_t)(strlen((char *)param->extusername) + 7);
param->nwrites++;
@@ -53,7 +53,7 @@ void * pop3pchild(struct clientparam* param) {
}
else dolog(param, NULL);
if(param->clisock != INVALID_SOCKET) {
- if ((param->res > 0 && param->res < 100) || (param->res > 611 && param->res <700)) socksend(param->clisock, (unsigned char *)"-ERR\r\n", 6,conf.timeouts[STRING_S]);
+ if ((param->res > 0 && param->res < 100) || (param->res > 611 && param->res <700)) socksend(param->clisock, (char *)"-ERR\r\n", 6,conf.timeouts[STRING_S]);
}
freeparam(param);
return (NULL);
@@ -69,4 +69,5 @@ struct proxydef childdef = {
};
#include "proxymain.c"
+#include "log.c"
#endif
diff --git a/src/proxy.c b/src/proxy.c
index 0f530c24..4ecb08c8 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -89,9 +89,6 @@ char * proxy_stringtable[] = {
"403 Access Denied
Access control list denies you to access this resource