diff --git a/ecrire/action/export_all.php b/ecrire/action/export_all.php
index a391c1da0bbfb16653b775d6132b110e30ed29af..1c9e5c74f83068148087dd9c9eafcb61d58073a1 100644
--- a/ecrire/action/export_all.php
+++ b/ecrire/action/export_all.php
@@ -16,7 +16,6 @@ include_spip('inc/export');
 include_spip('inc/actions');
 include_spip('inc/minipres');
 
-// http://doc.spip.org/@action_export_all_dist
 function action_export_all_dist()
 {
 	global $gz, $connect_toutes_rubriques ;
@@ -30,17 +29,15 @@ function action_export_all_dist()
 		$dir = _DIR_DUMP;
 
 	$file =  $dir . $arg;
-	spip_log("actionexp $file");
-	$f = ($gz) ? gzopen($file, "ab") : fopen($file, "ab");
-	$_fputs = ($gz) ? gzputs : fputs;
-	$_fputs($f, export_entete());
 
 	if ($GLOBALS['flag_ob_flush']) ob_flush();
 	flush();
 
+	$f = ($gz) ? gzopen($file, "ab") : fopen($file, "ab");
+	$_fputs = ($gz) ? gzputs : fputs;
+	$_fputs($f, export_entete());
 	$files = ramasse_parties($file, $gz, $file . ".part");
-
-	$_fputs ($f, build_end_tag("SPIP")."\n");
+	$_fputs($f, export_enpied());
 	if ($gz) gzclose($f); else fclose($f);
 		
 	effacer_meta("status_dump");
diff --git a/ecrire/exec/export_all.php b/ecrire/exec/export_all.php
index a83503864a77428223787969c0e01a7d516ecc98..13109f3c807517c0b5352d58bbd6cd8404848354 100644
--- a/ecrire/exec/export_all.php
+++ b/ecrire/exec/export_all.php
@@ -15,7 +15,7 @@ if (!defined("_ECRIRE_INC_VERSION")) return;
 
 include_spip('base/serial');
 include_spip('base/auxiliaires');
-include_spip('inc/indexation'); // pour la fonction primary_index_table 
+include_spip('public/interfaces'); // pour table_des_tables
 include_spip('inc/flock');
 include_spip('inc/actions');
 include_spip('inc/export');
@@ -102,6 +102,20 @@ function exec_export_all_dist()
 		$reprise = '';
 	} else	$reprise = " (" . $status_dump[2] . ", " . $status_dump[3] . ")";
 
+	list($tables_for_dump, $tables_for_link) = export_all_list_tables();
+
+	$status_dump = explode("::",$GLOBALS['meta']["status_dump"]);
+	$etape = $status_dump[2];
+
+	// Pour avoir les valeurs de _DIR_IMG etc relatives a l'espace public
+	// la phase finale de reunion des fichiers en un seul est faite la-bas
+	$href = generer_action_auteur("export_all",$archive,'',true);
+
+	if ($etape >= count($tables_for_dump)){ // au timeout
+		include_spip('inc/headers');
+		redirige_par_entete($href);
+	}
+
 	echo install_debut_html(_T('info_sauvegarde'));
 	echo "<p>",_T("info_sauvegarde"), $reprise, "</p>\n";
 	$f = ($gz) ? gzopen($file, "ab") : fopen($file, "ab");
@@ -116,51 +130,43 @@ function exec_export_all_dist()
 	$_fputs = ($gz) ? gzputs : fputs;
 	if ($gz) gzclose($f); else fclose($f);
 
-	list($tables_for_dump, $tables_for_link) = export_all_list_tables();
-
 	if ($GLOBALS['flag_ob_flush']) ob_flush();
 	flush();
 
-	$status_dump = explode("::",$GLOBALS['meta']["status_dump"]);
-	$etape = $status_dump[2];
+	if (!($timeout = ini_get('max_execution_time')*1000));
+	$timeout = 30000; // parions sur une valeur tellement courante ...
+	if ($start) $timeout = round($timeout/2);
+		// script de rechargement auto sur timeout
+	echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".generer_url_ecrire("export_all","archive=$archive&gz=$gz",true)."\";',$timeout);</script>\n");
+	$cpt = 0;
+	$paquets = 400; // nombre d'enregistrements dans chaque paquet
+	echo "<div style='text-align: left'>\n";
+	foreach($tables_for_dump as $i=>$table){
 
-	if ($etape < count($tables_for_dump)){
+		while (1){ // on ne connait pas le nb de paquets d'avance
 
-		if (!($timeout = ini_get('max_execution_time')*1000));
-			$timeout = 30000; // parions sur une valeur tellement courante ...
-		if ($start) $timeout = round($timeout/2);
-		// script de rechargement auto sur timeout
-		echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".generer_url_ecrire("export_all","archive=$archive&gz=$gz",true)."\";',$timeout);</script>\n");
-		$cpt = 0;
-		$paquets = 400; // nombre d'enregistrements dans chaque paquet
-		echo "<div style='text-align: left'>\n";
-		foreach($tables_for_dump as $i=>$table){
-			// par paquets
-			list($string,$status_dump)=export_objets($table, primary_index_table($table), $tables_for_link[$table],0, false, $i, _T("info_sauvegarde").", $table",$paquets);
-			while ($string!=''){
-
-				// on ecrit dans un fichier generique
+			list($string,$status_dump)=export_objets($table, $tables_for_link[$table],0, false, $i, _T("info_sauvegarde").", $table",$paquets);
+
+			if ($string) { 
+// on ecrit dans un fichier generique
+// puis on le renomme pour avoir une operation atomique 
 				ecrire_fichier ($partfile, $string);
-				// on le renomme avec un numero -> operation atomique en linux
 				rename($partfile,$partfile.".$cpt");
 				$cpt ++;
-				ecrire_meta("status_dump", implode("::",$status_dump),'non');
-				#lire_metas();
-				list($string,$status_dump)=export_objets($table, primary_index_table($table), $tables_for_link[$table],0, false, $i, _T("info_sauvegarde").", $table",$paquets);
 			}
+	// on se contente d'une ecriture en base pour aller plus vite
+	// a la relecture on en profitera pour mettre le cache a jour
 			ecrire_meta("status_dump", implode("::",$status_dump),'non');
-			#lire_metas();
+			// attention $string vide ne suffit pas a sortir
+			// car les admins restreints peuvent parcourir
+			// une portion de table vide pour eux.
+			if (!$status_dump[3]) break;
 		}
-		echo "</div>\n";
 	}
-		
-	// Reunir les fichiers en un seul, mais dans l'espace public
-	// pour avoir les valeurs de _DIR_IMG etc relatif a lui
-	$href = generer_action_auteur("export_all",$archive,'',true);
-
+	echo "</div>\n";
+	// si Javascript est dispo, anticiper le Time-out
 	echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"$href\";',0);</script>\n");
 	echo install_fin_html();
-
 }
 
 // construction de la liste des tables pour le dump :
@@ -168,7 +174,6 @@ function exec_export_all_dist()
 // + toutes les tables auxiliaires hors relations
 // + les tables relations dont les deux tables liees sont dans la liste
 
-// http://doc.spip.org/@export_all_list_tables
 function export_all_list_tables()
 {
 	$tables_for_dump = array();
@@ -217,7 +222,8 @@ function export_all_list_tables()
 				$connecte = false;
 		if ($connecte)
 			# on ajoute les liaisons en premier
-			# si une restauration est interrompue, cela se verra mieux si il manque des objets
+			# si une restauration est interrompue,
+			# cela se verra mieux si il manque des objets
 			# que des liens
 			array_unshift($tables_for_dump,$link_table);
 	}
diff --git a/ecrire/inc/export.php b/ecrire/inc/export.php
index 9ec43f74cdcdf5085de3077f40fa1f8a8395f95c..2c903e0a620a1046068d6e3552653360293ba93c 100644
--- a/ecrire/inc/export.php
+++ b/ecrire/inc/export.php
@@ -51,72 +51,57 @@ function ramasse_parties($archive, $gz, $partfile){
 // Exportation generique d'objets (fichier ou retour de fonction)
 //
 // http://doc.spip.org/@export_objets
-function export_objets($table, $primary, $liens, $file = 0, $gz = false, $etape_actuelle="", $nom_etape="",$limit=0) {
+function export_objets($table, $liens, $file = 0, $gz = false, $etape_actuelle="", $nom_etape="",$limit=0) {
 	static $etape_affichee=array();
-	static $table_fields=array();
-	$string='';
 
+	$string='';
 	$status_dump = explode("::",$GLOBALS['meta']["status_dump"]);
 	$etape_en_cours = $status_dump[2];
 	$pos_in_table = $status_dump[3];
-	
+
 	if ($etape_en_cours < 1 OR $etape_en_cours == $etape_actuelle){
 
+	  // on calcule ca autant de fois qu'il y a de paquets!
+	  // on devrait plutot le faire dans l'appelant
+	  // et le memoriser dans status_dump
 		$result = spip_query("SELECT COUNT(*) FROM $table");
 		$row = spip_fetch_array($result,SPIP_NUM);
 		$total = $row[0];
-		$debut = $pos_in_table;
 		if (!isset($etape_affichee[$etape_actuelle]) AND $total){
-			echo "<br /><strong>$etape_actuelle-$nom_etape</strong>";
-			echo " : $total";
+			echo "\n<br /><strong>$etape_actuelle-$nom_etape</strong>";
 			$etape_affichee[$etape_actuelle] = 1;
 		}
 		if ($pos_in_table!=0 AND $total)
-			echo "| ", $pos_in_table;
+			echo " ", $pos_in_table;
 		if ($GLOBALS['flag_ob_flush']) ob_flush();
 		flush();
+		if ($limit == 0) $limit = $total;
 
-		if ($limit == 0) $limit=$total;
-		$result = spip_query("SELECT * FROM $table LIMIT $debut,$limit");
-#" LIMIT  $limit OFFSET $debut" # PG
-
-		if (!isset($table_fields[$table])){
-			$nfields = mysql_num_fields($result);
-			// Recuperer les noms des champs
-			for ($i = 0; $i < $nfields; ++$i) $table_fields[$table][$i] = mysql_field_name($result, $i);
-		}
-		else
-			$nfields = count($table_fields[$table]);
-
-		$string = build_while($file,$gz, $nfields, $pos_in_table, $result, $status_dump, $table, $table_fields[$table]);
+		$string = build_while($pos_in_table, $limit, $table);
 
 		if ($pos_in_table>=$total){
-			// etape suivante : 
 			if ($total) echo " ok";
 			$status_dump[2] = $status_dump[2]+1;
 			$status_dump[3] = 0;
-		}
+		} else  $status_dump[3] = $pos_in_table;
+
 		if ($file) {
-			// on se contente d'une ecriture en base pour aller plus vite
-			// a la relecture on en profitera pour mettre le cache a jour
+			$_fputs = ($gz) ? gzputs : fputs;
+			$_fputs($file, $string);
+			fflush($file);
 			ecrire_meta("status_dump", implode("::",$status_dump),'non');
-			#lire_metas();
-			#ecrire_metas();
+			$string='';
 		}
-		spip_free_result($result);
-		return array($string,$status_dump);
-	} else {
-	if ($etape_actuelle < $etape_en_cours) {
+	} else { // ca ne sert plus il me semble
+	  if ($etape_actuelle < $etape_en_cours) {
 		if (!isset($etape_affichee[$etape_actuelle]))
-			echo "<li>", $etape_actuelle,'-',$nom_etape,"</li>";
-		if ($GLOBALS['flag_ob_flush']) ob_flush();
-		flush();
-	} else {
+			echo "\n<li>", $etape_actuelle,'-',$nom_etape,"</li>";
+	  } else {
 		if (!isset($etape_affichee[$etape_actuelle]))
-			echo "<li> <span style='color: #999999'>",$etape_actuelle,'-',$nom_etape,'</span></li>';
-		if ($GLOBALS['flag_ob_flush']) ob_flush();
-		flush();
-	}
+			echo "\n<li> <span style='color: #999999'>",$etape_actuelle,'-',$nom_etape,'</span></li>';
+	  }
+	  if ($GLOBALS['flag_ob_flush']) ob_flush();
+	  flush();
 	}
 	return array($string,$status_dump);
 }
@@ -124,47 +109,41 @@ function export_objets($table, $primary, $liens, $file = 0, $gz = false, $etape_
 // Exporter les champs de la table
 
 // http://doc.spip.org/@build_while
-function build_while($file,$gz, $nfields, &$pos_in_table, $result, &$status_dump, $table, $fields) {
+function build_while(&$pos_in_table, $limit, $table) {
 	global $connect_toutes_rubriques ;
+	global $tables_principales;
+	static $table_fields=array();
+
+	$result = spip_query("SELECT * FROM $table LIMIT " . intval($pos_in_table) .',' . intval($limit));
+	// Recuperer les noms des champs
+	// Ces infos sont donnees par le abstract_showtable
+	// les instructions natives mysql ne devraient pas apparaitre ici
+	if (!isset($table_fields[$table])){
+		$nfields = mysql_num_fields($result);
+		for ($i = 0; $i < $nfields; ++$i)
+		  $table_fields[$table][$i] = mysql_field_name($result, $i);
+	} else	$nfields = count($table_fields[$table]);
+
 	$string = '';
-	$begin = build_begin_tag($table);
-	$end = build_end_tag($table);
-	$all = $connect_toutes_rubriques || (!in_array('id_rubrique',$fields));
+	$all = $connect_toutes_rubriques
+	  ||(!in_array('id_rubrique',$table_fields[$table]));
+
 	while ($row = spip_fetch_array($result,SPIP_ASSOC)) {
-		$item = '';
-		if (!isset($row['impt']) OR $row['impt']=='oui'){
+		if ((!isset($row['impt']) OR $row['impt']=='oui')
+		AND ($all OR autoriser('publierdans','rubrique',$row['id_rubrique']))) {
+			$string .= "<$table>\n";
 			for ($i = 0; $i < $nfields; ++$i) {
-				$k = $fields[$i];
-				$item .= "<$k>" . text_to_xml($row[$k]) . "</$k>\n";
+				$k = $table_fields[$table][$i];
+				$string .= "<$k>" . text_to_xml($row[$k]) . "</$k>\n";
 			}
-			if ($all OR autoriser('publierdans','rubrique',$row['id_rubrique']))
-				$string .= "$begin$item$end";
+			$string .= "</$table>\n\n";
 		}
-		$status_dump[3] = $pos_in_table = $pos_in_table +1;
-	}
-
-	if ($file) {
-		$_fputs = ($gz) ? gzputs : fputs;
-		$_fputs($file, $string);
-		fflush($file);
-		// on se contente d'une ecriture en base pour aller plus vite
-		// a la relecture on en profitera pour mettre le cache a jour
-		ecrire_meta("status_dump", implode("::",$status_dump),'non');
-		$string = '';
+		$pos_in_table++;
 	}
+	spip_free_result($result);
 	return $string;
 }
 
-// http://doc.spip.org/@build_begin_tag
-function build_begin_tag($tag) {
-	return "<$tag>\n";
-}
-
-// http://doc.spip.org/@build_end_tag
-function build_end_tag($tag) {
-	return "</$tag>\n\n";
-}
-
 // Conversion texte -> xml (ajout d'entites)
 // http://doc.spip.org/@text_to_xml
 function text_to_xml($string) {
@@ -173,7 +152,6 @@ function text_to_xml($string) {
 
 // production de l'entete du fichier d'archive
 
-// http://doc.spip.org/@export_entete
 function export_entete()
 {
 	return
@@ -189,4 +167,6 @@ $GLOBALS['meta']['charset']."\"?".">\n" .
 >\n";
 }
 
+function export_enpied () { return  "</SPIP>\n";}
+
 ?>