Voici le résultat (effectivement il est bavard) :
NAS> bash -vx busyXtremMerge -v 2.pdf.001.xtm
#! /bin/bash
# Copyright (C) 2010 Zakhar for ubuntu-fr
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# The text of the GNU General Public License is available at
# http://www.gnu.org/licenses/gpl-2.0.html; if you cannot access it,
# write to the Free Software Foundation, Inc., 51 Franklin Street,
# Fifth Floor, Boston, MA 02110-1301 USA.
#===========================================================
# Fonction :
# ----------
# - Ce script fonctionne avec tuXtremMerge
# - Il vise à remplacer les fonctions qui n'existent pas sur
# Busybox 1.16.1 utilisé sur les Synology 1010+
# - Ce script fonctionne également sur Ubuntu (Lucid)... puisque
# c'est ainsi que je le teste !.. Mais il alourdirait inutilement
# les traitements puisque certaines commandes existantes sont réécrites
# en shell, donc plus lent, sujet à des bugs, etc...
# Par conséquent ça a été séparé expressément.
#
# Usage :
# -------
# SynoXtremMerge Nom_Du_Fichier_NNN.xtm
# (N'importe lequel des fichiers fonctionne : 001 ou autre)
#
# Tested : Début du test sur Synology 1010+, travail non terminé
# ------
#
# Version : Syno + version du script tuXtremMerge utilisé
# -------
#
# Date : 2011-04-29
# -----
#
# Author : Zakhar (ubuntu-fr)
# ------
#
# Contributor : // Ajouter votre nom si vous contribuez et redistribuez //
# -----------
# stadros83 @ ubuntu.fr : début des tests Synology 1010+
# - problèmes readlink sur Synology 1010+ (pas d'option -f)
# => retrait de readlink et remplacement par une fonction shell
# - problème od (commande inexistante)
# => Installation par une commande Syno : ipkg install textutils
# - problème du -B (option inexistante)
# => Supression de "du". En réalité pour homogénéiser, on utilise
# stat -c%s partout
# - problème stat -c (option inexistante)
# => Attente de commande pour debug
#
# History :
# ---------
# 0.9.0
# - readlink ne se comporte pas pareil sur Synology 1010+
# - Retrait de readlink, remplacé par la fonction shell readlnk
#==========================================================
# Messages and Error codes.
#+ This way it is easyier, if somebody would like to localise
readonly MSG_BUSY_VERSION="busyXtremMerge (turbo XTM), contournements pour Busybox, version 0.9.0"
+ readonly 'MSG_BUSY_VERSION=busyXtremMerge (turbo XTM), contournements pour Busybox, version 0.9.0'
+ MSG_BUSY_VERSION='busyXtremMerge (turbo XTM), contournements pour Busybox, version 0.9.0'
#==========================================================
# Fonctions de remplacement des commandes déficientes !
# Remplace readlink qui n'a pas le même comportement partout
# Par ex. sur Synology 1010+ tournant sous Busybox 1.16.1, l'option -f n'existe pas
# Retourne l'emplacement absolu du fichier en le déréférençant éventuellement
# Readlink est toujours utilisé dans le script principal sous cette forme :
# readlink -f Nom_Fichier
# On ne tient donc compte que tu deuxième argument
readlink()
{
if [ -h "$2" ]; then # C'est un lien symbolique !
temp=$( ls -l "$2" )
target=${temp#* -> }
if [ -h "$target" ]; then # Recursif...
pushd $(dirname "$target") >/dev/null
target=$(readlnk "$target")
popd >/dev/null
fi
else
target="$2"
fi
# Ici la variable "target" vaut soit $2 soit le déréférencement
temp=$(cd $(dirname "$target"); pwd)
if [ "$temp" != '/' ]; then # On rajoute / au dirname, sauf pour root
temp="${temp}/"
fi
echo -n "${temp}${target##*/}"
}
# Remplace stat qui n'a pas le même comportement sur les anciens Busybox
# Par ex. sur Synology 1010+ tournant sous Busybox 1.16.1, l'option -c n'existe pas
# C'est moche, mais on remplace donc par un ls + cut
# On utilise le 2ème paramètre car c'est toujours utilisé stat -c%s fichier
stat()
{
ls -l "$2" | tr -s [:blank:] | cut -d' ' -f 5
}
#==========================================================
# Et on source le script standard
# S'il n'est pas mis dans le même chemin, il faut donc changer la commande
THIS_SCRIPT_DIR=$( dirname $0 )
dirname $0
++ dirname busyXtremMerge
+ THIS_SCRIPT_DIR=.
. "${THIS_SCRIPT_DIR}/tuXtremMerge"
+ . ./tuXtremMerge
#! /bin/bash
# Copyright (C) 2010 Zakhar for ubuntu-fr
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# The text of the GNU General Public License is available at
# http://www.gnu.org/licenses/gpl-2.0.html; if you cannot access it,
# write to the Free Software Foundation, Inc., 51 Franklin Street,
# Fifth Floor, Boston, MA 02110-1301 USA.
#===========================================================
# Fonction :
# ----------
# - Rassemble des fichiers découpés par XtremSplit
# - Vérifie le MD5 s'il est inclus dans les fichiers source
#
# Usage :
# -------
# tuXtremMerge Nom_Du_Fichier_NNN.xtm
# (N'importe lequel des fichiers fonctionne : 001 ou autre)
#
# Tested : Ubuntu Lucid,Karmic
# ------
#
# Version : 1.5.6
# -------
#
# Date : 2011-05-18
# -----
#
# Author : Zakhar (ubuntu-fr)
# ------
#
# Contributor : // Ajouter votre nom si vous contribuez et redistribuez //
# -----------
# Hypnose @ ubuntu.fr : amélioration des spécifications
# Totor @ ubuntu.fr : amélioration et optimisation du code
# Moonface @ ubuntu.fr : témoignage, test et debug de fonctionnement sur Synology DS211j
#
# History :
# ---------
# 1.5.6
# - Remplacement de od par dd lorsqu'on doit lire des chaines.
# - Remplacement de basemane par interne ${var##*/}
# 1.5.5
# - Retour au code 1.5.3. (plus amélioration: suppression de 'du + cut' remplacé par 'stat -c%s')
# et séparation du code non fini pour Synology 1010+
# 1.5.4
# - Tentative du mise au point pour Synology 1010+ qui utilise une Busybox 1.16.1
# 1.5.2
# - Suppression useless cat ! (Totor @ ubuntu.fr)
# - Remplacement du fichier temporaire par un process substitution (Totor @ ubuntu.fr)
# - Isolation des libellés et codes erreur.
# - Nouveaux paramètre : V (Version), t (temps) [et donc désormais n'affiche plus par défaut les temps]
# 1.5.1
# - Sécurité : création du fichier temporaire avec mktemp
# - Amélioration de libellés
# - Ordonnancement plus logique des tests de cohérence initiaux.
# - Optimisations mineures.
# 1.5.0
# - Suppression et fusion des options -o et -a !..
# Le script utilise désormais toujours l'option -o (ce qui est sa plus-value)
# Si un traitement partiel est détecté, il reprend là où ça en était (deuxième plus-value)
# Ces deux options sont donc désormais inutiles car implicites... et cela simplifie le code !
# - Le script fonctionne désormais "à la mode Firefox", c'est à dire que le fichier résultat
# est d'abord écrit dans resultat.part, et celui-ci est renommé à la fin du traitement.
# La fonction de reprise tient compte de ce nouveau fonctionnement, de même que l'option -f
# - Le premier fichier bénéficie aussi de l'optimisation (parallelisme copie/md5)
# 1.2.0
# - Suppression de l'option -s devenue inutile. Le fichier est maintenant mis par défaut (suggestion Hypnose @ ubuntu-fr)
# dans le même répertoire que les fichiers source (xtm). Le mode par défaut précédent s'obtient en spécifiant "."
# (c'est à dire le répertoire courant) comme destination.
# - Rajout des options d'optimisation -a et -o
# -a permet de lancer le script en cours de téléchargement et d'obtenir un résultat partiel
# -o optimise les MD5/concaténation via un tee (tout est fait en une seule commande, une seule lecture).
# - Diverses corrections de bugs
# 1.1.0
# - Rajout de l'exploration des arguments
# - Rajout des options : voir description dans la fonction usage
# - Un peu de couleurs pour égayer l'affichage !
# 1.0.1
# - Correction du chemin si le script est lancé depuis via PATH (exemple script placé dans /usr/local/bin)
# - Affichage des fichiers tels que passés en paramètres avec leurs éventuels chemins relatifs/absolus
# 1.0.0
# - Supporte d'être lancé avec des noms de fichiers contenant des chemins
# - Deuxième paramètre optionnel pour spécifier le fichier destination
# - Support des noms de fichiers contenant des espaces (source et destination)
# - Vérification au préalable de l'existence du fichier destination pour éviter les écrasement intempestifs
# - Vérification avant de calculer les MD5 qu'on va bien pouvoir écrire sur le fichier destination
#==========================================================
# Messages and Error codes.
#+ This way it is easyier, if somebody would like to localise
readonly MSG_ERROR="\E[1;31mErreur\E[0m\n"
++ readonly 'MSG_ERROR=\E[1;31mErreur\E[0m\n'
++ MSG_ERROR='\E[1;31mErreur\E[0m\n'
readonly MSG_OK="\E[1;32mOK\E[0m"
++ readonly 'MSG_OK=\E[1;32mOK\E[0m'
++ MSG_OK='\E[1;32mOK\E[0m'
readonly MSG_ATTENTION="\E[1;33mAttention !\E[0m"
++ readonly 'MSG_ATTENTION=\E[1;33mAttention !\E[0m'
++ MSG_ATTENTION='\E[1;33mAttention !\E[0m'
readonly MSG_BAD_OPTION="Option - incorrecte"
++ readonly 'MSG_BAD_OPTION=Option - incorrecte'
++ MSG_BAD_OPTION='Option - incorrecte'
readonly MSG_TOO_MANY_PARAMS="Trop de paramètre :"
++ readonly 'MSG_TOO_MANY_PARAMS=Trop de paramètre :'
++ MSG_TOO_MANY_PARAMS='Trop de paramètre :'
readonly MSG_UNKNOWN_OPTION="Option inconnue :"
++ readonly 'MSG_UNKNOWN_OPTION=Option inconnue :'
++ MSG_UNKNOWN_OPTION='Option inconnue :'
readonly MSG_UNSPECIFIED_SOURCE_FILE="Fichier source non spécifié"
++ readonly 'MSG_UNSPECIFIED_SOURCE_FILE=Fichier source non spécifié'
++ MSG_UNSPECIFIED_SOURCE_FILE='Fichier source non spécifié'
readonly MSG_VERSION="tuXtremMerge (turbo XTM), version 1.5.6"
++ readonly 'MSG_VERSION=tuXtremMerge (turbo XTM), version 1.5.6'
++ MSG_VERSION='tuXtremMerge (turbo XTM), version 1.5.6'
readonly MSG_OPTION_M_AND_N="Vous ne pouvez spécifier les options \E[1;32m-m\E[0m et \E[1;32m-n\E[0m simultanément."
++ readonly 'MSG_OPTION_M_AND_N=Vous ne pouvez spécifier les options \E[1;32m-m\E[0m et \E[1;32m-n\E[0m simultanément.'
++ MSG_OPTION_M_AND_N='Vous ne pouvez spécifier les options \E[1;32m-m\E[0m et \E[1;32m-n\E[0m simultanément.'
readonly MSG_IGNORING_OPTION_F="L'option \E[1;32m-f\E[0m sera ignorée puisque l'option -\E[1;32m-m\E[0m est spécifiée."
++ readonly 'MSG_IGNORING_OPTION_F=L'\''option \E[1;32m-f\E[0m sera ignorée puisque l'\''option -\E[1;32m-m\E[0m est spécifiée.'
++ MSG_IGNORING_OPTION_F='L'\''option \E[1;32m-f\E[0m sera ignorée puisque l'\''option -\E[1;32m-m\E[0m est spécifiée.'
readonly MSG_IGNORING_DEST="Le nom du fichier résultat sera ignoré puisque l'option \E[1;32m-m\E[0m est spécifiée."
++ readonly 'MSG_IGNORING_DEST=Le nom du fichier résultat sera ignoré puisque l'\''option \E[1;32m-m\E[0m est spécifiée.'
++ MSG_IGNORING_DEST='Le nom du fichier résultat sera ignoré puisque l'\''option \E[1;32m-m\E[0m est spécifiée.'
readonly MSG_CHECKING="Vérifications ... "
++ readonly 'MSG_CHECKING=Vérifications ... '
++ MSG_CHECKING='Vérifications ... '
readonly MSG_CHECKING_FIRST_SOURCE_FILE="Vérification d'existence du premier fichier source..."
++ readonly 'MSG_CHECKING_FIRST_SOURCE_FILE=Vérification d'\''existence du premier fichier source...'
++ MSG_CHECKING_FIRST_SOURCE_FILE='Vérification d'\''existence du premier fichier source...'
readonly MSG_TIP="\E[1;34mAstuce :\E[0;34m il faut le premier et le dernier fichier, corrects et complets, pour que le script puisse fonctionner.\nVous pouvez optimiser le résultat en récupérant ces deux fichiers en priorité.\E[0m"
++ readonly 'MSG_TIP=\E[1;34mAstuce :\E[0;34m il faut le premier et le dernier fichier, corrects et complets, pour que le script puisse fonctionner.\nVous pouvez optimiser le résultat en récupérant ces deux fichiers en priorité.\E[0m'
++ MSG_TIP='\E[1;34mAstuce :\E[0;34m il faut le premier et le dernier fichier, corrects et complets, pour que le script puisse fonctionner.\nVous pouvez optimiser le résultat en récupérant ces deux fichiers en priorité.\E[0m'
readonly MSG_SUCCESS="==================================================\n\E[1;32mToutes les opérations sont terminées avec succès !\E[0m"
++ readonly 'MSG_SUCCESS===================================================\n\E[1;32mToutes les opérations sont terminées avec succès !\E[0m'
++ MSG_SUCCESS='==================================================\n\E[1;32mToutes les opérations sont terminées avec succès !\E[0m'
readonly MSG_FIRST_FILE_ERROR="001.xtm non trouvé, vide ou erreur"
++ readonly 'MSG_FIRST_FILE_ERROR=001.xtm non trouvé, vide ou erreur'
++ MSG_FIRST_FILE_ERROR='001.xtm non trouvé, vide ou erreur'
readonly MSG_FIRST_FILE_FOUND="Premier fichier source trouvé :"
++ readonly 'MSG_FIRST_FILE_FOUND=Premier fichier source trouvé :'
++ MSG_FIRST_FILE_FOUND='Premier fichier source trouvé :'
readonly MSG_OPTION_M_AND_NO_MD5="\E[1;33mRien à faire !\E[0m\nL'option \E[1;32m-m\E[0m est spécifiée, or il n'y a pas MD5 à vérifier dans ces fichiers xtm."
++ readonly 'MSG_OPTION_M_AND_NO_MD5=\E[1;33mRien à faire !\E[0m\nL'\''option \E[1;32m-m\E[0m est spécifiée, or il n'\''y a pas MD5 à vérifier dans ces fichiers xtm.'
++ MSG_OPTION_M_AND_NO_MD5='\E[1;33mRien à faire !\E[0m\nL'\''option \E[1;32m-m\E[0m est spécifiée, or il n'\''y a pas MD5 à vérifier dans ces fichiers xtm.'
readonly MSG_CHECKING_LAST_SOURCE_FILE="Vérification d'existence du dernier fichier source..."
++ readonly 'MSG_CHECKING_LAST_SOURCE_FILE=Vérification d'\''existence du dernier fichier source...'
++ MSG_CHECKING_LAST_SOURCE_FILE='Vérification d'\''existence du dernier fichier source...'
readonly MSG_LAST_FILE_ERROR="Fichier %s%3.3u.xtm non trouvé ou vide\n"
++ readonly 'MSG_LAST_FILE_ERROR=Fichier %s%3.3u.xtm non trouvé ou vide\n'
++ MSG_LAST_FILE_ERROR='Fichier %s%3.3u.xtm non trouvé ou vide\n'
readonly MSG_LAST_FILE_FOUND="Dernier fichier source trouvé: %s%3.3u.xtm\n"
++ readonly 'MSG_LAST_FILE_FOUND=Dernier fichier source trouvé: %s%3.3u.xtm\n'
++ MSG_LAST_FILE_FOUND='Dernier fichier source trouvé: %s%3.3u.xtm\n'
readonly MSG_FILE_SIZES_OK="Tailles premier et dernier fichier cohérentes."
++ readonly 'MSG_FILE_SIZES_OK=Tailles premier et dernier fichier cohérentes.'
++ MSG_FILE_SIZES_OK='Tailles premier et dernier fichier cohérentes.'
readonly MSG_FILE_SIZES_ERROR="Premier ou dernier fichier de taille incohérente."
++ readonly 'MSG_FILE_SIZES_ERROR=Premier ou dernier fichier de taille incohérente.'
++ MSG_FILE_SIZES_ERROR='Premier ou dernier fichier de taille incohérente.'
readonly MSG_NO_FILE_WRITTEN="Aucun fichier résultat ne sera écrit car l'option \E[1;32m-m\E[0m est spécifiée."
++ readonly 'MSG_NO_FILE_WRITTEN=Aucun fichier résultat ne sera écrit car l'\''option \E[1;32m-m\E[0m est spécifiée.'
++ MSG_NO_FILE_WRITTEN='Aucun fichier résultat ne sera écrit car l'\''option \E[1;32m-m\E[0m est spécifiée.'
readonly MSG_COMPUTING_DEST="Détermination de l'emplacement du résultat..."
++ readonly 'MSG_COMPUTING_DEST=Détermination de l'\''emplacement du résultat...'
++ MSG_COMPUTING_DEST='Détermination de l'\''emplacement du résultat...'
readonly MSG_DISPLAY_DEST="Emplacement du résultat :"
++ readonly 'MSG_DISPLAY_DEST=Emplacement du résultat :'
++ MSG_DISPLAY_DEST='Emplacement du résultat :'
readonly MSG_CHECK_DEST_WRITABLE="Vérification de la possibilité d'écrire le résultat : existence, autorisation d'écriture, espace disponible, etc..."
++ readonly 'MSG_CHECK_DEST_WRITABLE=Vérification de la possibilité d'\''écrire le résultat : existence, autorisation d'\''écriture, espace disponible, etc...'
++ MSG_CHECK_DEST_WRITABLE='Vérification de la possibilité d'\''écrire le résultat : existence, autorisation d'\''écriture, espace disponible, etc...'
readonly MSG_WARN_FORCED_OVERWRITE="\nEcrasement forcé par l'option \E[1;32m-f\E[0m, le fichier résultat existe déjà ."
++ readonly 'MSG_WARN_FORCED_OVERWRITE=\nEcrasement forcé par l'\''option \E[1;32m-f\E[0m, le fichier résultat existe déjà .'
++ MSG_WARN_FORCED_OVERWRITE='\nEcrasement forcé par l'\''option \E[1;32m-f\E[0m, le fichier résultat existe déjà .'
readonly MSG_WARN_OVERWRITE="\nLe fichier : %s existe déjà .\n"
++ readonly 'MSG_WARN_OVERWRITE=\nLe fichier : %s existe déjà .\n'
++ MSG_WARN_OVERWRITE='\nLe fichier : %s existe déjà .\n'
readonly MSG_FILE_SIZE_MATCHES="La taille du fichier correspond au résultat prévu dans le xtm."
++ readonly 'MSG_FILE_SIZE_MATCHES=La taille du fichier correspond au résultat prévu dans le xtm.'
++ MSG_FILE_SIZE_MATCHES='La taille du fichier correspond au résultat prévu dans le xtm.'
readonly MSG_FILE_SIZE_DOES_NOT_MATCH="La taille du fichier ne correspond pas au résultat prévu dans le xtm."
++ readonly 'MSG_FILE_SIZE_DOES_NOT_MATCH=La taille du fichier ne correspond pas au résultat prévu dans le xtm.'
++ MSG_FILE_SIZE_DOES_NOT_MATCH='La taille du fichier ne correspond pas au résultat prévu dans le xtm.'
readonly MSG_OVERWRITE_HINT="Si vous désirez ré-écrire ce fichier effacez/renommez-le au préalable ou spécifiez l'option \E[1;32m-f\E[0m pour forcer l'écrasement"
++ readonly 'MSG_OVERWRITE_HINT=Si vous désirez ré-écrire ce fichier effacez/renommez-le au préalable ou spécifiez l'\''option \E[1;32m-f\E[0m pour forcer l'\''écrasement'
++ MSG_OVERWRITE_HINT='Si vous désirez ré-écrire ce fichier effacez/renommez-le au préalable ou spécifiez l'\''option \E[1;32m-f\E[0m pour forcer l'\''écrasement'
readonly MSG_WRITE_ERROR="Ecriture de : %s impossible.\nVeuillez vérifier que vous avez l'autorisation d'écrire ce fichier et que son nom est correct.\n"
++ readonly 'MSG_WRITE_ERROR=Ecriture de : %s impossible.\nVeuillez vérifier que vous avez l'\''autorisation d'\''écrire ce fichier et que son nom est correct.\n'
++ MSG_WRITE_ERROR='Ecriture de : %s impossible.\nVeuillez vérifier que vous avez l'\''autorisation d'\''écrire ce fichier et que son nom est correct.\n'
readonly MSG_INSUFFICIENT_SPACE="Espace insuffisant sur %s pour créer le fichier %s.\nEspace nécessaire : %'u\nEspace disponible : %'u\n"
++ readonly 'MSG_INSUFFICIENT_SPACE=Espace insuffisant sur %s pour créer le fichier %s.\nEspace nécessaire : %'\''u\nEspace disponible : %'\''u\n'
++ MSG_INSUFFICIENT_SPACE='Espace insuffisant sur %s pour créer le fichier %s.\nEspace nécessaire : %'\''u\nEspace disponible : %'\''u\n'
readonly MSG_CHUNKS_AVAIL="fichiers déjà traités."
++ readonly 'MSG_CHUNKS_AVAIL=fichiers déjà traités.'
++ MSG_CHUNKS_AVAIL='fichiers déjà traités.'
readonly MSG_INFO_DELETED_OLD_FILE="Fichier partiel incohérent supprimé par option \E[1;32m-f\E[0m"
++ readonly 'MSG_INFO_DELETED_OLD_FILE=Fichier partiel incohérent supprimé par option \E[1;32m-f\E[0m'
++ MSG_INFO_DELETED_OLD_FILE='Fichier partiel incohérent supprimé par option \E[1;32m-f\E[0m'
readonly MSG_INCOHERENT_PARTIAL_FILE="La taille du fichier partiel n'est pas un multiple de la taille de découpage des fichiers xtm.\nSupprimez ce fichier (%s.part) ou utilisez l'option \E[1;32m-f\E[0m\n"
++ readonly 'MSG_INCOHERENT_PARTIAL_FILE=La taille du fichier partiel n'\''est pas un multiple de la taille de découpage des fichiers xtm.\nSupprimez ce fichier (%s.part) ou utilisez l'\''option \E[1;32m-f\E[0m\n'
++ MSG_INCOHERENT_PARTIAL_FILE='La taille du fichier partiel n'\''est pas un multiple de la taille de découpage des fichiers xtm.\nSupprimez ce fichier (%s.part) ou utilisez l'\''option \E[1;32m-f\E[0m\n'
readonly MSG_ALL_CHECKED_OK="Vérifications pour le fichier résultat terminées."
++ readonly 'MSG_ALL_CHECKED_OK=Vérifications pour le fichier résultat terminées.'
++ MSG_ALL_CHECKED_OK='Vérifications pour le fichier résultat terminées.'
readonly MSG_PROCESSING_START="\E[1mTraitement optimisé des %u fichiers\E[0m\n"
++ readonly 'MSG_PROCESSING_START=\E[1mTraitement optimisé des %u fichiers\E[0m\n'
++ MSG_PROCESSING_START='\E[1mTraitement optimisé des %u fichiers\E[0m\n'
readonly MSG_PROCESSING_RESTART="\E[1mReprise du traitement à partir du fichier %u\E[0m\nReste à traiter %u fichier(s)\n"
++ readonly 'MSG_PROCESSING_RESTART=\E[1mReprise du traitement à partir du fichier %u\E[0m\nReste à traiter %u fichier(s)\n'
++ MSG_PROCESSING_RESTART='\E[1mReprise du traitement à partir du fichier %u\E[0m\nReste à traiter %u fichier(s)\n'
readonly MSG_SEPARATOR="=================================="
++ readonly MSG_SEPARATOR===================================
++ MSG_SEPARATOR===================================
readonly MSG_PROCESSING_FILE="Traitement de %s%3.3u.xtm ... "
++ readonly 'MSG_PROCESSING_FILE=Traitement de %s%3.3u.xtm ... '
++ MSG_PROCESSING_FILE='Traitement de %s%3.3u.xtm ... '
readonly MSG_FILE_MISSING="*** Le fichier est manquant ou de taille incorrecte."
++ readonly 'MSG_FILE_MISSING=*** Le fichier est manquant ou de taille incorrecte.'
++ MSG_FILE_MISSING='*** Le fichier est manquant ou de taille incorrecte.'
readonly MSG_FILE_MISSING_TIP="*** Relancez le programme lorsque le fichier sera complet."
++ readonly 'MSG_FILE_MISSING_TIP=*** Relancez le programme lorsque le fichier sera complet.'
++ MSG_FILE_MISSING_TIP='*** Relancez le programme lorsque le fichier sera complet.'
readonly E_BAD_OPTION=65
++ readonly E_BAD_OPTION=65
++ E_BAD_OPTION=65
readonly E_UNKNOWN_OPTION=66
++ readonly E_UNKNOWN_OPTION=66
++ E_UNKNOWN_OPTION=66
readonly E_TOO_MANY_PARAMS=67
++ readonly E_TOO_MANY_PARAMS=67
++ E_TOO_MANY_PARAMS=67
readonly E_UNSPECIFIED_SOURCE_FILE=68
++ readonly E_UNSPECIFIED_SOURCE_FILE=68
++ E_UNSPECIFIED_SOURCE_FILE=68
readonly E_MSG_OPTION_M_AND_N=69
++ readonly E_MSG_OPTION_M_AND_N=69
++ E_MSG_OPTION_M_AND_N=69
readonly E_FIRST_FILE_ERROR=80
++ readonly E_FIRST_FILE_ERROR=80
++ E_FIRST_FILE_ERROR=80
readonly E_LAST_FILE_ERROR=81
++ readonly E_LAST_FILE_ERROR=81
++ E_LAST_FILE_ERROR=81
readonly E_FILE_SIZES_ERROR=82
++ readonly E_FILE_SIZES_ERROR=82
++ E_FILE_SIZES_ERROR=82
readonly E_WRITE_ERROR=83
++ readonly E_WRITE_ERROR=83
++ E_WRITE_ERROR=83
readonly E_INSUFFICIENT_SPACE=83
++ readonly E_INSUFFICIENT_SPACE=83
++ E_INSUFFICIENT_SPACE=83
readonly E_INCOHERENT_PARTIAL_FILE=84
++ readonly E_INCOHERENT_PARTIAL_FILE=84
++ E_INCOHERENT_PARTIAL_FILE=84
readonly E_WARN_OVERWRITE=96
++ readonly E_WARN_OVERWRITE=96
++ E_WARN_OVERWRITE=96
readonly E_CRITICAL_ERROR=127
++ readonly E_CRITICAL_ERROR=127
++ E_CRITICAL_ERROR=127
#==========================================================
# Utility functions
# usage : affiche l'usage/aide du script
# v_echo : affichage pour l'option verbeux
usage()
{
if [ -n "$1" ]; then echo "$1"; fi
cat <<EOF
Usage : tuXtremMerge [Options] Source [Destination]
Source : le fichier source, généralement de la forme [chemin/]fichier.001.xtm
On peut cependant indiquer n'importe lequel des xtm de la série, par
exemple fichier.007.xtm
Destination : nom du fichier destination souhaité.
Si la destination est un répertoire existant, le fichier résultat sera
stocké dans ce répertoire, avec le nom indiqué au découpage en xtm.
Par défaut, le fichier résultat est stocké dans le répertoire du
fichier source et porte le nom indiqué lors du découpage en xtm.
Options :
-h Affiche le présent message d'aide.
-n Ne vérifie pas les md5 (concaténation sans vérifier).
-m Vérifie seulement les md5 (pas de concaténation)
-f Force l'écriture du fichier résultat.
Si un fichier existe déjà il est écrasé.
-v Verbeux. Permet aussi de diagnostiquer les incohérences entre options.
-t Temps. Affiche les heures de début et fin de traitement.
Doublé (tt) affiche davantage de temps intermédiaires.
-V Affiche la version du script.
ASTUCE :
Dans tous les cas, le premier et le dernier fichier sont nécessaires pour
que le script puisse au moins commencer à assembler. S'il s'agit de fichiers
téléchargés, veillez donc à récupérer ces deux fichiers en priorité.
EOF
}
v_echo()
{
if [ $OPTION_v ]; then echo -e "*** $1"; fi
}
#______________________________
# Function that scan parameters
# It works with style: -a -v
# but also BSD style : -av
scan_parameters()
{
for param in "$@"
do
case "$param" in
-* )
if [ "$param" == "-" ]; then
usage "$MSG_BAD_OPTION"
exit $E_BAD_OPTION
fi
i=1
while [ $i -lt ${#param} ]
do
case ${param:$i:1} in
h )
usage
exit 0
;;
m )
OPTION_m='1'
;;
n )
OPTION_n='1'
;;
f )
OPTION_f='1'
;;
t )
if [ ${param:$i:2} = 'tt' ]; then
OPTION_t='2'
i=$(( $i + 1 ))
else
OPTION_t='1'
fi
;;
v )
OPTION_v='1'
;;
V )
if [ -n "$MSG_BUSY_VERSION" ]; then
echo "$MSG_BUSY_VERSION"
fi
echo "$MSG_VERSION"
exit 0
;;
* )
usage "$MSG_UNKNOWN_OPTION -${param:$i:1}"
exit $E_UNKNOWN_OPTION
;;
esac
i=$(( $i + 1 ))
done
;;
*)
if [ -z "$DISPLAY_SOURCE_FILE_NAME" ]; then
DISPLAY_SOURCE_FILE_NAME="$param"
elif [ -z "$DISPLAY_DEST_FILE_NAME" ]; then
DISPLAY_DEST_FILE_NAME="$param"
else
usage "$MSG_TOO_MANY_PARAMS $param"
exit $E_TOO_MANY_PARAMS
fi
;;
esac
done
if [ -z "$DISPLAY_SOURCE_FILE_NAME" ]; then
usage "$MSG_UNSPECIFIED_SOURCE_FILE"
exit $E_UNSPECIFIED_SOURCE_FILE
else
SOURCE_FILE_NAME=$( readlink -f "$DISPLAY_SOURCE_FILE_NAME" )
fi
}
#_________________________________
# Functions that check parameters
# and give some warnings or errors
# if things are not correct
check_parameters()
{
if [ $OPTION_m ]; then
if [ $OPTION_n ]; then
echo -e "$MSG_ERROR$MSG_OPTION_M_AND_N"
exit $E_MSG_OPTION_M_AND_N
fi
if [ $OPTION_f ]; then
v_echo "$MSG_IGNORING_OPTION_F"
fi
if [ -n "$DISPLAY_DEST_FILE_NAME" ]; then
v_echo "$MSG_IGNORING_DEST"
fi
fi
}
success()
{
if [ ! $OPTION_m ]; then
# If we mv directly it appears that system syncs, and so the script appears to run longer
#+ When we rm the file first, the async write continues after the script ends.
rm "$DEST_FILE_NAME"
mv "$DEST_FILE_NAME_PART" "$DEST_FILE_NAME"
fi
echo -e "$MSG_SUCCESS"
timing 1
exit 0
}
tip()
{
echo -e "$MSG_TIP"
exit $1
}
nop()
{
cat - >/dev/null
}
timing()
{
if [ $OPTION_t -ge $1 ]; then date +%T.%N; fi
}
#==========================================================
# START OF THE MAIN PROGRAM HERE !
# /TODO
# -> Traiter les interruptions (Ctrl-C) et erreurs par un truncate (au lieu de supprimer)
#_________________________________________
# Variables declaration and initialisation
declare -i i size SOURCE_FILE_NB DEST_FILE_NAME_LENGTH SPACE_AVAIL DISK_SPACE_NEEDED DEST_FILE_SIZE CHUNK_SIZE CHUNKS_AVAIL fMD5 LAST_SOURCE_FILE_SIZE
++ declare -i i size SOURCE_FILE_NB DEST_FILE_NAME_LENGTH SPACE_AVAIL DISK_SPACE_NEEDED DEST_FILE_SIZE CHUNK_SIZE CHUNKS_AVAIL fMD5 LAST_SOURCE_FILE_SIZE
OPTION_m=''
++ OPTION_m=
OPTION_n=''
++ OPTION_n=
OPTION_f=''
++ OPTION_f=
OPTION_v=''
++ OPTION_v=
declare -i OPTION_t=0
++ declare -i OPTION_t=0
DISPLAY_SOURCE_FILE_NAME=''
++ DISPLAY_SOURCE_FILE_NAME=
DISPLAY_DEST_FILE_NAME=''
++ DISPLAY_DEST_FILE_NAME=
CHUNKS_AVAIL=0
++ CHUNKS_AVAIL=0
scan_parameters "$@"
++ scan_parameters -v 2.pdf.001.xtm
++ for param in '"$@"'
++ case "$param" in
++ '[' -v == - ']'
++ i=1
++ '[' 1 -lt 2 ']'
++ case ${param:$i:1} in
++ OPTION_v=1
++ i=2
++ '[' 2 -lt 2 ']'
++ for param in '"$@"'
++ case "$param" in
++ '[' -z '' ']'
++ DISPLAY_SOURCE_FILE_NAME=2.pdf.001.xtm
++ '[' -z 2.pdf.001.xtm ']'
readlink -f "$DISPLAY_SOURCE_FILE_NAME"
+++ readlink -f 2.pdf.001.xtm
+++ '[' -h 2.pdf.001.xtm ']'
+++ target=2.pdf.001.xtm
cd $(dirname "$target"); pwd
dirname "$target"
+++++ dirname 2.pdf.001.xtm
++++ cd .
++++ pwd
+++ temp=/volume1/DATA/Incoming/Torrent/1
+++ '[' /volume1/DATA/Incoming/Torrent/1 '!=' / ']'
+++ temp=/volume1/DATA/Incoming/Torrent/1/
+++ echo -n /volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
++ SOURCE_FILE_NAME=/volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
timing 1
++ timing 1
++ '[' 0 -ge 1 ']'
if [ ! $OPTION_v ]; then
echo -n "$MSG_CHECKING"
fi
++ '[' '!' 1 ']'
check_parameters
++ check_parameters
++ '[' ']'
#==========================================================
# Checking file existence
# - On commence par vérifier le 001 qui contient le header
v_echo "$MSG_CHECKING_FIRST_SOURCE_FILE"
++ v_echo 'Vérification d'\''existence du premier fichier source...'
++ '[' 1 ']'
++ echo -e '*** Vérification d'\''existence du premier fichier source...'
*** Vérification d'existence du premier fichier source...
RADIX=$( echo "$SOURCE_FILE_NAME" | sed 's/...\.xtm$//' )
echo "$SOURCE_FILE_NAME" | sed 's/...\.xtm$//'
+++ echo /volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
+++ sed 's/...\.xtm$//'
++ RADIX=/volume1/DATA/Incoming/Torrent/1/2.pdf.
DISPLAY_RADIX=$( echo "$DISPLAY_SOURCE_FILE_NAME" | sed 's/...\.xtm$//' )
echo "$DISPLAY_SOURCE_FILE_NAME" | sed 's/...\.xtm$//'
+++ echo 2.pdf.001.xtm
+++ sed 's/...\.xtm$//'
++ DISPLAY_RADIX=2.pdf.
FIRST_SOURCE_FILE_NAME="${RADIX}001.xtm"
++ FIRST_SOURCE_FILE_NAME=/volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
if [ ! -f "$FIRST_SOURCE_FILE_NAME" ] || [ ! -s "$FIRST_SOURCE_FILE_NAME" ]; then
echo -e "$MSG_ERROR$DISPLAY_RADIX$MSG_FIRST_FILE_ERROR"
tip $E_FIRST_FILE_ERROR
else
v_echo "$MSG_FIRST_FILE_FOUND ${DISPLAY_RADIX}001.xtm"
fi
++ '[' '!' -f /volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm ']'
++ '[' '!' -s /volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm ']'
++ v_echo 'Premier fichier source trouvé : 2.pdf.001.xtm'
++ '[' 1 ']'
++ echo -e '*** Premier fichier source trouvé : 2.pdf.001.xtm'
*** Premier fichier source trouvé : 2.pdf.001.xtm
fMD5=$( od -An -vtu1 -j91 -N1 "$FIRST_SOURCE_FILE_NAME" )
od -An -vtu1 -j91 -N1 "$FIRST_SOURCE_FILE_NAME"
+++ od -An -vtu1 -j91 -N1 /volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
++ fMD5=' 1'
#==========================================================
# Checking if MD5 is included in that xtm
# If not and only a MD5 check is asked (option -m) exit with message
if [ $fMD5 -eq 0 ] && [ $OPTION_m ]; then
echo -e "$MSG_OPTION_M_AND_NO_MD5"
exit 0
fi
++ '[' 1 -eq 0 ']'
CHUNK_SIZE=$(( $( stat -c%s "$FIRST_SOURCE_FILE_NAME" ) - 104 ))
stat -c%s "$FIRST_SOURCE_FILE_NAME"
+++ stat -c%s /volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
+++ ls -l /volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
+++ cut '-d ' -f 5
+++ tr -s '[:blank:]'
++ CHUNK_SIZE=885984
SOURCE_FILE_NB=$( od -An -vtu4 -j92 -N4 "$FIRST_SOURCE_FILE_NAME" )
od -An -vtu4 -j92 -N4 "$FIRST_SOURCE_FILE_NAME"
+++ od -An -vtu4 -j92 -N4 /volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
++ SOURCE_FILE_NB=' 15'
DEST_FILE_SIZE=$( od -An -vtu8 -j96 -N8 "$FIRST_SOURCE_FILE_NAME" )
od -An -vtu8 -j96 -N8 "$FIRST_SOURCE_FILE_NAME"
+++ od -An -vtu8 -j96 -N8 /volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
++ DEST_FILE_SIZE=' 13289755'
#---------------------------------
# - On vérifie le dernier fichier
# => Dans le cas de MD5, celui-ci contient les MD5
# => Dans le cas non-MD5, cela sert à vérifier au moins la cohérence de taille des fichiers
v_echo "$MSG_CHECKING_LAST_SOURCE_FILE"
++ v_echo 'Vérification d'\''existence du dernier fichier source...'
++ '[' 1 ']'
++ echo -e '*** Vérification d'\''existence du dernier fichier source...'
*** Vérification d'existence du dernier fichier source...
LAST_SOURCE_FILE_NAME=$( printf "${RADIX}%3.3u.xtm" $SOURCE_FILE_NB )
printf "${RADIX}%3.3u.xtm" $SOURCE_FILE_NB
+++ printf /volume1/DATA/Incoming/Torrent/1/2.pdf.%3.3u.xtm 15
++ LAST_SOURCE_FILE_NAME=/volume1/DATA/Incoming/Torrent/1/2.pdf.015.xtm
if [ ! -f "$LAST_SOURCE_FILE_NAME" ] || [ ! -s "$LAST_SOURCE_FILE_NAME" ]; then
printf "$MSG_ERROR$MSG_LAST_FILE_ERROR" "$DISPLAY_RADIX" $SOURCE_FILE_NB
tip $E_LAST_FILE_ERROR
else
v_echo "$( printf "$MSG_LAST_FILE_FOUND" "$DISPLAY_RADIX" $SOURCE_FILE_NB )"
fi
++ '[' '!' -f /volume1/DATA/Incoming/Torrent/1/2.pdf.015.xtm ']'
++ '[' '!' -s /volume1/DATA/Incoming/Torrent/1/2.pdf.015.xtm ']'
printf "$MSG_LAST_FILE_FOUND" "$DISPLAY_RADIX" $SOURCE_FILE_NB
+++ printf 'Dernier fichier source trouvé: %s%3.3u.xtm\n' 2.pdf. 15
++ v_echo 'Dernier fichier source trouvé: 2.pdf.015.xtm'
++ '[' 1 ']'
++ echo -e '*** Dernier fichier source trouvé: 2.pdf.015.xtm'
*** Dernier fichier source trouvé: 2.pdf.015.xtm
LAST_SOURCE_FILE_SIZE=$(( $( stat -c%s "$LAST_SOURCE_FILE_NAME" ) - $fMD5 * $SOURCE_FILE_NB * 32 ))
stat -c%s "$LAST_SOURCE_FILE_NAME"
+++ stat -c%s /volume1/DATA/Incoming/Torrent/1/2.pdf.015.xtm
+++ ls -l /volume1/DATA/Incoming/Torrent/1/2.pdf.015.xtm
+++ tr -s '[:blank:]'
+++ cut '-d ' -f 5
++ LAST_SOURCE_FILE_SIZE=885979
if [ $(( $CHUNK_SIZE * ($SOURCE_FILE_NB - 1) + $LAST_SOURCE_FILE_SIZE )) -eq $DEST_FILE_SIZE ]; then
v_echo "$MSG_FILE_SIZES_OK"
else
echo -e "$MSG_ERROR$MSG_FILE_SIZES_ERROR"
tip $E_FILE_SIZES_ERROR
fi
++ '[' 13289755 -eq 13289755 ']'
++ v_echo 'Tailles premier et dernier fichier cohérentes.'
++ '[' 1 ']'
++ echo -e '*** Tailles premier et dernier fichier cohérentes.'
*** Tailles premier et dernier fichier cohérentes.
#==========================================================
# From here we have first and last file, we can do something!
# Checking output file
# - Vérifie qu'on ne va pas écraser un fichier (si option -f, juste message verbeux)
# - Vérifie qu'on peut bien écrire le fichier (autorisation, nom/chemin correct)
# - Vérifie qu'on a la place d'écrire le fichier
#
# Mais on commence par déterminer le nom du fichier résultat
# Ca dépend de plusieurs choses :
# - si un fichier destination a été spécifié en paramètre
# + et si c'est le cas, si c'est un répertoire existant ou pas
if [ $OPTION_m ]; then
v_echo "$MSG_NO_FILE_WRITTEN"
else
v_echo "$MSG_COMPUTING_DEST"
if [ -z "$DISPLAY_DEST_FILE_NAME" ] || [ -d "$DISPLAY_DEST_FILE_NAME" ]; then
DEST_FILE_NAME_LENGTH=$( od -An -vtu1 -j40 -N1 "$FIRST_SOURCE_FILE_NAME" )
DEFAULT_DEST_FILE_NAME=$( dd bs=1 skip=41 count=$DEST_FILE_NAME_LENGTH if="$FIRST_SOURCE_FILE_NAME" 2>/dev/null)
if [ -z "$DISPLAY_DEST_FILE_NAME" ]; then
this_file_radix=${DISPLAY_SOURCE_FILE_NAME%${DISPLAY_SOURCE_FILE_NAME##*/}}
else # Ici DISPLAY_DEST_FILE_NAME est forcément un répertoire
# on rajoute le / final si nécessaire
if [ ${DISPLAY_DEST_FILE_NAME:(-1)} == '/' ]; then
this_file_radix="$DISPLAY_DEST_FILE_NAME"
else
this_file_radix="$DISPLAY_DEST_FILE_NAME/"
fi
fi
DISPLAY_DEST_FILE_NAME="$this_file_radix$DEFAULT_DEST_FILE_NAME"
fi
v_echo "$MSG_DISPLAY_DEST $DISPLAY_DEST_FILE_NAME"
DEST_FILE_NAME=$( readlink -fn "$DISPLAY_DEST_FILE_NAME" )
DEST_FILE_NAME_PART="${DEST_FILE_NAME}.part"
#---------------------------------
# Vérifications de la possibilité d'écrire le fichier résultat
v_echo "$MSG_CHECK_DEST_WRITABLE"
if [ -f "$DEST_FILE_NAME" ] && [ -s "$DEST_FILE_NAME" ]; then
if [ $OPTION_f ]; then
v_echo "$MSG_ATTENTION$MSG_WARN_FORCED_OVERWRITE"
else
size=$( stat -c%s "$DEST_FILE_NAME" )
if [ $size -eq $DEST_FILE_SIZE ]; then
printf "$MSG_ATTENTION$MSG_WARN_OVERWRITE" $DISPLAY_DEST_FILE_NAME
echo "$MSG_FILE_SIZE_MATCHES"
else
printf "$MSG_ERROR$MSG_WARN_OVERWRITE" $DISPLAY_DEST_FILE_NAME
echo "$MSG_FILE_SIZE_DOES_NOT_MATCH"
fi
echo -e "$MSG_OVERWRITE_HINT"
exit $E_WARN_OVERWRITE
fi
fi
touch "$DEST_FILE_NAME" "$DEST_FILE_NAME_PART" 2>/dev/null
if [ $? -ne 0 ]; then
printf "$MSG_ERROR$MSG_WRITE_ERROR" $DISPLAY_DEST_FILE_NAME
exit $E_WRITE_ERROR
fi
TMP=$( df "$DEST_FILE_NAME" | sed -n '2p' )
SPACE_AVAIL=$(( $( echo $TMP | cut -d' ' -f 4 ) * 1024 - 1024))
v_echo "Espace disponible : $SPACE_AVAIL, sur $( echo $TMP | cut -d' ' -f 6 )"
size=$( stat -c%s "$DEST_FILE_NAME_PART" )
DISK_SPACE_NEEDED=$(( $DEST_FILE_SIZE - $size ))
if [ $DISK_SPACE_NEEDED == 0 ]; then
success
fi
if [ $SPACE_AVAIL -lt $DISK_SPACE_NEEDED ]; then
printf "$MSG_ERROR$MSG_INSUFFICIENT_SPACE" $( echo $TMP | cut -d' ' -f 6 ) "$DISPLAY_DEST_FILE_NAME" $DISK_SPACE_NEEDED $SPACE_AVAIL
exit $E_INSUFFICIENT_SPACE
fi
CHUNKS_AVAIL=$(( $size / $CHUNK_SIZE ))
if [ $(( $size % $CHUNK_SIZE )) -eq 0 ]; then
v_echo "$CHUNKS_AVAIL $MSG_CHUNKS_AVAIL"
else
if [ $OPTION_f ]; then
v_echo "$MSG_INFO_DELETED_OLD_FILE"
rm "$DEST_FILE_NAME_PART" 2>/dev/null
CHUNKS_AVAIL=0
else
printf "$MSG_ERROR$MSG_INCOHERENT_PARTIAL_FILE" $DISPLAY_DEST_FILE_NAME
exit $E_INCOHERENT_PARTIAL_FILE
fi
fi
v_echo "$MSG_ALL_CHECKED_OK"
fi
++ '[' ']'
++ v_echo 'Détermination de l'\''emplacement du résultat...'
++ '[' 1 ']'
++ echo -e '*** Détermination de l'\''emplacement du résultat...'
*** Détermination de l'emplacement du résultat...
++ '[' -z '' ']'
od -An -vtu1 -j40 -N1 "$FIRST_SOURCE_FILE_NAME"
+++ od -An -vtu1 -j40 -N1 /volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
++ DEST_FILE_NAME_LENGTH=' 22'
dd bs=1 skip=41 count=$DEST_FILE_NAME_LENGTH if="$FIRST_SOURCE_FILE_NAME" 2>/dev/null
+++ dd bs=1 skip=41 count=22 if=/volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm
++ DEFAULT_DEST_FILE_NAME=TX-SR603_FrEs_0426.pdf
++ '[' -z '' ']'
++ this_file_radix=
++ DISPLAY_DEST_FILE_NAME=TX-SR603_FrEs_0426.pdf
++ v_echo 'Emplacement du résultat : TX-SR603_FrEs_0426.pdf'
++ '[' 1 ']'
++ echo -e '*** Emplacement du résultat : TX-SR603_FrEs_0426.pdf'
*** Emplacement du résultat : TX-SR603_FrEs_0426.pdf
readlink -fn "$DISPLAY_DEST_FILE_NAME"
+++ readlink -fn TX-SR603_FrEs_0426.pdf
+++ '[' -h TX-SR603_FrEs_0426.pdf ']'
+++ target=TX-SR603_FrEs_0426.pdf
cd $(dirname "$target"); pwd
dirname "$target"
+++++ dirname TX-SR603_FrEs_0426.pdf
++++ cd .
++++ pwd
+++ temp=/volume1/DATA/Incoming/Torrent/1
+++ '[' /volume1/DATA/Incoming/Torrent/1 '!=' / ']'
+++ temp=/volume1/DATA/Incoming/Torrent/1/
+++ echo -n /volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf
++ DEST_FILE_NAME=/volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf
++ DEST_FILE_NAME_PART=/volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf.part
++ v_echo 'Vérification de la possibilité d'\''écrire le résultat : existence, autorisation d'\''écriture, espace disponible, etc...'
++ '[' 1 ']'
++ echo -e '*** Vérification de la possibilité d'\''écrire le résultat : existence, autorisation d'\''écriture, espace disponible, etc...'
*** Vérification de la possibilité d'écrire le résultat : existence, autorisation d'écriture, espace disponible, etc...
++ '[' -f /volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf ']'
++ touch /volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf /volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf.part
++ '[' 0 -ne 0 ']'
df "$DEST_FILE_NAME" | sed -n '2p'
+++ df /volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf
+++ sed -n 2p
++ TMP='/dev/vg1/lv 5749954288 1722118308 4027733580 30% /volume1'
echo $TMP | cut -d' ' -f 4
+++ echo /dev/vg1/lv 5749954288 1722118308 4027733580 30% /volume1
+++ cut '-d ' -f 4
++ SPACE_AVAIL=4124399184896
echo $TMP | cut -d' ' -f 6
+++ echo /dev/vg1/lv 5749954288 1722118308 4027733580 30% /volume1
+++ cut '-d ' -f 6
++ v_echo 'Espace disponible : 4124399184896, sur /volume1'
++ '[' 1 ']'
++ echo -e '*** Espace disponible : 4124399184896, sur /volume1'
*** Espace disponible : 4124399184896, sur /volume1
stat -c%s "$DEST_FILE_NAME_PART"
+++ stat -c%s /volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf.part
+++ ls -l /volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf.part
+++ tr -s '[:blank:]'
+++ cut '-d ' -f 5
++ size=0
++ DISK_SPACE_NEEDED=13289755
++ '[' 13289755 == 0 ']'
++ '[' 4124399184896 -lt 13289755 ']'
++ CHUNKS_AVAIL=0
++ '[' 0 -eq 0 ']'
++ v_echo '0 fichiers déjà traités.'
++ '[' 1 ']'
++ echo -e '*** 0 fichiers déjà traités.'
*** 0 fichiers déjà traités.
++ v_echo 'Vérifications pour le fichier résultat terminées.'
++ '[' 1 ']'
++ echo -e '*** Vérifications pour le fichier résultat terminées.'
*** Vérifications pour le fichier résultat terminées.
#==========================================================
# The Real work starts here!
# - Toutes les vérifications et préparations étant finies on commence
# la concaténation/checksum à proprement parler
if [ $OPTION_m ]; then
DEST_FILE_NAME_PART="/dev/null"
fi
++ '[' ']'
if [ $fMD5 -eq 0 ] || [ $OPTION_n ]; then
MD5_PROG="nop"
else
MD5_PROG="md5sum"
fi
++ '[' 1 -eq 0 ']'
++ '[' ']'
++ MD5_PROG=md5sum
if [ ! $OPTION_v ]; then
echo -e "$MSG_OK"
fi
++ '[' '!' 1 ']'
timing 1
++ timing 1
++ '[' 0 -ge 1 ']'
if [ $CHUNKS_AVAIL -eq 0 ]; then
printf "$MSG_PROCESSING_START" $SOURCE_FILE_NB
else
printf "$MSG_PROCESSING_RESTART" $(( $CHUNKS_AVAIL + 1 )) $(( $SOURCE_FILE_NB - $CHUNKS_AVAIL ))
fi
++ '[' 0 -eq 0 ']'
++ printf '\E[1mTraitement optimisé des %u fichiers\E[0m\n' 15
Traitement optimisé des 15 fichiers
echo "$MSG_SEPARATOR"
++ echo ==================================
==================================
i=$CHUNKS_AVAIL
++ i=0
while (( $i < $SOURCE_FILE_NB )) ; do
if [ $fMD5 -eq 1 ]; then
this_file_MD5=$( dd bs=1 skip=$(( $LAST_SOURCE_FILE_SIZE + $i * 32)) count=32 if="$LAST_SOURCE_FILE_NAME" 2>/dev/null )
fi
i=$(( $i + 1 ))
this_file_radix=$( printf "%s%3.3u" "$RADIX" $i )
printf "$MSG_PROCESSING_FILE" "$DISPLAY_RADIX" $i
case $i in
1 )
# Pour le premier fichier on ne 'tee' pas les 104 premiers octets, mais ils rentrent dans le md5
{ dd if="$this_file_radix.xtm" bs=104 count=1 2>/dev/null &&
dd if="$this_file_radix.xtm" ibs=104 obs=4096 skip=1 2>/dev/null | tee "$DEST_FILE_NAME_PART";
} | $MD5_PROG --status -c <(echo "$this_file_MD5 *-")
;;
$SOURCE_FILE_NB )
# Pour le dernier fichier on enlève les octets de MD5 (ou pas... s'il n'y en a pas !)
dd if="$this_file_radix.xtm" ibs=$LAST_SOURCE_FILE_SIZE obs=4096 count=1 2>/dev/null | \
tee -a "$DEST_FILE_NAME_PART" | \
$MD5_PROG --status -c <(echo "$this_file_MD5 *-")
;;
*)
# On vérifie la cohérence de taille du fichier seulement si ce n'est ni le premier
# ni le dernier, car pour c'est deux fichiers, c'est déjà vérifié avant !
size=$( stat -c%s "$this_file_radix.xtm" 2>/dev/null )
if [ $? -ne 0 ] || [ $size -ne $CHUNK_SIZE ]; then
echo -e "$MSG_ATTENTION"
echo "$MSG_FILE_MISSING"
if [ $OPTION_m ]; then
continue
else
echo "$MSG_FILE_MISSING_TIP"
exit $E_WARN_FILE_MISSING
fi
fi
tee -a "$DEST_FILE_NAME_PART" <"$this_file_radix.xtm" | $MD5_PROG --status -c <(echo "$this_file_MD5 *-")
esac
if [ $? -eq 0 ]; then # No error: all is OK
echo -e "$MSG_OK"
else # Error: it means we get an incorrect MD5, a write error, or other bad things, so here we cancel and abort
echo -e "$MSG_ERROR"
if [ ! $OPTION_m ]; then # But we stop only if no option -m.
# If option -m we continue so that we check ALL the files and not stop on the first error
rm "$DEST_FILE_NAME_PART" "$DEST_FILE_NAME" 2>/dev/null
exit $E_CRITICAL_ERROR
fi
fi
timing 2
done
++ (( 0 < 15 ))
++ '[' 1 -eq 1 ']'
dd bs=1 skip=$(( $LAST_SOURCE_FILE_SIZE + $i * 32)) count=32 if="$LAST_SOURCE_FILE_NAME" 2>/dev/null
+++ dd bs=1 skip=885979 count=32 if=/volume1/DATA/Incoming/Torrent/1/2.pdf.015.xtm
++ this_file_MD5=85D2DF1F63D3AF9605865820FB082179
++ i=1
printf "%s%3.3u" "$RADIX" $i
+++ printf %s%3.3u /volume1/DATA/Incoming/Torrent/1/2.pdf. 1
++ this_file_radix=/volume1/DATA/Incoming/Torrent/1/2.pdf.001
++ printf 'Traitement de %s%3.3u.xtm ... ' 2.pdf. 1
Traitement de 2.pdf.001.xtm ... ++ case $i in
++ dd if=/volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm bs=104 count=1
echo "$this_file_MD5 *-"
++ md5sum --status -c /dev/fd/63
+++ echo '85D2DF1F63D3AF9605865820FB082179 *-'
md5sum: /dev/fd/63: No such file or directory
++ dd if=/volume1/DATA/Incoming/Torrent/1/2.pdf.001.xtm ibs=104 obs=4096 skip=1
++ tee /volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf.part
++ '[' 1 -eq 0 ']'
++ echo -e '\E[1;31mErreur\E[0m\n'
Erreur
++ '[' '!' ']'
++ rm /volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf.part /volume1/DATA/Incoming/Torrent/1/TX-SR603_FrEs_0426.pdf
++ exit 127
NAS>