# # TimeStamp (dos) : 10 Juillet 03 11:14 -- x:\sovotw.pl # # sauvegarde des fichiers Windows # attention à la localisation de winzip ! sub syntaxe { # rappel des options print " syntaxe : sovotw disque [ nb_jours [ rep ] stop | -a ]\n\n" ; print " exemples : sovotw C: 1 \n" ; print " sovotw D: 7 /Crs/Stat\n" ; print " sovotw D: 7 /Crs/Stat stop\n" ; print " sovotw C: -a \n" ; print " sovotw V: -a pour Cibox \n" ; print "\n" ; print " en principe, le fichier x:\\sovotw.dates contient \n" ; print " toutes les dates de sauvegarde. \n" ; print "\n" ; } ; # fin sub syntaxe ########################################################### sub attends { # permet d'interrompre en mode "debug" print " ok ? " ; chop($repgh=) ; if (length($repgh)>0) { exit -1 } ; } ; # fin sub attends ########################################################### sub jDa { # donne le jour dans l'année (utilise la globale tdm) return 1 + $_[0] + $tdm[ $_[1] ] ; } ; # fin de sub jDa ########################################################### sub nbjedd { # nombre de jours entre deux dates # exemple : nbjedd(2,1,2000,3,3,2001) renvoie 2 + ( 31-2)+28 ) + 365 ($jd,$md,$ad,$jf,$mf,$af) = @_ ; my $p_d = &jDa($jf,$mf) ; my $l_d = &jDa($jd,$md) ; my $d_a = 365*($af-$ad) ; # print " diff entre jours : $p_d - $l_d années $d_a \n" ; # print " soit ".(1 + &jDa($jf,$mf) - &jDa($jd,$md) + 365*($af-$ad)) ; return 1 + &jDa($jf,$mf) - &jDa($jd,$md) + 365*($af-$ad) ; } ; # fin sub nbjedd ########################################################### sub analyseDirs { # on cherche tous les répertoires puis on les trie $rep = "$_[0]" ; $rep = &ajouteSlash($rep) ; ## chdir($rep) ; opendir(CD,$rep) ; if ($optDbg>=0) { $f_cdir = sprintf("%6d",$cdir) ; $f_nbdir = sprintf("%6d",$nbdir) ; print " $f_cdir / $f_nbdir : $rep \n" ; } ; # fin si debug while ($fic=readdir(CD)) { if ($optDbg>0) { print " $cdir / $nbdir : $rep -> $fic\n" ; } ; if (("*$fic*" ne "*.*") and ("*$fic*" ne "*..*") and ("*$fic*" ne "*RECYCLED*") ) { ##if ((-d $fic) and not (-l $fic)) { # il s'agit d'un répertoire if ((-d $rep.$fic) and not(-l $rep.$fic)) { # il s'agit d'un répertoire $aIgnorer = 0 ; # pour tests rapides # if ("$rep$fic" eq "C:/Program Files") { $aIgnorer = 1 ; }; # if (substr("$rep$fic",0,10) eq uc("C:/Windows")) { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "C:/WINDOWS/SYSTEM") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "C:/WINDOWS/SYSTEM32") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "C:/Tools") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "C:/Aides") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "C:/Users") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "C:/Users/gH/public_html") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "C:/jdk1.2.2") { $aIgnorer = 1 ; }; # fintests rapides # à ignorer sur C: Sony GRX616 if ("$rep$fic" eq "C:/Archives") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Documents and Settings") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Local") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/NewCd") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Program Files/Fichiers communs") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Program Files/RECYCLER") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Program Files/Uninstall Information") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Program Files/eDonkey2000") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/recycler") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/RECYCLER") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/System Volume Information") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Temp") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/temp") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/TEMP") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/TMP") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Tools/Bin/RECYCLER") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Tools/Perl") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Tools/RECYCLER") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Windows") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/WINDOWS") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "C:/Vidéo") { $aIgnorer = 1 ; }; # à ignorer sur D: Sony GRX616 if ("$rep$fic" eq "D:/Archives") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Cache") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/ListeCd") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/NewCd") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Norton") { $aIgnorer = 1 ; }; # en fait Norton Fac --> Sas if ("$rep$fic" eq "D:/Perl") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Program Files/Fichiers communs/Microsoft Shared") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Program Files/Fichiers communs/Microsoft Shared") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Program Files/Uninstall Information") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Program Files/Universalis 8") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/SCANDISK.LOG") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/System Volume Information") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Temp") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Tmp") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Tools/TeX") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Windows") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/WINDOWS") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/Vidéo") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "C:/WINDOWS/Application Data/ACD Systems/ACDSee") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "C:/WINDOWS/Application Data/Mozilla/Users50/gilles.hunault") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "D:/Archives") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "D:/ListeCd") { $aIgnorer = 1 ; }; # if ("$rep$fic" eq "D:/ListeFichiers") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "D:/New") { $aIgnorer = 1 ; }; # pour Cibox if ("$rep$fic" eq "V:/Tools") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "V:/ListeCd") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "V:/WINDOWS") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "V:/VIDEOAS") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "V:/Tmp") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "V:/Temp") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "V:/Program Files") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "V:/Mes documents") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "V:/My Music") { $aIgnorer = 1 ; }; if ("$rep$fic" eq "V:/newCd") { $aIgnorer = 1 ; }; if ($aIgnorer == 0) { $nbdir++ ; $tabDir[$nbdir] = $rep.$fic; if ($optDbg>0) { print " $nbdir : *".$rep.$fic."*\n" ; } ; # fin si debug $tabNomD{$rep.$fic}++ ; } ; # fin de si n ignore certains répertoires } else { if ($optDbg>0) { print " $nbdir : *".$rep.$fic."* n'est pas un répertoire \n" ; } ; # fin si debug } ; # fin de si sur répertoire ou fichier } ; # fin si ce n'est ni . ni .. } ; # fin de tant que on parcourt le répertoire $cdir++ ; if ($optDbg>0) { print " $cdir / $nbdir : FIN DE $rep \n" ; } ; # fin si debug } ; # fin sub analyseDirs ########################################################### sub ajouteSlash { # rajoute un / si besoin est au nom de répertoire if (substr($_[0],-1,1) eq "/") { return $_[0] } else { return "$_[0]/" } ; } ; # fin sub ajouteSlash ########################################################### sub trieDirs { # pour un bel affichage... my $idir ; undef @tabDir ; $idir = 1 ; $tabDir[1] = $repBase ; my $fmt_ndir = sprintf("%6d",$idir) ; my $fmt_nf = &ajouteSlash($repBase) ; if ($optDir>0) { print " $fmt_ndir $fmt_nf \n" ; } foreach $nomD (sort keys %tabNomD) { $idir++ ; $tabDir[$idir] = $nomD ; $fmt_ndir = sprintf("%6d",$idir) ; $fmt_nf = &ajouteSlash($nomD) ; if ($optDir>0) { print " $fmt_ndir $fmt_nf \n" ; } } ; # fin pour chaque nomD $nbdir = $idir ; } ; # fin sub trieDirs ########################################################### sub afficheRep { # voici les fichiers du répertoire $rep = "$_[0]" ; $rep = &ajouteSlash($rep) ; opendir(CD,$rep) ; $optDbg = 0 ; $optDbg2 = 0 ; $optDbgAR = 1 ; if ($optDbg2>0) { print " rép. $cdir / $nbdir : $rep \n" ; &attends() ; } ; # fin si debug # on passe en revue toutes les entrée du répertoire # si c'est un répertoire, on le met dans le tableau gtabNomD # si c'est un fichier, on le met dans le tableau gtabNomF while ($fic=readdir(CD)) { if (($fic ne ".") and ($fic ne "..")) { $ficlong = $rep.$fic ; @df = lstat($ficlong) ; $b = " " x 55 ; $tf = $df[7]/1024.0 ; $nf = sprintf("%-45s",substr("$fic $b",0,45)) ; $rep = &ajouteSlash($rep) ; $frep = $rep ; $nr = sprintf("%-50s",$frep) ; $nr = $rep ; if (substr($nr,0,6) eq "/cdrom") { $nr = substr($nr,6) ; } ; if ($tf <= 1) { $tf = 1 } ; $tf = sprintf("%9.0f",$tf) ; ($sec,$min,$eur,$day,$moi,$ann,$jsm,$atj,$isdt) = gmtime($df[9]) ; $ann += 1900 ; if (length($day)<2) { $day = "0".$day } if (length($moi)<2) { $moi = "0".$moi } if (length($eur)<2) { $eur = "0".$eur } if (length($min)<2) { $min = "0".$min } if ((-d $ficlong) and not (-l $ficlong)) { # il s'agit d'un répertoire $tf = " " ; $gtabNomD{$rep.$fic} = "$nf $tf $dm $day/$moi/$ann $eur:$min $nr\n" ; ## print " répertoire *$fic* soit $ficlong \n" ; } else { # il s'agit d'un fichier "normal" $gtabNomF{$fic} = "$nf $tf $dm $day/$moi/$ann $eur:$min $nr\n" ; ## print " fichier *$fic* soit $ficlong \n" ; } ; # fin de si sur répertoire ou fichier ##&attends() ; } ; # fin si ce n'est ni . ni .. } ; # fin de tant que on parcourt le répertoire # une fois le répertoire principal passé en revue, on parcourt # le tableau associatif gtabNomF : # pour chaque fichier de ce tableau, on prépare la liste à zipper si le nombre de jours # écoulés est inférieur au nombre demandés foreach $nomF (sort keys %gtabNomF) { my $infoF = $gtabNomF{$nomF} ; my ($nomDuf,$tailleDuf,$dateDuf,$heurDuf) = split(" ",$infoF) ; my ($jourDuf,$moisDuf,$anDuf) = split("/",$dateDuf) ; $moisDuf++ ; # on archive proprement tous les mois, donc pas de fichier des années précédentes... if ($anDuf<$anAuj) { $jourec = -1 ; } else { $jourec = &nbjedd($jourDuf,$moisDuf,$anDuf,$jourAuj,$nfmoisAuj,$anAuj) ; } ; # fin si sur an # // #if (-d $nomF) { print "\n\n REP *$nomF*\n" ; } # else { print "\n\n fichier *$nomF*\n" ; } ; # #print " nom : $nomDuf \n" ; #print "\n\n REP *$nomF*\n" ; #print " taille : $tailleDuf \n" ; #print " date : $dateDuf soit $jourDuf $moisDuf $anDuf jour ".jDa($jourDuf,$moisDuf,$anDuf)."\n" ; #print " heur = $heurDuf \n" ; #print " jours écoulés : $jourec et on en veut au plus $nbjours\n\n" ; # #&attends() ; # #// # premier test : le nb de jours écoulés est positif if ($jourec>0) { if ($jourec<=$nbjours) { print " $rep$nomDuf $jourDuf $moisDuf $anDuf\n" ; print SOVLST $gtabNomF{$nomF} ; if ($noZip ==0) { print SOVLST $gtabNomF{$nomF} ; print LALISTE "$rep$nomDuf\n" ; # &attends() ; } ; # fin de zip } else { # print "rien à faire pour ". $gtabNomF{$nomF} ." car $jourec jours\n" ; } ; # fin si on zippe } ; # fin si jourec > 0 } ; # fin pour chaque F # on détruit le tableau associatif pour pouvoir le réutiliser le coup d'après undef %gtabNomF ; } ; # fin sub afficheRep ####################################################################### ## # ## programme principal # ## # ####################################################################### print "\n (gH) 2001 ; sovotw : sauvegarde incrémentale de fichers Windows\n\n" ; @nbj_pm = (31,28,31,30,31,30,31,31,30,31,30,31) ; $idm = 1 ; $tdm[1] = 0 ; for $im (@nbj_pm) { $idm++ ; $tdm[$idm] = $tdm[$idm-1] + $im ; } ; # fin pour chaque mois ($sec,$min,$hour,$mday,$mmon,$year,$jda)=localtime(); ($jourAuj,$moisAuj,$anAuj) = ($mday,$mmon,$year+1900) ; ($nfjourAuj,$nfmoisAuj,$nfanAuj) = ($mday,$mmon+1,$year-100) ; if (length($nfjourAuj)<2) { $nfjourAuj = "0$nfjourAuj" ; } ; if (length($nfmoisAuj)<2) { $nfmoisAuj = "0$nfmoisAuj" ; } ; if (length($nfanAuj)<2) { $nfanAuj = "0$nfanAuj" ; } ; print " Nous sommes le $nfjourAuj $nfmoisAuj $nfanAuj soit le jour " ; $cljd = &jDa($nfjourAuj,$nfmoisAuj,$nfanAuj) ; print "$cljd \n" ; if ($#ARGV==-1) { &syntaxe() ; exit -1 ; } ; # fin si sur le nombre d'arguments $optDbg = 0 ; # 0 pour normal, 1 pour debug $optDbg2 = 2 ; # 0 pour normal, 1 pour debug $disque = "$ARGV[0]/" ; $disque = uc($disque) ; $fDates = "x:\\sovotw.dates" ; if ($ARGV[1] eq "-a") { print " Exécution en mode automatique \n" ; $repBase = "" ; # on utilise fDates pour trouver la dernière date de sauvegarde open(LSTDATES,"<".$fDates) or die " Pb de lecture avec le fichier $fDates \n" ; $dernLig = "??? ??? ??? 0 ??? " ; while () { @tdernLig = split(" ",$_) ; if ($tdernLig[4] eq $disque) { $dernLig = $_ ; } ; } ; # fin de tant que sur fDates @tdernLig = split(" ",$dernLig) ; print " Dernière sauvegarde en date du $tdernLig[0] $tdernLig[1] $tdernLig[2] soit le jour $tdernLig[3] \n" ; print " (vu dans $fDates)\n" ; close(LSTDATES) ; $nbjours = $cljd + 1 - $tdernLig[3] ; } else { $nbjours = $ARGV[1] ; $repBase = $ARGV[2] ; } ; # fin de si mde automatique ou non if ($nbjours<0) { $nbjours += 366 ; } ; print "\n" ; print " Sauvegarde à partir du répertoire $repBase pour une durée de $nbjours jours.\n" ; $optStop = 0 ; $noZip = 0 ; if (substr($disque,1,1) ne ":") { print "\n erreur la deuxième lettre du mot 1 doit etre le symbole :\n" ; print " comme dans C:, Z: etc. ; " ; print " rappel de l'utilisation de sovotw : \n\n" ; &syntaxe() ; exit -1 ; } ; # fin si sur le nombre d'arguments $baseNomSov = "C:\\temp\\".substr($disque,0,1)."_$nfmoisAuj"."_"."$nfjourAuj" ; $nomZip = "$baseNomSov.zip" ; $nomLst = "$baseNomSov.lst" ; $nomLali = "$baseNomSov.l4z" ; open(SOVLST,">".$nomLst) or die " Pb d'écriture avec le fichier $nomLst \n" ; open(LALISTE,">".$nomLali) or die " Pb d'écriture avec le fichier $nomLali \n" ; if ($ARGV[3] eq "stop") { $optStop = 1 } ; if ($ARGV[2] eq "stop") { $repBase = "" ; $optStop = 1 } if ($ARGV[3] eq "nozip") { $noZip = 1 } ; if ($ARGV[2] eq "nozip") { $repBase = "" ; $noZip = 1 } ; $baseChem = "$disque$repBase" ; print " sauvegarde de : $baseChem sur $nbjours jours\n" ; print " dans le fichier $nomZip\n\n" ; &attends() ; # premier tour : gestion des répertoires $repBase = $baseChem ; chdir($baseChem) ; $nbdir = 1 ; $cdir = 1 ; $tabDir[$cdir] = $repBase ; print STDERR "\n recherche des répertoires \n" ; while ($cdir <= $nbdir) { if ($optDbg>0) { print " analyse de : ".$tabDir[$cdir]."\n" ; } ; &analyseDirs($tabDir[$cdir]) ; } ; # fin tant que print STDERR "\n tri des répertoires puis sauvegarde \n\n" ; &trieDirs() ; # arret éventuel si paramètre stop if ($optStop>0) { print STDERR "arret par option stop \n" ; exit 0 ; } # deuxième tour : gestion des fichiers dans les répertoires $optDbg = 0 ; $optDbgMain = 0 ; $cdir = 1 ; #$nbdir = 3 ; while ($cdir <= $nbdir) { if ($optDbgMain>0) { print " debut affichage de : ".$tabDir[$cdir]."\n" ; } ; $f_cdir = sprintf("%4d",$cdir) ; $f_nbdir = sprintf("%4d",$nbdir) ; # passage en revue véritable des fichiers &afficheRep($tabDir[$cdir]) ; if ($optDbgMain>0) { print " fin affichage de : ".$tabDir[$cdir]."\n\n" ; } ; # fin si debug $cdir++ ; } ; # fin tant que close(SOVLST) ; close(LALISTE) ; # étape trois : on zipe avec une liste $cmd = "call zip -u -P $nomZip \@$nomLali " ; print "$cmd \n\n" ; system($cmd) ; $phr = "$nfjourAuj $nfmoisAuj $nfanAuj ".jDa($nfjourAuj,$nfmoisAuj,$nfanAuj) ; $phr = "$phr $disque $repBase $nbjours " ; # étape quatre : on met la date d'aujourd'hui dans la liste des dates de sauvegarde system("echo $phr >> $fDates ") ; print STDERR " le fichier $fDates a été mis à jour.\n" ; print STDERR "\n vous pouvez consulter les fichiers : $baseNomSov.*\n" ; system(" dir $baseNomSov.*") ; # fin de sovotw.pl