1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
|
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <dirent.h>
#define STEP 15
/* -ed- des globales, ? */
/* -Al- c'est problèmatique ?*/
FILE *Log; /* Declaration fichier log */
/* -ed- les commentaires, c'est bien, mais ils doivent rester lisibles
et de pas depasser 80 colonnes.
'//' n'est pas conforme a C 90. */
/* -Al- Merci pour ton travail de mise en page :) */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Cette fonction determine si un dossier est un projet ou pas */
int Project_Or_Not (char *FULLPATH)
{
/* Déclaration de la structure qui contiendra le dossier en cours */
struct dirent *lecture;
DIR *rep;
/* Chaine temporaire */
char TEMP[256];
int sub = 0;
/* Ouvre les sous dossiers de PATH */
rep = opendir (FULLPATH);
/* -ed- la definition d'une variable apres une fonction
n'est pas conforme a C90. */
/* -Al- Mis à jour */
while ((lecture = readdir (rep)))
{
/* On lit le nom de chaque sous dossier */
sprintf (TEMP, "%s", lecture->d_name);
/* Si il a un des noms suivant, on incrémente le compteur "sub".
From_Cust, To_Cust, WORK, Admin sont des sous dossiers d'un projet */
if (!strcmp (TEMP, "From_Cust"))
sub++;
if (!strcmp (TEMP, "To_Cust"))
sub++;
if (!strcmp (TEMP, "WORK"))
sub++;
if (!strcmp (TEMP, "Admin"))
sub++;
}
if (sub >= 2) /*si il y a au moins 2 de ces sous dossiers*/
return 1;
return 0; /*retourne 0 sinon*/
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Cette fonction copie l'exe de winzip dans c:\windows\temp,
afin de le lancer d'un chemin sans espace (pose des problèmes sinon) */
/* -ed- ne retourne rien : void. */
void Copy_wzzip (void)
{
/* crée une copie de winzip dans c:\windows\temp */
system ("copy \"C:\\Program Files\\WinZip\\wzzip.exe\" c:\\windows\\temp");
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Cette fonction zippera un dossier dont le chemin contiendra
le code d'erreur */
int Add_Folder (char *FULLPATH)
{
int Code;
int i;
int j;
int l;
/* Contiendra le nom du projet */
char NAME[256];
/* Contient le chemin sans le nom de projet */
char *SHORTPATH = NULL;
/* Contiendra les Ligne de Commande passées au système */
char *CmdLine;
/* -ed- qui dit que la taille est suffisante ?
L'allocation dynamique est plus sure (strdup(),
par exemple, qui est POSIX.1, donc tres portable) */
/* -Al- Mis à jour */
SHORTPATH=strdup(FULLPATH);
/* -ed- c'est pas une bonne idee de mettre une
fonction dans une boucle, surtout si
c'est un invariant. Perte de temps.
Pour faire ce genre de recherche,
envisager strchr() ou strrchr()...
*/
/* -Al- Je ne connaissais pas ces fontions, elles m'ont l'air plutôt utile
effectivement, j'essaierais de changer ça quand j'aurais un code qui
fonctionne.
J'ai corrigé le problème du strlen appelé en boucle, effectivement c'est
une perte de temps */
/* Cette boucle parcours la chaine a l'envers */
l=strlen (SHORTPATH);
for (i = (l - 1); i >= 0; i--)
{
if (SHORTPATH[i] == '\\') /* si on tombe sur un "\" on va remplace par \0*/
{
/* Cette boucle extrait le nom de dossier */
for (j = i + 1; j <= l; j++)
{
NAME[j - (i + 1)] = SHORTPATH[j]; /* Copie caractère par caractère */
}
SHORTPATH[i] = '\0';
i = -1;
}
}
CmdLine = malloc ((strlen(FULLPATH)+strlen(SHORTPATH)+80)*sizeof(char));
/* preparation de la ligne de commande qui lance la Compression */
sprintf (CmdLine, "C:\\windows\\temp\\wzzip.exe"
" -r -p -whs -en \"%s\\%s.zip\" \"%s\"",
SHORTPATH, NAME, FULLPATH);
/* on recupere le code d'état renvoyé par la ligne de commande */
Code = system (CmdLine);
/* Ajouter la ligne qui efface le dossier */
/* -ed- BUG ! On ne peut libérer que ce qui a ete alloue. */
/* -Al- Mis à jour */
/* Liberation de l'espace memoire reservé pour les chaines */
if(SHORTPATH != NULL) free (SHORTPATH);
if(CmdLine != NULL) free (CmdLine);
if (NAME != NULL) free (NAME);
return Code; /* retourne le code d'état */
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int arbo (char *PATH)
/* Cette fonction parcoureras l'arborescence à la recherche de projets
et essaiera de zipper les projets qu'elle trouve
Prends le chemin du dossier à analyser en paramètre,
et renvoie 1 si un projet a été archivé, 0 si aucun projet n'a été trouvé */
{
int i = 0;
int j;
int z = 0;
int u = 0;
/* -ed- sizeof(char) vaut 1 par definition.
Pourquoi allouer 1 caractere ?
Autant laisser NULL. */
/* -Al- Mis à jour*/
char *CmdLine = NULL;
/* Contiendra le chemin complet du dossier en cours */
char *FULLPATH = NULL;
/* contiendra une valeur associée a un sous dossier
(RESULTS[i] associé a SubFolderNames[i]) */
int *RESULTS = NULL;
int State; /* Code d'état (zip+rd) */
/* Contient tous les sous dossiers du dossier en cours */
char **SubFolderNames = NULL;
/* Contient les sous dossiers dont la valeur associée est 0 */
char **FoldersNotZipped = NULL;
/* Déclaration de la structure qui contiendra le dossier en cours */
struct dirent *folder;
DIR *rep;
rep = opendir (PATH); /* Ouvre les sous dossiers de rep */
/* boucle qui traite tous les sous dossiers */
while ((folder = readdir (rep)))
{
if (i % STEP == 2)
{
/* Assignation mémoire SubFolderNames */
SubFolderNames =
realloc (SubFolderNames, (i + STEP) * sizeof (char *));
}
if (i > 1)
/* si i=0 d_name=. et si i=1 d_name=.. (la procédure ne s'applique pas) */
{
/* assignation memoire RESULT */
RESULTS = realloc (RESULTS, (i + 1) * sizeof (int));
/* Assignation mémoire SubFolderNames[i] */
SubFolderNames[i] = malloc (strlen (folder->d_name) + 1);
/* Assignation de mémoire pour FULLPATH si plus grand que */
if (strlen (FULLPATH) <
(strlen (SubFolderNames[i]) + strlen (PATH) + 1))
{
FULLPATH =
realloc (FULLPATH,
(strlen (SubFolderNames[i]) + strlen (PATH) +
1) * sizeof (char));
}
if (SubFolderNames[i] != NULL)
{
/* On recupère le nom du ième sous dossier dans SubFolderNames */
strcpy (SubFolderNames[i], folder->d_name);
}
else
{
printf ("\nNo more memory available\n");
system ("pause");
exit (-1);
}
RESULTS[i] = 0;
/* On stocke le chemin du sous dossier en cours dans FullPATH */
sprintf (FULLPATH, "%s\\%s", PATH, SubFolderNames[i]);
/* Si le sous dossier est un projet ou un dossier Common */
if (Project_Or_Not (FULLPATH)
|| !strcmp (SubFolderNames[i], "_Common"))
{
State = Add_Folder (FULLPATH); /* On le zippe */
if (State != 0)
{
fprintf (Log, "%s\n", FULLPATH);
State = 0;
} /* si erreur pendant la compression -> log */
else
{
/* memoire pour CmdLine */
CmdLine =
realloc (CmdLine, (strlen (FULLPATH) + 20) * sizeof (char));
if (CmdLine != NULL)
{
sprintf (CmdLine, "rd /S /Q \"%s\"", FULLPATH);
State = system (CmdLine); /* suppression du dossier */
}
else
{
printf ("\nNo more memory available\n");
system ("pause");
exit (-1);
}
}
if (State != 0)
{
fprintf (Log, "%s\n", FULLPATH);
} /* Si erreur pendant la supression ->log */
RESULTS[i] = 1;
}
else
{
if (opendir (FULLPATH))
{
/* appelle la fonction sur les sous dossiers */
RESULTS[i] = arbo (FULLPATH);
}
else
{
RESULTS[i] = 0;
}
}
} /* fin de if (i>1) */
i++;
} /* Fin de la boucle qui traite les sous dossiers*/
/* Cette boucle compte les 0 et les 1 renvoyés par
l'appel de la fonction sur les sous dossier du
dossier en cours */
for (j = 2; j < i; j++)
{
if (j % STEP == 2)
{
FoldersNotZipped =
realloc (FoldersNotZipped, (j + STEP) * sizeof (char *));
}
if (RESULTS[j] == 0)
{
/* On stocke le chemin du sous dossier en cours dans FullPATH */
sprintf (FULLPATH, "%s\\%s", PATH, SubFolderNames[j]);
FoldersNotZipped[z] =
malloc ((strlen (FULLPATH) + 1) * sizeof (char));
if (FoldersNotZipped[z] != NULL)
{
/* On stocke les chemins associé a un 0 dans le
tableau FoldersNotZipped
On recupère le nom du ième sous dossier dans SubFolderNames */
strcpy (FoldersNotZipped[z], FULLPATH);
}
else
{
printf ("\nNo more memory available\n");
system ("pause");
exit (-1);
}
z++;
}
else
{
u++;
}
} /* fin de for (j=2;j<i;j++) */
/* Liberation des mémoires reservées */
free (SubFolderNames);
free (RESULTS);
/* En fonction des valeurs renvoyées par les sous dossiers,
on renvoie 1 , 0 ou on renvoie 1 et on log le nom de dossier */
if (u == 0)
{
free (FoldersNotZipped);
return 0;
}
for (i = 0; i < z; i++)
{
if (opendir (FoldersNotZipped[i]))
{
fprintf (Log, "%s\n", FoldersNotZipped[i]);
}
}
free (FoldersNotZipped);
return 1;
}
/* -ed- DANGER ! Fonction douteuse.
Il y a possibilite de quitter cette fonction
recursive sans retourner une valeur valide.
Risque de comportement indefini.
D'une maniere generale, les returns multiples
sont un risque pour le programme et nuisent à
la lecture et à la qualité du code. */
/* -Al- Mis à jour : Est-ce suffisemment simplifié?*/
/* fin de la fonction arbo */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int main (int argc, char *argv[])
{
/* --ed- argc n'est pas utilise,
ce qui signifie que le nombre de parametres
n'est pas controle. Il y a un risque important
de comportement indéfini */
/* -Al- Mis à jour */
char CmdLine[256];
clock_t temps_initial, /* Temps initial en micro-secondes */
temps_final; /* Temps final en micro-secondes */
/* -ed- pourquoi float alors que le calcul se fait en double ? */
/* -Al- Mis à jour */
double temps_cpu; /* Temps total en micro-secondes */
Log = fopen ("c:\\windows\\temp\\log.txt", "w+");
if (Log == NULL)
{ /* Ouverture du fichier de logs */
fprintf (stderr, "The Log file could not be created");
system ("pause");
exit (-1);
}
Copy_wzzip (); /* crée une copie de wzzip (sans espace dans le chemin) */
temps_initial = clock (); /* Prends l'heure de départ */
if (argc==2)
arbo (argv[1]); /* appelle la fonction qui parcours l'arborescence*/
else
printf("Please check arguments\n");
fclose (Log); /* Ferme le fichier de logs */
temps_final = clock (); /* Prends l'heure de fin */
/* -ed- Les calculs de temps doivent etre faits
avec CLOCKS_PER_SEC et non une constante
tiree d'un chapeau... */
/* -Al- Mis à jour */
/* calcule le temps ecoulé et le convertit en secondes */
temps_cpu = (temps_final - temps_initial) / CLOCKS_PER_SEC;
printf ("\ntemps : %d\n", temps_cpu);
system ("del c:\\windows\\temp\\wzzip.exe");
sprintf (CmdLine,
"Move \"c:\\windows\\temp\\log.txt\" \"%%USERPROFILE%%\\DESKTOP\\\"");
system (CmdLine);
system ("PAUSE");
return 0;
} |