如何在档案文件中打印文件名?

我是C和系统编程的新手。 我想打开一个存档文件并打印出存档文件中文件的名称(例如,我的存档文件是weds.a;在weds.a中,我有thurs.txt和fri.txt“。我想创建显示thurs.txt fri.txt的输出

编辑:它应该像ar -t命令一样工作。

有人可以给我一些如何做的提示吗? 我一直在阅读手册页并在线查找示例,但我没有在哪里。 我相信我错过了一些东西。 我下面的代码只打印链接计数。 有人可以帮忙吗? 在此先感谢您的帮助!!

#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; } 

最简单的方法是使用ar程序列出名称:

 ar -tv weds.a 

-是可选的; v意味着你将获得大小和时间信息。

如果您想要阅读存档文件本身,您必须了解不同系统上格式的差异。 相关标题是(通常) 。 我有许多系统的信息,其中许多已经过时,并且有多种不同的技巧用于处理长文件名(以及其他更基本的文件格式问题),但您可能考虑的范围更为有限。 任何基于工作都是非平凡的; 如果可能的话,你最好重新使用已经存在的东西( ar程序)。


这是来自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: $ 

幸运的是,相同的文件在Linux上也产生了基本相同的存档。 在Linux头文件您会发现:

 /* Archive files start with the ARMAG identifying string. 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" /* String that begins an archive file. */ #define SARMAG 8 /* Size of that string. */ #define ARFMAG "`\n" /* String 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. */ }; 

Mac OS X标头具有相同的结构和ARMAG和ARFMAG值,但有一个额外的宏:

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

您可以在文件的开头看到ARMAG字符串。 然后每个文件前面都有一个struct ar_hdr 。 请注意,此处的示例名称为空白终止,而不是斜杠终止。 之后,您将找到该文件的数据。 您可以完整阅读标题。 请注意,如果任何名称超过15个字符,或者名称包含空格,那么您将在包含文件名字符串的存档文件的开头获得一个额外的条目,并且您还可以获得一个修改后的名称条目。 -file标头,用于标识字符串表中的相关字符串。

Linux档案,名字很长等

 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: 

Mac OS X存档,名称较长等

 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: 

差异

Linux归档文件在文件顶部有一个必须记住的字符串列表。 Mac OS X存档具有特殊条目#1/28 ,它标识标题后跟一个包含文件名的28字节条目(空填充为4个字节的倍数;给定的长度包括空填充)。 Mac档案名称后面没有空格,正好是16个字符长; Linux归档文件将16个字符的名称放入字符串表中。