c - How to print the name of the files inside an archive file? -
i'm new c , system programming. want open archive file , print out name of files inside archive file (e.g., archive file weds.a; inside weds.a, have thurs.txt , fri.txt". want create output shows thurs.txt fri.txt
edited: should work ar -t command.
can give me tips on how it? i've been reading man page , looking examples online, i'm getting no where. believe i'm missing something. code have below prints link count. can help? in advance help!!
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> #include <sys/utsname.h> #include <ctype.h> #include <string.h> 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 exit_success exit_failure } //open archive file (e.g., 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; }
the easiest way use ar
program list names:
ar -tv weds.a
the -
optional; v
means you'll size , time information.
if want reading archive file itself, you'll have aware of differences in formats on different systems. relevant header (normally) <ar.h>
. have information number of systems, many of them obsolete, , there variety of different tricks used handling long file names (and other more basic file format issues) may have more limited scope in mind. such work based on <ar.h>
non-trivial; you're best off reusing exists (the ar
program) if @ possible.
this archive mac os x 10.8.4 machine.
$ 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 !<arch>.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: $
fortunately you, same files produce same archive on linux too. in linux header <ar.h>
find:
/* archive files start armag identifying string. follows `struct ar_hdr', , many bytes of member file data `ar_size' member indicates, each member file. */ #define armag "!<arch>\n" /* string begins archive file. */ #define sarmag 8 /* size of string. */ #define arfmag "`\n" /* string in ar_fmag @ end of each header. */ struct ar_hdr { char ar_name[16]; /* member file name, / terminated. */ char ar_date[12]; /* file date, decimal seconds since epoch. */ char ar_uid[6], ar_gid[6]; /* user , 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]; /* contains arfmag. */ };
the mac os x header has same structure , armag , arfmag values, 1 macro:
#define ar_efmt1 "#1/" /* extended format #1 */
you can see armag string @ start of file. each file preceded struct ar_hdr
. note example names here blank terminated, not slash terminated. after that, find data file. can read header in entirety. note if of names reaches above 15 characters, or if name contains spaces, entry @ start of archive file contains file name strings, , modified name entry in per-file header identifies relevant string in string table.
linux archive long names etc
0x0000: 21 3c 61 72 63 68 3e 0a 2f 2f 20 20 20 20 20 20 !<arch>.// 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 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 archive long names etc
0x0000: 21 3c 61 72 63 68 3e 0a 74 68 75 72 73 2e 74 78 !<arch>.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 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:
differences
the linux archive has list of strings @ top of file have remembered. mac os x archive has special entry #1/28
identifies header being followed 28-byte entry containing file name (null padded multiple of 4 bytes; length given includes null padding). mac archive has no space after name when 16 characters long; linux archive puts 16-character name string table.
Comments
Post a Comment