From 11d0272744f453e48673885769da36159e7e3a25 Mon Sep 17 00:00:00 2001
From: "Committo,Ergo:sum" <esj@rezo.net>
Date: Mon, 20 Aug 2007 17:15:31 +0000
Subject: [PATCH] =?UTF-8?q?#209:=20L'identifiant=20de=20session=20d'import?=
 =?UTF-8?q?ation=20introduit=20par=20[9903]=20est=20=C3=A9tendu=20dans=20l?=
 =?UTF-8?q?a=20fonction=20'''inc=5Fadmin'''=20=C3=A0=20un=20identifiant=20?=
 =?UTF-8?q?de=20session=20d'administration,=20afin=20d'emp=C3=AAcher=20plu?=
 =?UTF-8?q?s=20g=C3=A9n=C3=A9ralement=20deux=20connexions=20dans=20l'espac?=
 =?UTF-8?q?e=20priv=C3=A9=20lorsqu'une=20op=C3=A9ration=20lourde=20a=20lie?=
 =?UTF-8?q?u=20(actuellement:=20mise=20=C3=A0=20jour=20de=20SPIP,=20=20imp?=
 =?UTF-8?q?ortation/fusion=20d'archives,=20conversion=20de=20caract=C3=A8r?=
 =?UTF-8?q?es=20par=20SQL=20ou=20par=20PHP,=20destruction=20des=20statisti?=
 =?UTF-8?q?ques=20ou=20de=20la=20base).=20Grace=20=C3=A0=20=C3=A7a,=20les?=
 =?UTF-8?q?=20deux=20verrous=20MySQL=20pour=20les=20conversions=20de=20car?=
 =?UTF-8?q?act=C3=A8res=20passent=20=C3=A0=20la=20trappe.=20Plus=20que=203?=
 =?UTF-8?q?=20verrous=20MySQL=20=C3=A0=20=C3=A9liminer.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ecrire/base/convert_sql_utf8.php |  7 ------
 ecrire/base/convert_utf8.php     |  6 -----
 ecrire/base/import_all.php       |  1 -
 ecrire/inc/admin.php             | 38 +++++++++++++++++++++++++++-----
 ecrire/inc/import.php            | 17 --------------
 ecrire/inc/import_1_3.php        |  1 -
 ecrire/index.php                 | 17 +++++++++-----
 ecrire/install/etape_3.php       |  9 +++++---
 8 files changed, 49 insertions(+), 47 deletions(-)

diff --git a/ecrire/base/convert_sql_utf8.php b/ecrire/base/convert_sql_utf8.php
index 86813cc728..af8baae0d5 100644
--- a/ecrire/base/convert_sql_utf8.php
+++ b/ecrire/base/convert_sql_utf8.php
@@ -16,12 +16,6 @@ if (!defined("_ECRIRE_INC_VERSION")) return;
 // http://doc.spip.org/@base_convert_sql_utf8_dist
 function base_convert_sql_utf8_dist($titre, $reprise=false)
 {
-	// poser un verrou (et abandonner si l'action est en cours)
-
-	if (!spip_get_lock('conversion_charset_sql')) {
-		echo minipres(_T('utf8_convert_attendez'));
-		exit;
-	}
 
 	include_spip('inc/meta');
 	ecrire_meta('convert_sql_utf8','oui','non');
@@ -135,6 +129,5 @@ function convert_sql_utf8(){
 	ecrire_meta('charset_sql_base',$sql_charset,'non');
 	ecrire_meta('charset_sql_connexion',$sql_charset,'non');
 	ecrire_metas();
-	spip_release_lock('conversion_charset_sql');
 }
 ?>
diff --git a/ecrire/base/convert_utf8.php b/ecrire/base/convert_utf8.php
index 3190e01390..141d3ac26d 100644
--- a/ecrire/base/convert_utf8.php
+++ b/ecrire/base/convert_utf8.php
@@ -38,12 +38,6 @@ function convert_utf8_init($tables_a_convertir)
 // http://doc.spip.org/@base_convert_utf8_dist
 function base_convert_utf8_dist($titre, $reprise=false)
 {
-	// poser un verrou (et abandonner si l'action est en cours)
-
-	if (!spip_get_lock('conversion_charset')) {
-		echo minipres(_T('utf8_convert_attendez'));
-		exit;
-	}
 	// une liste des tables a convertir, avec le champ dans lequel on
 	// indique '<CONVERT charset>' ; on commence par les rubriques sinon
 	// ca fait desordre dans l'interface privee
diff --git a/ecrire/base/import_all.php b/ecrire/base/import_all.php
index 397fa538bc..a2e7defce7 100644
--- a/ecrire/base/import_all.php
+++ b/ecrire/base/import_all.php
@@ -115,7 +115,6 @@ function import_all_fin($request) {
 	effacer_meta("date_optimisation");
 	effacer_meta('version_archive_restauration');
 	effacer_meta('tag_archive_restauration');
-	effacer_meta('restauration_session_id');
 	effacer_meta('restauration_charset_sql_connexion');
 	ecrire_metas();
 	if ($request['insertion'] == 'passe2') 
diff --git a/ecrire/inc/admin.php b/ecrire/inc/admin.php
index d3604ad746..28fa7a1ebc 100644
--- a/ecrire/inc/admin.php
+++ b/ecrire/inc/admin.php
@@ -29,17 +29,39 @@ function inc_admin_dist($script, $titre, $comment='', $retour='')
 		spip_log("meta: $script " . join(',', $_POST));
 		ecrire_meta($script, serialize($_POST));
 		ecrire_metas();
-	} else spip_log("reprise de $script");
+	} else 	admin_verifie_session($script);
+
 	$base = charger_fonction($script, 'base');
 	$base($titre,$reprise);
-	effacer_meta($script);
-	ecrire_metas();
-	spip_unlink(_FILE_META);
 	fin_admin($script);
-	spip_log("efface meta: $script " . ($retour ? $retour : ''));
+	spip_log("efface les meta admin et $script " . ($retour ? $retour : ''));
 	if ($retour) redirige_par_entete($retour);
 }
 
+// Gestion dans la meta "admin" du script d'administation demande,
+// pour eviter des executions en parallele, notamment apres Time-Out.
+// Cette meta contient le nom du script et, a un codage pres, du demandeur.
+// Le code de ecrire/index.php devie toute demande d'execution d'un script
+// vers le script d'administration indique par cette meta si elle est l�.
+// Au niveau de la fonction inc_admin, on controle la meta 'admin'.
+// Si la meta n'est pas la, c'est le debut on la cree 
+// Sinon, on verifie que le connecte est bien celui ayant entame 
+// l'operation d'administration, 
+// Si le connecte n'est pas le bon, on refuse la connexion.
+
+// http://doc.spip.org/@import_verifie_session
+function admin_verifie_session($script) {
+
+	$signal = $script . ' ' . fichier_admin($action);
+	$row = sql_fetsel('valeur', 'spip_meta', "nom='admin'");
+	if (!$row) {
+		ecrire_meta('admin', $signal,'non');
+		ecrire_metas();
+	} elseif ($row['valeur'] != $signal)
+		die(_T('info_travaux_texte'));
+	else spip_log("reprise de $script");
+}
+
 // http://doc.spip.org/@dir_admin
 function dir_admin()
 {
@@ -123,8 +145,12 @@ function debut_admin($script, $action='', $commentaire='') {
 // http://doc.spip.org/@fin_admin
 function fin_admin($action) {
 	$signal = dir_admin() . fichier_admin($action);
+	@rmdir($signal); // par precaution
 	spip_unlink($signal);
-	@rmdir($signal);
+	spip_unlink(_FILE_META);
+	effacer_meta($action);
+	effacer_meta('admin');
+	ecrire_metas();
 }
 
 // http://doc.spip.org/@copy_request
diff --git a/ecrire/inc/import.php b/ecrire/inc/import.php
index f6d2c4e613..c69ee4e5ff 100644
--- a/ecrire/inc/import.php
+++ b/ecrire/inc/import.php
@@ -180,17 +180,6 @@ function detruit_restaurateur()
 	}
 }
 
-// verifier que l'id de session restauration place dans une meta correspond toujours a la session en cours
-// sinon cela signifie que la page a ete rechargee, et qu'une autre session a repris depuis le dernier abs_pos
-// il faut absolument ne plus rien faire et mourir ...
-
-// http://doc.spip.org/@import_verifie_session
-function import_verifie_session() {
-	$row = sql_fetsel(array('valeur'),array('spip_meta'),array("nom='restauration_session_id'"));
-	if ($row['valeur']!=_RESTAURATION_SESSION_ID)
-		die('la place est prise');
-}
-
 // http://doc.spip.org/@import_tables
 function import_tables($request, $dir) {
 	global $import_ok, $abs_pos,  $affiche_progression_pourcent;
@@ -228,12 +217,6 @@ function import_tables($request, $dir) {
 			$gz = 'fread';
 	}
 
-	// creer un id de la session d'import qui sera utilise pour verifier qu'on a toujours la main
-	// avant chaque insert/update
-	// permet d'eviter les process concourants qui realisent le meme insert/update
-	include_spip('inc/acces');
-	@define('_RESTAURATION_SESSION_ID',creer_uniqid());
-	ecrire_meta('restauration_session_id',_RESTAURATION_SESSION_ID,'non');
 	
 	if ($abs_pos==0) {
 		list($tag, $atts, $charset) = import_debut($file, $gz);
diff --git a/ecrire/inc/import_1_3.php b/ecrire/inc/import_1_3.php
index 63188a2279..bf16247d07 100644
--- a/ecrire/inc/import_1_3.php
+++ b/ecrire/inc/import_1_3.php
@@ -69,7 +69,6 @@ function inc_import_1_3_dist($lecteur, $request, $gz='fread', $atts=array()) {
 
 	if ($values === false) return  ($import_ok = false);
 
-	import_verifie_session(); // verifier qu'on a toujours la main pour faire des insertions en base
 	if ($values) $boucle($values, $new, $desc, $request, $atts);
 
 	return $import_ok = $new;
diff --git a/ecrire/index.php b/ecrire/index.php
index d3c6ce3fb5..cb8b9fda64 100644
--- a/ecrire/index.php
+++ b/ecrire/index.php
@@ -128,13 +128,18 @@ AND (!isset($var_ajaxcharset))
 AND ($GLOBALS['spip_version'] != (str_replace(',','.',$GLOBALS['meta']['version_installee']))))
 	$exec = 'demande_mise_a_jour';
 
-// Si interruption d'une longue restauration
-// detourner le script demande pour qu'il reprenne le boulot, et
-// refuser Ajax et non-admin pour eviter des restaurations paralleles
-elseif (isset($GLOBALS['meta']["import_all"])) {
+// Quand une action d'administration est en cours (meta "admin"),
+// refuser les connexions non-admin ou Ajax pour laisser la base intacte.
+// Si c'est une admin, detourner le script demande vers cette action:
+// si l'action est vraiment en cours, inc_admin refusera cette 2e demande,
+// sinon c'est qu'elle a ete interrompue et il faut la reprendre
+
+elseif (isset($GLOBALS['meta']["admin"])) {
 	if (isset($var_ajaxcharset) OR !isset($_COOKIE['spip_admin']))
-		die('Importation en cours, revenez plus tard.');
-	$exec = 'import_all';
+		die(_T('info_travaux_texte'));
+	$l = $GLOBALS['meta']["admin"];
+	spip_log("Le script $l, en cours, se substitue a $exec");
+	$exec = substr($l, 0, strpos($l, ' '));
 }
 // si nom pas plausible, prendre le script par defaut
 elseif (!preg_match(',^[a-z_][0-9a-z_]*$,i', $exec)) $exec = "accueil";
diff --git a/ecrire/install/etape_3.php b/ecrire/install/etape_3.php
index ad718a04e9..ad605cb11a 100644
--- a/ecrire/install/etape_3.php
+++ b/ecrire/install/etape_3.php
@@ -97,7 +97,9 @@ function install_bases(){
 		$finsert('spip_meta', '(nom, valeur,impt)', "('version_installee', '$spip_version','non')");
 	} else {
 
-	  creer_base($server_db); // pour recrer les tables disparues au besoin
+	  // pour recreer les tables disparues au besoin
+	  creer_base($server_db); 
+
 	  $r = $fquery ("SELECT valeur FROM spip_meta WHERE nom='version_installee'");
 	  if ($r) $r = $ffetch($r);
 	  if ($r) $version_installee = (double) $r['valeur'];
@@ -138,8 +140,9 @@ function install_bases(){
 		
 		$result_ok = $finsert("spip_meta", "(nom, valeur)", "('nouvelle_install', '1')");
 	} else {
-	  // en cas de reinstall sur mise a jour mal passee
-		@$fquery("DELETE FROM spip_meta WHERE nom='import_all'");
+	  // eliminer la derniere operation d'admin mal terminee
+	  // notamment la mise a jour 
+		@$fquery("DELETE FROM spip_meta WHERE nom='import_all' OR  nom='admin'");
 		$result_ok = @$fquery("SELECT COUNT(*) FROM spip_meta");
 	}
 
-- 
GitLab