diff --git a/src/Jirafeau/a.php b/src/Jirafeau/a.php new file mode 100644 index 0000000..3a5b24b --- /dev/null +++ b/src/Jirafeau/a.php @@ -0,0 +1,308 @@ + deadline + a.php?g=l~k => zip + a.php?s=mel@domain.org => send status e-mail +*/ + + +define('JIRAFEAU_ROOT', dirname(__FILE__) . '/'); + +require(JIRAFEAU_ROOT . 'lib/settings.php'); +require(JIRAFEAU_ROOT . 'lib/functions.php'); +require(JIRAFEAU_ROOT . 'lib/lang.php'); + +/* Operations may take a long time. + * Be sure PHP's safe mode is off. + */ +@set_time_limit (0); +/* Remove errors. */ +@error_reporting (0); + +$do_update = false; +if (isset ($_REQUEST['u']) && !empty ($_REQUEST['u'])) { + $do_update = true; +} + +$do_download = false; +if (isset ($_REQUEST['g']) && !empty ($_REQUEST['g'])) { + $do_download = true; +} + +// ======================================== +function return_error ($msg) { + require (JIRAFEAU_ROOT.'lib/template/header.php'); + echo '

' . $msg . '

'; + require (JIRAFEAU_ROOT.'lib/template/footer.php'); + exit; +} + +// ======================================== +/** Update link + * @param $link the link's name (hash) + * @param $update_period the periode (i.e in : "month") + */ +function jirafeau_update_link ($link_name, $link, $update_period) { + $time_max = $link ['time']; + $time_up = time () + $update_period; + $time_more = $time_up + JIRAFEAU_HOUR; + if ($time_max < 0 || $time_up < $time_max) + return $time_max; + $link ['time'] = $time_more; + $link_tmp_name = VAR_LINKS . $link['hash'] . rand (0, 10000) . '.tmp'; + $handle = fopen ($link_tmp_name, 'w'); + fwrite ($handle, + $link['file_name'] .NL. $link['mime_type'] .NL. $link['file_size'] .NL. $link['key'] .NL. $link['time'] .NL. + $link['hash'] .NL. $link['onetime'] .' '.JIRAFEAU_MONTH . ' '. JIRAFEAU_DAY .NL. $link['upload_date'] .NL. + $link['ip'] .NL. $link['link_code'] .NL. $link['crypted']); + fclose ($handle); + $link_file = VAR_LINKS . s2p("$link_name") . $link_name; + rename ($link_tmp_name, $link_file); + return $time_more; +} + +// ======================================== +function read_archive_info ($link) { + $p = s2p ($link ['hash']); + // read archive info + $result=[]; + foreach (file (VAR_FILES . $p . $link['hash']) as $line) { + switch (true) { + case preg_match ("/^\s*src:\s*(([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6})\s*$/i", $line, $matches): + $result['sender'] = $matches[1]; + break; + case preg_match ("/^\s*time:\s*(\d{4}([:-]\d{2}){5})\s*$/i", $line, $matches): + $result['timestamp'] = $matches[1]; + break; + case preg_match ("/^\s*old:\s*([0-9a-zA-Z_-]+)\s+([0-9a-zA-Z_-]+)\s*$/", $line, $matches): + $result['old'][] = [$matches[1], $matches[2]]; + break; + case preg_match ("/^\s*new:\s*([0-9a-zA-Z_-]+)\s+([0-9a-zA-Z_-]+)\s*$/", $line, $matches): + $result['new'][] = [$matches[1], $matches[2]]; + break; + default: + break; + } + } + return $result; +} + + +// ======================================== +if ($do_update) { + $update_period = JIRAFEAU_MONTH; + switch ($_REQUEST['u']) { + case 'minute': + $update_period = JIRAFEAU_MINUTE; + break; + case 'hour': + $update_period = JIRAFEAU_HOUR; + break; + case 'day': + $update_period = JIRAFEAU_DAY; + break; + case 'week': + $update_period = JIRAFEAU_WEEK; + break; + case 'month': + $update_period = JIRAFEAU_MONTH; + break; + case 'quarter': + $update_period = JIRAFEAU_QUARTER; + break; + case 'year': + $update_period = JIRAFEAU_YEAR; + break; + default: + return_error (t('ERR_OCC') . ' (update_period)'); + } + $link_name = $_GET['h']; + if (!preg_match('/[0-9a-zA-Z_-]+$/', $link_name)) + return_error (t('FILE_404')); + $link = jirafeau_get_link($link_name); + if (count($link) == 0) + return_error (t('FILE_404')); + $time = jirafeau_update_link($link_name, $link, $update_period); + $content = '' . $time . NL; + header('HTTP/1.0 200 OK'); + header('Content-Length: ' . strlen ($content)); + header('Content-Type: text/plain'); + echo $content; + exit; +} + +// ======================================== +if ($do_download) { + // check archive exist + $couple = explode ("~", $_REQUEST['g'], 2); + if (count ($couple) == 0) + return_error ("bad archive name format : ".$_REQUEST['g']); + $link_name = $couple [0]; + if (!$link_name || !preg_match ('/[0-9a-zA-Z_-]+$/', $link_name)) + return_error ("bad archive name format : ".$_REQUEST['g']); + $crypt_key = count ($couple) == 2 ? $couple [1] : ""; + $link = jirafeau_get_link ($link_name); + if (count ($link) == 0) + return_error (t ('FILE_404')); + $key = $link['key']; + if ($key && (empty ($crypt_key) || $key != $crypt_key)) + return_error (t ('BAD_PSW')); + + $archive_info = read_archive_info ($link); + + // check entries + $archive_content = []; + $modif = false; + foreach (["old", "new"] as $cat) { + $single_name = []; + if (isset ($archive_info[$cat])) + foreach ($archive_info[$cat] as [$link_name, $crypt_key]) { + $link = jirafeau_get_link ($link_name); + if (count ($link) == 0) { + ++$archive_content[$cat]['not_found']; + $modif = true; + continue; + } + $key = $link['key']; + if ($key && (empty ($crypt_key) || $key != $crypt_key)) { + ++$archive_content[$cat]['bad_pass']; + $modif = true; + continue; + } + $src_name = $dst_name = $link['file_name']; + if (in_array ($src_name, $single_name)) + for ($i = 0; $i < 10000; ++$i) { + $dst_name = sprintf ("%s-%2d", $src_name, $i); + if (!in_array ($dst_name, $single_name)) { + ++$archive_content[$cat]['rename']; + $modif = true; + break; + } + } + $single_name [] = $dst_name; + $archive_content[$cat]['entries'][] = ['hash' => $link['hash'], 'file_name' => $dst_name, 'crypt_key' => $crypt_key, 'crypted' => $link['crypted']]; + } + } + + // build zip + $dirname = (isset ($archive_info['sender']) && !empty ($archive_info['sender'])) + ? $archive_info['sender'] : "kaz"; + $dirname .= "-" . (isset ($archive_info['timestamp']) && !empty ($archive_info['timestamp'])) + ? $archive_info['timestamp'] : date ("Ymd-His"); + $tmpFileName = tempnam (sys_get_temp_dir (), $dirname."-"); + $zip = new ZipArchive; + if (!$zip) + return_error ("can't create zip"); + if ($zip->open ($tmpFileName.".zip", ZipArchive::CREATE) !== TRUE) + return_error ("can't open zip"); + + // create info XXX + if ($modif) { + $info = ''; + $not_found = $bad_pass = $rename = 0; + foreach (["old", "new"] as $cat) { + if (isset ($archive_info[$cat]['not_found'])) + $not_found += $archive_info[$cat]['not_found']; + if (isset ($archive_info[$cat]['bad_pass'])) + $bad_pass += $archive_info[$cat]['bad_pass']; + if (isset ($archive_info[$cat]['rename'])) + $rename += $archive_info[$cat]['rename']; + } + if ($not_found) + $info .= $not_found. ($not_found ? " fichier est expiré." : " fichiers sont expirés.").NL; + if ($bad_pass) + $info .= "Mauvaise clef pour ". $bad_pass. ($bad_pass ? " fichier" : " fichiers.").NL; + if ($rename) + $info .= $rename. ($rename ? " fichier renommé." : " fichiers sont renommés.").NL; + $zip->addFromString ($dirname."-Avertissement.txt", $info); + } + foreach (["old", "new"] as $cat) + if (isset ($archive_info [$cat])) { + $subdir = $dirname . ($cat == "new" ? "" : "/origine"); + foreach ($archive_content [$cat]['entries'] as $entry) { + $p = s2p ($entry ['hash']); + if ($entry['crypted']) { + $m = mcrypt_module_open ('rijndael-256', '', 'ofb', ''); + $md5_key = md5 ($entry['crypt_key']); + $iv = jirafeau_crypt_create_iv ($md5_key, mcrypt_enc_get_iv_size ($m)); + mcrypt_generic_init ($m, $md5_key, $iv); + $r = fopen (VAR_FILES . $p . $entry['hash'], 'r'); + $content = ""; + while (!feof ($r)) { + $dec = mdecrypt_generic ($m, fread ($r, 1024)); + $content .= $dec; + ob_flush (); + } + fclose ($r); + $zip->addFromString ($subdir."/".$entry['file_name'], $content); + mcrypt_generic_deinit ($m); + mcrypt_module_close ($m); + continue; + } + $zip->addFile (VAR_FILES.$p.$entry['hash'], $subdir."/".$entry['file_name']); + } + } + $zip->close (); + + + if (!is_file ($tmpFileName.".zip")) + return_error ("can't retreive tmp"); + + if (false) { + // log + $content = print_r ($archive_info, 1); + $content .= print_r ($archive_content, 1); + + header('HTTP/1.0 200 OK'); + header('Content-Length: ' . strlen ($content)); + header('Content-Type: text/plain'); + echo $content; + exit; + } + + header ("Content-Type: application/zip"); + header ('Content-Disposition: filename="'.$dirname.'.zip"'); + $r = fopen($tmpFileName.".zip", 'r'); + while (!feof ($r)) { + print fread ($r, 1024); + ob_flush (); + } + fclose ($r); + + unlink ($tmpFileName.".zip"); + unlink ($tmpFileName); + exit; +} + +// ======================================== +// XXX form send +$content = "TODO send form".NL; + +if (isset ($_REQUEST['s']) && !empty ($_REQUEST['s'])) { + $sender=$_REQUEST ['s']; + if (!preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $sender)) + return_error ("bad dir name format : ".$sender); + + $content = "${sender}".NL; +} + + +// XXX find +// add link : name / time / download / delete +// sort by name ? + +// $tmpFileName = tempnam (sys_get_temp_dir (), $dirname."-"); +// $fd = fopen ($tmpFileName, "w"); +// if (!$fd) +// return_error ("Unable to open tmp file!"); +// fwrite ($fd, $content); +// fclose ($fd); + +header('HTTP/1.0 200 OK'); +header('Content-Length: ' . strlen ($content)); +header('Content-Type: text/plain'); +echo $content; +?> diff --git a/src/Jirafeau/t.php b/src/Jirafeau/t.php index 8dc8cd3..138d4e3 100644 --- a/src/Jirafeau/t.php +++ b/src/Jirafeau/t.php @@ -65,9 +65,19 @@ if ($zip->open ($tmpFileName.".zip", ZipArchive::CREATE) !== TRUE) if ($notFoundCount) { $zip->addFromString ($dirname."-Avertissement.txt", $notFoundCount. ($notFoundCount ? " fichier est expiré." : " fichiers sont expirés.")); } +$single_name=[]; foreach ($map as $link_name => $crypt_key) { $link = jirafeau_get_link ($link_name); - $p = s2p ($link ['md5']); + $p = s2p ($link ['hash']); + + $src_name = $dst_name = $link['file_name']; + if (in_array ($src_name, $single_name)) + for ($i = 0; $i < 10000; ++$i) { + $dst_name = sprintf ("%s-%2d", $src_name, $i); + if (!in_array ($dst_name, $single_name)) + break; + } + $single_name[]=$dst_name; // send if ($link['crypted']) { @@ -75,7 +85,7 @@ foreach ($map as $link_name => $crypt_key) { $md5_key = md5 ($crypt_key); $iv = jirafeau_crypt_create_iv ($md5_key, mcrypt_enc_get_iv_size ($m)); mcrypt_generic_init ($m, $md5_key, $iv); - $r = fopen (VAR_FILES . $p . $link['md5'], 'r'); + $r = fopen (VAR_FILES . $p . $link['hash'], 'r'); $content = ""; while (!feof ($r)) { $dec = mdecrypt_generic ($m, fread ($r, 1024)); @@ -83,13 +93,13 @@ foreach ($map as $link_name => $crypt_key) { ob_flush (); } fclose ($r); - $zip->addFromString ($dirname."/".$link['file_name'], $content); + $zip->addFromString ($dirname."/".$dst_name, $content); mcrypt_generic_deinit ($m); mcrypt_module_close ($m); continue; } - $zip->addFile (VAR_FILES . $p . $link['md5'], $dirname."/".$link['file_name']); + $zip->addFile (VAR_FILES . $p . $link['hash'], $dirname."/".$dst_name); } $zip->close (); diff --git a/src/bash/filter.sh b/src/bash/filter.sh index 9a860b1..7e72952 100644 --- a/src/bash/filter.sh +++ b/src/bash/filter.sh @@ -42,8 +42,8 @@ ########################################################################## cd $(dirname $0) - -# Exit coINSPECT_DIRdes from +DOMAINNAME=$(cat domainname) +# Exit codes from EX_TEMPFAIL=75 EX_UNAVAILABLE=69 EX_TOO_LARGE=552 @@ -55,8 +55,8 @@ MAX_KEEP_IN_MAIL=24ki MAX_UPLOAD_SIZE=100Mi SHRINK_CMD=/home/filter/eMailShrinker JIRAFEAU_CMD=/home/filter/jirafeauAPI -JIRAFEAU_OLDURL="https://\(file\|depot\)\.kaz\.bzh" -JIRAFEAU_URL=https://depot.kaz.bzh +JIRAFEAU_URL=https://depot.${DOMAINNAME:-"kaz.bzh"} +JIRAFEAU_LOCAL=http://depot JIRAFEAU_TIME=month MD5_CMD=/usr/bin/md5sum DISCLAMER_CMD=altermime @@ -78,10 +78,12 @@ DATE_TEMPS=$(date "+%Y-%m-%d-%H:%M:%S") REP_PIECE_JOINTE=$(echo "${MAILS}/${DATE_TEMPS}_${MAIL_SOURCE}_$$") cd "${INSPECT_DIR}" || { echo "${INSPECT_DIR} does not exist"; exit "${EX_TEMPFAIL}"; } +# lien renvoyé par le téléverssement ONE_LINK="${REP_PIECE_JOINTE}/one.txt" -ALL_LINKS="${REP_PIECE_JOINTE}/url-list.txt" +# anciens liens à réactiver OLD_LINKS="${REP_PIECE_JOINTE}/url-to-refresh.txt" -PREV_CODES="${REP_PIECE_JOINTE}/prev-codes.txt" +# contenu de l'archive +ARCHIVE_CONTENT="${REP_PIECE_JOINTE}/archive-content.txt" # Clean up when done or when aborting. trap "rm -rf in.$$ in.$$.altered ${REP_PIECE_JOINTE}" 0 1 2 3 15 @@ -91,27 +93,28 @@ cat > "in.$$" || { LOG_FIC "Cannot save mail to file"; exit "${EX_TEMPFAIL}"; } # cp "${INSPECT_DIR}/in.$$" "${INSPECT_DIR}/in.$$.bak" mkdir -p "${REP_PIECE_JOINTE}/" ->"${ALL_LINKS}" >"${OLD_LINKS}" ->"${PREV_CODES}" +>"${ARCHIVE_CONTENT}" # Etape de rafraichissement des anciens fichiers inclus -OLD_CODES="" +cat > "${ARCHIVE_CONTENT}" <> \"${FIC_LOG}\" > \"${OLD_LINKS}\"" "${SHRINK_CMD}" -u "${INSPECT_DIR}/in.$$" 2>> "${FIC_LOG}" > "${OLD_LINKS}" -cat "${OLD_LINKS}" | grep "${JIRAFEAU_OLDURL}" | while read REMOTE_LINK +cat "${OLD_LINKS}" | grep "${JIRAFEAU_URL}" | while read REMOTE_LINK do REMOTE_REF=$(echo "${REMOTE_LINK}" | sed -e 's/.*h=\([^&]*\).*/\1/' -e 's/.*http.*//') [ -z "${REMOTE_REF}" ] && continue REMOTE_KEY=$(echo "${REMOTE_LINK}" | grep "k=" | sed 's%.*k=\([^&]*\).*%\1%') # update periode for download - LOG_FIC " - \"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_URL}\" -t \"${JIRAFEAU_TIME}\" update \"${REMOTE_REF}\" 2>&1 >> \"${FIC_LOG}\"" - "${JIRAFEAU_CMD}" -f "${JIRAFEAU_URL}" -t "${JIRAFEAU_TIME}" update "${REMOTE_REF}" 2>&1 >> "${FIC_LOG}" - echo -n "/${REMOTE_REF}~${REMOTE_KEY}" >> "${PREV_CODES}" + LOG_FIC " - \"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${JIRAFEAU_TIME}\" update \"${REMOTE_REF}\" 2>&1 >> \"${FIC_LOG}\"" + "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${JIRAFEAU_TIME}" update "${REMOTE_REF}" 2>&1 >> "${FIC_LOG}" + echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${ARCHIVE_CONTENT}" done -OLD_CODES=$(cat "${PREV_CODES}") -LOG_FIC " - OLD_CODES=${OLD_CODES}" +LOG_FIC " - archive starts with: $(cat ${ARCHIVE_CONTENT})" # Etape extraction des pieces jointes LOG_FIC "${SHRINK_CMD} -s ${MAX_KEEP_IN_MAIL} -d ${REP_PIECE_JOINTE} ${INSPECT_DIR}/in.$$" @@ -124,46 +127,67 @@ LOG_FIC "${SHRINK_CMD} -s ${MAX_KEEP_IN_MAIL} -d ${REP_PIECE_JOINTE} ${INSPECT_D ATTACH_NAME=$(grep "^Name: " "${ATTACH_TMP_NAME}/meta" | cut -c 7- ) ATTACH_CONTENT_TYPE=$(grep "^Content-Type: " "${ATTACH_TMP_NAME}/meta" | cut -c 15- ) else - # XXX a virer - ATTACH_MEDIA="${ATTACH_TMP_NAME}" - ATTACH_NAME=$(basename "${ATTACH_MEDIA}") - ATTACH_CONTENT_TYPE="" + # XXX error + continue fi # Etape de televersement des pieces jointes PASSWORD=$(apg -n 1 -m 12) PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1) - actualSize=$(ls -l "${ATTACH_MEDIA}") - LOG_FIC " - \"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_URL}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ATTACH_CONTENT_TYPE}\" -n \"${ATTACH_NAME}\" send \"${ATTACH_MEDIA}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"" - "${JIRAFEAU_CMD}" -f "${JIRAFEAU_URL}" -s "${MAX_UPLOAD_SIZE}" -c "${ATTACH_CONTENT_TYPE}" -n "${ATTACH_NAME}" send "${ATTACH_MEDIA}" "${PASSWORD}" 2>> "${FIC_LOG}" > "${ONE_LINK}" + LOG_FIC " - \"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ATTACH_CONTENT_TYPE}\" -n \"${ATTACH_NAME}\" send \"${ATTACH_MEDIA}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"" + "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -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 - LOG_FIC " - Jirafeau envoie ${JIR_TOKEN} et ${JIR_CODE}" + LOG_FIC " - Jirafeau retourne ${JIR_TOKEN} et ${JIR_CODE}" case "${JIR_TOKEN}" in "" | no | *Error* | \<* ) LOG_FIC " - impossible de televerser ${ATTACH_TMP_FILE} (${JIR_TOKEN}), il ne sera pas remplace dans le message" - echo "" + echo "new:" ;; * ) LOG_FIC " - substitution par ${JIRAFEAU_URL}/f.php?d=1&h=${JIR_TOKEN}&k=${PASSWORD_MD5}" - echo "${JIRAFEAU_URL}/f.php?d=1&h=${JIR_TOKEN}&k=${PASSWORD_MD5} /${JIR_TOKEN}~${PASSWORD_MD5}" - echo "${JIRAFEAU_URL}/f.php?d=1&h=${JIR_TOKEN}&k=${PASSWORD_MD5}" >> "${ALL_LINKS}" + echo "url: ${JIRAFEAU_URL}/f.php?d=1&h=${JIR_TOKEN}&k=${PASSWORD_MD5}" + echo "new: ${JIR_TOKEN} ${PASSWORD_MD5}" >> "${ARCHIVE_CONTENT}" ;; esac } LOG_FIC " - supprimer l'extraction ${ATTACH_TMP_FILE}" rm -f "${ATTACH_TMP_FILE}" done + # Création de l'archive + if [ "$(wc -l < "${ARCHIVE_CONTENT}")" -ge 4 ]; then + PASSWORD=$(apg -n 1 -m 12) + PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1) + LOG_FIC " - \"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"text/plain\" -n \"archive_content\" send \"${ARCHIVE_CONTENT}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"" + "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -s "${MAX_UPLOAD_SIZE}" -c "text/plain" -n "archive_content" send "${ARCHIVE_CONTENT}" "${PASSWORD}" 2>> "${FIC_LOG}" > "${ONE_LINK}" + cat "${ONE_LINK}" | { + read JIR_TOKEN + read JIR_CODE + LOG_FIC " - Jirafeau retourne ${JIR_TOKEN} et ${JIR_CODE}" + case "${JIR_TOKEN}" in + "" | no | *Error* | \<* ) + LOG_FIC " - impossible de televerser l'archive (${JIR_TOKEN}), il ne sera pas remplace dans le message" + echo "arch: bad" + ;; + * ) + LOG_FIC " - ajoute de l'archive ${JIRAFEAU_URL}/a.php?g=${JIR_TOKEN}~${PASSWORD_MD5}" + echo "arch: ${JIRAFEAU_URL}/a.php?g=${JIR_TOKEN}~${PASSWORD_MD5}" + ;; + esac + } + else + LOG_FIC " - pas d'archive (moins de 2 PJ)" + echo "arch: none" + fi # Etape de substitution - LOG_FIC "${SHRINK_CMD} -a \"${JIRAFEAU_URL}/t.php?n=${MAIL_SOURCE}_${DATE_TEMPS}&l=${OLD_CODES}\" -s \"${MAX_KEEP_IN_MAIL}\" \"${INSPECT_DIR}/in.$$\" \"${INSPECT_DIR}/in.$$.altered\" 2>> \"${FIC_LOG}\"" -} | "${SHRINK_CMD}" -a "${JIRAFEAU_URL}/t.php?n=${MAIL_SOURCE}_${DATE_TEMPS}&l=${OLD_CODES}" -s "${MAX_KEEP_IN_MAIL}" "${INSPECT_DIR}/in.$$" "${INSPECT_DIR}/in.$$.altered" 2>> "${FIC_LOG}" + LOG_FIC "${SHRINK_CMD} -s \"${MAX_KEEP_IN_MAIL}\" \"${INSPECT_DIR}/in.$$\" \"${INSPECT_DIR}/in.$$.altered\" 2>> \"${FIC_LOG}\"" +} | "${SHRINK_CMD}" -s "${MAX_KEEP_IN_MAIL}" "${INSPECT_DIR}/in.$$" "${INSPECT_DIR}/in.$$.altered" 2>> "${FIC_LOG}" # XXX trace # cp "${INSPECT_DIR}/in.$$" "${INSPECT_DIR}/in.$$.altered" /var/mail/tmp/ # Etape choix de modification du message d'origine -if [ -s "${ALL_LINKS}" -o -s "${OLD_LINKS}" ] -then +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 diff --git a/src/bash/master.cf.update b/src/bash/master.cf.update new file mode 100644 index 0000000..63db8e3 --- /dev/null +++ b/src/bash/master.cf.update @@ -0,0 +1,4 @@ + +filter unix - n n - 10 pipe + flags=Rq user=filter null_sender= + argv=/home/filter/filter.sh -f ${sender} -- ${recipient} diff --git a/src/cpp/EmbeddedData.cpp b/src/cpp/EmbeddedData.cpp index d998014..e59ccb6 100644 --- a/src/cpp/EmbeddedData.cpp +++ b/src/cpp/EmbeddedData.cpp @@ -89,7 +89,7 @@ kaz::operator << (ostream& os, const EmbeddedData& embeddedData) { os << embeddedData.imgIdx << ": " << embeddedData.contentType << " - " << embeddedData.name << " (" << embeddedData.startData << " / " << embeddedData.dataLength << ") " - << embeddedData.downloadUrl << " - " << embeddedData.downloadId + << embeddedData.downloadUrl << endl; return os; } diff --git a/src/cpp/MainAttachment.cpp b/src/cpp/MainAttachment.cpp index 79da002..5251409 100644 --- a/src/cpp/MainAttachment.cpp +++ b/src/cpp/MainAttachment.cpp @@ -124,18 +124,28 @@ MainAttachment::copy (ifstream &mbox, ofstream &outbox, const streamoff &begin, // ================================================================================ void -MainAttachment::fillUrlId (string &url, string &id) { - DEF_LOG ("MainAttachment::fillUrlId", ""); - url = id = ""; - string urlId; - getline (cin, urlId); - LOG ("get URL: " << urlId); - vector urlIdVect { sregex_token_iterator (urlId.begin(), urlId.end (), whiteSpaceRegEx, -1), {} }; - if (urlIdVect [0].empty ()) +MainAttachment::readArchiveUrl () { + DEF_LOG ("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 << ")"); + if (line.rfind ("arch: none", 0) == 0) return; - url = urlIdVect [0]; - if (urlIdVect.size () > 1) - id = urlIdVect [1]; + archiveDownloadURL = line.substr (6); +} + +// ================================================================================ +void +MainAttachment::readDownloadUrl (string &url) { + DEF_LOG ("MainAttachment::readDownloadUrl", ""); + 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 << ")"); + url = line.substr (5); } // ================================================================================ @@ -148,11 +158,6 @@ MainAttachment::setExtractDir (const bfs::path &extractDir) { bfs::create_directory (extractDir); } -void -MainAttachment::setArchiveDownloadURL (const string &archiveDownloadURL) { - this->archiveDownloadURL = archiveDownloadURL; -} - // ================================================================================ void MainAttachment::addLink (string &plain, string &html, const string &url, const string &name) const { @@ -175,14 +180,12 @@ MainAttachment::getDisclaim (string &plain, string &html) const { plain = html = ""; int linkCount (0); - string allId; string plainNewLinks, htmlNewLinks; for (Attachment *attachP : allMarkedPtrs) { if (!attachP->toExtract) continue; addLink (plainNewLinks, htmlNewLinks, attachP->downloadUrl, attachP->getAttachName ()); ++linkCount; - allId += attachP->downloadId; // if (previousLinks [attachP->downloadUrl] != previousLinks.end ()) // // impossible puisque le lien est toujours nouveau // previousLinks.erase (attachP->downloadUrl); @@ -193,10 +196,8 @@ MainAttachment::getDisclaim (string &plain, string &html) const { for (EmbeddedData &embedded : attachP->embeddedData) { addLink (plainNewLinks, htmlNewLinks, embedded.downloadUrl, embedded.name); ++linkCount; - allId += embedded.downloadId; } } - LOG ("allId:" << allId); string plainOldLinks, htmlOldLinks; for (map ::const_iterator it = previousLinks.begin (); it != previousLinks.end (); ++it) @@ -215,11 +216,10 @@ MainAttachment::getDisclaim (string &plain, string &html) const { } if (linkCount > 1 && archiveDownloadURL.length ()) { string allPlainLinks (templatePlainAllLink); - replaceAll (allPlainLinks, TMPL_DOWNLOAD, archiveDownloadURL+allId); + replaceAll (allPlainLinks, TMPL_DOWNLOAD, archiveDownloadURL); plain += allPlainLinks; string allLinks (templateHtmlAllLink); - // allId => & => & done - replaceAll (allLinks, TMPL_DOWNLOAD, archiveDownloadURL+allId); + replaceAll (allLinks, TMPL_DOWNLOAD, archiveDownloadURL); html += allLinks; } html += templateHtmlFooter; @@ -503,7 +503,7 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min map translateHtml; for (Attachment *attachP : allMarkedPtrs) if (attachP->toExtract) { - fillUrlId (attachP->downloadUrl, attachP->downloadId); + readDownloadUrl (attachP->downloadUrl); if (attachP->downloadUrl.empty ()) { LOG ("no change"); attachP->toExtract = false; @@ -519,8 +519,9 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min if (!attachP->embeddedData.size ()) continue; for (EmbeddedData &embedded : attachP->embeddedData) - fillUrlId (embedded.downloadUrl, embedded.downloadId); + readDownloadUrl (embedded.downloadUrl); } + readArchiveUrl (); string plainDisclaim, htmlDisclaim; getDisclaim (plainDisclaim, htmlDisclaim); // copy email diff --git a/src/cpp/eMailShrinker.cpp b/src/cpp/eMailShrinker.cpp index a5e6513..6eb094a 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 "eMailShrinker 1.4 2021-05-07" +#define LAST_VERSION "2.0 2022-02-08 eMailShrinker" #include #include @@ -67,7 +67,7 @@ usage (const string &msg = "", const bool &hidden = false) { << "Usage: " << endl << " A) " << prog << " -u mbox > url-list" << endl << " B) " << prog << " [-s size] [-d dirName}] mbox > file-list" << endl - << " C) " << prog << " [-s size] [-a url] mbox altered-mbox < url-list" << endl + << " C) " << prog << " [-s size] mbox altered-mbox < url-list" << endl << endl << " filter attachments" << endl << endl << " A: list previous embded url need to be refresh (no added option)" << endl << " => downloadURL list" << endl @@ -114,7 +114,7 @@ main (int argc, char** argv) { updateListFlag (false), useTheForceLuke (false), listFlag (false); - string inputName, outputName, archiveDownloadURL; + string inputName, outputName; bfs::path extractDir (bfs::temp_directory_path ()); SizeArg minAttachSize ("48 Ki"); @@ -125,7 +125,6 @@ main (int argc, char** argv) { ("size,s", value (&minAttachSize)->default_value (minAttachSize), "minimum size for extration") ("updateList,u", bool_switch (&updateListFlag), "list URL need refresh") ("extractDir,d", value (&extractDir)->default_value (extractDir), "set tmp directory name for extraction") - ("archiveDownloadURL,a", value (&archiveDownloadURL)->default_value (archiveDownloadURL), "set url root web site to get bundle (like https://file.kaz.bzh/t.php?)") ; hide.add_options () @@ -203,7 +202,7 @@ main (int argc, char** argv) { cerr << attachment; if (updateListFlag) { - // update + // case update mbox.open (inputName); attachment.getUpdatedURL (mbox); showTime ("Find old links"); @@ -211,7 +210,7 @@ main (int argc, char** argv) { } if (outputName.empty ()) { - // extract + // case extract attachment.setExtractDir (extractDir); mbox.open (inputName); attachment.extract (mbox, minAttachSize); @@ -219,9 +218,7 @@ main (int argc, char** argv) { return 0; } - // substitute - if (archiveDownloadURL.length ()) - attachment.setArchiveDownloadURL (archiveDownloadURL); + // case substitute mbox.open (inputName); ofstream outbox (outputName); attachment.substitute (mbox, outbox, minAttachSize); diff --git a/src/include/Attachment.hpp b/src/include/Attachment.hpp index 4b4577b..0ffef82 100644 --- a/src/include/Attachment.hpp +++ b/src/include/Attachment.hpp @@ -103,8 +103,8 @@ namespace kaz { bool toExtract, toUpdate, toDisclaim; /*! id of an image embedded in mbox */ string cid; - /*! url to replace the attachment and its short id */ - string downloadUrl, downloadId; + /*! url to replace the attachment */ + string downloadUrl; /*! properties of embedded image (self encoded with base64)*/ vector embeddedData; diff --git a/src/include/EmbeddedData.hpp b/src/include/EmbeddedData.hpp index 8bc8e3f..060ad46 100644 --- a/src/include/EmbeddedData.hpp +++ b/src/include/EmbeddedData.hpp @@ -50,7 +50,7 @@ namespace kaz { int imgIdx; /*! extracted in first pass */ string contentType, name; - string downloadUrl, downloadId; + string downloadUrl; /*! area of base64 relative in the image section */ string::size_type startData, dataLength; diff --git a/src/include/MainAttachment.hpp b/src/include/MainAttachment.hpp index 8b4d4fd..7c08df7 100644 --- a/src/include/MainAttachment.hpp +++ b/src/include/MainAttachment.hpp @@ -56,13 +56,14 @@ namespace kaz { /*! copy a slice of mbox to stdout */ static void copy (ifstream &mbox, ofstream &outbox, const streamoff &begin, const streamoff &end); - /*! get url and id (space separated) from stdin */ - void fillUrlId (string &url, string &id); + /*! get url from stdin */ + void readDownloadUrl (string &url); + + /*! get archive url from stdin */ + void readArchiveUrl (); /*! location of extracted files */ void setExtractDir (const bfs::path &extractDir); - /*! URL base for archive download of all extracted files */ - void setArchiveDownloadURL (const string &archiveDownloadURL); /*! add a single link in disclaim */ void addLink (string &plain, string &html, const string &url, const string &name) const; /*! get disclaim according alls links (retreived or create) */ @@ -80,7 +81,7 @@ namespace kaz { /*! dir path for extraction */ bfs::path extractDir; - /*! URL base for download archives */ + /*! URL for download archives */ string archiveDownloadURL; /*! subset in the tree of all attachments to be consider for extraction or modification */