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 '
';
+    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 */