a.txt
et b.txt
contenant quelques
lignes de texte. Exécutez la commande hd -v a.txt
et comprenez ce qui est
affiché. Exécutez la commande od -v -Ad -td1z a.txt
et comprenez ce qui est
affiché.
Le programme tar
est un logiciel d'archivage. Il permet de
regrouper en un seul fichier plusieurs fichiers et répertoires afin, par
exemple, de les stocker ensuite plus facilement, ou de les compresser.
On crée le fichier toto.tar
contenant les fichiers a.c
,
bc.z
et 16.64
par la commande:
tar cvf toto.tar a.c bc.z 16.64
On peut extraire les fichiers à partir de l'archive à l'aide de la commande
tar xvf toto.tar
On se contentera de ces deux opérations dans le TP.
Un fichier tar
contenant des fichiers 1.txt
, 2.txt
, ..., n.txt
est constitué:
1.txt
1.txt
.
2.txt
2.txt
n.txt
n.txt
Afin de permettre une lecture du fichier plus facile (et également pour des
raisons historiques), le contenu du fichier est aligné sur un multiple de 512:
Par exemple, si le fichier fait 3678 octets, on lui ajoutera
artificiellement 418 octets de façon à arriver à 4096, un multiple de 512.
Décrivons maintenant le format des 512 octets de l'entête:
Octets | En Hexa | Contenu | Précisions |
---|---|---|---|
0-99 | 0-63 | Nom du fichier | Terminé par le caractère \0 |
100-107 | 64-6B | Permissions | Codé en base 8 |
108-115 | 6C-73 | Propriétaire | Codé en base 8 |
116-123 | 74-7B | Groupe | Codé en base 8 |
124-135 | 7C-87 | Taille | Codé en base 8 |
136-147 | 88-93 | Date de modification | Codé en base 8 |
148-155 | 94-9B | Checksum | Voir plus loin |
156-156 | 9C-9C | Type | Toujours le caractère '0' pour nous |
157-511 | 9D-1FF | Divers | Rien du tout |
test1.tar
et test2.tar
.
hd -v test1.tar | less
. Vérifiez que le résultat correspond à la description. Remarquez en particulier qu'à la fin de chaque champ indiqué ci-dessus, il y a un caractère \0 (qu'il ne faudra pas oublier de mettre dans le code).
On cherche maintenant à réaliser un programme qui crée un .tar
à partir d'un ou plusieurs fichiers.
resultat.tar
. Lire et exécutez ce fichier debut.c. Examiner le résultat avec la commande hd -v resultat.tar
. Notez en particulier que le "666" n'est pas affiché en entier, car on demande à la fonction snprintf d'afficher le résultat sur 3 caractères, ce qui prend en compte le caractère de fin '\0' qu'il ajoute à la fin de toute chaîne.
resultat.tar
très très proche du fichier test1.tar
. Il est conseillé de procéder pas à pas en comparant votre résultat avec le fichier test1.tar à l'aide de la commande hd -v
. Lire la suite de l'énoncé pour des informations supplémentaires utiles, en particulier sur l'utilisation de la commande stat
et sur la manière de calculer la checksum.
La checksum (somme de contrôle) est un entier permettant de contrôler la validité de l'entête du fichier. Elle est calculée comme suit:
sscanf
qui est à
scanf
ce que sprintf
est à printf
.
snprintf
fonctionne comme la commande printf
,
mais permet d'écrire le résultat dans une chaîne de
caractères plutôt que sur la sortie. Elle prend deux arguments de plus que
printf
: La chaîne de caractères à remplir, et la taille
maximale à remplir. Par exemple
snprintf(chaine, 25, "Hello %d", 1664);Le paramètre
"%o"
permet d'écrire des nombres en base 8.
stat
permet de récupérer la plupart des informations
dont vous avez besoin. Voilà un exemple d'utilisation (à
tester !):
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> int main(){ struct stat param; stat("a.txt", ¶m); printf("Permissions: %0o\n", param.st_mode); printf("Propriétaire: %d\n", param.st_uid); printf("Groupe: %d\n", param.st_gid); printf("Taille: %d\n", param.st_size); printf("Date: %d\n", param.st_mtime); }
open/read
ou
fopen/fread
:
#include <fcntl.h> int main(){ int fd; char buffer[512]; int i, r; fd = open("a.txt", O_RDONLY); while ((r = read(fd, buffer, 512)) > 0) { /* r est le nombre de caractères réellement lus */ for (i = 0; i < r; i++) putchar(buffer[i]); } close(fd); }ou
#include <stdio.h> int main(){ FILE* fd; char buffer[512]; int i, r; fd = fopen("a.txt", "r"); while (!feof(fd)) { r = fread(buffer, 1, 512, fd); for (i = 0; i < r; i++) putchar(buffer[i]); } fclose(fd); }
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> int main(){ int fd; fd = open("test.tar", O_WRONLY | O_CREAT | O_TRUNC , 0644); char buf[10] = "abcdefg"; write(fd, buf,10); close(fd); }
s = "%06o" % n
ord(c)
renvoie le code ascii du caractère c
.
stat
permet de récupérer la plupart des informations
dont vous avez besoin. Voici un exemple très simple d'utilisation (à tester !)
import os infos = os.stat("apple.pdf") print "Permissions: ", "%0o" % infos.st_mode print "Proprietaire: ", infos.st_uid print "Groupe: ", infos.st_gid print "Taille: ", infos.st_size print "Date: ", infos.st_mtime
s
:
f = open("apple.pdf", "rb") s = f.read(100) while s != "": faire un truc avec s s=f.read(100)
s
:
f = open("test", "w") f.write(s)