Comment imprimer le nom des fichiers dans un fichier archive?

Je suis nouveau en programmation C et système. Je veux ouvrir un fichier archive et imprimer le nom des fichiers qu’il contient (par exemple, mon fichier archive est weds.a; à l’intérieur weds.a, j’ai thurs.txt et fri.txt “. Je veux créer une sortie qui montre thurs.txt fri.txt

EDITED: Cela devrait fonctionner comme la commande ar -t.

Quelqu’un peut-il me donner des conseils sur la façon de le faire? J’ai lu la page de manuel et cherché des exemples en ligne, mais je ne me retrouve nulle part. Je crois que je manque quelque chose. Le code que j’ai ci-dessous n’imprime que le nombre de liens. Quelqu’un peut aider? Merci d’avance pour votre aide!!

#include  #include  #include  #include  #include  #include  #include  #include  #include  #include  int main (int argc, char **argv) { int in_fd; struct stat sb; if (argc != 2) { printf("Error", argv[0]); exit(EXIT_FAILURE); } if (stat(argv[1], &sb) == -1) { perror("stat"); exit(EXIT_FAILURE); //change from EXIT_SUCCESS to EXIT_FAILURE } //open the archive file (eg, hw.a) in_fd = open(argv[1], O_RDONLY); if (in_fd == -1) { perror("Can't open input file\n"); exit(-1); } printf("Link Count: %ld\n", (long)sb.st_nlink); return 0; } 

Le moyen le plus simple consiste à utiliser le programme ar pour répertorier les noms:

 ar -tv weds.a 

Le - est facultatif; le v signifie que vous obtiendrez des informations sur la taille et l’heure.

Si vous voulez vous lancer dans la lecture du fichier d’archive lui-même, vous devez être conscient des différences entre les formats sur différents systèmes. L’en-tête approprié est (normalement) . J’ai des informations sur un certain nombre de systèmes, dont beaucoup sont obsolètes, et diverses astuces sont utilisées pour gérer les noms de fichiers longs (et d’autres problèmes encore plus fondamentaux liés au format de fichier), mais vous avez peut-être une scope plus limitée. Tout travail de ce type basé sur sera non sortingvial; vous feriez mieux de réutiliser ce qui existe déjà (le programme ar ) si possible.


Ceci est une archive d’un ordinateur Mac OS X 10.8.4.

 $ cat thurs.txt 0123456789:;<=>?@ABCDEFGHIJKLMNO $ cat fri.txt PQRSTUVWXYZ[\]^_`abcdefghijklmno $ odx weds.a 0x0000: 21 3C 61 72 63 68 3E 0A 74 68 75 72 73 2E 74 78 !.thurs.tx 0x0010: 74 20 20 20 20 20 20 20 31 33 37 34 30 39 36 30 t 13740960 0x0020: 31 32 20 20 32 38 37 36 20 20 35 30 30 30 20 20 12 2876 5000 0x0030: 31 30 30 36 34 34 20 20 33 33 20 20 20 20 20 20 100644 33 0x0040: 20 20 60 0A 30 31 32 33 34 35 36 37 38 39 3A 3B `.0123456789:; 0x0050: 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B <=>?@ABCDEFGHIJK 0x0060: 4C 4D 4E 4F 0A 0A 66 72 69 2E 74 78 74 20 20 20 LMNO..fri.txt 0x0070: 20 20 20 20 20 20 31 33 37 34 30 39 36 30 30 35 1374096005 0x0080: 20 20 32 38 37 36 20 20 35 30 30 30 20 20 31 30 2876 5000 10 0x0090: 30 36 34 34 20 20 33 33 20 20 20 20 20 20 20 20 0644 33 0x00A0: 60 0A 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D `.PQRSTUVWXYZ[\] 0x00B0: 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D ^_`abcdefghijklm 0x00C0: 6E 6F 0A 0A no.. 0x00C4: $ 

Heureusement pour vous, les mêmes fichiers produisent essentiellement la même archive sous Linux. Dans l’en-tête Linux vous trouvez:

 /* Archive files start with the ARMAG identifying ssortingng. Then follows a `struct ar_hdr', and as many bytes of member file data as its `ar_size' member indicates, for each member file. */ #define ARMAG "!\n" /* Ssortingng that begins an archive file. */ #define SARMAG 8 /* Size of that ssortingng. */ #define ARFMAG "`\n" /* Ssortingng in ar_fmag at end of each header. */ struct ar_hdr { char ar_name[16]; /* Member file name, sometimes / terminated. */ char ar_date[12]; /* File date, decimal seconds since Epoch. */ char ar_uid[6], ar_gid[6]; /* User and group IDs, in ASCII decimal. */ char ar_mode[8]; /* File mode, in ASCII octal. */ char ar_size[10]; /* File size, in ASCII decimal. */ char ar_fmag[2]; /* Always contains ARFMAG. */ }; 

L’en-tête Mac OS X a la même structure et les mêmes valeurs ARMAG et ARFMAG, mais une macro supplémentaire:

 #define AR_EFMT1 "#1/" /* extended format #1 */ 

Vous pouvez voir la chaîne ARMAG au début du fichier. Chaque fichier est ensuite précédé d’une struct ar_hdr . Notez que les exemples de noms indiqués ici sont des caractères vierges, et non des slash. Après cela, vous trouvez les données pour le fichier. Vous pouvez lire l’en-tête dans son intégralité. Notez que si l’un des noms dépasse 15 caractères ou si un nom contient des espaces, vous obtenez une entrée supplémentaire au début du fichier d’archive contenant les chaînes de nom de fichier, ainsi qu’une entrée de nom modifié En-tête de fichier qui identifie la chaîne pertinente dans la table des chaînes.

Archive Linux avec noms longs, etc.

 0x0000: 21 3C 61 72 63 68 3E 0A 2F 2F 20 20 20 20 20 20 !.// 0x0010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 * (1) 0x0030: 20 20 20 20 20 20 20 20 34 36 20 20 20 20 20 20 46 0x0040: 20 20 60 0A 66 69 6C 74 65 72 2E 73 74 64 65 72 `.filter.stder 0x0050: 72 2E 73 68 2F 0A 6C 6F 6E 67 20 6E 61 6D 65 20 r.sh/.long name 0x0060: 77 69 74 68 20 73 70 61 63 65 73 2E 74 78 74 2F with spaces.txt/ 0x0070: 0A 0A 74 68 75 72 73 2E 74 78 74 2F 20 20 20 20 ..thurs.txt/ 0x0080: 20 20 31 33 37 34 30 39 36 32 31 31 20 20 31 39 1374096211 19 0x0090: 39 34 38 34 35 30 30 30 20 20 31 30 30 36 34 30 94845000 100640 0x00A0: 20 20 33 33 20 20 20 20 20 20 20 20 60 0A 30 31 33 `.01 0x00B0: 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 23456789:;<=>?@A 0x00C0: 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 0A 0A BCDEFGHIJKLMNO.. 0x00D0: 66 72 69 2E 74 78 74 2F 20 20 20 20 20 20 20 20 fri.txt/ 0x00E0: 31 33 37 34 30 39 36 31 39 37 20 20 31 39 39 34 1374096197 1994 0x00F0: 38 34 35 30 30 30 20 20 31 30 30 36 34 30 20 20 845000 100640 0x0100: 33 33 20 20 20 20 20 20 20 20 60 0A 50 51 52 53 33 `.PQRS 0x0110: 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 TUVWXYZ[\]^_`abc 0x0120: 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 0A 0A 2F 30 defghijklmno../0 0x0130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 31 33 13 0x0140: 37 31 31 34 35 35 38 34 20 20 31 39 39 34 38 34 71145584 199484 0x0150: 35 30 30 30 20 20 31 30 30 36 34 30 20 20 32 33 5000 100640 23 0x0160: 30 20 20 20 20 20 20 20 60 0A 23 21 2F 62 69 6E 0 `.#!/bin 0x0170: 2F 62 61 73 68 0A 73 65 74 20 2D 78 0A 72 6D 20 /bash.set -x.rm 0x0180: 2D 66 20 6F 75 74 2E 5B 31 32 33 5D 0A 2E 2F 67 -f out.[123]../g 0x0190: 65 6E 6F 75 74 65 72 72 2E 73 68 20 31 3E 2F 64 enouterr.sh 1>/d 0x01A0: 65 76 2F 6E 75 6C 6C 0A 2E 2F 67 65 6E 6F 75 74 ev/null../genout 0x01B0: 65 72 72 2E 73 68 20 32 3E 2F 64 65 76 2F 6E 75 err.sh 2>/dev/nu 0x01C0: 6C 6C 0A 28 20 2E 2F 67 65 6E 6F 75 74 65 72 72 ll.( ./genouterr 0x01D0: 2E 73 68 20 32 3E 26 31 20 31 3E 26 33 20 7C 20 .sh 2>&1 1>&3 | 0x01E0: 67 72 65 70 20 27 5B 30 2D 39 5D 30 27 20 3E 26 grep '[0-9]0' >& 0x01F0: 32 29 20 33 3E 6F 75 74 2E 33 20 32 3E 6F 75 74 2) 3>out.3 2>out 0x0200: 2E 32 20 31 3E 6F 75 74 2E 31 0A 6C 73 20 2D 6C .2 1>out.1.ls -l 0x0210: 20 6F 75 74 2E 5B 31 32 33 5D 0A 28 20 2E 2F 67 out.[123].( ./g 0x0220: 65 6E 6F 75 74 65 72 72 2E 73 68 20 32 3E 26 31 enouterr.sh 2>&1 0x0230: 20 31 3E 26 33 20 7C 20 67 72 65 70 20 27 5B 30 1>&3 | grep '[0 0x0240: 2D 39 5D 30 27 20 3E 26 32 29 20 33 3E 26 31 0A -9]0' >&2) 3>&1. 0x0250: 2F 31 38 20 20 20 20 20 20 20 20 20 20 20 20 20 /18 0x0260: 31 33 37 34 30 39 36 35 37 37 20 20 31 39 39 34 1374096577 1994 0x0270: 38 34 35 30 30 30 20 20 31 30 30 36 34 30 20 20 845000 100640 0x0280: 33 33 20 20 20 20 20 20 20 20 60 0A 30 31 32 33 33 `.0123 0x0290: 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 456789:;<=>?@ABC 0x02A0: 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 0A 0A DEFGHIJKLMNO.. 0x02AE: 

Archive Mac OS X avec noms longs, etc.

 0x0000: 21 3C 61 72 63 68 3E 0A 74 68 75 72 73 2E 74 78 !.thurs.tx 0x0010: 74 20 20 20 20 20 20 20 31 33 37 34 30 39 36 30 t 13740960 0x0020: 31 32 20 20 32 38 37 36 20 20 35 30 30 30 20 20 12 2876 5000 0x0030: 31 30 30 36 34 34 20 20 33 33 20 20 20 20 20 20 100644 33 0x0040: 20 20 60 0A 30 31 32 33 34 35 36 37 38 39 3A 3B `.0123456789:; 0x0050: 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B <=>?@ABCDEFGHIJK 0x0060: 4C 4D 4E 4F 0A 0A 66 72 69 2E 74 78 74 20 20 20 LMNO..fri.txt 0x0070: 20 20 20 20 20 20 31 33 37 34 30 39 36 30 30 35 1374096005 0x0080: 20 20 32 38 37 36 20 20 35 30 30 30 20 20 31 30 2876 5000 10 0x0090: 30 36 34 34 20 20 33 33 20 20 20 20 20 20 20 20 0644 33 0x00A0: 60 0A 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D `.PQRSTUVWXYZ[\] 0x00B0: 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D ^_`abcdefghijklm 0x00C0: 6E 6F 0A 0A 66 69 6C 74 65 72 2E 73 74 64 65 72 no..filter.stder 0x00D0: 72 2E 73 68 31 33 37 34 30 39 37 37 39 34 20 20 r.sh1374097794 0x00E0: 32 38 37 36 20 20 35 30 30 30 20 20 31 30 30 36 2876 5000 1006 0x00F0: 34 34 20 20 32 33 30 20 20 20 20 20 20 20 60 0A 44 230 `. 0x0100: 23 21 2F 62 69 6E 2F 62 61 73 68 0A 73 65 74 20 #!/bin/bash.set 0x0110: 2D 78 0A 72 6D 20 2D 66 20 6F 75 74 2E 5B 31 32 -x.rm -f out.[12 0x0120: 33 5D 0A 2E 2F 67 65 6E 6F 75 74 65 72 72 2E 73 3]../genouterr.s 0x0130: 68 20 31 3E 2F 64 65 76 2F 6E 75 6C 6C 0A 2E 2F h 1>/dev/null../ 0x0140: 67 65 6E 6F 75 74 65 72 72 2E 73 68 20 32 3E 2F genouterr.sh 2>/ 0x0150: 64 65 76 2F 6E 75 6C 6C 0A 28 20 2E 2F 67 65 6E dev/null.( ./gen 0x0160: 6F 75 74 65 72 72 2E 73 68 20 32 3E 26 31 20 31 outerr.sh 2>&1 1 0x0170: 3E 26 33 20 7C 20 67 72 65 70 20 27 5B 30 2D 39 >&3 | grep '[0-9 0x0180: 5D 30 27 20 3E 26 32 29 20 33 3E 6F 75 74 2E 33 ]0' >&2) 3>out.3 0x0190: 20 32 3E 6F 75 74 2E 32 20 31 3E 6F 75 74 2E 31 2>out.2 1>out.1 0x01A0: 0A 6C 73 20 2D 6C 20 6F 75 74 2E 5B 31 32 33 5D .ls -l out.[123] 0x01B0: 0A 28 20 2E 2F 67 65 6E 6F 75 74 65 72 72 2E 73 .( ./genouterr.s 0x01C0: 68 20 32 3E 26 31 20 31 3E 26 33 20 7C 20 67 72 h 2>&1 1>&3 | gr 0x01D0: 65 70 20 27 5B 30 2D 39 5D 30 27 20 3E 26 32 29 ep '[0-9]0' >&2) 0x01E0: 20 33 3E 26 31 0A 23 31 2F 32 38 20 20 20 20 20 3>&1.#1/28 0x01F0: 20 20 20 20 20 20 31 33 37 34 30 39 37 38 32 32 1374097822 0x0200: 20 20 32 38 37 36 20 20 35 30 30 30 20 20 31 30 2876 5000 10 0x0210: 30 36 34 34 20 20 36 31 20 20 20 20 20 20 20 20 0644 61 0x0220: 60 0A 6C 6F 6E 67 20 6E 61 6D 65 20 77 69 74 68 `.long name with 0x0230: 20 73 70 61 63 65 73 2E 74 78 74 00 00 00 30 31 spaces.txt...01 0x0240: 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 23456789:;<=>?@A 0x0250: 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 0A 0A BCDEFGHIJKLMNO.. 0x0260: 

Différences

L’archive Linux a une liste de chaînes en haut du fichier qui doivent être mémorisées. L’archive Mac OS X comporte l’entrée spéciale #1/28 qui identifie l’en-tête comme étant suivi d’une entrée de 28 octets contenant le nom du fichier (null complété à un multiple de 4 octets; la longueur indiquée inclut le remplissage nul). L’archive Mac n’a pas d’espace après le nom quand elle contient exactement 16 caractères; l’archive Linux place le nom de 16 caractères dans la table des chaînes.