cpioヘッダ(その2)

前回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$ 

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA