前回cpioアーカイブの構造体はcpio.hではなく、cpiohdr.hにあることが分かりました。
今回は、cpiohdr.h内の構造体を特定して、アーカイブの構造を確認していこうと思います。
まず、構造体のキーワードはstructなので、cpiohdr.hで定義されているstructを検索します。
takk@deb9:~/src/cpio-2.11+dfsg/src$ grep struct cpiohdr.h struct old_cpio_header struct old_ascii_header struct new_ascii_header struct cpio_file_stat /* Internal representation of a CPIO header */ takk@deb9:~/src/cpio-2.11+dfsg/src$
たくさん出てきました。どの構造体がcopyout.c時に使用されているか調べるため、grepパターンリストとして/tmp/greplistに抽出します。
/tmpディレクトリはこのようなときに便利ですね。/tmpの中のファイルは一度使ったら気にしない、とルールを決めておけば困ることはありません。
takk@deb9:~/src/cpio-2.11+dfsg/src$ grep struct cpiohdr.h | cut -d' ' -f2 old_cpio_header old_ascii_header new_ascii_header cpio_file_stat takk@deb9:~/src/cpio-2.11+dfsg/src$ grep struct cpiohdr.h | cut -d' ' -f2 > /tmp/greplist takk@deb9:~/src/cpio-2.11+dfsg/src$
さらにgrepする時単語区切りになるように/tmp/greplistをは各検索キーワードを\<~\>で囲んでおきます。
takk@deb9:~/src/cpio-2.11+dfsg/src$ cat /tmp/greplist \<old_cpio_header\> \<old_ascii_header\> \<new_ascii_header\> \<cpio_file_stat\> takk@deb9:~/src/cpio-2.11+dfsg/src$
grep -fオプションで、/tmp/greplistを与えて、copyout.cの中に各キーワードがあるか探します。
takk@deb9:~/src/cpio-2.11+dfsg/src$ grep -f /tmp/greplist copyout.c count_defered_links_to_dev_ino (struct cpio_file_stat *file_hdr) last_link (struct cpio_file_stat *file_hdr) add_link_defer (struct cpio_file_stat *file_hdr) writeout_other_defers (struct cpio_file_stat *file_hdr, int out_des) writeout_defered_file (struct cpio_file_stat *header, int out_file_des) struct cpio_file_stat file_hdr; struct cpio_file_stat file_hdr; struct cpio_file_stat *file_hdr, int out_des) struct cpio_file_stat *file_hdr, int out_des) hp_compute_dev (struct cpio_file_stat *file_hdr, dev_t *pdev, dev_t *prdev) struct cpio_file_stat *file_hdr, int out_des) struct old_cpio_header short_hdr; write_out_header (struct cpio_file_stat *file_hdr, int out_des) struct cpio_file_stat file_hdr; /* Output header information. */ takk@deb9:~/src/cpio-2.11+dfsg/src$
たくさん出てきて見づらいです。このような時はカラーオプション等をつければ、色がついて一目で確認できるようになります。
一か所out~というところもありますが、write_out_header関数で使用していることを考えると、cpio_file_statが目的の構造体のようですので、cpio_file_statをcpiohdr.hから抽出しましょう。
20Byteもあれば足りるでしょう。grepに-A20を指定します。
takk@deb9:~/src/cpio-2.11+dfsg/src$ grep -A20 cpio_file_stat cpiohdr.h struct cpio_file_stat /* Internal representation of a CPIO header */ { unsigned short c_magic; ino_t c_ino; mode_t c_mode; uid_t c_uid; gid_t c_gid; size_t c_nlink; time_t c_mtime; off_t c_filesize; long c_dev_maj; long c_dev_min; long c_rdev_maj; long c_rdev_min; size_t c_namesize; unsigned long c_chksum; char *c_name; char *c_tar_linkname; }; takk@deb9:~/src/cpio-2.11+dfsg/src$
前回作成したa.binをアーカイブ化したファイルa.bin.cpioのダンプをもう一度見てみましょう。
takk@deb9:~/tmp$ hd !$ hd a.bin.cpio 00000000 c7 71 01 08 56 58 a4 81 e8 03 e8 03 01 00 00 00 |.q..VX..........| 00000010 f0 5a 44 3a 06 00 00 00 03 00 61 2e 62 69 6e 00 |.ZD:......a.bin.| 00000020 01 03 03 00 c7 71 00 00 00 00 00 00 00 00 00 00 |.....q..........| 00000030 01 00 00 00 00 00 00 00 0b 00 00 00 00 00 54 52 |..............TR| 00000040 41 49 4c 45 52 21 21 21 00 00 00 00 00 00 00 00 |AILER!!!........| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000200 takk@deb9:~/tmp$
ファイル名であるa.binの文字列を追っていくと該当メンバが探しやすいです。
char *c_nameを中心に3つに分離してみます。
c_magicからchar *c_nameの前まで
00000000 c7 71 01 08 56 58 a4 81 e8 03 e8 03 01 00 00 00 |.q..VX..........| 00000010 f0 5a 44 3a 06 00 00 00 03 00
char *c_name
61 2e 62 69 6e 00 |a.bin.|
char *c_tar_linkname
00000020 01 03 03 00 c7 71 00 00 00 00 00 00 00 00 00 00 |.....q..........| 00000030 01 00 00 00 00 00 00 00 0b 00 00 00 00 00 54 52 |..............TR| 00000040 41 49 4c 45 52 21 21 21 00 00 00 00 00 00 00 00 |AILER!!!........| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000200 takk@deb9:~/tmp$
ものすごく単純な構成であることが分かりました。
別のファイルでも試してみます。b.binを作成しアーカイブ化。
takk@deb9:~/tmp$ echo -ne "\x11\x22\x33" > b.bin takk@deb9:~/tmp$ echo b.bin | cpio -o > b.bin.cpio 1 block takk@deb9:~/tmp$ hd b.bin.cpio 00000000 c7 71 01 08 82 58 a4 81 e8 03 e8 03 01 00 00 00 |.q...X..........| 00000010 f6 5a f4 b9 06 00 00 00 03 00 62 2e 62 69 6e 00 |.Z........b.bin.| 00000020 11 22 33 00 c7 71 00 00 00 00 00 00 00 00 00 00 |."3..q..........| 00000030 01 00 00 00 00 00 00 00 0b 00 00 00 00 00 54 52 |..............TR| 00000040 41 49 4c 45 52 21 21 21 00 00 00 00 00 00 00 00 |AILER!!!........| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000200 takk@deb9:~/tmp$
今回、1ファイルをアーカイブ化した場合のバイナリしか見ていませんが、
ポイントとして、cpiohdr.hの struct cpio_file_statを押さえておけばよいことが分かりました。
最後に今回確認したcpiohdr.hの全文を載せておきます。
takk@deb9:~/src/cpio-2.11+dfsg/src$ cat -n cpiohdr.h 1 /* Extended cpio header from POSIX.1. 2 Copyright (C) 1992, 2006, 2007, 2010 Free Software Foundation, Inc. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3, or (at your option) 7 any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public 15 License along with this program; if not, write to the Free 16 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Boston, MA 02110-1301 USA. */ 18 19 #ifndef _CPIOHDR_H 20 21 #define _CPIOHDR_H 1 22 23 #include <cpio.h> 24 25 #ifdef HAVE_ATTRIB_PACKED 26 #define ATTRIB_PACKED __attribute__((packed)) 27 #endif 28 29 #ifdef HAVE_PRAGMA_PACK 30 #pragma pack(1) 31 #endif 32 33 #ifdef HAVE_PRAGMA_PACK_HPPA 34 #pragma pack 1 35 #endif 36 37 struct old_cpio_header 38 { 39 unsigned short c_magic; 40 unsigned short c_dev; 41 unsigned short c_ino; 42 unsigned short c_mode; 43 unsigned short c_uid; 44 unsigned short c_gid; 45 unsigned short c_nlink; 46 unsigned short c_rdev; 47 unsigned short c_mtimes[2]; 48 unsigned short c_namesize; 49 unsigned short c_filesizes[2]; 50 } ATTRIB_PACKED; 51 52 #ifdef HAVE_PRAGMA_PACK 53 #pragma pack(1) 54 #endif 55 56 #ifdef HAVE_PRAGMA_PACK_HPPA 57 #pragma pack 1 58 #endif 59 struct old_ascii_header 60 { 61 char c_magic[6]; 62 char c_dev[6]; 63 char c_ino[6]; 64 char c_mode[6]; 65 char c_uid[6]; 66 char c_gid[6]; 67 char c_nlink[6]; 68 char c_rdev[6]; 69 char c_mtime[11]; 70 char c_namesize[6]; 71 char c_filesize[11]; 72 } ATTRIB_PACKED; 73 74 /* "New" portable format and CRC format: 75 76 Each file has a 110 byte header, 77 a variable length, NUL terminated filename, 78 and variable length file data. 79 A header for a filename "TRAILER!!!" indicates the end of the archive. */ 80 81 /* All the fields in the header are ISO 646 (approximately ASCII) strings 82 of hexadecimal numbers, left padded, not NUL terminated: */ 83 84 #ifdef HAVE_PRAGMA_PACK 85 #pragma pack(1) 86 #endif 87 88 #ifdef HAVE_PRAGMA_PACK_HPPA 89 #pragma pack 1 90 #endif 91 struct new_ascii_header 92 { 93 char c_magic[6]; /* "070701" for "new" portable format 94 "070702" for CRC format */ 95 char c_ino[8]; 96 char c_mode[8]; 97 char c_uid[8]; 98 char c_gid[8]; 99 char c_nlink[8]; 100 char c_mtime[8]; 101 char c_filesize[8]; /* must be 0 for FIFOs and directories */ 102 char c_dev_maj[8]; 103 char c_dev_min[8]; 104 char c_rdev_maj[8]; /* only valid for chr and blk special files */ 105 char c_rdev_min[8]; /* only valid for chr and blk special files */ 106 char c_namesize[8]; /* count includes terminating NUL in pathname */ 107 char c_chksum[8]; /* 0 for "new" portable format; for CRC format 108 the sum of all the bytes in the file */ 109 } ATTRIB_PACKED; 110 111 struct cpio_file_stat /* Internal representation of a CPIO header */ 112 { 113 unsigned short c_magic; 114 ino_t c_ino; 115 mode_t c_mode; 116 uid_t c_uid; 117 gid_t c_gid; 118 size_t c_nlink; 119 time_t c_mtime; 120 off_t c_filesize; 121 long c_dev_maj; 122 long c_dev_min; 123 long c_rdev_maj; 124 long c_rdev_min; 125 size_t c_namesize; 126 unsigned long c_chksum; 127 char *c_name; 128 char *c_tar_linkname; 129 }; 130 131 132 #endif /* cpiohdr.h */ takk@deb9:~/src/cpio-2.11+dfsg/src$
コメント