From 51865cfce2bc71f620c3b1d96f28b3a62c27228b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 1 Dec 2022 07:47:25 +0100 Subject: [PATCH] add MODE "none" --- src/Jirafeau/a.php | 4 +- src/bash/filter.sh | 59 +++++++++++++------------- src/cpp/Attachment.cpp | 30 +++++++++---- src/cpp/MainAttachment.cpp | 77 +++++++++++++++++++++------------- src/cpp/eMailShrinker.cpp | 2 +- src/cpp/kazMisc.cpp | 11 +++++ src/include/MainAttachment.hpp | 2 + src/include/kazMisc.hpp | 2 + 8 files changed, 117 insertions(+), 70 deletions(-) diff --git a/src/Jirafeau/a.php b/src/Jirafeau/a.php index 6dac4ca..75570c3 100644 --- a/src/Jirafeau/a.php +++ b/src/Jirafeau/a.php @@ -77,7 +77,7 @@ define ('M_WELCOME', "

Informations concernant le compte : ___SENDER___ define ('M_INCONSISTENT_DATES', " (dates incohéantes avec ___FILENAME___ : ___DIRTIME___ != ___FILETIME___)"); -define ('A_ACTION', 'a'); // action : T_LOGIN, T_LOGOUT, A_MODE(footer|attachment|both), A_RECORD+(on|off), A_PERIOD(minute|hour|day|week|month|quarter), A_LANG(fr|en|br) +define ('A_ACTION', 'a'); // action : T_LOGIN, T_LOGOUT, A_MODE(none|footer|attachment|both), A_RECORD+(on|off), A_PERIOD(minute|hour|day|week|month|quarter), A_LANG(fr|en|br) define ('A_GET', 'g'); // get archive define ('A_HASH', 'h'); // file to update or delete define ('A_OPEN_TOKEN', 'o'); // ask token @@ -114,7 +114,7 @@ define ('T_ARCHIVE_TITLE', "archive_content"); define ('T_ARCHIVE_MIME', "text/kaz_email_archive"); -$modeText = ['footer' => "pied de page", 'attachment' => "pièce jointe", 'both' => "les deux"]; +$modeText = ['none' => "sans", 'footer' => "pied de page", 'attachment' => "pièce jointe", 'both' => "les deux"]; $trackText = ['on' => "oui", 'off' => "non"]; $periodText = ['minute' => "minute", 'hour' => "heure", 'day' => "jour", 'week' => "semaine", 'month' => "mois"]; // XXX , 'quarter' => "trimestre"]; diff --git a/src/bash/filter.sh b/src/bash/filter.sh index 8150880..6233085 100644 --- a/src/bash/filter.sh +++ b/src/bash/filter.sh @@ -53,7 +53,7 @@ EX_UNAVAILABLE=69 EX_TOO_LARGE=552 INSPECT_DIR=/var/spool/filter DIR_LOG=/var/log/mail -FIC_LOG=${DIR_LOG}/filter.log +FIC_LOG="${DIR_LOG}/filter.log" SENDMAIL="/usr/sbin/sendmail -G -i" MAILS=/tmp/FILTER MAX_KEEP_IN_MAIL=5ki @@ -62,7 +62,6 @@ SHRINK_CMD=/home/filter/eMailShrinker JIRAFEAU_CMD=/home/filter/jirafeauAPI JIRAFEAU_URL=https://depot.${DOMAINNAME:-"kaz.bzh"} JIRAFEAU_LOCAL=http://depot -JIRAFEAU_TIME=month MD5_CMD=/usr/bin/md5sum DISCLAMER_CMD=altermime MAX_FINAL_SIZE=2097152 # 2Mi @@ -113,22 +112,18 @@ DATE_TEMPS=$(date "+%Y-%m-%d-%H:%M:%S") REP_PIECE_JOINTE="${MAILS}/${DATE_TEMPS}_${MAIL_SOURCE}_$$" MODE=$(curl "${JIRAFEAU_LOCAL}/a.php?m=${MAIL_SOURCE}" 2>/dev/null ) -[[ "${MODE}" =~ ^(footer|attachment|both)$ ]] || MODE="${DEFAULT_MODE}" +[[ "${MODE}" =~ ^(none|footer|attachment|both)$ ]] || MODE="${DEFAULT_MODE}" TRACK=$(curl "${JIRAFEAU_LOCAL}/a.php?r=${MAIL_SOURCE}" 2>/dev/null ) [[ "${TRACK}" =~ ^(|0|1|false|true|FALSE|TRUE|on|off)$ ]] || TRACK="${DEFAULT_TRACK}" PERIOD=$(curl "${JIRAFEAU_LOCAL}/a.php?p=${MAIL_SOURCE}" 2>/dev/null ) [[ "${PERIOD}" =~ ^(minute|hour|day|week|month|quarter)$ ]] || PERIOD="${DEFAULT_PERIOD}" -if [ -n "$(echo "${PERIOD}" | grep -e minute -e hour -e day -e week -e month -e quarter 2>/dev/null)" ]; then - JIRAFEAU_TIME="${PERIOD}" -fi - -LOG_FIC "\n" \ - " MAIL_SOURCE : ${YELLOW}${MAIL_SOURCE}${NC}\n" \ - " DATE_TEMPS : ${YELLOW}${DATE_TEMPS=}${NC}\n" \ - " TRACK : ${YELLOW}${TRACK}${NC}\n" \ - " PERIOD : ${YELLOW}${PERIOD}${NC}\n" \ - " JIRAFEAU_TIME: ${YELLOW}${JIRAFEAU_TIME}${NC}" +LOG_FIC "${NL}" \ + " MAIL_SOURCE : ${YELLOW}${MAIL_SOURCE}${NC}${NL}" \ + " DATE_TEMPS : ${YELLOW}${DATE_TEMPS=}${NC}${NL}" \ + " MODE : ${YELLOW}${MODE}${NC}${NL}" \ + " TRACK : ${YELLOW}${TRACK}${NC}${NL}" \ + " PERIOD : ${YELLOW}${PERIOD}${NC}${NL}" if ! cd "${INSPECT_DIR}"; then echo "${INSPECT_DIR} does not exist" @@ -145,13 +140,13 @@ ARCHIVE_CONTENT="${REP_PIECE_JOINTE}/archive-content.txt" JIRAFEAU_ERROR="${REP_PIECE_JOINTE}/jirafeau-error.txt" # Clean up when done or when aborting. -[ -z "${DEBUG}" ] && trap "rm -rf in.$$ in.$$.altered ${REP_PIECE_JOINTE}" 0 1 2 3 15 +[ -z "${DEBUG}" ] && trap "cd ${INSPECT_DIR}; rm -rf in.$$ in.$$.altered ${REP_PIECE_JOINTE}" 0 1 2 3 15 -if ! cat > "in.$$"; then +if ! cat > "${INSPECT_DIR}/in.$$"; then LOG_FIC "${RED}Cannot save mail to file${NC}" quitFilter "${EX_TEMPFAIL}" fi -LOG_FIC "\n" \ +LOG_FIC "${NL}" \ " size: ${YELLOW}$(wc -c < "${INSPECT_DIR}/in.$$")${NC}" [ -n "${DEBUG}" ] && (mkdir -p "${DIR_LOG}/pb/" ; cp "${INSPECT_DIR}/in.$$" "${DIR_LOG}/pb/in.$$.orig") @@ -159,8 +154,14 @@ mkdir -p "${REP_PIECE_JOINTE}/" >"${OLD_LINKS}" >"${ARCHIVE_CONTENT}" +if [ "${MODE}" = "none" ]; then + LOG_FIC " - ${GREEN}send without change (MODE=none)${NC}" + ${SENDMAIL} "$@" < "${INSPECT_DIR}/in.$$" + quitFilter 0 +fi + # Etape de rafraichissement des anciens fichiers inclus -echo "time: ${DATE_TEMPS}\nid: $(date +%s)" > "${ARCHIVE_CONTENT}" +echo "time: ${DATE_TEMPS}${NL}id: $(date +%s)" > "${ARCHIVE_CONTENT}" [ -n "${TRACK}" ] && echo "sender: ${MAIL_SOURCE}" >> "${ARCHIVE_CONTENT}" LOG_FIC "${CYAN}${SHRINK_CMD} -u \"${INSPECT_DIR}/in.$$\" 2>> \"${FIC_LOG}\" > \"${OLD_LINKS}\"${NC}" @@ -171,14 +172,14 @@ cat "${OLD_LINKS}" | grep "${JIRAFEAU_URL}" | while read REMOTE_LINK; do [ -z "${REMOTE_REF}" ] && continue REMOTE_KEY=$(echo "${REMOTE_LINK}" | grep "k=" | sed 's%.*k=\([^&]*\).*%\1%') # update periode for download - LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${JIRAFEAU_TIME}\" update \"${REMOTE_REF}\" 2>&1 >> \"${FIC_LOG}\"${NC}" - "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${JIRAFEAU_TIME}" update "${REMOTE_REF}" 2>&1 >> "${FIC_LOG}" + LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${PERIOD}\" update \"${REMOTE_REF}\" 2>&1 >> \"${FIC_LOG}\"${NC}" + "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${PERIOD}" update "${REMOTE_REF}" 2>&1 >> "${FIC_LOG}" echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${ARCHIVE_CONTENT}" done LOG_FIC " - archive starts with: ${NL}${YELLOW}$(cat ${ARCHIVE_CONTENT})${NC}" # Etape extraction des pieces jointes -LOG_FIC "${CYAN}${SHRINK_CMD} -s ${MAX_KEEP_IN_MAIL} -d ${REP_PIECE_JOINTE} ${INSPECT_DIR}/in.$$ ${NC}" +LOG_FIC "${CYAN}${SHRINK_CMD} -s \"${MAX_KEEP_IN_MAIL}\" -d \"${REP_PIECE_JOINTE}\" \"${INSPECT_DIR}/in.$$\"${NC}" "${SHRINK_CMD}" -s "${MAX_KEEP_IN_MAIL}" -d "${REP_PIECE_JOINTE}" "${INSPECT_DIR}/in.$$" 2>> "${FIC_LOG}" | { while read ATTACH_TMP_NAME; do if [ -d "${ATTACH_TMP_NAME}" ]; then @@ -193,8 +194,8 @@ LOG_FIC "${CYAN}${SHRINK_CMD} -s ${MAX_KEEP_IN_MAIL} -d ${REP_PIECE_JOINTE} ${IN # Etape de televersement des pieces jointes PASSWORD=$(apg -n 1 -m 12) PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1) - LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${JIRAFEAU_TIME}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ATTACH_CONTENT_TYPE}\" -n \"${ATTACH_NAME}\" send \"${ATTACH_MEDIA}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"${NC}" - "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${JIRAFEAU_TIME}" -s "${MAX_UPLOAD_SIZE}" -c "${ATTACH_CONTENT_TYPE}" -n "${ATTACH_NAME}" send "${ATTACH_MEDIA}" "${PASSWORD}" 2>> "${FIC_LOG}" > "${ONE_LINK}" + LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${PERIOD}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ATTACH_CONTENT_TYPE}\" -n \"${ATTACH_NAME}\" send \"${ATTACH_MEDIA}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"${NC}" + "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${PERIOD}" -s "${MAX_UPLOAD_SIZE}" -c "${ATTACH_CONTENT_TYPE}" -n "${ATTACH_NAME}" send "${ATTACH_MEDIA}" "${PASSWORD}" 2>> "${FIC_LOG}" > "${ONE_LINK}" cat "${ONE_LINK}" | { read JIR_TOKEN read JIR_CODE @@ -207,8 +208,8 @@ LOG_FIC "${CYAN}${SHRINK_CMD} -s ${MAX_KEEP_IN_MAIL} -d ${REP_PIECE_JOINTE} ${IN echo "UPLOAD_FAIL" >> "${JIRAFEAU_ERROR}" ;; * ) - LOG_FIC " - change by link ${YELLOW}${JIRAFEAU_URL}/f.php?d=1&h=${JIR_TOKEN}&k=${PASSWORD_MD5}${NC}" - echo "url: ${JIRAFEAU_URL}/f.php?d=1&h=${JIR_TOKEN}&k=${PASSWORD_MD5}" + LOG_FIC " - change by link ${YELLOW}${JIRAFEAU_URL}/f.php?d=0&h=${JIR_TOKEN}&k=${PASSWORD_MD5}${NC}" + echo "url: ${JIRAFEAU_URL}/f.php?d=0&h=${JIR_TOKEN}&k=${PASSWORD_MD5}" echo "new: ${JIR_TOKEN} ${PASSWORD_MD5}" >> "${ARCHIVE_CONTENT}" ;; esac @@ -220,8 +221,8 @@ LOG_FIC "${CYAN}${SHRINK_CMD} -s ${MAX_KEEP_IN_MAIL} -d ${REP_PIECE_JOINTE} ${IN PASSWORD=$(apg -n 1 -m 12) PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1) LOG_FIC " - ${MAGENTA}upload archive${NC}" - LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${JIRAFEAU_TIME}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ARCHIVE_MIME}\" -n \"${ARCHIVE_TITLE}\" send \"${ARCHIVE_CONTENT}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"${NC}" - "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${JIRAFEAU_TIME}" -s "${MAX_UPLOAD_SIZE}" -c "${ARCHIVE_MIME}" -n "${ARCHIVE_TITLE}" send "${ARCHIVE_CONTENT}" "${PASSWORD}" 2>> "${FIC_LOG}" > "${ONE_LINK}" + LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${PERIOD}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ARCHIVE_MIME}\" -n \"${ARCHIVE_TITLE}\" send \"${ARCHIVE_CONTENT}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"${NC}" + "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${PERIOD}" -s "${MAX_UPLOAD_SIZE}" -c "${ARCHIVE_MIME}" -n "${ARCHIVE_TITLE}" send "${ARCHIVE_CONTENT}" "${PASSWORD}" 2>> "${FIC_LOG}" > "${ONE_LINK}" fi LOG_FIC " - final archive content: ${NL}${YELLOW}$(cat ${ARCHIVE_CONTENT})${NC}" if [ "${NB_ATTACH}" -gt 1 ]; then @@ -261,7 +262,7 @@ fi if [ "$(wc -l < "${ARCHIVE_CONTENT}")" -ge 3 ]; then # verification de taille finale actualSize=$(wc -c < "${INSPECT_DIR}/in.$$.altered") - if [ ${actualSize} -ge $MAX_FINAL_SIZE ]; then + if [ "${actualSize}" -ge "${MAX_FINAL_SIZE}" ]; then LOG_FIC " - ${RED}too big even after diet ${INSPECT_DIR}/in.$$.altered (${actualSize})${NC}" keepFailed "${INSPECT_DIR}/in.$$" quitFilter "${EX_TOO_LARGE}" @@ -271,13 +272,13 @@ if [ "$(wc -l < "${ARCHIVE_CONTENT}")" -ge 3 ]; then else # verification de taille finale actualSize=$(wc -c < "${INSPECT_DIR}/in.$$") - if [ ${actualSize} -ge $MAX_FINAL_SIZE ]; then + if [ "${actualSize}" -ge "${MAX_FINAL_SIZE}" ]; then LOG_FIC " - ${RED}too big without diet ${INSPECT_DIR}/in.$$ (${actualSize}) ${NC}" keepFailed "${INSPECT_DIR}/in.$$" quitFilter "${EX_TOO_LARGE}" fi LOG_FIC " - ${GREEN}send without attach file${NC}" - ${SENDMAIL} "$@" < "in.$$" + ${SENDMAIL} "$@" < "${INSPECT_DIR}/in.$$" fi quitFilter 0 diff --git a/src/cpp/Attachment.cpp b/src/cpp/Attachment.cpp index dbb0905..dba811e 100644 --- a/src/cpp/Attachment.cpp +++ b/src/cpp/Attachment.cpp @@ -64,8 +64,8 @@ const string Attachment::ALTERNATIVE ("alternative"); const string Attachment::KAZ_ATTACH_NAME (".---KazAttachment---.html"); -const regex Attachment::nameCharsetRegEx (".*name\\*=(.*)"); -const regex Attachment::nameRegEx (".*name=\\s*\"?(.*)\"?\\s*;?\\s*"); +const regex Attachment::nameCharsetRegEx (".*name\\*=[ \t]*(.*)"); +const regex Attachment::nameRegEx (".*name=[ \t]*((\"(\\\\.|[^\\\\\r])*\")|[^\r; ]*);?.*"); // boundary="----=_Part_796779_1154936629.1668080348646" // boundary="------------040709000505010508040808" // boundary="----------=_1668606031-941125-91" @@ -73,7 +73,7 @@ const regex Attachment::nameRegEx (".*name=\\s*\"?(.*)\"?\\s*;?\\s*"); // boundary="_000_PAVPR10MB6792713B313048E3A259B215B2079PAVPR10MB6792EURP_" // boundary=--boundary_1351_64006126-2b0e-4a3b-98ac-4797d1634188 // boundary=--boundary_1352_7e294c9a-cfab-44a0-bfb3-7310380ac7cb; -const regex Attachment::boundaryRegEx (".*boundary=\"?([^\"; ]*)\"?;?.*"); +const regex Attachment::boundaryRegEx (".*boundary=[ \t]*((\"(\\\\.|[^\\\\\r])*\")|[^\r; ]*);?.*"); const regex Attachment::cidDefRegEx (".*<([^>]*)>.*"); const regex Attachment::textRegEx (".*text/("+PLAIN+"|"+HTML+").*"); const regex Attachment::multiRegEx ("\\s*multipart/(mixed|"+RELATED+"|"+ALTERNATIVE+").*"); @@ -184,12 +184,14 @@ const string Attachment::getAttachName () const { DEF_LOG ("Attachment::getAttachName", ""); string result = getProp (contentTypeToken, nameRegEx); + removeQuote (result); if (result.length ()) { LOG ("name=: " << result); encodedWord (result); return result; } result = getProp (contentTypeToken, nameCharsetRegEx); + removeQuote (result); if (result.length ()) { LOG ("name*=: " << result); charsetValue (result); @@ -197,13 +199,15 @@ Attachment::getAttachName () const { } // XXX il faut composer s'il y a plusieurs ligne filename*x= result = getProp (contentDispositionToken, nameRegEx); + removeQuote (result); if (result.length ()) { LOG ("filename=: " << result); encodedWord (result); return result; } // XXX il faut composer s'il y a plusieurs ligne filename*x*= - result = getProp (contentDispositionToken, nameRegEx); + result = getProp (contentDispositionToken, nameCharsetRegEx); + removeQuote (result); if (result.length ()) { LOG ("filename*=: " << result); charsetValue (result); @@ -282,6 +286,13 @@ Attachment::Attachment (ifstream &mbox, const int &level, const streamoff beginI } // ================================================================================ +inline string +cleanString (const string &line) { + if (!line.empty () && line[line.size() - 1] == '\r') + return line.substr (0, line.size () - 1); + return line; +} + void Attachment::readMime (ifstream &mbox, streamoff &curPos) { DEF_LOG ("Attachment::readMime", "curPos: " << curPos); @@ -290,7 +301,7 @@ Attachment::readMime (ifstream &mbox, streamoff &curPos) { for (; getline (mbox, line); ) { LOG ("pos: " << curPos << " line: " << line); curPos += line.length () + 1; - if (line.empty ()) + if (line.empty () || "\r" == line) break; if (line[0] == ' ' || line[0] == '\t') { if (lastVar.empty ()) { @@ -298,8 +309,8 @@ Attachment::readMime (ifstream &mbox, streamoff &curPos) { LOG_BUG (true, /**/, "eMailShrinker: bug A5: not compliant MIME. pos: " << (curPos - (line.length () + 1)) << " line: " << line); } else { LOG ("add line to var: " << line); - env.find (lastVar)->second += line; - LOG ("new val: " << env.find (lastVar)->second); + env.find (lastVar)->second += cleanString (line); + LOG ("new val: <" << lastVar << " <=> " << env.find (lastVar)->second << ">"); } continue; } @@ -308,8 +319,8 @@ Attachment::readMime (ifstream &mbox, streamoff &curPos) { lastVar = line.substr (0, colonPos); toLower (lastVar); LOG ("find var: " << lastVar); - string val (line.length () >= colonPos+2 ? line.substr (colonPos+2) : ""); // XXX check RFC " " after ": " - LOG ("new var: " << lastVar << " <=> " << val); + string val (cleanString (line.length () >= colonPos+2 ? line.substr (colonPos+2) : "")); // XXX check RFC " " after ": " + LOG ("new var: <" << lastVar << " <=> " << val << ">"); env [lastVar] = val; } } @@ -318,6 +329,7 @@ Attachment::readMime (ifstream &mbox, streamoff &curPos) { contentPos = curPos; cid = getProp (contentIDToken, cidDefRegEx); boundary = getProp (contentTypeToken, boundaryRegEx); + removeQuote (boundary); LOG ("boundary: " << boundary); if (boundary.length ()) { boundary = "--"+boundary+"--"; diff --git a/src/cpp/MainAttachment.cpp b/src/cpp/MainAttachment.cpp index d52b809..1e9680e 100644 --- a/src/cpp/MainAttachment.cpp +++ b/src/cpp/MainAttachment.cpp @@ -177,8 +177,8 @@ MainAttachment::readArchiveUrl () { archiveDownloadURL.clear (); string line; getline (cin, line); - LOG_BUG (line.rfind ("arch: ", 0) != 0, return, "eMailShrinker: bug ZZ: no archive link. (line: " << line << ")"); - LOG_BUG (line.rfind ("arch: bad", 0) == 0, return, "eMailShrinker: bug ZZ: bad archive link. (line: " << line << ")"); + LOG_BUG (line.rfind ("arch: ", 0) != 0, return, "eMailShrinker: bug 9: no archive link. (line: " << line << ")"); + LOG_BUG (line.rfind ("arch: bad", 0) == 0, return, "eMailShrinker: bug 10: bad archive link. (line: " << line << ")"); if (line.rfind ("arch: none", 0) == 0) return; archiveDownloadURL = line.substr (6); @@ -192,7 +192,7 @@ MainAttachment::readDownloadUrl (string &url) { string line; getline (cin, line); LOG ("get URL: " << line); - LOG_BUG (line.rfind ("url: ", 0) != 0, return, "eMailShrinker: bug ZZ: no download link. (line: " << line << ")"); + LOG_BUG (line.rfind ("url: ", 0) != 0, return, "eMailShrinker: bug 11: no download link. (line: " << line << ")"); url = line.substr (5); } @@ -371,30 +371,39 @@ MainAttachment::extractLinks (const vector &liOne) { } } +void +MainAttachment::extractPreviousKAZ (string &extractedPlainKAZ, string &extractedHtmlKAZ, ifstream &mbox, const Attachment &attach) { + DEF_LOG ("MainAttachment::extractPreviousKAZ", "attach:" << attach); + if (!(attach.toUpdate || attach.isKazAttachment)) // isKazAttachment => toUpdate + return; + string textProp = attach.getProp (contentTypeToken, textRegEx); + if (textProp.empty ()) + return; + string content (attach.getContent (mbox)); + if (textProp == PLAIN) { + LOG (PLAIN); + extractedPlainKAZ += attach.getSection (content, KAZ_PLAIN_START, KAZ_PLAIN_STOP); + } + if (textProp == HTML) { + LOG (HTML); + string section = attach.getSection (content, KAZ_HTML_START, KAZ_HTML_STOP); + section += attach.getSection (content, KAZ_PLAIN_START, KAZ_PLAIN_STOP); + // update href from HTML attachments + replaceAll (section, "&", "&"); + extractedHtmlKAZ += section; + } +} + void MainAttachment::extractPreviousKAZ (ifstream &mbox) { DEF_LOG ("MainAttachment::extractPreviousKAZ", ""); string extractedPlainKAZ, extractedHtmlKAZ; - for (const Attachment *attachP : allMarkedPtrs) { - if (!(attachP->toUpdate || attachP->isKazAttachment)) // isKazAttachment => toUpdate - continue; - string textProp = attachP->getProp (contentTypeToken, textRegEx); - if (textProp.empty ()) - continue; - string content (attachP->getContent (mbox)); - if (textProp == PLAIN) { - LOG (PLAIN); - extractedPlainKAZ += attachP->getSection (content, KAZ_PLAIN_START, KAZ_PLAIN_STOP); - } - if (textProp == HTML) { - LOG (HTML); - string section = attachP->getSection (content, KAZ_HTML_START, KAZ_HTML_STOP); - section += attachP->getSection (content, KAZ_PLAIN_START, KAZ_PLAIN_STOP); - // update href from HTML attachments - replaceAll (section, "&", "&"); - extractedHtmlKAZ += section; - } - } + if (boundary.empty ()) + extractPreviousKAZ (extractedPlainKAZ, extractedHtmlKAZ, mbox, *this); + else + for (const Attachment *attachP : allMarkedPtrs) + extractPreviousKAZ (extractedPlainKAZ, extractedHtmlKAZ, mbox, *attachP); + LOG ("extractedPlainKAZ: "<< extractedPlainKAZ); extractLinks (extractedPlainKAZ); @@ -590,8 +599,13 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min removePreviousArchive (); string plainDisclaim, htmlDisclaim; getDisclaim (plainDisclaim, htmlDisclaim); + // copy email streamoff curPos = 0; + if (boundary.empty () && plainDisclaim.size () && (attachMode & ATTACHMENT)) { + // XXX if no multipart ? + LOG_BUG (true, /* */, "eMailShrinker: bug 12: not multipart."); + } copy (mbox, outbox, curPos, contentPos); curPos = contentPos; @@ -599,7 +613,7 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min if (emptyEMail && (attachMode & FOOTER)) { // check no main text LOG ("Force main text"); - LOG_BUG (boundary.empty () || ! subAttachements.size (), /**/, "eMailShrinker: can't force add footer M9: : " << *this); + cerr << "eMailShrinker: force footer" << endl; string content (plainDisclaim); base64Encode (content); outbox << boundary.substr (0, boundary.length () -2) << endl @@ -614,6 +628,7 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min if (attachP->toExtract || attachP->isKazAttachment) { LOG ("skip Extracted or previous attachments"); + } else if (attachP->toUpdate) { string textProp = attachP->getProp (contentTypeToken, textRegEx); @@ -685,20 +700,24 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min curPos = attachP->endPos; } if (plainDisclaim.size () && (attachMode & ATTACHMENT)) { - // XXX si pas de multipart LOG ("Add kaz attachment"); - LOG_BUG (boundary.empty () || ! subAttachements.size (), /**/, "eMailShrinker: can't add Kaz attachment M10: : " << *this); + cerr << "eMailShrinker: force attachment" << endl; streamoff lastPos = subAttachements.back ().endPos; copy (mbox, outbox, curPos, lastPos); curPos = lastPos; string content (KAZ_HTML_CONTENT+htmlDisclaim+BODY_END+HTML_END); base64Encode (content); - outbox << boundary.substr (0, boundary.length () -2) << endl - << KAZ_ATTACHMENT_TEXT_HTML << endl - << content << endl; + + if (boundary.size ()) + outbox << boundary.substr (0, boundary.length () -2) << endl + << KAZ_ATTACHMENT_TEXT_HTML << endl + << content << endl; + else + outbox << "coucou No multipart" << endl; outbox.flush (); } copy (mbox, outbox, curPos, endPos); + outbox << endl; outbox.close (); } diff --git a/src/cpp/eMailShrinker.cpp b/src/cpp/eMailShrinker.cpp index d51202b..f3c2845 100644 --- a/src/cpp/eMailShrinker.cpp +++ b/src/cpp/eMailShrinker.cpp @@ -32,7 +32,7 @@ // knowledge of the CeCILL-B license and that you accept its terms. // //////////////////////////////////////////////////////////////////////////// -#define LAST_VERSION "2.3 2022-11-25 eMailShrinker" +#define LAST_VERSION "2.4 2022-11-30 eMailShrinker" #include #include diff --git a/src/cpp/kazMisc.cpp b/src/cpp/kazMisc.cpp index 1ecd422..250bd5c 100644 --- a/src/cpp/kazMisc.cpp +++ b/src/cpp/kazMisc.cpp @@ -435,3 +435,14 @@ kaz::charsetValue (string &content) { } // ================================================================================ +void +kaz::removeQuote (string &content) { + if (content.empty () || content [0] !='"') + return; + string::size_type stop = content.rfind ('"'); + content = stop ? + content.substr (1, stop-1) : + content.substr (1); +} + +// ================================================================================ diff --git a/src/include/MainAttachment.hpp b/src/include/MainAttachment.hpp index 4587717..e093d21 100644 --- a/src/include/MainAttachment.hpp +++ b/src/include/MainAttachment.hpp @@ -106,6 +106,8 @@ namespace kaz { void extractLinks (const string &extractedPlainKAZ); /*! extract previous links from html-li list. Used by extractPreviousKAZ */ void extractLinks (const vector &liOne); + /*! extract previous links in mbox on one attachment section. Used by extractPreviousKAZ */ + void extractPreviousKAZ (string &extractedPlainKAZ, string &extractedHtmlKAZ, ifstream &mbox, const Attachment &attach); /*! extract previous links in mbox. Used by getUpdatedURL and substitute */ void extractPreviousKAZ (ifstream &mbox); /*! remove previous links to archive. Used by substitute */ diff --git a/src/include/kazMisc.hpp b/src/include/kazMisc.hpp index 55f317f..6445024 100644 --- a/src/include/kazMisc.hpp +++ b/src/include/kazMisc.hpp @@ -86,6 +86,8 @@ namespace kaz { void encodedWord (string &content); /*! side effect to get the charsetValue according rfc2184 */ void charsetValue (string &content); + /*! side effect to remove quote */ + void removeQuote (string &content); // ======================================================================= /*! return if the c need no quote */