|
|
|
@@ -18,7 +18,7 @@ int8_t archivage_bdd(char * chaine_date_fin, uint8_t type);
|
|
|
|
|
// Variables globales :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
//==================================================================================================================================================================
|
|
|
|
|
// Fonction : Cette fonction génère un fichier de sauvegarde de la base de données.
|
|
|
|
|
// Le fichier est stocké dans le répertoire d'upload pour pouvoir être remonté au serveur Koriolan via FTP ensuite (cette remontée ne fait pas partie de la présente fonction)
|
|
|
|
@@ -321,6 +321,369 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, "Fin de sauvegarde de la BDD", TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
//==================================================================================================================================================================
|
|
|
|
|
// Fonction : Cette fonction génère un fichier de sauvegarde de la base de données.
|
|
|
|
|
// Le fichier est stocké dans le répertoire d'upload pour pouvoir être remonté au serveur ship2net (récupéré via l'API shipheart_api, cf synthèse §32).
|
|
|
|
|
// La base de données est sauvegardée en totalité (tous les enregistrements de toutes les tables) SAUF :
|
|
|
|
|
// - les tables TB_Mesures_xxx : seuls les enregistrements dont le champ Archive vaut 0 sont remontés.
|
|
|
|
|
// - la table TB_Historique : seuls les enregistrements dont le champ Archive vaut 0 sont remontés.
|
|
|
|
|
// Le champ Archive de ces tables est mis à 1 une fois l'archive validée (remplace l'ancien mécanisme de No_paquet,
|
|
|
|
|
// source de risques en cas de réinitialisation usine ou de restauration d'une sauvegarde ancienne - cf synthèse §32.4).
|
|
|
|
|
// Le nom du fichier intègre désormais une empreinte (SHA-256 tronquée à 16 caractères) du fichier chiffré final,
|
|
|
|
|
// calculée une fois celui-ci produit et vérifié : elle sert à la fois de contrôle d'intégrité et d'identifiant
|
|
|
|
|
// unique côté serveur (il n'y a donc plus de notion de No_paquet dans le nom).
|
|
|
|
|
// Reçoit : Rien
|
|
|
|
|
// Renvoit : 0 si pas d'erreur. Valeur de retour du premier appel 'system()' qui est différent de 0.
|
|
|
|
|
//==================================================================================================================================================================
|
|
|
|
|
int32_t sauvegarde_bdd(void)
|
|
|
|
|
{
|
|
|
|
|
int32_t retour_commande;
|
|
|
|
|
char str_date[MAX_LONGUEUR_DATE_COURANTE];
|
|
|
|
|
char nom_base[75]; // <Adresse_mac>_<Date_fichier>, sans extension ni empreinte
|
|
|
|
|
char nom_fichier_sauvegarde[MAX_LONGUEUR_NOM_FICHIER_SAUVEGARDE_BDD];
|
|
|
|
|
char nom_fichier_final[MAX_LONGUEUR_NOM_FICHIER_SAUVEGARDE_BDD]; // Nom définitif, après renommage avec l'empreinte
|
|
|
|
|
char chemin_temp_empreinte[MAX_LONGUEUR_NOM_FICHIER_SAUVEGARDE_BDD];
|
|
|
|
|
char empreinte[17]; // 16 caractères hexadécimaux + '\0'
|
|
|
|
|
char no_mmsi[16]; // "000000000" par défaut (9 chiffres) - cf TB_Configuration
|
|
|
|
|
FILE * ptr_fichier_sauvegarde;
|
|
|
|
|
FILE * ptr_fichier_empreinte;
|
|
|
|
|
char requete[MAX_LONGUEUR_REQUETE_MYSQL];
|
|
|
|
|
char commande[MAX_TAILLE_COMMANDE_SHELL];
|
|
|
|
|
char options[MAX_LONGUEUR_OPTION_COMMANDE_SAUVEGARDE_BDD];
|
|
|
|
|
char filtre_table[MAX_LONGUEUR_OPTION_COMMANDE_SAUVEGARDE_BDD];
|
|
|
|
|
char param[MAX_LONGUEUR_OPTION_COMMANDE_SAUVEGARDE_BDD];
|
|
|
|
|
struct {
|
|
|
|
|
char nom[MAX_LONGUEUR_NOM_TABLE]; // Nom de la table (par exemple, TB_Mesures_capteurs')
|
|
|
|
|
} tables_fragmentees[MAX_NOMBRE_TABLES_FRAGMENTEES];
|
|
|
|
|
uint8_t nb_tables_fragmentees;
|
|
|
|
|
MYSQL_RES *result = NULL;
|
|
|
|
|
MYSQL_ROW row = NULL;
|
|
|
|
|
uint16_t i;
|
|
|
|
|
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sprintf(tmp, "Début de sauvegarde de la BDD (marquage par ligne, remplace No_paquet - cf synthèse §32.4)");
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
|
|
|
|
|
|
|
|
|
|
// SDIR # 202 (début) :
|
|
|
|
|
// Vérification qu'une phase d'archivage n'est pas en cours (si c'est le cas, on va décaler la sauvagarde pour éviter de surcharger inutilement le système) :
|
|
|
|
|
if (get_pid_numbers_from_name(NOM_FICHIER_ARCHIVAGE, "") > 0) // Il y a au moins 1 processus d'archivage en cours...
|
|
|
|
|
{
|
|
|
|
|
systeme.compteur_sauvegarde_bdd = SYSTEME_TEMPO_REPORT_SAUVEGARDE; // Dans ce cas, on relance une tempo courte (5s typique) avant de refaire une tentative.
|
|
|
|
|
|
|
|
|
|
sprintf(tmp, "Un processus [%s] a été détecté en cours d'exécution. La sauvegarde est temporisée pour %i secondes", NOM_FICHIER_ARCHIVAGE, systeme.compteur_sauvegarde_bdd);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|
|
|
|
|
// SDIR # 202 (fin)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
retour_commande = 0;
|
|
|
|
|
|
|
|
|
|
// Calcul de la date et de l'heure, au bon format :
|
|
|
|
|
date_courante(str_date, DATE_COURANTE_SANS_MS, FORMAT_DATE_COURANTE_FICHIER);
|
|
|
|
|
|
|
|
|
|
// NOUVEAU : lecture du MMSI courant (TB_Configuration.No_mmsi), transmis dans l'en-tête de l'archive (cf synthèse §32.3) :
|
|
|
|
|
sprintf(requete, "SELECT Valeur FROM TB_Configuration WHERE Nom='No_mmsi'");
|
|
|
|
|
mysql_query(bdd.pointeur, requete);
|
|
|
|
|
result = mysql_store_result(bdd.pointeur);
|
|
|
|
|
if ((result != NULL) && ((row = mysql_fetch_row(result)) != NULL)) strcpy(no_mmsi, row[0]);
|
|
|
|
|
else strcpy(no_mmsi, "000000000"); // Valeur par défaut si jamais introuvable (ne devrait normalement pas arriver)
|
|
|
|
|
if (result != NULL) mysql_free_result(result);
|
|
|
|
|
|
|
|
|
|
// Nom de base du fichier - SANS empreinte (inconnue à ce stade, calculée plus bas) NI No_paquet (abandonné) :
|
|
|
|
|
sprintf(nom_base, "%02X%02X%02X%02X%02X%02X_%s",
|
|
|
|
|
systeme.modules_physiques[0].adresse_mac[0], systeme.modules_physiques[0].adresse_mac[1], systeme.modules_physiques[0].adresse_mac[2],
|
|
|
|
|
systeme.modules_physiques[0].adresse_mac[3], systeme.modules_physiques[0].adresse_mac[4], systeme.modules_physiques[0].adresse_mac[5],
|
|
|
|
|
str_date);
|
|
|
|
|
sprintf(nom_fichier_sauvegarde, "%s/%s.sql", REPERTOIRE_SERVER_UPLOAD, nom_base);
|
|
|
|
|
|
|
|
|
|
// Options de la commande de sauvegarde (utilisée sur la commande 'mysqldump' :
|
|
|
|
|
sprintf(options, "--single-transaction --no-create-info --compact --complete-insert");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
do // Fake loop...
|
|
|
|
|
{
|
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
|
|
|
// Remplissage de l'entête du fichier de sauvegarde (SDIR #292) :
|
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
|
|
|
ptr_fichier_sauvegarde = fopen(nom_fichier_sauvegarde, "w+"); // Ouverture du flux en lecture/écriture. Si le fichier existe, il sera alors écrasé et la position courante est fixée au début du fichier. Sinon le fichier sera créé.
|
|
|
|
|
if (ptr_fichier_sauvegarde == NULL)
|
|
|
|
|
{
|
|
|
|
|
printf("Ouverture du fichier de sauvegarde [ %s ] impossible. La sauvegarde est arrêtée !\n", nom_fichier_sauvegarde);
|
|
|
|
|
retour_commande = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Attention : le format '# [nom_de_champ=valeur_du_champ]' est utilisé par le traitement côté serveur...
|
|
|
|
|
// Il est donc fortement conseillé de ne PAS modifier le format de ces trames d'entête !!!
|
|
|
|
|
fprintf(ptr_fichier_sauvegarde,
|
|
|
|
|
"# [Adresse_mac=%02X:%02X:%02X:%02X:%02X:%02X]\n",
|
|
|
|
|
systeme.modules_physiques[0].adresse_mac[0], systeme.modules_physiques[0].adresse_mac[1], systeme.modules_physiques[0].adresse_mac[2],
|
|
|
|
|
systeme.modules_physiques[0].adresse_mac[3], systeme.modules_physiques[0].adresse_mac[4], systeme.modules_physiques[0].adresse_mac[5]);
|
|
|
|
|
fprintf(ptr_fichier_sauvegarde, "# [Nom_du_bateau=%s]\n", systeme.nom_bateau);
|
|
|
|
|
fprintf(ptr_fichier_sauvegarde, "# [Date_fichier=%s]\n", str_date);
|
|
|
|
|
fprintf(ptr_fichier_sauvegarde, "# [Version_soft_no_package=%s]\n", systeme.package_no_version);
|
|
|
|
|
fprintf(ptr_fichier_sauvegarde, "# [No_mmsi=%s]\n", no_mmsi); // NOUVEAU (cf synthèse §32.3/32.4)
|
|
|
|
|
|
|
|
|
|
fclose(ptr_fichier_sauvegarde);
|
|
|
|
|
|
|
|
|
|
// Fin de SDIR #292
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
|
|
|
// Recherche des tables fragmentées : TB_Mesures* et TB_Historique
|
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
|
|
|
nb_tables_fragmentees = 0;
|
|
|
|
|
|
|
|
|
|
// Tables de mesures :
|
|
|
|
|
sprintf(requete, "SHOW TABLES FROM shipheart LIKE 'TB_Mesures%%'");
|
|
|
|
|
mysql_query(bdd.pointeur, requete);
|
|
|
|
|
result = mysql_store_result(bdd.pointeur);
|
|
|
|
|
while((row = mysql_fetch_row(result)))
|
|
|
|
|
{
|
|
|
|
|
strcpy(tables_fragmentees[nb_tables_fragmentees ++].nom, row[0]);
|
|
|
|
|
}
|
|
|
|
|
mysql_free_result(result);
|
|
|
|
|
|
|
|
|
|
// Table historique :
|
|
|
|
|
strcpy(tables_fragmentees[nb_tables_fragmentees ++].nom, "TB_Historique");
|
|
|
|
|
|
|
|
|
|
// Vérification du nombre de tables max :
|
|
|
|
|
if (nb_tables_fragmentees > MAX_NOMBRE_TABLES_FRAGMENTEES)
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "Le nombre de tables fragmentées (qui sont sauvegardées par fragment) est supérieur au nombre maxi (%i tables trouvées pour maxi = %i). La sauvegarde de la BDD est arrêté.", nb_tables_fragmentees, MAX_NOMBRE_TABLES_FRAGMENTEES);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
retour_commande = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
|
|
|
// Sauvegarde de toutes les tables, sauf TB_Mesures* et TB_Historique :
|
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Début de la commande de dump:
|
|
|
|
|
sprintf(commande, "mysqldump %s -u %s --password=%s %s ", options, BDD_USER, BDD_PASSWORD, BDD_DATABASE);
|
|
|
|
|
|
|
|
|
|
// Suppression des tables fragmentées du dump :
|
|
|
|
|
for (i = 0; i < nb_tables_fragmentees; i ++)
|
|
|
|
|
{
|
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wformat-overflow"
|
|
|
|
|
sprintf(param, "--ignore-table=%s.%s ", BDD_DATABASE, tables_fragmentees[i].nom); // Warning connu mais non justifié : tables_fragmentees[].nom : 50 car et param : 300 car
|
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
|
|
|
|
|
|
strcat(commande, param);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fin de la commande :
|
|
|
|
|
sprintf(param, ">> %s ", nom_fichier_sauvegarde);
|
|
|
|
|
strcat(commande, param);
|
|
|
|
|
|
|
|
|
|
retour_commande = commande_shell(commande);
|
|
|
|
|
if (retour_commande != 0)
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "La commande de sauvegarde de toutes les tables non fragmentées [%s] a échoué avec le code %i", commande, retour_commande);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// Sauvegarde des derniers enregistrements des tables fragmentées :
|
|
|
|
|
// CHANGEMENT : le filtre passe de 'No_paquet=%i' à 'Archive=0' - le marquage effectif (Archive=1) n'a lieu que plus bas, une fois
|
|
|
|
|
// l'archive entièrement validée (cf synthèse §32.4). Tant que ce marquage n'a pas eu lieu, ces mêmes lignes seront reprises par la
|
|
|
|
|
// prochaine tentative en cas d'échec à n'importe quelle étape suivante.
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
for (i = 0; i < nb_tables_fragmentees; i ++)
|
|
|
|
|
{
|
|
|
|
|
// Suppression des 'Type>0' pour TB_Mesures_circuits :
|
|
|
|
|
if (strstr(tables_fragmentees[i].nom, "TB_Mesures_circuits") != NULL) strcpy(filtre_table, " AND Type=0");
|
|
|
|
|
else strcpy(filtre_table, "");
|
|
|
|
|
sprintf(commande, "mysqldump %s -u %s --password=%s %s %s --where=\"Archive=0 %s \" >> %s", options, BDD_USER, BDD_PASSWORD, BDD_DATABASE, tables_fragmentees[i].nom, filtre_table, nom_fichier_sauvegarde);
|
|
|
|
|
retour_commande = commande_shell(commande);
|
|
|
|
|
if (retour_commande != 0)
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "La commande de sauvegarde de la table fragmentée %s [%s] a échoué avec le code %i", tables_fragmentees[i].nom, commande, retour_commande);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
break; // Sortie de la boucle FOR
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (retour_commande != 0) break;
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// Compression du fichier de sauvegarde :
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// SDIR #170 : ajout du paramètre '-k' dans la commande de compresion afin de conserver le fichier SQL initial (sinon, il n'est pas conservé par GZIP)
|
|
|
|
|
sprintf(commande, "gzip %s -k -S .%s", nom_fichier_sauvegarde, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD);
|
|
|
|
|
retour_commande = commande_shell(commande);
|
|
|
|
|
if (retour_commande != 0)
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "La commande de compression du fichier de sauvegarde [%s] a échoué avec le code %i", commande, retour_commande);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// Encryption du fichier de sauvegarde :
|
|
|
|
|
// CHANGEMENT : mot de passe dédié (CLE_CHIFFREMENT_ARCHIVE), distinct
|
|
|
|
|
// de BDD_PASSWORD - à définir dans localisation.h (cf synthèse §32.4).
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
sprintf(commande, "openssl enc -aes-256-cbc -pbkdf2 -iter 10000 -md sha256 -in %s.%s -out %s.%s.%s -pass pass:%s", nom_fichier_sauvegarde, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD, nom_fichier_sauvegarde, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD, SUFFIXE_NOM_FICHIER_ENCRYPTE_SAUVEGARDE_BDD, CLE_CHIFFREMENT_ARCHIVE);
|
|
|
|
|
retour_commande = commande_shell(commande);
|
|
|
|
|
if (retour_commande != 0)
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "La commande d'encryption du fichier de sauvegarde [%s] a échoué avec le code %i", commande, retour_commande);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// Décryptage du fichier final (vérification - même mot de passe dédié) :
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
sprintf(commande, "openssl enc -aes-256-cbc -pbkdf2 -iter 10000 -md sha256 -d -in %s.%s.%s -out %s/%s.sql.%s -pass pass:%s", nom_fichier_sauvegarde, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD, SUFFIXE_NOM_FICHIER_ENCRYPTE_SAUVEGARDE_BDD, REPERTOIRE_TMP_BDD, NOM_FICHIER_CHECK_SAUVEGARDE, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD, CLE_CHIFFREMENT_ARCHIVE);
|
|
|
|
|
retour_commande = commande_shell(commande);
|
|
|
|
|
if (retour_commande != 0)
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "La commande de décrytage temporaire du fichier de sauvegarde [%s] a échoué avec le code %i", commande, retour_commande);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// Décompression du fichier temporaire :
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
sprintf(commande, "gzip -d -f %s/%s.sql.%s", REPERTOIRE_TMP_BDD, NOM_FICHIER_CHECK_SAUVEGARDE, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD);
|
|
|
|
|
retour_commande = commande_shell(commande);
|
|
|
|
|
if (retour_commande != 0)
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "La commande de décompression temporaire [%s] a échoué avec le code %i", commande, retour_commande);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// Comparaison du fichier temporaire avec le fichier inital :
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
sprintf(commande, "diff -q %s %s/%s.sql", nom_fichier_sauvegarde, REPERTOIRE_TMP_BDD, NOM_FICHIER_CHECK_SAUVEGARDE);
|
|
|
|
|
retour_commande = commande_shell(commande);
|
|
|
|
|
if (retour_commande != 0)
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "La comparaison du fichier temporaire avec le fichier inital [%s] indique deux fichiers différents [%i]", commande, retour_commande);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// NOUVEAU : calcul de l'empreinte (SHA-256 tronquée à 16 caractères)
|
|
|
|
|
// du fichier chiffré final, et renommage pour l'y intégrer. Ne se
|
|
|
|
|
// fait qu'à ce stade : la vérification ci-dessus (diff) vient de
|
|
|
|
|
// confirmer que ce fichier est intègre, donc l'empreinte qu'on y
|
|
|
|
|
// appose est fiable (cf synthèse §32.4).
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
sprintf(chemin_temp_empreinte, "%s/empreinte_archive.tmp", REPERTOIRE_TMP_BDD);
|
|
|
|
|
sprintf(commande, "sha256sum %s.%s.%s | cut -c1-16 > %s", nom_fichier_sauvegarde, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD, SUFFIXE_NOM_FICHIER_ENCRYPTE_SAUVEGARDE_BDD, chemin_temp_empreinte);
|
|
|
|
|
retour_commande = commande_shell(commande);
|
|
|
|
|
if (retour_commande != 0)
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "Le calcul de l'empreinte du fichier de sauvegarde [%s] a échoué avec le code %i", commande, retour_commande);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ptr_fichier_empreinte = fopen(chemin_temp_empreinte, "r");
|
|
|
|
|
if ((ptr_fichier_empreinte == NULL) || (fgets(empreinte, sizeof(empreinte), ptr_fichier_empreinte) == NULL))
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "La lecture de l'empreinte calculée [%s] a échoué.", chemin_temp_empreinte);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
if (ptr_fichier_empreinte != NULL) fclose(ptr_fichier_empreinte);
|
|
|
|
|
retour_commande = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
fclose(ptr_fichier_empreinte);
|
|
|
|
|
remove(chemin_temp_empreinte);
|
|
|
|
|
empreinte[16] = '\0'; // Sécurité : ne garder que les 16 premiers caractères, même si un caractère de fin de ligne traînait
|
|
|
|
|
|
|
|
|
|
sprintf(nom_fichier_final, "%s/%s_%s.sql.%s.%s", REPERTOIRE_SERVER_UPLOAD, nom_base, empreinte, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD, SUFFIXE_NOM_FICHIER_ENCRYPTE_SAUVEGARDE_BDD);
|
|
|
|
|
sprintf(commande, "%s.%s.%s", nom_fichier_sauvegarde, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD, SUFFIXE_NOM_FICHIER_ENCRYPTE_SAUVEGARDE_BDD);
|
|
|
|
|
if (rename(commande, nom_fichier_final) != 0)
|
|
|
|
|
{
|
|
|
|
|
sprintf(tmp, "Le renommage du fichier de sauvegarde [%s] vers [%s] a échoué.", commande, nom_fichier_final);
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
retour_commande = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// NOUVEAU : marquage des lignes archivées (remplace l'incrémentation
|
|
|
|
|
// de No_paquet). Même filtre que celui utilisé pour le dump (donc
|
|
|
|
|
// 'AND Type=0' repris pour TB_Mesures_circuits), pour ne marquer que
|
|
|
|
|
// ce qui vient réellement d'être archivé (cf synthèse §32.4) :
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
for (i = 0; i < nb_tables_fragmentees; i ++)
|
|
|
|
|
{
|
|
|
|
|
if (strstr(tables_fragmentees[i].nom, "TB_Mesures_circuits") != NULL) strcpy(filtre_table, " AND Type=0");
|
|
|
|
|
else strcpy(filtre_table, "");
|
|
|
|
|
sprintf(requete, "UPDATE %s SET Archive=1 WHERE Archive=0 %s", tables_fragmentees[i].nom, filtre_table);
|
|
|
|
|
if (mysql_query(bdd.pointeur, requete) != 0)
|
|
|
|
|
{
|
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wformat-overflow"
|
|
|
|
|
sprintf(tmp, "Le marquage des lignes archivées de la table %s [%s] a échoué : %s", tables_fragmentees[i].nom, requete, mysql_error(bdd.pointeur));
|
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
|
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
retour_commande = -1;
|
|
|
|
|
break; // Sortie de la boucle FOR
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (retour_commande != 0) break;
|
|
|
|
|
|
|
|
|
|
} while(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// Vérification que la sauvegarde s'est bien passée et retour :
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
if (retour_commande != 0) // Cas où au moins l'une des opérations de sauvegarde ne s'est pas bien passée
|
|
|
|
|
{
|
|
|
|
|
// Enregistrement dans l'historique :
|
|
|
|
|
enregistrement_historique(TYPE_SOURCE_HISTORIQUE_SYSTEME, SYSTEME_ERREUR_SAUVEGARDE_BDD, 0, 0, tmp);
|
|
|
|
|
|
|
|
|
|
// Suppression de tous les fichiers possibles, quelle que soit l'étape où l'échec a eu lieu (y compris après renommage) :
|
|
|
|
|
remove(nom_fichier_sauvegarde);
|
|
|
|
|
sprintf(commande, "%s.%s", nom_fichier_sauvegarde, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD);
|
|
|
|
|
remove(commande);
|
|
|
|
|
sprintf(commande, "%s.%s.%s", nom_fichier_sauvegarde, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD, SUFFIXE_NOM_FICHIER_ENCRYPTE_SAUVEGARDE_BDD);
|
|
|
|
|
remove(commande);
|
|
|
|
|
remove(nom_fichier_final); // Au cas où l'échec ait eu lieu APRÈS le renommage (lors du marquage des lignes, par exemple)
|
|
|
|
|
|
|
|
|
|
sprintf(tmp, "La sauvegarde de la BDD est abandonnée. Les fichiers créés ont été supprimés.");
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
|
|
|
// NB : contrairement à l'ancien mécanisme (No_paquet non incrémenté en cas d'échec), le marquage par ligne
|
|
|
|
|
// (Archive=1) n'est fait qu'en tout dernier lieu, une fois le fichier final confirmé intègre et renommé -
|
|
|
|
|
// un échec à n'importe quelle étape antérieure laisse donc naturellement les lignes concernées à Archive=0,
|
|
|
|
|
// qui seront reprises par la prochaine tentative sans aucune action supplémentaire nécessaire.
|
|
|
|
|
|
|
|
|
|
return(retour_commande);
|
|
|
|
|
}
|
|
|
|
|
else // Cas normal, sans erreur :
|
|
|
|
|
{
|
|
|
|
|
// Supression du fichier SQL (qui a été volontairement conservé via le paramètre '-k' de GZIP)...
|
|
|
|
|
// ... et du fichier compressé (openssl ne peut pas "écraser" la source si elle est dans le même répertoire ; on le fait donc manuellement)...
|
|
|
|
|
// ... seul le fichier final (chiffré et renommé avec son empreinte) est conservé :
|
|
|
|
|
remove(nom_fichier_sauvegarde);
|
|
|
|
|
sprintf(commande, "%s.%s", nom_fichier_sauvegarde, SUFFIXE_NOM_FICHIER_COMPRESSE_SAUVEGARDE_BDD);
|
|
|
|
|
remove(commande);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
affichage_debug(__FILE__, __LINE__, "Fin de sauvegarde de la BDD", TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|