Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
874dd95a25 | |||
705f4f71c5 | |||
333402a9f2 | |||
e0f1e8f2f7 | |||
0f38d26b7b | |||
928153cd3d | |||
b046089d96 | |||
331db8370d | |||
511e14785b | |||
033c497d41 | |||
4c0af57e01 | |||
a84af46ede | |||
f48d5b7a25 | |||
6afbaf1fb2 | |||
|
c2656fd377 |
74
Dockerfile
Normal file
74
Dockerfile
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# docker build -t depollueur . -f ./docker/Dockerfile
|
||||||
|
# two stage building
|
||||||
|
# 1) install compiler and compile filter
|
||||||
|
# 2) copy filter and install postfix
|
||||||
|
# Doxkerfile patern from https://vsupalov.com/cache-docker-build-dependencies-without-volume-mounting/
|
||||||
|
FROM debian as intermediate_depollueur
|
||||||
|
|
||||||
|
########################################
|
||||||
|
RUN apt-get update && apt-get -y autoremove
|
||||||
|
RUN apt-get -y install locales locales-all
|
||||||
|
RUN sed -i '/fr_FR.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
|
||||||
|
ENV LC_ALL fr_FR.UTF-8
|
||||||
|
ENV LANG fr_FR.UTF-8
|
||||||
|
ENV LANGUAGE fr_FR:fr
|
||||||
|
RUN update-locale LANG=fr_FR.UTF-8
|
||||||
|
|
||||||
|
RUN apt-get -y install emacs elpa-php-mode apg
|
||||||
|
RUN apt-get -y install apg dos2unix
|
||||||
|
|
||||||
|
# creation du user filter,son repertoire home, copie des fichiers
|
||||||
|
RUN mkdir /home/filter ; useradd -d /home/filter filter ; chown filter /home/filter
|
||||||
|
########## >>> ce qui suit va être jetté
|
||||||
|
RUN apt-get install -y --fix-missing doxygen git \
|
||||||
|
build-essential make g++ libboost-program-options-dev libboost-system-dev libboost-filesystem-dev libcurl4-gnutls-dev libssl-dev
|
||||||
|
WORKDIR /home/
|
||||||
|
RUN git clone https://git.kaz.bzh/KAZ/depollueur.git
|
||||||
|
WORKDIR /home/depollueur/
|
||||||
|
RUN make
|
||||||
|
RUN cp build/out/* /home/filter/
|
||||||
|
RUN cp src/bash/* /home/filter/
|
||||||
|
########## <<< on ne garde que le répertoire ci-dessous
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# ###################################################################### #
|
||||||
|
# # # #
|
||||||
|
# # On jette tous ce qui est au-dessus pour ne garder que /home/filter # #
|
||||||
|
# # # #
|
||||||
|
# ###################################################################### #
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
FROM debian
|
||||||
|
|
||||||
|
########################################
|
||||||
|
RUN apt-get update && apt-get -y autoremove
|
||||||
|
RUN apt-get -y install locales locales-all
|
||||||
|
RUN sed -i '/fr_FR.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
|
||||||
|
ENV LC_ALL fr_FR.UTF-8
|
||||||
|
ENV LANG fr_FR.UTF-8
|
||||||
|
ENV LANGUAGE fr_FR:fr
|
||||||
|
RUN update-locale LANG=fr_FR.UTF-8
|
||||||
|
|
||||||
|
RUN apt-get -y install emacs elpa-php-mode apg
|
||||||
|
RUN apt-get -y install apg dos2unix
|
||||||
|
|
||||||
|
# creation du user filter,son repertoire home, copie des fichiers
|
||||||
|
RUN mkdir /home/filter ; useradd -d /home/filter filter ; chown filter /home/filter
|
||||||
|
########## >>> On fait excatement la même chose que la première fois *
|
||||||
|
RUN apt-get -y install libboost-program-options-dev libboost-system-dev libboost-filesystem-dev libcurl4-gnutls-dev
|
||||||
|
########## pour profiter du cahe des couche de docker
|
||||||
|
COPY --from=intermediate_depollueur /home/filter /home/filter
|
||||||
|
########## <<< mais cette fois on n'installe pas le compilo
|
||||||
|
RUN chown filter /home/filter/*; chmod a+rx /home/filter/*
|
||||||
|
|
||||||
|
# pour le confort : modif du .bashrc de root
|
||||||
|
RUN sed -i 's/# alias/alias/g' /root/.bashrc
|
||||||
|
|
||||||
|
RUN mkdir /var/log/mail ; chmod a+wrx /var/log/mail
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
VOLUME [ "/var/log/mail" ]
|
||||||
|
ENTRYPOINT [ "/home/filter/server" ]
|
||||||
|
|
||||||
|
#HEALTHCHECK --interval=10s --timeout=5s --start-period=20s \
|
||||||
|
# CMD XXX || exit 1
|
52
Makefile
52
Makefile
@ -44,17 +44,23 @@ OUT_DIR = $(BLD_DIR)/out
|
|||||||
LIB_DIR = $(BLD_DIR)/lib
|
LIB_DIR = $(BLD_DIR)/lib
|
||||||
OBJ_DIR = $(BLD_DIR)/obj
|
OBJ_DIR = $(BLD_DIR)/obj
|
||||||
|
|
||||||
KAZ_PRG = eMailShrinker
|
EMS_PRG = eMailShrinker
|
||||||
KAZ_MOD = eMailShrinker EmbeddedData Attachment MainAttachment SizeArg kazDebug kazMisc
|
EMS_MOD = eMailShrinker EmbeddedData Attachment MainAttachment SizeArg kazDebug kazMisc
|
||||||
KAZ_SRC = $(patsubst %, $(CPP_DIR)/%.cpp, $(KAZ_MOD))
|
EMS_SRC = $(patsubst %, $(CPP_DIR)/%.cpp, $(EMS_MOD))
|
||||||
KAZ_OBJ = $(patsubst %, $(OBJ_DIR)/%.o, $(KAZ_MOD))
|
EMS_OBJ = $(patsubst %, $(OBJ_DIR)/%.o, $(EMS_MOD))
|
||||||
KAZ_OUT = $(patsubst %, $(OUT_DIR)/%, $(KAZ_PRG))
|
EMS_OUT = $(patsubst %, $(OUT_DIR)/%, $(EMS_PRG))
|
||||||
|
|
||||||
JIR_PRG = jirafeauAPI
|
SRV_PRG = server
|
||||||
JIR_MOD = jirafeauAPI SizeArg kazDebug kazMisc
|
SRV_MOD = server kazDebug kazMisc
|
||||||
JIR_SRC = $(patsubst %, $(CPP_DIR)/%.cpp, $(JIR_MOD))
|
SRV_SRC = $(patsubst %, $(CPP_DIR)/%.cpp, $(SRV_MOD))
|
||||||
JIR_OBJ = $(patsubst %, $(OBJ_DIR)/%.o, $(JIR_MOD))
|
SRV_OBJ = $(patsubst %, $(OBJ_DIR)/%.o, $(SRV_MOD))
|
||||||
JIR_OUT = $(patsubst %, $(OUT_DIR)/%, $(JIR_PRG))
|
SRV_OUT = $(patsubst %, $(OUT_DIR)/%, $(SRV_PRG))
|
||||||
|
|
||||||
|
TSRV_PRG = testServerRW
|
||||||
|
TSRV_MOD = testServerRW kazDebug
|
||||||
|
TSRV_SRC = $(patsubst %, $(CPP_DIR)/%.cpp, $(TSRV_MOD))
|
||||||
|
TSRV_OBJ = $(patsubst %, $(OBJ_DIR)/%.o, $(TSRV_MOD))
|
||||||
|
TSRV_OUT = $(patsubst %, $(OUT_DIR)/%, $(TSRV_PRG))
|
||||||
|
|
||||||
## FLAGS ###############################
|
## FLAGS ###############################
|
||||||
|
|
||||||
@ -71,17 +77,25 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/*/%.cpp
|
|||||||
$(CC) $< $(IFLAGS) -cpp -c -o $@
|
$(CC) $< $(IFLAGS) -cpp -c -o $@
|
||||||
|
|
||||||
## ENTRIES #############################
|
## ENTRIES #############################
|
||||||
all: init eMailShrinker jirafeauAPI doc
|
all: init $(EMS_PRG) $(SRV_PRG) $(TSRV_PRG) doc
|
||||||
|
|
||||||
eMailShrinker: $(KAZ_OUT)
|
$(EMS_PRG): $(EMS_OUT)
|
||||||
|
|
||||||
$(KAZ_OUT): $(KAZ_OBJ)
|
$(EMS_OUT): $(EMS_OBJ)
|
||||||
$(CC) $(KAZ_OBJ) $(IFLAGS) -cpp -L$(LIB_DIR) $(LFLAGS) -o $@
|
$(CC) $(EMS_OBJ) $(IFLAGS) -cpp -L$(LIB_DIR) $(LFLAGS) -o $@
|
||||||
|
|
||||||
jirafeauAPI: $(JIR_OUT)
|
$(SRV_PRG): $(SRV_OUT)
|
||||||
|
|
||||||
$(JIR_OUT): $(JIR_OBJ)
|
$(SRV_OUT): $(SRV_OBJ)
|
||||||
$(CC) $(JIR_OBJ) $(IFLAGS) -cpp -L$(LIB_DIR) $(LFLAGS) -o $@
|
$(CC) $(SRV_OBJ) $(IFLAGS) -cpp -L$(LIB_DIR) $(LFLAGS) -o $@
|
||||||
|
|
||||||
|
$(TSRV_PRG): $(TSRV_OUT)
|
||||||
|
|
||||||
|
$(TSRV_OUT): $(TSRV_OBJ)
|
||||||
|
$(CC) $(TSRV_OBJ) $(IFLAGS) -cpp -L$(LIB_DIR) $(LFLAGS) -o $@
|
||||||
|
|
||||||
|
image:
|
||||||
|
docker build -t depollueur . -f ./Dockerfile
|
||||||
|
|
||||||
doc:
|
doc:
|
||||||
doxygen src/Doxyfile
|
doxygen src/Doxyfile
|
||||||
@ -97,8 +111,8 @@ wipe: clean
|
|||||||
-rm -rf $(OUT_DIR) $(LIB_DIR) $(BLD_DIR)
|
-rm -rf $(OUT_DIR) $(LIB_DIR) $(BLD_DIR)
|
||||||
|
|
||||||
## DEPENDS #############################
|
## DEPENDS #############################
|
||||||
ALL_OUT = $(KAZ_PRG) $(JIR_PRG)
|
ALL_OUT = $(EMS_PRG) $(SRV_PRG) $(TSRV_PRG)
|
||||||
ALL_OBJ = $(KAZ_OBJ) $(JIR_OBJ)
|
ALL_OBJ = $(EMS_OBJ) $(SRV_OBJ) $(TSRV_OBJ)
|
||||||
|
|
||||||
DEPENDS = ${ALL_OUT:=.d} ${ALL_OBJ:.o=.d}
|
DEPENDS = ${ALL_OUT:=.d} ${ALL_OBJ:.o=.d}
|
||||||
-include ${DEPENDS}
|
-include ${DEPENDS}
|
||||||
|
@ -13,7 +13,6 @@ depollueur/
|
|||||||
│ ├── Attachment.cpp
|
│ ├── Attachment.cpp
|
||||||
│ ├── eMailShrinker.cpp
|
│ ├── eMailShrinker.cpp
|
||||||
│ ├── EmbeddedData.cpp
|
│ ├── EmbeddedData.cpp
|
||||||
│ ├── jirafeauAPI.cpp
|
|
||||||
│ ├── kazDebug.cpp
|
│ ├── kazDebug.cpp
|
||||||
│ ├── kazMisc.cpp
|
│ ├── kazMisc.cpp
|
||||||
│ ├── MainAttachment.cpp
|
│ ├── MainAttachment.cpp
|
||||||
|
18
docker-compose.yml
Normal file
18
docker-compose.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
version: '3.3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
depollueur:
|
||||||
|
# ports:
|
||||||
|
# - 8088:80
|
||||||
|
image: depollueur
|
||||||
|
container_name: depollueurServ
|
||||||
|
# restart: ${restartPolicy}
|
||||||
|
volumes:
|
||||||
|
- mailLog:/var/log/mail
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mailLog:
|
||||||
|
# config:
|
@ -2,6 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* Kaz addon (see https://git.kaz.bzh/KAZ/depollueur for information)
|
* Kaz addon (see https://git.kaz.bzh/KAZ/depollueur for information)
|
||||||
* create un archive for a set of file or update file deadline
|
* create un archive for a set of file or update file deadline
|
||||||
|
* version : 2.21 (2024-06-04)
|
||||||
|
|
||||||
a.php?r=email => track
|
a.php?r=email => track
|
||||||
a.php?p=email => period
|
a.php?p=email => period
|
||||||
@ -31,6 +32,8 @@ define ('VAR_PERIOD', $cfg ['var_root'].'period/');
|
|||||||
define ('VAR_LANG', $cfg ['var_root'].'lang/');
|
define ('VAR_LANG', $cfg ['var_root'].'lang/');
|
||||||
define ('VAR_FAKE', $cfg ['var_root'].'fake/');
|
define ('VAR_FAKE', $cfg ['var_root'].'fake/');
|
||||||
define ('VAR_ADMIN', $cfg ['var_root'].'admin/');
|
define ('VAR_ADMIN', $cfg ['var_root'].'admin/');
|
||||||
|
define ('VAR_CONFIG', $cfg ['var_root'].'config/');
|
||||||
|
define ('FILE_CONFIG', VAR_CONFIG.'default.php');
|
||||||
|
|
||||||
$domain="kaz.local";
|
$domain="kaz.local";
|
||||||
if (preg_match ("%^.*//([^/]*)/?.*$%", $cfg ['web_root'], $matches))
|
if (preg_match ("%^.*//([^/]*)/?.*$%", $cfg ['web_root'], $matches))
|
||||||
@ -40,9 +43,19 @@ define ('MAX_VALID_UPLOAD_TIME', 60);
|
|||||||
define ('TOKEN_USE_LIMIT', "-2 hours");
|
define ('TOKEN_USE_LIMIT', "-2 hours");
|
||||||
define ('TOKEN_LOGIN_LIMIT', "-15 minutes");
|
define ('TOKEN_LOGIN_LIMIT', "-15 minutes");
|
||||||
define ('TOKEN_LOGOUT_LIMIT', "-8 hours");
|
define ('TOKEN_LOGOUT_LIMIT', "-8 hours");
|
||||||
define ('DEFAULT_MODE', "footer");
|
if (!file_exists (VAR_CONFIG))
|
||||||
define ('DEFAULT_PERIOD', "month");
|
mkdir (VAR_CONFIG, 0755);
|
||||||
define ('DEFAULT_LANG', "fr");
|
if (!file_exists (FILE_CONFIG)) {
|
||||||
|
file_put_contents (FILE_CONFIG, "<?php".NL.
|
||||||
|
"/* if error with DEFAULT_MODE, DEFAULT_PERIOD or DEFAULT_LANG then remove this file. */".NL.
|
||||||
|
"define ('DEFAULT_MODE', 'footer');".NL.
|
||||||
|
"define ('DEFAULT_PERIOD', 'month');".NL.
|
||||||
|
"define ('DEFAULT_LANG', 'fr');".NL.NL);
|
||||||
|
define ('DEFAULT_MODE', 'footer');
|
||||||
|
define ('DEFAULT_PERIOD', 'month');
|
||||||
|
define ('DEFAULT_LANG', 'fr');
|
||||||
|
} else
|
||||||
|
require (FILE_CONFIG);
|
||||||
|
|
||||||
define ('E_BAD_ARCHIVE_NAME', 'Bad archive name format');
|
define ('E_BAD_ARCHIVE_NAME', 'Bad archive name format');
|
||||||
define ('E_CREATE_ZIP', "Impossible de créer l'archive.");
|
define ('E_CREATE_ZIP', "Impossible de créer l'archive.");
|
||||||
|
78
src/bash/checkAltered.sh
Executable file
78
src/bash/checkAltered.sh
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
##########################################################################
|
||||||
|
# Copyright KAZ 2021 #
|
||||||
|
# #
|
||||||
|
# contact (at) kaz.bzh #
|
||||||
|
# #
|
||||||
|
# This software is a filter to shrink email by attachment extraction. #
|
||||||
|
# #
|
||||||
|
# This software is governed by the CeCILL-B license under French law and #
|
||||||
|
# abiding by the rules of distribution of free software. You can use, #
|
||||||
|
# modify and/or redistribute the software under the terms of the #
|
||||||
|
# CeCILL-B license as circulated by CEA, CNRS and INRIA at the following #
|
||||||
|
# URL "http://www.cecill.info". #
|
||||||
|
# #
|
||||||
|
# As a counterpart to the access to the source code and rights to copy, #
|
||||||
|
# modify and redistribute granted by the license, users are provided #
|
||||||
|
# only with a limited warranty and the software's author, the holder of #
|
||||||
|
# the economic rights, and the successive licensors have only limited #
|
||||||
|
# liability. #
|
||||||
|
# #
|
||||||
|
# In this respect, the user's attention is drawn to the risks associated #
|
||||||
|
# with loading, using, modifying and/or developing or reproducing the #
|
||||||
|
# software by the user in light of its specific status of free software, #
|
||||||
|
# that may mean that it is complicated to manipulate, and that also #
|
||||||
|
# therefore means that it is reserved for developers and experienced #
|
||||||
|
# professionals having in-depth computer knowledge. Users are therefore #
|
||||||
|
# encouraged to load and test the software's suitability as regards #
|
||||||
|
# their requirements in conditions enabling the security of their #
|
||||||
|
# systems and/or data to be ensured and, more generally, to use and #
|
||||||
|
# operate it in the same conditions as regards security. #
|
||||||
|
# #
|
||||||
|
# The fact that you are presently reading this means that you have had #
|
||||||
|
# knowledge of the CeCILL-B license and that you accept its terms. #
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
PRG=$(basename $0)
|
||||||
|
|
||||||
|
usage () {
|
||||||
|
echo "Usage: ${PRG} logDir"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
BOLD='\e[1m'
|
||||||
|
RED='\e[0;31m'
|
||||||
|
GREEN='\e[0;32m'
|
||||||
|
YELLOW='\e[0;33m'
|
||||||
|
BLUE='\e[0;34m'
|
||||||
|
MAGENTA='\e[0;35m'
|
||||||
|
CYAN='\e[0;36m'
|
||||||
|
NC='\e[0m' # No Color
|
||||||
|
NL='
|
||||||
|
'
|
||||||
|
[ "$#" -eq 1 ] || usage
|
||||||
|
logDir=$(realpath "$1")
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# recherche des binaires
|
||||||
|
cd $(dirname $0)
|
||||||
|
eMailShrinker="$(realpath "./eMailShrinker")"
|
||||||
|
[ -x "${eMailShrinker}" ] || eMailShrinker="$(realpath "../../build/out/eMailShrinker")"
|
||||||
|
[ -x "${eMailShrinker}" ] || ( echo "${RED}eMailShrinker not found${NC}" ; exit)
|
||||||
|
|
||||||
|
|
||||||
|
cd "${logDir}"
|
||||||
|
for i in in.*.orig;
|
||||||
|
do
|
||||||
|
clear
|
||||||
|
echo -e " ${GREEN}${BOLD}${i//.orig}${NC}\n"
|
||||||
|
"${eMailShrinker}" -l ${i}
|
||||||
|
echo -e "\n ####################\n"
|
||||||
|
"${eMailShrinker}" -l ${i//.orig}.altered
|
||||||
|
echo -en "\n(q = quit / y = rm / default = continue)? "
|
||||||
|
read rep
|
||||||
|
case "${rep}" in
|
||||||
|
"q" ) break;;
|
||||||
|
"y") rm ${i} ${i//.orig}.altered
|
||||||
|
esac
|
||||||
|
done
|
99
src/bash/checkShrinker.sh
Executable file
99
src/bash/checkShrinker.sh
Executable file
@ -0,0 +1,99 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
##########################################################################
|
||||||
|
# Copyright KAZ 2021 #
|
||||||
|
# #
|
||||||
|
# contact (at) kaz.bzh #
|
||||||
|
# #
|
||||||
|
# This software is a filter to shrink email by attachment extraction. #
|
||||||
|
# #
|
||||||
|
# This software is governed by the CeCILL-B license under French law and #
|
||||||
|
# abiding by the rules of distribution of free software. You can use, #
|
||||||
|
# modify and/or redistribute the software under the terms of the #
|
||||||
|
# CeCILL-B license as circulated by CEA, CNRS and INRIA at the following #
|
||||||
|
# URL "http://www.cecill.info". #
|
||||||
|
# #
|
||||||
|
# As a counterpart to the access to the source code and rights to copy, #
|
||||||
|
# modify and redistribute granted by the license, users are provided #
|
||||||
|
# only with a limited warranty and the software's author, the holder of #
|
||||||
|
# the economic rights, and the successive licensors have only limited #
|
||||||
|
# liability. #
|
||||||
|
# #
|
||||||
|
# In this respect, the user's attention is drawn to the risks associated #
|
||||||
|
# with loading, using, modifying and/or developing or reproducing the #
|
||||||
|
# software by the user in light of its specific status of free software, #
|
||||||
|
# that may mean that it is complicated to manipulate, and that also #
|
||||||
|
# therefore means that it is reserved for developers and experienced #
|
||||||
|
# professionals having in-depth computer knowledge. Users are therefore #
|
||||||
|
# encouraged to load and test the software's suitability as regards #
|
||||||
|
# their requirements in conditions enabling the security of their #
|
||||||
|
# systems and/or data to be ensured and, more generally, to use and #
|
||||||
|
# operate it in the same conditions as regards security. #
|
||||||
|
# #
|
||||||
|
# The fact that you are presently reading this means that you have had #
|
||||||
|
# knowledge of the CeCILL-B license and that you accept its terms. #
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
PRG=$(basename $0)
|
||||||
|
FILTER_TEST="$(realpath "$(dirname $0)/filterTest.sh")"
|
||||||
|
|
||||||
|
ATTACH_MODE="FOOTER"
|
||||||
|
|
||||||
|
usage () {
|
||||||
|
echo "Usage: ${PRG} {NONE|FOOTER|ATTACHMENT|BOTH} mbox..."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################
|
||||||
|
BOLD='\e[1m'
|
||||||
|
RED='\e[0;31m'
|
||||||
|
GREEN='\e[0;32m'
|
||||||
|
YELLOW='\e[0;33m'
|
||||||
|
BLUE='\e[0;34m'
|
||||||
|
MAGENTA='\e[0;35m'
|
||||||
|
CYAN='\e[0;36m'
|
||||||
|
GREY='\e[0;90m'
|
||||||
|
BG_BLACK='\e[0;40m'
|
||||||
|
BG_RED='\e[0;41m'
|
||||||
|
BG_GREEN='\e[0;42m'
|
||||||
|
BG_YELLOW='\e[0;43m'
|
||||||
|
BG_BLUE='\e[0;44m'
|
||||||
|
BG_MAGENTA='\e[0;45m'
|
||||||
|
CYAN='\e[0;36m'
|
||||||
|
NC='\e[0m' # No Color
|
||||||
|
NL='
|
||||||
|
'
|
||||||
|
|
||||||
|
########################################
|
||||||
|
[ "$#" -lt 2 ] && usage
|
||||||
|
|
||||||
|
ATTACH_MODE="$1"; shift
|
||||||
|
|
||||||
|
case "${ATTACH_MODE}" in
|
||||||
|
""|NONE|FOOTER|ATTACHMENT|BOTH);;
|
||||||
|
*) usage;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
start=0
|
||||||
|
loop=true
|
||||||
|
while [ ! -z "${loop}" ]; do
|
||||||
|
loop=""
|
||||||
|
count=0
|
||||||
|
for mbox in $*; do
|
||||||
|
clear
|
||||||
|
((count=count+1))
|
||||||
|
(( count < start )) && continue
|
||||||
|
echo -e " ${GREY}${count}/$# ${GREEN}${BOLD}${mbox}${NC}\n"
|
||||||
|
"${FILTER_TEST}" -s -m "${ATTACH_MODE}" "${mbox}"
|
||||||
|
echo -en "\n(q = quit / [0-9]* = goto / default = continue)? "
|
||||||
|
read rep
|
||||||
|
case "${rep}" in
|
||||||
|
"q" ) break;;
|
||||||
|
[0-9]* )
|
||||||
|
start="${rep}"
|
||||||
|
(( count < start )) && continue
|
||||||
|
loop=true
|
||||||
|
break;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
done
|
@ -38,18 +38,17 @@
|
|||||||
# - installer l'utilitaire dos2unix
|
# - installer l'utilitaire dos2unix
|
||||||
# - le contenu de INSPECT_DIR doit être accessible en écriture pour le
|
# - le contenu de INSPECT_DIR doit être accessible en écriture pour le
|
||||||
# proriétaire du script
|
# proriétaire du script
|
||||||
# - shrinkEMail et jirafeau.sh doivent être accessible en execution pour
|
# - shrinkEMail doit être accessible en execution pour le proriétaire
|
||||||
# le roriétaire du script
|
# - comme le programme n'a pas de privigèle, il faut que root fasse avant :
|
||||||
# - il faut que root fasse avant :
|
|
||||||
# mkdir -p "${DIR_LOG}/pb/" ; chmod a+rwx "${DIR_LOG}/pb/"
|
# mkdir -p "${DIR_LOG}/pb/" ; chmod a+rwx "${DIR_LOG}/pb/"
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
DEFAULT_MODE="footer"
|
DEFAULT_MODE="both"
|
||||||
DEFAULT_PERIOD="month"
|
DEFAULT_PERIOD="month"
|
||||||
DEFAULT_TRACK=""
|
DEFAULT_TRACK=""
|
||||||
|
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
DOMAINNAME=$(cat domainname)
|
DOMAINEDEPOT=$(cat config/domainedepot)
|
||||||
# Exit codes from <sysexits.h>
|
# Exit codes from <sysexits.h>
|
||||||
EX_TEMPFAIL=75
|
EX_TEMPFAIL=75
|
||||||
EX_UNAVAILABLE=69
|
EX_UNAVAILABLE=69
|
||||||
@ -63,8 +62,7 @@ MAILS=/tmp/FILTER
|
|||||||
MAX_KEEP_IN_MAIL=5ki
|
MAX_KEEP_IN_MAIL=5ki
|
||||||
MAX_UPLOAD_SIZE=1Gi
|
MAX_UPLOAD_SIZE=1Gi
|
||||||
SHRINK_CMD=/home/filter/eMailShrinker
|
SHRINK_CMD=/home/filter/eMailShrinker
|
||||||
JIRAFEAU_CMD=/home/filter/jirafeauAPI
|
JIRAFEAU_URL=https://depot.${DOMAINEDEPOT:-"kaz.bzh"}
|
||||||
JIRAFEAU_URL=https://depot.${DOMAINNAME:-"kaz.bzh"}
|
|
||||||
JIRAFEAU_LOCAL=http://depot
|
JIRAFEAU_LOCAL=http://depot
|
||||||
MD5_CMD=/usr/bin/md5sum
|
MD5_CMD=/usr/bin/md5sum
|
||||||
DISCLAMER_CMD=altermime
|
DISCLAMER_CMD=altermime
|
||||||
@ -72,28 +70,28 @@ MAX_FINAL_SIZE=2097152 # 2Mi
|
|||||||
ARCHIVE_TITLE="archive_content"
|
ARCHIVE_TITLE="archive_content"
|
||||||
ARCHIVE_MIME="text/kaz_email_archive"
|
ARCHIVE_MIME="text/kaz_email_archive"
|
||||||
|
|
||||||
FILE_SKIP_DOMAINS="/tmp/docker-mailserver/file_domaines_non_depollues.txt"
|
FILE_SKIP_DOMAINS="config/file_domaines_non_depollues.txt"
|
||||||
#on enlève les commentaires et les lignes vides
|
#on enlève les commentaires et les lignes vides
|
||||||
SKIP_DOMAINS=`grep -Ev '^#|^[[:space:]]*$' $FILE_SKIP_DOMAINS`
|
SKIP_DOMAINS=$(grep -Ev '^#|^[[:space:]]*$' $FILE_SKIP_DOMAINS 2>/dev/null)
|
||||||
|
|
||||||
KEEP_FAILED=true
|
KEEP_FAILED=true
|
||||||
DEBUG=true
|
DEBUG=true
|
||||||
|
|
||||||
#################### FONCTIONS ############################################
|
#################### FONCTIONS ############################################
|
||||||
BOLD='[1m'
|
BOLD='\e[1m'
|
||||||
RED='[0;31m'
|
RED='\e[0;31m'
|
||||||
GREEN='[0;32m'
|
GREEN='\e[0;32m'
|
||||||
YELLOW='[0;33m'
|
YELLOW='\e[0;33m'
|
||||||
BLUE='[0;34m'
|
BLUE='\e[0;34m'
|
||||||
MAGENTA='[0;35m'
|
MAGENTA='\e[0;35m'
|
||||||
CYAN='[0;36m'
|
CYAN='\e[0;36m'
|
||||||
NC='[0m' # No Color
|
NC='\e[0m' # No Color
|
||||||
NL='
|
NL='
|
||||||
'
|
'
|
||||||
|
|
||||||
#--------------------- Fichier de LOG -------------------
|
#--------------------- Fichier de LOG -------------------
|
||||||
LOG_FIC () {
|
LOG_FIC () {
|
||||||
echo "${BLUE}$(date +%d-%m-%Y-%H-%M-%S)${NC} : $*" >> "${TMP_LOG}"
|
echo -e "${BLUE}$(date +%d-%m-%Y-%H-%M-%S)${NC} : $*" >> "${TMP_LOG}"
|
||||||
}
|
}
|
||||||
|
|
||||||
quitFilter () {
|
quitFilter () {
|
||||||
@ -124,11 +122,11 @@ curlJirafeauSend () {
|
|||||||
# $4: name
|
# $4: name
|
||||||
# $5: password
|
# $5: password
|
||||||
|
|
||||||
type=$3
|
type="type=$3;"
|
||||||
[ -z "${type}" ] && type="text/plain"
|
[ -z "$3" -o "$3" = "/" ] && type=""
|
||||||
LOG_FIC " - curl -X POST -F \"time=$1\" -F \"key=$5\" -F \"file=@$2;type=${type};filename=\\\"$4\\\"\" \"${JIRAFEAU_LOCAL}/a.php\""
|
LOG_FIC " - curl -X POST -F \"time=$1\" -F \"key=$5\" -F \"file=@$2;${type}filename=\\\"$4\\\"\" \"${JIRAFEAU_LOCAL}/a.php\""
|
||||||
for num in {1..2}; do
|
for num in {1..2}; do
|
||||||
OUTPUT=$(curl -X POST -F "time=$1" -F "key=$5" -F "file=@$2;type=${type};filename=\"$4\"" "${JIRAFEAU_LOCAL}/a.php")
|
OUTPUT=$(curl -X POST -F "time=$1" -F "key=$5" -F "file=@$2;${type}filename=\"$4\"" "${JIRAFEAU_LOCAL}/a.php")
|
||||||
read JIR_TOKEN <<< "${OUTPUT}"
|
read JIR_TOKEN <<< "${OUTPUT}"
|
||||||
case "${JIR_TOKEN}" in
|
case "${JIR_TOKEN}" in
|
||||||
"" | no | *Error* | \<* )
|
"" | no | *Error* | \<* )
|
||||||
@ -151,7 +149,7 @@ function check_skip_domains() {
|
|||||||
local domain="${email##*@}"
|
local domain="${email##*@}"
|
||||||
|
|
||||||
# Utiliser grep pour vérifier si le domaine est dans la liste des domaines à sauter
|
# Utiliser grep pour vérifier si le domaine est dans la liste des domaines à sauter
|
||||||
if echo "$SKIP_DOMAINS" | grep -q -w "$domain"; then
|
if echo "${SKIP_DOMAINS}" | grep -q -w "${domain}"; then
|
||||||
echo "yes"
|
echo "yes"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
@ -162,7 +160,7 @@ function check_skip_domains() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#################### MAIN #################################################
|
#################### MAIN #################################################
|
||||||
echo "${NL}${BLUE}$(date +%d-%m-%Y-%H-%M-%S)${NC} : ${GREEN}######################################## filter start (log in ${TMP_LOG})${NC}" >> "${FIC_LOG}"
|
echo -e "${NL}${BLUE}$(date +%d-%m-%Y-%H-%M-%S)${NC} : ${GREEN}######################################## filter start (log in ${TMP_LOG})${NC}" >> "${FIC_LOG}"
|
||||||
LOG_FIC "${GREEN}######################################## ${TMP_LOG} ${NC}"
|
LOG_FIC "${GREEN}######################################## ${TMP_LOG} ${NC}"
|
||||||
|
|
||||||
if ! mkdir -p "${MAILS}"; then
|
if ! mkdir -p "${MAILS}"; then
|
||||||
|
@ -36,22 +36,21 @@
|
|||||||
PRG=$(basename $0)
|
PRG=$(basename $0)
|
||||||
|
|
||||||
ATTACH_MODE="FOOTER"
|
ATTACH_MODE="FOOTER"
|
||||||
|
export SIMULATE=""
|
||||||
|
|
||||||
BOLD='[1m'
|
BOLD='\e[1m'
|
||||||
RED='[0;31m'
|
RED='\e[0;31m'
|
||||||
GREEN='[0;32m'
|
GREEN='\e[0;32m'
|
||||||
YELLOW='[0;33m'
|
YELLOW='\e[0;33m'
|
||||||
BLUE='[0;34m'
|
BLUE='\e[0;34m'
|
||||||
MAGENTA='[0;35m'
|
MAGENTA='\e[0;35m'
|
||||||
CYAN='[0;36m'
|
CYAN='\e[0;36m'
|
||||||
NC='[0m' # No Color
|
NC='\e[0m' # No Color
|
||||||
NL='
|
NL='
|
||||||
'
|
'
|
||||||
|
|
||||||
TTY=$(tty)
|
|
||||||
########################################
|
########################################
|
||||||
LOG () {
|
LOG () {
|
||||||
echo "$1" >> "${TTY}"
|
echo -e "$1" 1>&2
|
||||||
}
|
}
|
||||||
|
|
||||||
usage () {
|
usage () {
|
||||||
@ -64,6 +63,7 @@ while : ; do
|
|||||||
-h*) usage;;
|
-h*) usage;;
|
||||||
-v*) "${eMailShrinker}" -v; exit;;
|
-v*) "${eMailShrinker}" -v; exit;;
|
||||||
-g) DEBUG="-g"; shift;;
|
-g) DEBUG="-g"; shift;;
|
||||||
|
-s) SIMULATE="echo"; shift;;
|
||||||
-m) shift; ATTACH_MODE="$1"; shift;;
|
-m) shift; ATTACH_MODE="$1"; shift;;
|
||||||
*) break;;
|
*) break;;
|
||||||
esac
|
esac
|
||||||
@ -83,12 +83,12 @@ mbox=$(realpath "$1")
|
|||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
eMailShrinker="$(realpath "./eMailShrinker")"
|
eMailShrinker="$(realpath "./eMailShrinker")"
|
||||||
[ -x "${eMailShrinker}" ] || eMailShrinker="$(realpath "../../build/out/eMailShrinker")"
|
[ -x "${eMailShrinker}" ] || eMailShrinker="$(realpath "../../build/out/eMailShrinker")"
|
||||||
[ -x "${eMailShrinker}" ] || ( echo "${RED}eMailShrinker not found${NC}" ; exit)
|
[ -x "${eMailShrinker}" ] || ( echo -e "${RED}eMailShrinker not found${NC}" ; exit)
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
dos2unix "${mbox}"
|
dos2unix "${mbox}"
|
||||||
DOMAINNAME="$(cat domainname)"
|
[ -z "${SIMULATE}" ] && DOMAINEDEPOT="$(cat domainedepot)"
|
||||||
JIRAFEAU_URL="https://depot.${DOMAINNAME}"
|
JIRAFEAU_URL="https://depot.${DOMAINEDEPOT}"
|
||||||
JIRAFEAU_LOCAL="${JIRAFEAU_URL}"
|
JIRAFEAU_LOCAL="${JIRAFEAU_URL}"
|
||||||
|
|
||||||
TMP_DIR="$(mktemp)"
|
TMP_DIR="$(mktemp)"
|
||||||
@ -99,8 +99,7 @@ curlJirafeauUpdate () {
|
|||||||
# $1: periode
|
# $1: periode
|
||||||
# $2: jirafeauItemRef
|
# $2: jirafeauItemRef
|
||||||
|
|
||||||
curl -X POST -d "u=$1" -d "h=$2" "${JIRAFEAU_LOCAL}/a.php"
|
[ -z "${SIMULATE}" ] && curl -X POST -d "u=$1" -d "h=$2" "${JIRAFEAU_LOCAL}/a.php"
|
||||||
#"${jirafeauAPI}" -f "${JIRAFEAU_LOCAL}" -t "$1" update "$2"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
curlJirafeauSend () {
|
curlJirafeauSend () {
|
||||||
@ -110,11 +109,14 @@ curlJirafeauSend () {
|
|||||||
# $4: name
|
# $4: name
|
||||||
# $5: password
|
# $5: password
|
||||||
|
|
||||||
type=$3
|
if [ -n "${SIMULATE}" ]; then
|
||||||
[ -z "${type}" ] && type="text/plain"
|
echo -e "TokenXXX\nCodeX"
|
||||||
LOG "curl -X POST -F \"time=$1\" -F \"key=$5\" -F \"file=@$2;type=${type};filename=\\\"$4\\\"\" \"${JIRAFEAU_LOCAL}/a.php\""
|
return
|
||||||
curl -X POST -F "time=$1" -F "key=$5" -F "file=@$2;type=${type};filename=\"$4\"" "${JIRAFEAU_LOCAL}/a.php" || exit 1
|
fi
|
||||||
#"${jirafeauAPI}" -f "${JIRAFEAU_LOCAL}" -t "$1" -s "1Gi" -c "${type}" -n "$4" send "$2" "$5"
|
type="type=$3;"
|
||||||
|
[ -z "$3" -o "$3" = "/" ] && type=""
|
||||||
|
LOG "curl -X POST -F \"time=$1\" -F \"key=$5\" -F \"file=@$2;${type}filename=\\\"$4\\\"\" \"${JIRAFEAU_LOCAL}/a.php\""
|
||||||
|
curl -X POST -F "time=$1" -F "key=$5" -F "file=@$2;${type}filename=\"$4\"" "${JIRAFEAU_LOCAL}/a.php" || exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
@ -126,19 +128,18 @@ echo -e "time: $(date "+%Y-%m-%d-%H:%M:%S")\nid: $(date +%s)" > "${TMP_DIR}/arch
|
|||||||
|
|
||||||
########################################
|
########################################
|
||||||
# affichage de la structure de départ
|
# affichage de la structure de départ
|
||||||
LOG " - ${BLUE}mbox: ${mbox}${NC}"
|
LOG " - ${BLUE}mbox: ${mbox}${NC}${YELLOW}"
|
||||||
"${eMailShrinker}" -l "${mbox}"
|
"${eMailShrinker}" -l "${mbox}"
|
||||||
LOG
|
LOG "${NC}"
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# recherche des prolongations des délais de grace
|
# recherche des prolongations des délais de grace
|
||||||
"${eMailShrinker}" ${DEBUG} -u "${mbox}" > "${TMP_DIR}/url-to-refresh.txt" 2>> "${TTY}"
|
"${eMailShrinker}" ${DEBUG} -u "${mbox}" > "${TMP_DIR}/url-to-refresh.txt"
|
||||||
cat "${TMP_DIR}/url-to-refresh.txt" | grep "${JIRAFEAU_URL}" | while read REMOTE_LINK; do
|
cat "${TMP_DIR}/url-to-refresh.txt" | grep "${JIRAFEAU_URL}" | while read REMOTE_LINK; do
|
||||||
REMOTE_REF=$(echo "${REMOTE_LINK}" | sed -e 's/.*h=\([^&]*\).*/\1/' -e 's/.*http.*//')
|
REMOTE_REF=$(echo "${REMOTE_LINK}" | sed -e 's/.*h=\([^&]*\).*/\1/' -e 's/.*http.*//')
|
||||||
[ -z "${REMOTE_REF}" ] && continue
|
[ -z "${REMOTE_REF}" ] && continue
|
||||||
LOG " - ${BLUE}update ${REMOTE_REF}${NC}"
|
LOG " - ${BLUE}update ${REMOTE_REF}${NC}"
|
||||||
curlJirafeauUpdate "month" "${REMOTE_REF}" 2>> "${TTY}"
|
curlJirafeauUpdate "month" "${REMOTE_REF}"
|
||||||
LOG
|
|
||||||
echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${TMP_DIR}/archive-content.txt"
|
echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${TMP_DIR}/archive-content.txt"
|
||||||
done
|
done
|
||||||
|
|
||||||
@ -167,7 +168,7 @@ cat "${TMP_DIR}/PJ-name.txt" | {
|
|||||||
LOG " - ${BLUE}find ${ATTACH_NAME} / (${ATTACH_CONTENT_TYPE}) / ${ATTACH_MEDIA} ${NC}"
|
LOG " - ${BLUE}find ${ATTACH_NAME} / (${ATTACH_CONTENT_TYPE}) / ${ATTACH_MEDIA} ${NC}"
|
||||||
PASSWORD=$(apg -n 1 -m 12 -M cln)
|
PASSWORD=$(apg -n 1 -m 12 -M cln)
|
||||||
PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1)
|
PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1)
|
||||||
curlJirafeauSend "month" "${ATTACH_MEDIA}" "${ATTACH_CONTENT_TYPE}" "${ATTACH_NAME}" "${PASSWORD}" 2>> "${TTY}" > "${TMP_DIR}/one.txt"
|
curlJirafeauSend "month" "${ATTACH_MEDIA}" "${ATTACH_CONTENT_TYPE}" "${ATTACH_NAME}" "${PASSWORD}" > "${TMP_DIR}/one.txt"
|
||||||
|
|
||||||
cat "${TMP_DIR}/one.txt" | {
|
cat "${TMP_DIR}/one.txt" | {
|
||||||
read JIR_TOKEN
|
read JIR_TOKEN
|
||||||
@ -175,7 +176,7 @@ cat "${TMP_DIR}/PJ-name.txt" | {
|
|||||||
case "${JIR_TOKEN}" in
|
case "${JIR_TOKEN}" in
|
||||||
"" | no | *Error* | \<* )
|
"" | no | *Error* | \<* )
|
||||||
LOG " - ${RED}can't upload ${ATTACH_MEDIA} <${JIR_TOKEN}> <${JIR_CODE}>${NC}"
|
LOG " - ${RED}can't upload ${ATTACH_MEDIA} <${JIR_TOKEN}> <${JIR_CODE}>${NC}"
|
||||||
cat "${TMP_DIR}/one.txt" >> "${TTY}"
|
cat "${TMP_DIR}/one.txt" >&2
|
||||||
echo "url:"
|
echo "url:"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
@ -191,7 +192,7 @@ cat "${TMP_DIR}/PJ-name.txt" | {
|
|||||||
if [ "${NB_ATTACH}" -gt 1 ]; then
|
if [ "${NB_ATTACH}" -gt 1 ]; then
|
||||||
PASSWORD=$(apg -n 1 -m 12 -M cln)
|
PASSWORD=$(apg -n 1 -m 12 -M cln)
|
||||||
PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1)
|
PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1)
|
||||||
curlJirafeauSend "month" "${TMP_DIR}/archive-content.txt" "text/kaz_email_archive" "archive_content" "${PASSWORD}" 2>> "${TTY}" > "${TMP_DIR}/one.txt" || exit 1
|
curlJirafeauSend "month" "${TMP_DIR}/archive-content.txt" "text/kaz_email_archive" "archive_content" "${PASSWORD}" > "${TMP_DIR}/one.txt" || exit 1
|
||||||
cat "${TMP_DIR}/one.txt" | {
|
cat "${TMP_DIR}/one.txt" | {
|
||||||
read JIR_TOKEN
|
read JIR_TOKEN
|
||||||
read JIR_CODE
|
read JIR_CODE
|
||||||
@ -221,12 +222,12 @@ LOG " - ${GREEN}ATTACH_MODE: ${ATTACH_MODE}${NC}"
|
|||||||
|
|
||||||
########################################
|
########################################
|
||||||
# substitution des pièces jointes par les codes fournis par jirafeau
|
# substitution des pièces jointes par les codes fournis par jirafeau
|
||||||
cat "${TMP_DIR}/PJ-Keys.txt" | "${eMailShrinker}" ${DEBUG} ${ATTACH_MODE} -s "5ki" "${mbox}" "${TMP_DIR}/new-mbox" 2>> "${TTY}" || exit 1
|
cat "${TMP_DIR}/PJ-Keys.txt" | "${eMailShrinker}" ${DEBUG} ${ATTACH_MODE} -s "5ki" "${mbox}" "${TMP_DIR}/new-mbox" || exit 1
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# affichage de la structure à la fin
|
# affichage de la structure à la fin
|
||||||
LOG " - ${BLUE}new-mbox:${NC}"
|
LOG " - ${BLUE}new-mbox:${NC}${YELLOW}"
|
||||||
"${eMailShrinker}" -l "${TMP_DIR}/new-mbox" 2>> "${TTY}" || exit 1
|
"${eMailShrinker}" -l "${TMP_DIR}/new-mbox" || ( LOG "${NC}" ; exit 1)
|
||||||
|
|
||||||
echo -e "\nresul in ${TMP_DIR}/new-mbox"
|
echo -e "\n${NC}${GREEN}${BOLD}resul in ${TMP_DIR}/new-mbox${NC}"
|
||||||
exit 0
|
exit 0
|
||||||
|
8
src/bash/testCopyInOut.sh
Normal file
8
src/bash/testCopyInOut.sh
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
TMP_LOG="$(mktemp)"
|
||||||
|
|
||||||
|
#trap "rm -rf ${TMP_LOG}" 0 1 2 3 15
|
||||||
|
|
||||||
|
cat > ${TMP_LOG}
|
||||||
|
cat ${TMP_LOG}
|
@ -125,7 +125,7 @@ Attachment::removeSection (string &content, const string &beginTag, const string
|
|||||||
// ================================================================================
|
// ================================================================================
|
||||||
string
|
string
|
||||||
Attachment::getSection (const string &content, const string &beginTag, const string &endTag) {
|
Attachment::getSection (const string &content, const string &beginTag, const string &endTag) {
|
||||||
DEF_LOG ("Attachment::getSection", "beginTag: " << beginTag << " endTag: " << endTag << " content: " << content);
|
DEF_LOG ("Attachment::getSection", "beginTag: " << beginTag << " endTag: " << endTag << " content: " << content.substr (0, 100) << "...");
|
||||||
vector<string> list;
|
vector<string> list;
|
||||||
getSection (content, beginTag, endTag, list);
|
getSection (content, beginTag, endTag, list);
|
||||||
size_t sum (0);
|
size_t sum (0);
|
||||||
@ -142,15 +142,14 @@ Attachment::getSection (const string &content, const string &beginTag, const str
|
|||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
Attachment::getSection (const string &content, const string &beginTag, const string &endTag, vector<string> &result) {
|
Attachment::getSection (const string &content, const string &beginTag, const string &endTag, vector<string> &result) {
|
||||||
DEF_LOG ("Attachment::getSection", "beginTag: " << beginTag << " endTag: " << endTag << " content: " << content);
|
DEF_LOG ("Attachment::getSection", "beginTag: " << beginTag << " endTag: " << endTag << " content: " << content.substr (0, 100) << "...");
|
||||||
for (string::size_type startPos (0);
|
for (string::size_type startPos (0);
|
||||||
(startPos = caseInsensitiveFind (content, beginTag, startPos)) != string::npos;
|
(startPos = caseInsensitiveFind (content, beginTag, startPos)) != string::npos;
|
||||||
) {
|
) {
|
||||||
LOG (beginTag << ": " << startPos);
|
LOG (beginTag << ": " << startPos);
|
||||||
string::size_type stopPos = caseInsensitiveFind (content, endTag, startPos);
|
string::size_type stopPos = caseInsensitiveFind (content, endTag, startPos);
|
||||||
|
|
||||||
LOG_BUG (stopPos == string::npos, break, "eMailShrinker: bug A3: " << endTag << " not found! at: " << startPos);
|
LOG_BUG (stopPos == string::npos, break, "eMailShrinker: bug A3: " << endTag << " not found! at: " << startPos << endl << content.substr (0, 100) << "...");
|
||||||
// LOG_BUG (stopPos == string::npos, break, "eMailShrinker: bug A3: " << endTag << " not found! at: " << startPos << endl << content);
|
|
||||||
LOG ("start: " << startPos << " stop: " << stopPos);
|
LOG ("start: " << startPos << " stop: " << stopPos);
|
||||||
|
|
||||||
LOG_BUG (startPos == stopPos, /* */, "eMailShrinker: bug A4: " << endTag << " without " << beginTag << " at: " << startPos);
|
LOG_BUG (startPos == stopPos, /* */, "eMailShrinker: bug A4: " << endTag << " without " << beginTag << " at: " << startPos);
|
||||||
@ -297,11 +296,36 @@ Attachment::Attachment (ifstream &mbox, const int &level, const streamoff beginI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
|
/*! lower case "var in string " VAR=val; ..." */
|
||||||
inline string
|
inline string
|
||||||
cleanString (const string &line) {
|
cleanString (string line) {
|
||||||
|
DEF_LOG ("Attachment::cleanString", "line: " << line.substr (0, 100) << "...");
|
||||||
|
|
||||||
|
static const regex findPart ("(((\"(\\\\.|[^\\\\])*\")|\\s|[^;\\\"])+;?)");
|
||||||
|
static const regex findVarVal ("(\\s*[a-zA-Z_*-]+(\\*[0-9]+\\*)?=)(.*;?)");
|
||||||
|
string result;
|
||||||
|
smatch m1, m2;
|
||||||
|
|
||||||
|
while (regex_search (line, m1, findPart)) {
|
||||||
|
if (m1.prefix ().length ())
|
||||||
|
result += m1.prefix (); // XXX when \" on multi-lines
|
||||||
|
string part (m1[1]);
|
||||||
|
LOG ("part: " << part);
|
||||||
|
if (regex_search (part, m2, findVarVal) && !m2.prefix ().length ()) {
|
||||||
|
string id (m2[1]);
|
||||||
|
LOG ("id: " << id);
|
||||||
|
toLower (id);
|
||||||
|
result += id;
|
||||||
|
result += m2[3];
|
||||||
|
} else
|
||||||
|
result += part;
|
||||||
|
line = m1.suffix ();
|
||||||
|
}
|
||||||
if (!line.empty () && line[line.size() - 1] == '\r')
|
if (!line.empty () && line[line.size() - 1] == '\r')
|
||||||
return line.substr (0, line.size () - 1);
|
line = line.substr (0, line.size () - 1);
|
||||||
return line;
|
result += line;
|
||||||
|
LOG ("result: " << result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -321,7 +345,7 @@ Attachment::readMime (ifstream &mbox, streamoff &curPos) {
|
|||||||
} else {
|
} else {
|
||||||
LOG ("add line to var: " << line);
|
LOG ("add line to var: " << line);
|
||||||
env.find (lastVar)->second += cleanString (line);
|
env.find (lastVar)->second += cleanString (line);
|
||||||
LOG ("new val: <" << lastVar << " <=> " << env.find (lastVar)->second << ">");
|
LOG ("new val(a): <" << lastVar << " <=> " << env.find (lastVar)->second << ">");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -334,7 +358,7 @@ Attachment::readMime (ifstream &mbox, streamoff &curPos) {
|
|||||||
if (line.length () >= colonPos && line [colonPos] == ' ')
|
if (line.length () >= colonPos && line [colonPos] == ' ')
|
||||||
++colonPos;
|
++colonPos;
|
||||||
string val (cleanString (line.length () >= colonPos ? line.substr (colonPos) : ""));
|
string val (cleanString (line.length () >= colonPos ? line.substr (colonPos) : ""));
|
||||||
LOG ("new var: <" << lastVar << " <=> " << val << ">");
|
LOG ("new var(b): <" << lastVar << " <=> " << val << ">");
|
||||||
env [lastVar] = val;
|
env [lastVar] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -500,7 +524,7 @@ Attachment::getContent (ifstream &mbox) const {
|
|||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
Attachment::println (ofstream &outbox, string content) const {
|
Attachment::println (ofstream &outbox, string content) const {
|
||||||
DEF_LOG ("Attachment::println", "content: " << content);
|
DEF_LOG ("Attachment::println", "content: " << content.substr (0, 100) << "...");
|
||||||
if (isBase64Encoding ())
|
if (isBase64Encoding ())
|
||||||
base64Encode (content);
|
base64Encode (content);
|
||||||
if (isQuotedPrintableEnconding ())
|
if (isQuotedPrintableEnconding ())
|
||||||
|
@ -160,14 +160,13 @@ kaz::operator >> (istream &in, AttachMode &attachMode) {
|
|||||||
// ================================================================================
|
// ================================================================================
|
||||||
const string
|
const string
|
||||||
kaz::headerTypeLabels[] = {
|
kaz::headerTypeLabels[] = {
|
||||||
"Same", "Multi", "MainPlain", "AttachHtml"
|
"Same", "Mixed", "MainPlain"
|
||||||
};
|
};
|
||||||
const map<string, HeaderType>
|
const map<string, HeaderType>
|
||||||
kaz::headerTypeMap = boost::assign::map_list_of
|
kaz::headerTypeMap = boost::assign::map_list_of
|
||||||
("same", SAME)
|
("same", SAME)
|
||||||
("multi", MULTI)
|
("mixed", MIXED)
|
||||||
("mainplain", MAIN_PLAIN)
|
("mainplain", MAIN_PLAIN)
|
||||||
("attachhtml", ATTACH_HTML)
|
|
||||||
;
|
;
|
||||||
ostream &
|
ostream &
|
||||||
kaz::operator << (ostream &out, const HeaderType &headerType) {
|
kaz::operator << (ostream &out, const HeaderType &headerType) {
|
||||||
@ -254,7 +253,7 @@ MainAttachment::addLink (string &plain, string &html, const string &url, const s
|
|||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
MainAttachment::getDisclaim (string &plain, string &html) const {
|
MainAttachment::getDisclaim (string &plain, string &html) const {
|
||||||
DEF_LOG ("Attachment::getDisclaim", "");
|
DEF_LOG ("MainAttachment::getDisclaim", "");
|
||||||
plain = html = "";
|
plain = html = "";
|
||||||
|
|
||||||
int linkCount (0);
|
int linkCount (0);
|
||||||
@ -310,7 +309,7 @@ MainAttachment::getDisclaim (string &plain, string &html) const {
|
|||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
MainAttachment::addPrevious (const string &href, const string &name, const bool &trust) {
|
MainAttachment::addPrevious (const string &href, const string &name, const bool &trust) {
|
||||||
DEF_LOG ("Attachment::addPrevious", "href: " << href << " name: " << name);
|
DEF_LOG ("MainAttachment::addPrevious", "href: " << href << " name: " << name);
|
||||||
const string oldVal = previousLinks [href];
|
const string oldVal = previousLinks [href];
|
||||||
if (name.empty ())
|
if (name.empty ())
|
||||||
return;
|
return;
|
||||||
@ -324,7 +323,7 @@ MainAttachment::addPrevious (const string &href, const string &name, const bool
|
|||||||
void
|
void
|
||||||
MainAttachment::extractLinks (const string &extractedPlainKAZ) {
|
MainAttachment::extractLinks (const string &extractedPlainKAZ) {
|
||||||
// plain text => "* name <url>"
|
// plain text => "* name <url>"
|
||||||
DEF_LOG ("Attachment::extractedPlainKAZ", "extractedPlainKAZ: " << extractedPlainKAZ);
|
DEF_LOG ("MainAttachment::extractedPlainKAZ", "extractedPlainKAZ: " << extractedPlainKAZ);
|
||||||
for (string::size_type startPos (0);
|
for (string::size_type startPos (0);
|
||||||
(startPos = extractedPlainKAZ.find ("http", startPos)) != string::npos;
|
(startPos = extractedPlainKAZ.find ("http", startPos)) != string::npos;
|
||||||
) {
|
) {
|
||||||
@ -369,7 +368,7 @@ MainAttachment::extractLinks (const string &extractedPlainKAZ) {
|
|||||||
void
|
void
|
||||||
MainAttachment::extractLinks (const vector<string> &liOne) {
|
MainAttachment::extractLinks (const vector<string> &liOne) {
|
||||||
// html text => "<li ...><a href="url">name</a>"
|
// html text => "<li ...><a href="url">name</a>"
|
||||||
DEF_LOG ("Attachment::extractedPlainKAZ", "liOne.size: " << liOne.size ());
|
DEF_LOG ("MainAttachment::extractedPlainKAZ", "liOne.size: " << liOne.size ());
|
||||||
for (const string &one : liOne) {
|
for (const string &one : liOne) {
|
||||||
if (caseInsensitiveFind (one, CLASS_ONE) == string::npos)
|
if (caseInsensitiveFind (one, CLASS_ONE) == string::npos)
|
||||||
continue;
|
continue;
|
||||||
@ -463,38 +462,60 @@ MainAttachment::removePreviousArchive () {
|
|||||||
// ================================================================================
|
// ================================================================================
|
||||||
void MainAttachment::rewriteHeaders (ifstream &mbox, ofstream &outbox, const HeaderType &headerType) {
|
void MainAttachment::rewriteHeaders (ifstream &mbox, ofstream &outbox, const HeaderType &headerType) {
|
||||||
DEF_LOG ("MainAttachment::rewriteHeaders", "headerType: " << headerType);
|
DEF_LOG ("MainAttachment::rewriteHeaders", "headerType: " << headerType);
|
||||||
if (SAME == headerType) {
|
switch (headerType) {
|
||||||
|
case SAME:
|
||||||
|
copy (mbox, outbox, 0, contentPos);
|
||||||
|
return;
|
||||||
|
case MAIN_PLAIN:
|
||||||
|
break;
|
||||||
|
case MIXED:
|
||||||
|
if (boost::iequals (getContentType (), "multipart/mixed")) {
|
||||||
copy (mbox, outbox, 0, contentPos);
|
copy (mbox, outbox, 0, contentPos);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
string mime (getMime (mbox));
|
string mime (getMime (mbox));
|
||||||
|
mime.insert (0, "\n");
|
||||||
string::size_type startPos = (0);
|
string::size_type startPos = (0);
|
||||||
for (string token : {string ("content-transfer-encoding"), Attachment::contentTypeToken}) {
|
// remove previous content-type at begin of ligne (after a "\n")
|
||||||
startPos = caseInsensitiveFind (mime, token);
|
for (string token : {string ("content-transfer-encoding"),
|
||||||
for (string::size_type stopPos (startPos);
|
Attachment::contentTypeToken}) {
|
||||||
|
LOG ("token:" << token);
|
||||||
|
startPos = caseInsensitiveFind (mime, string ("\n")+token);
|
||||||
|
if (startPos == string::npos)
|
||||||
|
continue;
|
||||||
|
for (string::size_type stopPos (startPos+1);
|
||||||
(stopPos = mime.find ("\n", stopPos)) != string::npos;
|
(stopPos = mime.find ("\n", stopPos)) != string::npos;
|
||||||
) {
|
) {
|
||||||
if (string (" \t").find (mime [stopPos+1]) == string::npos) {
|
if (string (" \t").find (mime [stopPos+1]) == string::npos) {
|
||||||
|
// not wrap after
|
||||||
|
movedContentType += mime.substr (startPos+1, stopPos-startPos);
|
||||||
mime.erase (startPos, stopPos-startPos);
|
mime.erase (startPos, stopPos-startPos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// merge wrap lines
|
||||||
|
// find next endl
|
||||||
|
++stopPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
string contentType (KAZ_EMPTY_TEXT_PLAIN);
|
string contentType (KAZ_EMPTY_TEXT_PLAIN);
|
||||||
switch (headerType) {
|
switch (headerType) {
|
||||||
case SAME: /* no way */;
|
case SAME: /* no way */ break;
|
||||||
case MAIN_PLAIN: contentType = KAZ_EMPTY_TEXT_PLAIN; break;
|
case MAIN_PLAIN: contentType = KAZ_EMPTY_TEXT_PLAIN; break;
|
||||||
case ATTACH_HTML: contentType = KAZ_ATTACHMENT_TEXT_HTML; break;
|
case MIXED:
|
||||||
case MULTI:
|
addedBoundary = "__KAZ__"+boundaryGen (40);
|
||||||
boundary = "__KAZ__"+boundaryGen (40);
|
contentType = "Content-Type: multipart/mixed; boundary=\""+addedBoundary+"\"\n";
|
||||||
contentType = "Content-Type: multipart/mixed; boundary=\""+boundary+"\"";
|
addedBoundary = "--"+addedBoundary+"--";
|
||||||
boundary = "--"+boundary+"--";
|
addedBoundaryMiddleSize = addedBoundary.length () - 2;
|
||||||
boundaryMiddleSize = boundary.length () - 2;
|
|
||||||
}
|
}
|
||||||
|
// skip '\n'
|
||||||
|
++startPos;
|
||||||
if (startPos >= mime.length ())
|
if (startPos >= mime.length ())
|
||||||
startPos = mime.length () - 1;
|
startPos = mime.length () - 1;
|
||||||
mime.insert (startPos, contentType);
|
mime.insert (startPos, contentType);
|
||||||
outbox << mime << flush;
|
outbox << mime.substr (1) << endl << flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
@ -646,7 +667,7 @@ void
|
|||||||
MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &minSize, AttachMode attachMode) {
|
MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &minSize, AttachMode attachMode) {
|
||||||
DEF_LOG ("MainAttachment::substitute", "minSize: " << minSize << " AttachMode: " << attachMode);
|
DEF_LOG ("MainAttachment::substitute", "minSize: " << minSize << " AttachMode: " << attachMode);
|
||||||
|
|
||||||
// preparation
|
// setup
|
||||||
extractPreviousKAZ (mbox);
|
extractPreviousKAZ (mbox);
|
||||||
removePreviousArchive ();
|
removePreviousArchive ();
|
||||||
map<const string, const string> translateHtml;
|
map<const string, const string> translateHtml;
|
||||||
@ -676,14 +697,29 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min
|
|||||||
string plainDisclaim, htmlDisclaim;
|
string plainDisclaim, htmlDisclaim;
|
||||||
getDisclaim (plainDisclaim, htmlDisclaim);
|
getDisclaim (plainDisclaim, htmlDisclaim);
|
||||||
|
|
||||||
|
LOG_BUG (plainDisclaim.empty () ^ htmlDisclaim.empty (), /* */,
|
||||||
|
"eMailShrinker: bug M8: not empty disclaim. (plainDisclaim: " << plainDisclaim.size () << " htmlDisclaim: " << htmlDisclaim.size () << ")");
|
||||||
|
if (plainDisclaim.empty ()) {
|
||||||
|
// no change
|
||||||
|
cerr << "eMailShrinker: original email inchanged" << endl;
|
||||||
|
copy (mbox, outbox, 0, endPos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boost::iequals (getContentType (), "multipart/report")) {
|
||||||
|
// no change
|
||||||
|
cerr << "eMailShrinker: repport email inchange" << endl;
|
||||||
|
copy (mbox, outbox, 0, endPos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HeaderType headerType (SAME);
|
HeaderType headerType (SAME);
|
||||||
// copy email
|
// copy email
|
||||||
if (!boundary.size () && plainDisclaim.size ())
|
|
||||||
switch (attachMode) {
|
switch (attachMode) {
|
||||||
case NONE: LOG_BUG (true, /* */, "eMailShrinker: bug M12: nothing to do"); break;
|
case NONE: LOG_BUG (true, /* */, "eMailShrinker: bug M12: nothing to do"); break;
|
||||||
case FOOTER: headerType = (emptyEMail ? MAIN_PLAIN : SAME); break;
|
case FOOTER: headerType = (emptyEMail && !boundary.size ()) ? MAIN_PLAIN : SAME; break;
|
||||||
case BOTH: headerType = MULTI; break;
|
case BOTH: headerType = MIXED; break;
|
||||||
case ATTACHMENT: headerType = ATTACH_HTML; break;
|
case ATTACHMENT: headerType = MIXED; break;
|
||||||
}
|
}
|
||||||
rewriteHeaders (mbox, outbox, headerType);
|
rewriteHeaders (mbox, outbox, headerType);
|
||||||
streamoff curPos = contentPos;
|
streamoff curPos = contentPos;
|
||||||
@ -696,37 +732,38 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min
|
|||||||
outbox.flush ();
|
outbox.flush ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ATTACH_HTML == headerType) {
|
|
||||||
LOG ("Replace old content with html");
|
|
||||||
string content (plainDisclaim);
|
|
||||||
base64Encode (content);
|
|
||||||
outbox << content << endl;
|
|
||||||
outbox.flush ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plainDisclaim.size () && emptyEMail && (attachMode & FOOTER)) {
|
// // XXX => MIXED
|
||||||
|
// if (ATTACH_HTML == headerType) {
|
||||||
|
// LOG ("Replace old content with html");
|
||||||
|
// string content (plainDisclaim);
|
||||||
|
// base64Encode (content);
|
||||||
|
// outbox << content << endl;
|
||||||
|
// outbox.flush ();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (emptyEMail && (attachMode & FOOTER)) {
|
||||||
// case : multi
|
// case : multi
|
||||||
LOG ("Force main text");
|
LOG ("Force main text");
|
||||||
cerr << "eMailShrinker: force main text" << endl;
|
cerr << "eMailShrinker: force main text" << endl;
|
||||||
string content (plainDisclaim);
|
string content (plainDisclaim);
|
||||||
base64Encode (content);
|
base64Encode (content);
|
||||||
outbox << boundary.substr (0, boundary.length () -2) << endl
|
outbox << boundary.substr (0, boundaryMiddleSize) << endl
|
||||||
<< KAZ_EMPTY_TEXT_PLAIN << endl
|
<< KAZ_EMPTY_TEXT_PLAIN << endl
|
||||||
<< content << endl;
|
<< content << endl;
|
||||||
outbox.flush ();
|
outbox.flush ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MULTI == headerType) {
|
if (movedContentType.size ()) {
|
||||||
LOG ("New boundary");
|
LOG ("New boundary");
|
||||||
map<string, string>::const_iterator it (env.find (contentTypeToken));
|
outbox << addedBoundary.substr (0, addedBoundaryMiddleSize) << endl
|
||||||
LOG_BUG (it == env.end (), /* */, "eMailShrinker: bug M13: no content-type");
|
<< movedContentType << endl;
|
||||||
outbox << boundary.substr (0, boundary.length () -2) << endl
|
|
||||||
<< Attachment::contentTypeToken << ": " << it->second << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Attachment *attachP : allMarkedPtrs) {
|
for (Attachment *attachP : allMarkedPtrs) {
|
||||||
copy (mbox, outbox, curPos, attachP->beginInParent);
|
copy (mbox, outbox, curPos, attachP->beginInParent);
|
||||||
|
outbox << endl; // force end MIME section
|
||||||
LOG_BUG (attachP->toUpdate && attachP->toExtract, /* */, "eMailShrinker: bug M5: update and extract. pos: " << attachP->beginPos);
|
LOG_BUG (attachP->toUpdate && attachP->toExtract, /* */, "eMailShrinker: bug M5: update and extract. pos: " << attachP->beginPos);
|
||||||
|
|
||||||
if (attachP->isSigned) {
|
if (attachP->isSigned) {
|
||||||
@ -806,25 +843,31 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min
|
|||||||
curPos = attachP->endPos;
|
curPos = attachP->endPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plainDisclaim.size () && (attachMode & ATTACHMENT)) {
|
|
||||||
LOG ("Add kaz attachment");
|
|
||||||
cerr << "eMailShrinker: force attachment" << endl;
|
|
||||||
if (subAttachements.size ()) {
|
if (subAttachements.size ()) {
|
||||||
streamoff lastPos = subAttachements.back ().endPos;
|
streamoff lastPos = subAttachements.back ().endPos;
|
||||||
copy (mbox, outbox, curPos, lastPos);
|
copy (mbox, outbox, curPos, lastPos);
|
||||||
curPos = lastPos;
|
curPos = lastPos;
|
||||||
}
|
}
|
||||||
|
if (attachMode & ATTACHMENT) {
|
||||||
|
LOG ("Add kaz attachment");
|
||||||
|
if (movedContentType.size ()) {
|
||||||
|
copy (mbox, outbox, curPos, endPos);
|
||||||
|
outbox << addedBoundary.substr (0, addedBoundaryMiddleSize) << endl
|
||||||
|
<< KAZ_ATTACHMENT_TEXT_HTML << endl;
|
||||||
|
} else
|
||||||
|
outbox << boundary.substr (0, boundaryMiddleSize) << endl
|
||||||
|
<< KAZ_ATTACHMENT_TEXT_HTML << endl;
|
||||||
|
cerr << "eMailShrinker: force attachment" << endl;
|
||||||
string content (KAZ_HTML_CONTENT+htmlDisclaim+BODY_END+HTML_END);
|
string content (KAZ_HTML_CONTENT+htmlDisclaim+BODY_END+HTML_END);
|
||||||
base64Encode (content);
|
base64Encode (content);
|
||||||
|
|
||||||
outbox << boundary.substr (0, boundary.length () -2) << endl
|
outbox << content << endl;
|
||||||
<< KAZ_ATTACHMENT_TEXT_HTML << endl
|
|
||||||
<< content << endl;
|
|
||||||
outbox.flush ();
|
outbox.flush ();
|
||||||
}
|
}
|
||||||
|
if (!movedContentType.size ())
|
||||||
copy (mbox, outbox, curPos, endPos);
|
copy (mbox, outbox, curPos, endPos);
|
||||||
if (MULTI == headerType)
|
else
|
||||||
outbox << boundary.substr (0, boundary.length ()) << endl;
|
outbox << addedBoundary << endl;
|
||||||
outbox.close ();
|
outbox.close ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
const std::string kaz::LAST_VERSION_NUM ("2.17");
|
const std::string kaz::LAST_VERSION_NUM ("2.21");
|
||||||
const std::string kaz::LAST_VERSION_DATE ("2023-04-23");
|
const std::string kaz::LAST_VERSION_DATE ("2024-06-04");
|
||||||
const std::string kaz::LAST_VERSION (LAST_VERSION_NUM+" "+LAST_VERSION_DATE+" eMailShrinker");
|
const std::string kaz::LAST_VERSION (LAST_VERSION_NUM+" "+LAST_VERSION_DATE+" eMailShrinker");
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -202,9 +202,11 @@ main (int argc, char** argv) {
|
|||||||
attachment.markSignificant (minAttachSize, mbox);
|
attachment.markSignificant (minAttachSize, mbox);
|
||||||
mbox.close ();
|
mbox.close ();
|
||||||
|
|
||||||
if (listFlag)
|
if (listFlag) {
|
||||||
// debug
|
// debug
|
||||||
cerr << attachment;
|
cerr << attachment;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (updateListFlag) {
|
if (updateListFlag) {
|
||||||
// case update
|
// case update
|
||||||
|
@ -1,294 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Copyright KAZ 2021 //
|
|
||||||
// //
|
|
||||||
// contact (at) kaz.bzh //
|
|
||||||
// //
|
|
||||||
// This software is a filter to shrink email by attachment extraction. //
|
|
||||||
// //
|
|
||||||
// This software is governed by the CeCILL-B license under French law and //
|
|
||||||
// abiding by the rules of distribution of free software. You can use, //
|
|
||||||
// modify and/or redistribute the software under the terms of the //
|
|
||||||
// CeCILL-B license as circulated by CEA, CNRS and INRIA at the following //
|
|
||||||
// URL "http://www.cecill.info". //
|
|
||||||
// //
|
|
||||||
// As a counterpart to the access to the source code and rights to copy, //
|
|
||||||
// modify and redistribute granted by the license, users are provided //
|
|
||||||
// only with a limited warranty and the software's author, the holder of //
|
|
||||||
// the economic rights, and the successive licensors have only limited //
|
|
||||||
// liability. //
|
|
||||||
// //
|
|
||||||
// In this respect, the user's attention is drawn to the risks associated //
|
|
||||||
// with loading, using, modifying and/or developing or reproducing the //
|
|
||||||
// software by the user in light of its specific status of free software, //
|
|
||||||
// that may mean that it is complicated to manipulate, and that also //
|
|
||||||
// therefore means that it is reserved for developers and experienced //
|
|
||||||
// professionals having in-depth computer knowledge. Users are therefore //
|
|
||||||
// encouraged to load and test the software's suitability as regards //
|
|
||||||
// their requirements in conditions enabling the security of their //
|
|
||||||
// systems and/or data to be ensured and, more generally, to use and //
|
|
||||||
// operate it in the same conditions as regards security. //
|
|
||||||
// //
|
|
||||||
// The fact that you are presently reading this means that you have had //
|
|
||||||
// knowledge of the CeCILL-B license and that you accept its terms. //
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define LAST_VERSION "1.1 2022-10-30 jirafeauAPI"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include <chrono>
|
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
|
|
||||||
#include "kazDebug.hpp"
|
|
||||||
#include "kazMisc.hpp"
|
|
||||||
#include "SizeArg.hpp"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace boost;
|
|
||||||
using namespace boost::program_options;
|
|
||||||
using namespace kaz;
|
|
||||||
|
|
||||||
namespace bfs = boost::filesystem;
|
|
||||||
|
|
||||||
// ================================================================================
|
|
||||||
static options_description mainDescription ("Main options", getCols ());
|
|
||||||
static options_description hide ("Hidded options", getCols ());
|
|
||||||
static char *prog = NULL;
|
|
||||||
|
|
||||||
// ================================================================================
|
|
||||||
void
|
|
||||||
usage (const string &msg = "", const bool &hidden = false) {
|
|
||||||
if (!msg.empty ()) {
|
|
||||||
cout << msg << endl;
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
cout << endl
|
|
||||||
<< "Usage: " << endl
|
|
||||||
<< " A) " << prog << " [-s size] [-t period] [-c content-type] [-n attachName] [-f server] send file [password] > url,delCode" << endl
|
|
||||||
<< " B) " << prog << " [-t period] [-f server] update ref > dealine" << endl
|
|
||||||
<< endl << " store ficle" << endl << endl
|
|
||||||
<< " A: send file (options : s, t)" << endl
|
|
||||||
<< " B: update deadline (options : t) " << endl
|
|
||||||
<< endl << mainDescription
|
|
||||||
<< endl;
|
|
||||||
if (hidden)
|
|
||||||
cout << hide << endl;
|
|
||||||
exit (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
version () {
|
|
||||||
cout << LAST_VERSION << " KAZ team production (https://kaz.bzh/)" << endl;
|
|
||||||
exit (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto startPrg = std::chrono::high_resolution_clock::now ();
|
|
||||||
void
|
|
||||||
showTime (string msg) {
|
|
||||||
using namespace std::chrono;
|
|
||||||
static auto stopPrg = high_resolution_clock::now ();
|
|
||||||
|
|
||||||
cerr << msg << " done in " << ns2string (duration_cast<duration<double> > (stopPrg-startPrg).count ()) << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================================
|
|
||||||
static size_t
|
|
||||||
WriteCallback (void *contents, size_t size, size_t nmemb, void *userp) {
|
|
||||||
((std::string*) userp)->append ((char*) contents, size * nmemb);
|
|
||||||
return size * nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================================
|
|
||||||
static const string inputFile = "input-file";
|
|
||||||
static const char *const inputFileC = inputFile.c_str ();
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char** argv) {
|
|
||||||
// uncomment next line in case of debug parse options
|
|
||||||
// Log::debug = true;
|
|
||||||
DEF_LOG ("main:", "");
|
|
||||||
prog = argv [0];
|
|
||||||
bool
|
|
||||||
debugFlag (false),
|
|
||||||
helpFlag (false),
|
|
||||||
versionFlag (false),
|
|
||||||
useTheForceLuke (false);
|
|
||||||
enum JirCmd { SEND, UPDATE } jirCmd;
|
|
||||||
string
|
|
||||||
inputFileName,
|
|
||||||
password,
|
|
||||||
contentType,
|
|
||||||
attachName,
|
|
||||||
urlBase ("http://file.kaz.bzh"),
|
|
||||||
uploadPage ("/a.php"),
|
|
||||||
updatePage ("/a.php"),
|
|
||||||
minimumAvailability ("month"),
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
SizeArg maxUploadSize ("100 Mi");
|
|
||||||
|
|
||||||
try {
|
|
||||||
mainDescription.add_options ()
|
|
||||||
("help,h", bool_switch (&helpFlag), "produce this help message")
|
|
||||||
("version,v", bool_switch (&versionFlag), "display version information")
|
|
||||||
("contentType,c", value<string> (&contentType)->default_value (contentType), "content-type of the sended file")
|
|
||||||
("attachName,n", value<string> (&attachName)->default_value (attachName), "force attachment name")
|
|
||||||
("minimumAvailability,t", value<string> (&minimumAvailability)->default_value (minimumAvailability), "minimum period of available download")
|
|
||||||
("maxUploadSize,s", value<SizeArg> (&maxUploadSize)->default_value (maxUploadSize), "maximum upload size")
|
|
||||||
("file server registery,f", value<string> (&urlBase)->default_value (urlBase), "server where file are temporary stored")
|
|
||||||
;
|
|
||||||
|
|
||||||
hide.add_options ()
|
|
||||||
("useTheForceLuke", bool_switch (&useTheForceLuke), "display hidded options")
|
|
||||||
("debug,g", bool_switch (&debugFlag), "debug mode")
|
|
||||||
("proxy,p", value<string> (&proxy)->default_value (proxy), "set proxy (proxy-host.org:8080)")
|
|
||||||
("uploadPage,u", value<string> (&uploadPage)->default_value (uploadPage), "upload page")
|
|
||||||
("updatePage,v", value<string> (&updatePage)->default_value (updatePage), "update page")
|
|
||||||
;
|
|
||||||
|
|
||||||
options_description cmd ("All options");
|
|
||||||
cmd.add (mainDescription).add (hide).add_options ()
|
|
||||||
(inputFileC, value<vector<string> > (), "input")
|
|
||||||
;
|
|
||||||
positional_options_description p;
|
|
||||||
p.add (inputFileC, -1);
|
|
||||||
variables_map vm;
|
|
||||||
basic_parsed_options<char> parsed = command_line_parser (argc, argv).options (cmd).positional (p).run ();
|
|
||||||
store (parsed, vm);
|
|
||||||
notify (vm);
|
|
||||||
|
|
||||||
if (debugFlag) {
|
|
||||||
#ifdef DISABLE_LOG
|
|
||||||
cerr << "No debug option available (was compiled with -DDISABLE_LOG)" << endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
Log::debug = debugFlag;
|
|
||||||
|
|
||||||
if (useTheForceLuke)
|
|
||||||
usage ("", true);
|
|
||||||
if (versionFlag)
|
|
||||||
version ();
|
|
||||||
if (helpFlag)
|
|
||||||
usage ();
|
|
||||||
|
|
||||||
if (vm.count (inputFileC)) {
|
|
||||||
vector<string> var = vm[inputFileC].as<vector<string> > ();
|
|
||||||
int nbArgs = vm[inputFileC].as<vector<string> > ().size ();
|
|
||||||
if (!nbArgs)
|
|
||||||
usage ("No command");
|
|
||||||
if (var [0].compare ("send") == 0)
|
|
||||||
jirCmd = SEND;
|
|
||||||
else if (var [0].compare ("update") == 0)
|
|
||||||
jirCmd = UPDATE;
|
|
||||||
else
|
|
||||||
usage ("Unknown command ("+var [0]+")");
|
|
||||||
if (nbArgs < 2)
|
|
||||||
usage ("no input file");
|
|
||||||
inputFileName = var [1];
|
|
||||||
if (nbArgs == 3)
|
|
||||||
password = var [2];
|
|
||||||
if (nbArgs > 3)
|
|
||||||
usage ("Too much arguments");
|
|
||||||
}
|
|
||||||
} catch (std::exception &e) {
|
|
||||||
cerr << "error: " << e.what() << endl;
|
|
||||||
usage ();
|
|
||||||
return 1;
|
|
||||||
} catch (...) {
|
|
||||||
cerr << "Exception of unknown type!" << endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inputFileName.empty ())
|
|
||||||
usage ("no input");
|
|
||||||
|
|
||||||
CURL *easyhandle = curl_easy_init ();
|
|
||||||
if (! easyhandle) {
|
|
||||||
cerr << "no curl" << endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
string readBuffer;
|
|
||||||
if (proxy.length ())
|
|
||||||
curl_easy_setopt(easyhandle, CURLOPT_PROXY, proxy.c_str ());
|
|
||||||
curl_easy_setopt (easyhandle, CURLOPT_WRITEFUNCTION, WriteCallback);
|
|
||||||
curl_easy_setopt (easyhandle, CURLOPT_WRITEDATA, &readBuffer);
|
|
||||||
curl_mime *multipart = curl_mime_init (easyhandle);
|
|
||||||
curl_mimepart *part = nullptr;
|
|
||||||
|
|
||||||
switch (jirCmd) {
|
|
||||||
case SEND: {
|
|
||||||
LOG ("SEND: " << (urlBase+uploadPage));
|
|
||||||
curl_easy_setopt (easyhandle, CURLOPT_URL, (urlBase+uploadPage).c_str ());
|
|
||||||
|
|
||||||
LOG ("maxUploadSize: " << maxUploadSize);
|
|
||||||
long uploadsize = (size_t) maxUploadSize;
|
|
||||||
curl_easy_setopt (easyhandle, CURLOPT_INFILESIZE, uploadsize);
|
|
||||||
|
|
||||||
LOG ("time: " << minimumAvailability);
|
|
||||||
part = curl_mime_addpart (multipart);
|
|
||||||
curl_mime_name (part, "time");
|
|
||||||
curl_mime_data (part, minimumAvailability.c_str (), CURL_ZERO_TERMINATED);
|
|
||||||
|
|
||||||
if (password.size ()) {
|
|
||||||
LOG ("key: " << password);
|
|
||||||
part = curl_mime_addpart (multipart);
|
|
||||||
curl_mime_name (part, "key");
|
|
||||||
curl_mime_data (part, password.c_str (), CURL_ZERO_TERMINATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG ("inputFileName: " << bfs::path (inputFileName).filename ());
|
|
||||||
part = curl_mime_addpart (multipart);
|
|
||||||
curl_mime_name (part, "file");
|
|
||||||
if (contentType.length ()) {
|
|
||||||
LOG ("contentType: " << contentType);
|
|
||||||
curl_mime_type (part, contentType.c_str ());
|
|
||||||
}
|
|
||||||
if (attachName.empty ()) {
|
|
||||||
attachName = bfs::path (inputFileName).filename ().c_str ();
|
|
||||||
LOG ("attachName: " << attachName);
|
|
||||||
}
|
|
||||||
curl_mime_filename (part, attachName.c_str ());
|
|
||||||
FILE *fp = fopen (inputFileName.c_str (), "r");
|
|
||||||
fseek (fp, 0L, SEEK_END);
|
|
||||||
long int fsize (ftell (fp));
|
|
||||||
fseek (fp, 0L, SEEK_SET);
|
|
||||||
curl_mime_data_cb (part, fsize,
|
|
||||||
(curl_read_callback) fread,
|
|
||||||
(curl_seek_callback) fseek,
|
|
||||||
NULL, //(curl_seek_callback) fclose,
|
|
||||||
fp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UPDATE: {
|
|
||||||
LOG ("UPDATE: " << (urlBase+updatePage));
|
|
||||||
curl_easy_setopt (easyhandle, CURLOPT_URL, (urlBase+updatePage).c_str ());
|
|
||||||
|
|
||||||
LOG ("h: " << inputFileName);
|
|
||||||
part = curl_mime_addpart (multipart);
|
|
||||||
curl_mime_name (part, "h");
|
|
||||||
curl_mime_data (part, inputFileName.c_str (), CURL_ZERO_TERMINATED);
|
|
||||||
|
|
||||||
LOG ("u: " << minimumAvailability);
|
|
||||||
part = curl_mime_addpart (multipart);
|
|
||||||
curl_mime_name (part, "u");
|
|
||||||
curl_mime_data (part, minimumAvailability.c_str (), CURL_ZERO_TERMINATED);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_setopt (easyhandle, CURLOPT_MIMEPOST, multipart);
|
|
||||||
CURLcode res (curl_easy_perform (easyhandle));
|
|
||||||
curl_easy_cleanup (easyhandle);
|
|
||||||
cout << readBuffer << endl;
|
|
||||||
|
|
||||||
showTime ("Upload");
|
|
||||||
if (res != CURLE_OK)
|
|
||||||
cerr << prog << " failed: " << curl_easy_strerror (res) << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================================
|
|
@ -105,7 +105,7 @@ kaz::ns2string (const double &delta) {
|
|||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
kaz::replaceAll (string& str, const string &from, const string &to) {
|
kaz::replaceAll (string& str, const string &from, const string &to) {
|
||||||
DEF_LOG ("kaz::replaceAll", "form: " << from << " to: " << to);
|
DEF_LOG ("kazMisc::replaceAll", "form: " << from << " to: " << to);
|
||||||
if (str.empty () || from.empty ())
|
if (str.empty () || from.empty ())
|
||||||
return;
|
return;
|
||||||
for (string::size_type startPos (0);
|
for (string::size_type startPos (0);
|
||||||
@ -116,7 +116,7 @@ kaz::replaceAll (string& str, const string &from, const string &to) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
kaz::replaceAll (string& str, const map<const string, const string> &subst) {
|
kaz::replaceAll (string& str, const map<const string, const string> &subst) {
|
||||||
DEF_LOG ("kaz::replaceAll", "str: " << str);
|
DEF_LOG ("kazMisc::replaceAll", "str: " << str.substr (0, 100) << "...");
|
||||||
for (map<const string, const string>::const_iterator it = subst.begin (); it != subst.end (); ++it)
|
for (map<const string, const string>::const_iterator it = subst.begin (); it != subst.end (); ++it)
|
||||||
replaceAll (str, it->first, it->second);
|
replaceAll (str, it->first, it->second);
|
||||||
}
|
}
|
||||||
@ -124,16 +124,16 @@ kaz::replaceAll (string& str, const map<const string, const string> &subst) {
|
|||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
kaz::toLower (string &content) {
|
kaz::toLower (string &content) {
|
||||||
DEF_LOG ("kaz::toLower", "content: " << content);
|
DEF_LOG ("kazMisc::toLower", "content: " << content.substr (0, 100) << "...");
|
||||||
static locale loc;
|
static locale loc;
|
||||||
for (string::size_type i = 0; i < content.length (); ++i)
|
for (string::size_type i = 0; i < content.length (); ++i)
|
||||||
content [i] = tolower (content[i], loc);
|
content [i] = tolower (content[i], loc);
|
||||||
LOG ("content: " << content);
|
LOG ("content: " << content.substr (0, 100) << "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
const string &
|
const string &
|
||||||
kaz::toUpperIfNeed (const string &src, string &tmp) {
|
kaz::toUpperIfNeed (const string &src, string &tmp) {
|
||||||
DEF_LOG ("kaz::toUpperIfNeed", "src: " << src);
|
DEF_LOG ("kazMisc::toUpperIfNeed", "src: " << src);
|
||||||
for (string::const_iterator it = src.begin (); it != src.end (); ++it)
|
for (string::const_iterator it = src.begin (); it != src.end (); ++it)
|
||||||
if (*it != toupper (*it)) {
|
if (*it != toupper (*it)) {
|
||||||
tmp.reserve ();
|
tmp.reserve ();
|
||||||
@ -151,7 +151,7 @@ caseInsensitiveCharCompare (char a, char b) {
|
|||||||
|
|
||||||
string::size_type
|
string::size_type
|
||||||
kaz::caseInsensitiveFind (const string& s, const string& pattern, const string::size_type &pos) {
|
kaz::caseInsensitiveFind (const string& s, const string& pattern, const string::size_type &pos) {
|
||||||
DEF_LOG ("kaz::caseInsensitiveFind", "pattern: " << pattern << " pos: " << pos << " s: " << s);
|
DEF_LOG ("kazMisc::caseInsensitiveFind", "pattern: " << pattern << " pos: " << pos << " s: " << s.substr (0, 100) << "...");
|
||||||
string tmp;
|
string tmp;
|
||||||
const string &upperPattern (toUpperIfNeed (pattern, tmp));
|
const string &upperPattern (toUpperIfNeed (pattern, tmp));
|
||||||
LOG ("pattern: " << upperPattern);
|
LOG ("pattern: " << upperPattern);
|
||||||
@ -164,7 +164,7 @@ kaz::caseInsensitiveFind (const string& s, const string& pattern, const string::
|
|||||||
|
|
||||||
string::size_type
|
string::size_type
|
||||||
kaz::caseInsensitiveRFind (const string& s, const string& pattern, const string::size_type &pos) {
|
kaz::caseInsensitiveRFind (const string& s, const string& pattern, const string::size_type &pos) {
|
||||||
DEF_LOG ("kaz::caseInsensitiveRFind", "pattern: " << pattern << " pos: " << pos << " s: " << s);
|
DEF_LOG ("kazMisc::caseInsensitiveRFind", "pattern: " << pattern << " pos: " << pos << " s: " << s.substr (0, 100) << "...");
|
||||||
string tmp;
|
string tmp;
|
||||||
const string &upperPattern (toUpperIfNeed (pattern, tmp));
|
const string &upperPattern (toUpperIfNeed (pattern, tmp));
|
||||||
LOG ("pattern: " << upperPattern);
|
LOG ("pattern: " << upperPattern);
|
||||||
@ -192,7 +192,7 @@ kaz::boundaryGen (const int &size) {
|
|||||||
template<char delim>
|
template<char delim>
|
||||||
void
|
void
|
||||||
kaz::quotedDecode (string &content) {
|
kaz::quotedDecode (string &content) {
|
||||||
DEF_LOG ("kaz::quotedDecode", "delim: " << delim << " content: " << content);
|
DEF_LOG ("kazMisc::quotedDecode", "delim: " << delim << " content: " << content.substr (0, 100) << "...");
|
||||||
string::size_type len (content.length ());
|
string::size_type len (content.length ());
|
||||||
if (!len)
|
if (!len)
|
||||||
return;
|
return;
|
||||||
@ -206,25 +206,24 @@ kaz::quotedDecode (string &content) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (p+1 < content.end () && *(p+1) == '\n') {
|
if (p+1 < content.end () && *(p+1) == '\n') {
|
||||||
|
LOG_BUG (q == content.begin (), ++p;continue, "kazMisc::quotedDecode bug: bad quoted-printable format. (start with '=', delim: " << int (delim) << " content: " << content.substr (0, 100) << "...)");
|
||||||
LOG_BUG (q == content.begin (), ++p;continue, "kazMisc::quotedDecode bug: bad quoted-printable format. (start with '=', delim: " << int (delim) << " content: " << content << ")");
|
|
||||||
++p;
|
++p;
|
||||||
--q;
|
--q;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_BUG (p+3 > content.end () || !isxdigit (p[1]) || !isxdigit (p[2]), return, "kazMisc::quotedDecode bug: bad quoted-printable format. (delim: " << int (delim) << " content: " << content << ")");
|
LOG_BUG (p+3 > content.end () || !isxdigit (p[1]) || !isxdigit (p[2]), return, "kazMisc::quotedDecode bug: bad quoted-printable format. (delim: " << int (delim) << " p:" << content.substr (p-content.begin (), 3) << " content: " << content.substr (0, 100) << "... len: " << len << ")");
|
||||||
*q = (char) ((getHexaVal (p[1]) << 4) + getHexaVal (p[2]));
|
*q = (char) ((getHexaVal (p[1]) << 4) + getHexaVal (p[2]));
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
content.resize (q-content.begin ());
|
content.resize (q-content.begin ());
|
||||||
LOG ("content: " << content);
|
LOG ("content: " << content.substr (0, 100) << "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
kaz::quotedEncode (string &content) {
|
kaz::quotedEncode (string &content) {
|
||||||
DEF_LOG ("kaz::quotedDecode", "content: " << content);
|
DEF_LOG ("kazMisc::quotedDecode", "content: " << content.substr (0, 100) << "...");
|
||||||
string::size_type nbQuoted (0);
|
string::size_type nbQuoted (0);
|
||||||
for (string::const_iterator it = content.begin (); it != content.end (); ++it)
|
for (string::const_iterator it = content.begin (); it != content.end (); ++it)
|
||||||
if (isQuotedPrintable (*it))
|
if (isQuotedPrintable (*it))
|
||||||
@ -267,13 +266,13 @@ kaz::quotedEncode (string &content) {
|
|||||||
++cols;
|
++cols;
|
||||||
}
|
}
|
||||||
content.swap (result);
|
content.swap (result);
|
||||||
LOG ("content: " << content);
|
LOG ("content: " << content.substr (0, 100) << "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
kaz::base64Decode (string &content) {
|
kaz::base64Decode (string &content) {
|
||||||
DEF_LOG ("kaz::base64Decode", "content: " << content);
|
DEF_LOG ("kazMisc::base64Decode", "content: " << content.substr (0, 100) << "...");
|
||||||
string::size_type len (content.length ());
|
string::size_type len (content.length ());
|
||||||
if (!len)
|
if (!len)
|
||||||
return;
|
return;
|
||||||
@ -294,7 +293,7 @@ kaz::base64Decode (string &content) {
|
|||||||
|
|
||||||
if (!isBase64 (c)) {
|
if (!isBase64 (c)) {
|
||||||
content.resize (lastOK-content.begin ());
|
content.resize (lastOK-content.begin ());
|
||||||
LOG ("kazMisc::base64Decode bug: bad base64 format. (content: " << content << ")");
|
LOG ("kazMisc::base64Decode bug: bad base64 format. (content: " << content.substr (0, 100) << "...)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buff [idx] = getBase64Val (c);
|
buff [idx] = getBase64Val (c);
|
||||||
@ -317,13 +316,13 @@ kaz::base64Decode (string &content) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
content.resize (q-content.begin ());
|
content.resize (q-content.begin ());
|
||||||
LOG ("content: " << content);
|
LOG ("content: " << content.substr (0, 100) << "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
kaz::base64Encode (string &content) {
|
kaz::base64Encode (string &content) {
|
||||||
DEF_LOG ("kaz::base64Encode", "content: " << content);
|
DEF_LOG ("kazMisc::base64Encode", "content: " << content.substr (0, 100) << "...");
|
||||||
string::size_type length (content.length ());
|
string::size_type length (content.length ());
|
||||||
std::string result;
|
std::string result;
|
||||||
result.reserve ((length + 2) / 3 * 4 + length / MAX_QUOTED_PRINTABLE_SIZE + 1);
|
result.reserve ((length + 2) / 3 * 4 + length / MAX_QUOTED_PRINTABLE_SIZE + 1);
|
||||||
@ -353,13 +352,13 @@ kaz::base64Encode (string &content) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
content = result;
|
content = result;
|
||||||
LOG ("content: " << content);
|
LOG ("content: " << content.substr (0, 100) << "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
kaz::iso2utf (string &content) {
|
kaz::iso2utf (string &content) {
|
||||||
DEF_LOG ("kaz::iso2utf", "content: " << content);
|
DEF_LOG ("kazMisc::iso2utf", "content: " << content.substr (0, 100) << "...");
|
||||||
string::size_type len (content.length ());
|
string::size_type len (content.length ());
|
||||||
if (!len)
|
if (!len)
|
||||||
return;
|
return;
|
||||||
@ -385,14 +384,14 @@ kaz::iso2utf (string &content) {
|
|||||||
if (p == q)
|
if (p == q)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LOG ("content: " << content);
|
LOG ("content: " << content.substr (0, 100) << "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
kaz::encodedWordDecode (string &content) {
|
kaz::encodedWordDecode (string &content) {
|
||||||
// rfc2047
|
// rfc2047
|
||||||
DEF_LOG ("kaz::encodedWordDecode", "content: " << content);
|
DEF_LOG ("kazMisc::encodedWordDecode", "content: " << content.substr (0, 100) << "...");
|
||||||
string::size_type charsetPos = content.find ("=?");
|
string::size_type charsetPos = content.find ("=?");
|
||||||
if (charsetPos == string::npos)
|
if (charsetPos == string::npos)
|
||||||
return;
|
return;
|
||||||
@ -436,29 +435,29 @@ kaz::encodedWordDecode (string &content) {
|
|||||||
pos = m.position () + m.str ().length ();
|
pos = m.position () + m.str ().length ();
|
||||||
}
|
}
|
||||||
content = result + content.substr (pos);
|
content = result + content.substr (pos);
|
||||||
LOG ("content: " << content);
|
LOG ("content: " << content.substr (0, 100) << "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
void
|
void
|
||||||
kaz::charsetValueDecode (string &content) {
|
kaz::charsetValueDecode (string &content) {
|
||||||
// rfc2184
|
// rfc2184
|
||||||
DEF_LOG ("kaz::charsetValueDecode", "content: " << content);
|
DEF_LOG ("kazMisc::charsetValueDecode", "content: " << content.substr (0, 100) << "...");
|
||||||
string::size_type langPos = content.find ("'");
|
string::size_type langPos = content.find ("'");
|
||||||
|
|
||||||
LOG_BUG (langPos == string::npos, return, "kazMisc::charsetValueDecode bug: no '. (content: " << content << ")");
|
LOG_BUG (langPos == string::npos, return, "kazMisc::charsetValueDecode bug: no '. (content: " << content.substr (0, 100) << "...)");
|
||||||
string::size_type contentPos = content.find ("'", langPos+1);
|
string::size_type contentPos = content.find ("'", langPos+1);
|
||||||
|
|
||||||
LOG_BUG (contentPos == string::npos, return, "kazMisc::charsetValueDecode bug: no double '. (content: " << content << ")");
|
LOG_BUG (contentPos == string::npos, return, "kazMisc::charsetValueDecode bug: no double '. (content: " << content.substr (0, 100) << "...)");
|
||||||
string tmp (content.substr (contentPos+1));
|
string tmp (content.substr (contentPos+1));
|
||||||
quotedDecode<'%'> (tmp);
|
quotedDecode<'%'> (tmp);
|
||||||
LOG ("tmp: " << tmp);
|
LOG ("tmp: " << tmp.substr (0, 100) << "...");
|
||||||
string charset (content.substr (0, langPos));
|
string charset (content.substr (0, langPos));
|
||||||
toLower (charset);
|
toLower (charset);
|
||||||
if (! caseInsensitiveFind (charset, "ISO"))
|
if (! caseInsensitiveFind (charset, "ISO"))
|
||||||
iso2utf (tmp);
|
iso2utf (tmp);
|
||||||
content = tmp;
|
content = tmp;
|
||||||
LOG ("content: " << content);
|
LOG ("content: " << content.substr (0, 100) << "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
|
223
src/cpp/server.cpp
Normal file
223
src/cpp/server.cpp
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright KAZ 2021 //
|
||||||
|
// //
|
||||||
|
// contact (at) kaz.bzh //
|
||||||
|
// //
|
||||||
|
// This software is a filter to shrink email by attachment extraction. //
|
||||||
|
// //
|
||||||
|
// This software is governed by the CeCILL-B license under French law and //
|
||||||
|
// abiding by the rules of distribution of free software. You can use, //
|
||||||
|
// modify and/or redistribute the software under the terms of the //
|
||||||
|
// CeCILL-B license as circulated by CEA, CNRS and INRIA at the following //
|
||||||
|
// URL "http://www.cecill.info". //
|
||||||
|
// //
|
||||||
|
// As a counterpart to the access to the source code and rights to copy, //
|
||||||
|
// modify and redistribute granted by the license, users are provided //
|
||||||
|
// only with a limited warranty and the software's author, the holder of //
|
||||||
|
// the economic rights, and the successive licensors have only limited //
|
||||||
|
// liability. //
|
||||||
|
// //
|
||||||
|
// In this respect, the user's attention is drawn to the risks associated //
|
||||||
|
// with loading, using, modifying and/or developing or reproducing the //
|
||||||
|
// software by the user in light of its specific status of free software, //
|
||||||
|
// that may mean that it is complicated to manipulate, and that also //
|
||||||
|
// therefore means that it is reserved for developers and experienced //
|
||||||
|
// professionals having in-depth computer knowledge. Users are therefore //
|
||||||
|
// encouraged to load and test the software's suitability as regards //
|
||||||
|
// their requirements in conditions enabling the security of their //
|
||||||
|
// systems and/or data to be ensured and, more generally, to use and //
|
||||||
|
// operate it in the same conditions as regards security. //
|
||||||
|
// //
|
||||||
|
// The fact that you are presently reading this means that you have had //
|
||||||
|
// knowledge of the CeCILL-B license and that you accept its terms. //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <map>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "kazDebug.hpp"
|
||||||
|
#include "kazMisc.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace boost;
|
||||||
|
using namespace boost::program_options;
|
||||||
|
using namespace kaz;
|
||||||
|
|
||||||
|
#define CONSOLE(expr) {if (!quietFlag) {std::cerr << Log::getLocalTimeStr () << " " << expr << std::endl << std::flush; }}
|
||||||
|
|
||||||
|
// ================================================================================
|
||||||
|
const string LAST_VERSION_NUM ("3.0");
|
||||||
|
const string LAST_VERSION_DATE ("2024-01-01");
|
||||||
|
const string LAST_VERSION (LAST_VERSION_NUM+" "+LAST_VERSION_DATE+" server");
|
||||||
|
|
||||||
|
#define PORT 8080
|
||||||
|
|
||||||
|
const string BASH ("/bin/bash");
|
||||||
|
const string FILTER_CMD ("/home/filter/testCopyInOut.sh");
|
||||||
|
|
||||||
|
// ================================================================================
|
||||||
|
static options_description mainDescription ("Main options", getCols ());
|
||||||
|
static options_description hide ("Hidded options", getCols ());
|
||||||
|
static const char *prog = NULL;
|
||||||
|
|
||||||
|
// ================================================================================
|
||||||
|
void
|
||||||
|
usage (const string &msg = "", const bool &hidden = false) {
|
||||||
|
if (!msg.empty ()) {
|
||||||
|
cout << msg << endl;
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
cout << endl
|
||||||
|
<< "Usage: " << endl
|
||||||
|
<< " " << prog << " [-p port] [-f filterFileName.sh]" << endl
|
||||||
|
<< endl << mainDescription
|
||||||
|
<< endl;
|
||||||
|
if (hidden)
|
||||||
|
cout << hide << endl;
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
version () {
|
||||||
|
cout << LAST_VERSION << " KAZ team production (https://kaz.bzh/)" << endl;
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================================================================
|
||||||
|
int
|
||||||
|
main (int argc, const char *argv[], char **envp) {
|
||||||
|
// uncomment next line in case of debug parse options
|
||||||
|
// Log::debug = true;
|
||||||
|
DEF_LOG ("main:", LAST_VERSION);
|
||||||
|
prog = argv [0];
|
||||||
|
bool
|
||||||
|
helpFlag (false),
|
||||||
|
versionFlag (false),
|
||||||
|
quietFlag (false),
|
||||||
|
useTheForceLuke (false),
|
||||||
|
debugFlag (false);
|
||||||
|
int port (PORT);
|
||||||
|
string filterFileName (FILTER_CMD);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mainDescription.add_options ()
|
||||||
|
("help,h", bool_switch (&helpFlag), "produce this help message")
|
||||||
|
("version,v", bool_switch (&versionFlag), "display version information")
|
||||||
|
("quiet,q", bool_switch (&quietFlag), "quiet mode")
|
||||||
|
("port,p", value<int> (&port)->default_value (port), "server port number")
|
||||||
|
("filter,f", value<string> (&filterFileName)->default_value (filterFileName), "filter file name script")
|
||||||
|
;
|
||||||
|
|
||||||
|
hide.add_options ()
|
||||||
|
("useTheForceLuke", bool_switch (&useTheForceLuke), "display hidded options")
|
||||||
|
("debug,g", bool_switch (&debugFlag), "debug mode")
|
||||||
|
;
|
||||||
|
options_description cmd ("All options");
|
||||||
|
cmd.add (mainDescription).add (hide).add_options ();
|
||||||
|
|
||||||
|
variables_map vm;
|
||||||
|
store (parse_command_line(argc, argv, cmd), vm);
|
||||||
|
notify (vm);
|
||||||
|
|
||||||
|
if (debugFlag) {
|
||||||
|
#ifdef DISABLE_LOG
|
||||||
|
cerr << "No debug option available (was compiled with -DDISABLE_LOG)" << endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Log::debug = debugFlag;
|
||||||
|
|
||||||
|
if (useTheForceLuke)
|
||||||
|
usage ("", true);
|
||||||
|
if (versionFlag)
|
||||||
|
version ();
|
||||||
|
if (helpFlag)
|
||||||
|
usage ();
|
||||||
|
|
||||||
|
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
cerr << "error: " << e.what() << endl;
|
||||||
|
usage ();
|
||||||
|
return 1;
|
||||||
|
} catch (...) {
|
||||||
|
cerr << "Exception of unknown type!" << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in address;
|
||||||
|
int opt = 1;
|
||||||
|
socklen_t addrlen = sizeof (address);
|
||||||
|
|
||||||
|
LOG ("create socket");
|
||||||
|
int serverSocket (socket (AF_INET, SOCK_STREAM, 0));
|
||||||
|
if (serverSocket < 0) {
|
||||||
|
perror ("socket failed");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG ("set socket options");
|
||||||
|
if (setsockopt (serverSocket, SOL_SOCKET,
|
||||||
|
SO_REUSEADDR | SO_REUSEPORT, &opt,
|
||||||
|
sizeof (opt))) {
|
||||||
|
perror ("setsockopt");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
address.sin_family = AF_INET;
|
||||||
|
address.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
address.sin_port = htons (port);
|
||||||
|
|
||||||
|
LOG ("bind");
|
||||||
|
if (bind (serverSocket, (struct sockaddr*)&address, sizeof (address)) < 0) {
|
||||||
|
perror ("bind failed");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG ("listen");
|
||||||
|
if (listen (serverSocket, 3) < 0) {
|
||||||
|
perror ("listen");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
CONSOLE ("Server started on port " << port);
|
||||||
|
for (;;) {
|
||||||
|
LOG ("accept");
|
||||||
|
int clientSocket (accept (serverSocket, (struct sockaddr*) &address, &addrlen));
|
||||||
|
if (clientSocket < 0) {
|
||||||
|
perror ("accept");
|
||||||
|
// XXX ne pas quitter
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
char *command[] = {const_cast<char *> (BASH.c_str ()),
|
||||||
|
const_cast<char *> (filterFileName.c_str ()), NULL};
|
||||||
|
switch (fork ()) {
|
||||||
|
case -1:
|
||||||
|
perror ("fork");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
case 0:
|
||||||
|
CONSOLE ("New request");
|
||||||
|
close (STDOUT_FILENO);
|
||||||
|
close (STDIN_FILENO);
|
||||||
|
dup2 (clientSocket, STDIN_FILENO);
|
||||||
|
dup2 (clientSocket, STDOUT_FILENO);
|
||||||
|
execve (BASH.c_str (), command, envp);
|
||||||
|
perror ("execve");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
close (clientSocket);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// XXX condition de sortie ?
|
||||||
|
close (serverSocket);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================================================================
|
118
src/cpp/testServerRW.cpp
Normal file
118
src/cpp/testServerRW.cpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright KAZ 2021 //
|
||||||
|
// //
|
||||||
|
// contact (at) kaz.bzh //
|
||||||
|
// //
|
||||||
|
// This software is a filter to shrink email by attachment extraction. //
|
||||||
|
// //
|
||||||
|
// This software is governed by the CeCILL-B license under French law and //
|
||||||
|
// abiding by the rules of distribution of free software. You can use, //
|
||||||
|
// modify and/or redistribute the software under the terms of the //
|
||||||
|
// CeCILL-B license as circulated by CEA, CNRS and INRIA at the following //
|
||||||
|
// URL "http://www.cecill.info". //
|
||||||
|
// //
|
||||||
|
// As a counterpart to the access to the source code and rights to copy, //
|
||||||
|
// modify and redistribute granted by the license, users are provided //
|
||||||
|
// only with a limited warranty and the software's author, the holder of //
|
||||||
|
// the economic rights, and the successive licensors have only limited //
|
||||||
|
// liability. //
|
||||||
|
// //
|
||||||
|
// In this respect, the user's attention is drawn to the risks associated //
|
||||||
|
// with loading, using, modifying and/or developing or reproducing the //
|
||||||
|
// software by the user in light of its specific status of free software, //
|
||||||
|
// that may mean that it is complicated to manipulate, and that also //
|
||||||
|
// therefore means that it is reserved for developers and experienced //
|
||||||
|
// professionals having in-depth computer knowledge. Users are therefore //
|
||||||
|
// encouraged to load and test the software's suitability as regards //
|
||||||
|
// their requirements in conditions enabling the security of their //
|
||||||
|
// systems and/or data to be ensured and, more generally, to use and //
|
||||||
|
// operate it in the same conditions as regards security. //
|
||||||
|
// //
|
||||||
|
// The fact that you are presently reading this means that you have had //
|
||||||
|
// knowledge of the CeCILL-B license and that you accept its terms. //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "kazDebug.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace kaz;
|
||||||
|
|
||||||
|
const string LAST_VERSION_NUM ("3.0");
|
||||||
|
const string LAST_VERSION_DATE ("2024-01-01");
|
||||||
|
const string LAST_VERSION (LAST_VERSION_NUM+" "+LAST_VERSION_DATE+" testServerRW");
|
||||||
|
|
||||||
|
#define PORT 8080
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char const* argv[]) {
|
||||||
|
Log::debug = true;
|
||||||
|
DEF_LOG ("main:", LAST_VERSION);
|
||||||
|
|
||||||
|
int clientSocket;
|
||||||
|
struct sockaddr_in serv_addr;
|
||||||
|
LOG ("create socket");
|
||||||
|
if ((clientSocket = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||||
|
cerr << endl << "Socket creation error" << endl;
|
||||||
|
perror ("socket failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
serv_addr.sin_family = AF_INET;
|
||||||
|
serv_addr.sin_port = htons (PORT);
|
||||||
|
|
||||||
|
LOG ("check address");
|
||||||
|
if (inet_pton (AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
|
||||||
|
cerr << endl << "Invalid address / Address not supported" << endl;
|
||||||
|
perror ("socket failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG ("connect on " << PORT);
|
||||||
|
if (connect (clientSocket, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
|
||||||
|
cerr << endl << "Connection Failed" << endl;
|
||||||
|
perror ("socket failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool end (false);
|
||||||
|
LOG ("send original email (end with QUIT)");
|
||||||
|
for (;;) {
|
||||||
|
if (!end) {
|
||||||
|
string hello;
|
||||||
|
cin >> hello;
|
||||||
|
if (hello == "QUIT") {
|
||||||
|
shutdown (clientSocket, SHUT_WR);
|
||||||
|
LOG ("shutdown send");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
LOG ("avant");
|
||||||
|
hello.push_back ('\n');
|
||||||
|
send (clientSocket, hello.c_str (), hello.size (), 0);
|
||||||
|
LOG ("apres");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG ("receive...");
|
||||||
|
for (;;) {
|
||||||
|
char buffer[1024] = { 0 };
|
||||||
|
ssize_t msgSize (recv (clientSocket, buffer, 1024 - 1, 0));
|
||||||
|
switch (msgSize) {
|
||||||
|
case -1 :
|
||||||
|
perror ("socket failed");
|
||||||
|
return -1;
|
||||||
|
case 0 :
|
||||||
|
LOG ("shutdown receive");
|
||||||
|
close (clientSocket);
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//cout.write (buffer, msgSize);
|
||||||
|
printf ("%s\n", buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -51,7 +51,7 @@ namespace kaz {
|
|||||||
ostream &operator << (ostream &out, const AttachMode &attachMode);
|
ostream &operator << (ostream &out, const AttachMode &attachMode);
|
||||||
istream &operator >> (istream &in, AttachMode &attachMode);
|
istream &operator >> (istream &in, AttachMode &attachMode);
|
||||||
|
|
||||||
enum HeaderType { SAME, MULTI, MAIN_PLAIN, ATTACH_HTML };
|
enum HeaderType { SAME, MIXED, MAIN_PLAIN };
|
||||||
extern const string headerTypeLabels[];
|
extern const string headerTypeLabels[];
|
||||||
extern const map<string, HeaderType> headerTypeMap;
|
extern const map<string, HeaderType> headerTypeMap;
|
||||||
ostream &operator << (ostream &out, const HeaderType &headerType);
|
ostream &operator << (ostream &out, const HeaderType &headerType);
|
||||||
@ -105,6 +105,14 @@ namespace kaz {
|
|||||||
vector<Attachment *> allMarkedPtrs;
|
vector<Attachment *> allMarkedPtrs;
|
||||||
/*! previous links find in mbox */
|
/*! previous links find in mbox */
|
||||||
map<string, string> previousLinks;
|
map<string, string> previousLinks;
|
||||||
|
/*! boundary if a mixed section is added including previous and next "--" */
|
||||||
|
string addedBoundary;
|
||||||
|
/*! size of added boundary before the last "--" */
|
||||||
|
streamoff addedBoundaryMiddleSize;
|
||||||
|
/*! moved conten-type headers */
|
||||||
|
string movedContentType;
|
||||||
|
|
||||||
|
|
||||||
/*! add link only if no significant value already exist. Trust the values from html.*/
|
/*! add link only if no significant value already exist. Trust the values from html.*/
|
||||||
void addPrevious (const string &href, const string &name, const bool &trust = false);
|
void addPrevious (const string &href, const string &name, const bool &trust = false);
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ namespace kaz {
|
|||||||
inline bool
|
inline bool
|
||||||
isQuotedPrintable (const char &c) {
|
isQuotedPrintable (const char &c) {
|
||||||
return
|
return
|
||||||
c == ' ' || c == '\t' || (c >= 33 && c <= 126 && c != '=' && c != '.');
|
c == ' ' || (c >= 33 && c <= 126 && c != '=' && c != '.');
|
||||||
// '.' is available in rfc2184 but it avoid to check '.' alone in a line :-)
|
// '.' is available in rfc2184 but it avoid to check '.' alone in a line :-)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,8 @@ Dans le cas où l'on souhaite signer ses messages, il faut au préalable dépose
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Main Programmes:
|
Main Programme:
|
||||||
* [eMailShrinker](eMailShrinker_8cpp.html)
|
* [eMailShrinker](eMailShrinker_8cpp.html)
|
||||||
* [jirafeauAPI](jirafeauAPI_8cpp.html)
|
|
||||||
|
|
||||||
Main classes:
|
Main classes:
|
||||||
* [MainAttachment](classkaz_1_1MainAttachment.html)
|
* [MainAttachment](classkaz_1_1MainAttachment.html)
|
||||||
|
BIN
structures.odt
Normal file
BIN
structures.odt
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user