By 柯允行 2010-03-16
1前言
這是一篇介紹tar file format,tar 為 linux 常用備份資料的工具.本文不是指令教學,而是希望能介紹其檔案構造.
tar file主要是把多個檔案包裝成一個檔案,一般會搭配一種壓縮法如gzip或bzip2,再對這個檔案壓縮成壓縮檔.其中把多個檔案包裝成一個檔案才是tar file format的範疇.概念下圖:
2檔頭格式
tar archive最小單位為一個block,一個block為512bytes.打包各個檔案時會有一個檔頭分別描述各個檔案,我們稱為header block,所以tar 檔頭為512bytes.
tar 檔頭為二種"TAR format"以及"USTAR format",差別在於"USTAR format"為"TAR format"的延伸,多定義一些欄位.結構如下:
/* tar Header Block, from POSIX 1003.1-1990. */
/* POSIX header. */
struct posix_header
{ /* byte offset */
char name[100]; /* 0 */
char mode[8]; /* 100 */
char uid[8]; /* 108 */
char gid[8]; /* 116 */
char size[12]; /* 124 */
char mtime[12]; /* 136 */
char chksum[8]; /* 148 */
char typeflag; /* 156 */
char linkname[100]; /* 157 */
char magic[6]; /* 257 */
char version[2]; /* 263 */
char uname[32]; /* 265 */
char gname[32]; /* 297 */
char devmajor[8]; /* 329 */
char devminor[8]; /* 337 */
char prefix[155]; /* 345 */
/* 500 */
};
3實際演練
以下的code說明如何在tar archive中,找尋你要的檔案,我們foo為包在test.tar中的一個檔案
int test_tar_browse_and_open(void)
{
int fd,i,sum;
char header[512];
char *basename="test.tar";
char *tarname="foo";
// open tar package
fd=open(basename,O_RDONLY);
if (fd<0)
{
printf("Cannot open tar file");
return -1;
}
for (;;)
{
int len;
if (read(fd,header,512)!=512)
{
printf("tar search failed");
close(fd);
return -1;
}
// check checksum;
sum=0;
for (i=0;i<148;i++) sum+=header[i];
for (i=156;i<512;i++) sum+=header[i];
//因為算checksum時會加上 ' ' * sizeof header->chksum
//所以反推要加上 32 * 8
sum+=32*8;
if (sum!=strtol(header+148,0,8))
{
printf("Invalid tar file,check sum error");
close(fd);
return -1;
}
// match name
if (!strncmp(tarname,header,100))
{
// found it!
printf("Found it");
return fd;
}
DEBUG("Tarred file not found, searching next one");
len=strtol(header+124,0,8);
len=(len+511)&~0x1ffU;
if (lseek(fd,len,SEEK_CUR)==-1)
{
printf("Cannot seek");
close(fd);
return -1;
}
}
}
3Reference
http://www.mkssoftware.com/docs/man4/tar.4.asp
http://en.wikipedia.org/wiki/Tar_(file_format)
沒有留言:
張貼留言