3 tar檔案解包實現
4 參考文章
tar檔案是一種打包檔案(非壓縮檔案),在電腦上我們經常能看到的一種檔案,是將多個檔案打包成乙個檔案,以方便拷貝和傳輸。在嵌入式系統中,tar檔案也是使用較為廣泛。
假設我們現在有乙個這樣的控制系統,乙個主控裝置管理器,下面通過乙太網/rs232/rs485連線著多個子控制節點,管理主控除了管理各個子節點的控制過程、資料功能外,還提供子節點的維護功能;如韌體更新、字型檔更新、引數更新等。
整體拓撲圖如下圖。
乙個控制系統拓撲
對於上述這種拓撲結構的系統,需要更新子節點的韌體、字型檔、引數時,如果單獨將子節點的更新檔案提供給管理主控去公升級,很顯然顯得繁瑣。優良的辦法是,將所有子節點的更新檔案打包成乙個檔案包,由管理主控去解包獲取每乙個子節點的更新檔案,比對版本後再進行子節點公升級。當然,「打包+壓縮」更好,前提是管理主控系統支援解壓功能。
打包檔案,通常我們使用的是「tar」格式。對於通用嵌入式作業系統,如linux、android、wince等,tar工具比較完善,只需安裝乙個tar工具即可實現打包、解包。對於其他嵌入式作業系統,如rt-thread、freertos等等,並未有比較完善的tar工具支援,而且對於資源比較緊張的場合,現在資源部足以安裝乙個tar工具。實質上,tar包檔案格式是乙個非常易於理解的格式,只需根據其儲存格式,即可快速實現乙個打包、解包過程。本文描述的是解包過程。
tar(tape archiver)檔案,中文名稱是磁帶存檔程式檔案,是將多個檔案儲存為未壓縮格式的單個文件檔案。tar檔案格式已經成為posix標準,其檔名稱字尾為「.tar」。unix系統和類unix系統(linux、macos)上通常整合tar工具。
通過乙個簡易tar檔案儲存結構來理解tar檔案的儲存特點。
tar檔案儲存格式
tar檔案頭是解析乙個tar檔案的關鍵資訊,tar檔案頭包含了有效檔案的具體資訊,如檔名稱(包括路徑)、檔案大小、檔案校驗等。完整的檔案頭資料結構,用c語言描述如下:
struct posix_tar_header
;
#define tsuid 04000
/* 設定uid可執行許可權 */
#define tsgid 02000
/* 設定gid可執行許可權 */
#define tsvtx 01000
/* 設定粘滯位 */
#define turead 00400
/* 檔案擁有者可讀 */
#define tuwrite 00200
/* 檔案擁有者可寫 */
#define tuexec 00100
/* 檔案擁有者可執行/搜尋 */
#define tgread 00040
/* 同組使用者可讀 */
#define tgwrite 00020
/* 同組使用者可寫 */
#define tgexec 00010
/* 同組使用者可執行/搜尋 */
#define toread 00004
/* 其他使用者可讀 */
#define towrite 00002
/* 其他使用者可寫 */
#define toexec 00001
/* 其他使用者可執行/搜尋 */
檔案頭記錄中,所有字元均使用八進位制ascii碼表示。結構體中每個欄位都是連續的,即結構中沒有冗餘資料。因此,對於我們解包來說,也是十分方便,每次讀取512位元組檔案頭,通過強制型別轉換即可獲取檔案資訊。
#define chkblanks " "
/* 8個空格, 無結尾符 */
巨集定義值含義
說明lf_normal
『\0』
普通檔案
目前tar版本使用
lf_oldnormal
『0』普通檔案
老版本tar使用
lf_link
『1』硬鏈結檔案
鏈結名由字段linkname指定,以』\0』為結尾符
lf_symlink
『2』軟鏈結檔案
鏈結名由字段linkname指定,以』\0』為結尾符
lf_chr
『3』字元裝置檔案
欄位devmajor儲存主裝置號;devminor儲存子裝置號
lf_blk
『4』塊裝置檔案
欄位devmajor儲存主裝置號;devminor儲存子裝置號
lf_dir
『5』目錄檔案
目錄名由欄位name指定,以』/'結尾;目錄對應的磁碟分配是基於欄位size,分配到最近的大小合適的磁碟塊
lf_fifo
『6』管道檔案
管道檔案的歸檔只儲存檔案記錄,不儲存檔案內容
lf_contig
『7』連續檔案
物理磁碟空間儲存是連續的檔案;對於不支援連續檔案的系統,該類檔案視為普通檔案;
如果uname和gname欄位有效,magic欄位使用tmagic巨集填充
#define tmagic "ustar "
/* 注意以空格作為結束符 */
如果是gnu格式轉儲條目,magic欄位使用gnumagic巨集填充
#define gnumagic "gnutar "
/* 注意以空格作為結束符 */
struct _file_info
;int
extract_tar
(int fd, uint32_t tar_file_addr, uint32_t tar_file_size,
struct _file_info *pout)
;char head_buf[
512]=;
struct posix_tar_header *ptar;
memset
(&head_buf[0]
,0,sizeof
(head_buf));
ptar =
(struct posix_tar_header *
)head_buf;if(
512!=
read
(fd, tar_file_addr,
&head_buf[0]
,512))
if(0x00
==strlen
(ptar->name))
pout->addr = tar_file_addr+
512;
strncpy
(pout->name,
&ptar->name[0]
,31);
pout->size =
strtoul
(ptar->size,0,
8);/* 8進製轉10進製 */
return0;
}
C C 檔案路徑解析
本系列文章由 yhl leo 首先,看一下c c 中的路徑解析與合成的兩個函式 splitpath與 makepath crt insecure deprecate splitpath s crtimp void cdecl splitpath in z const char fullpath,pr...
解析tar命令
tar命令的用法如下。摘自 鳥哥的私房菜 tar zxcvfpp tfile sfile 引數說明 z 是否同時具有 gzip 的屬性?x 解開乙個壓縮檔案的引數指令!t 檢視 tarfile 裡面的檔案!c 建立乙個壓縮檔案的引數指令 v 壓縮的過程中顯示檔案!f 使用檔名,請留意,在 f 之後要...
C C 標頭檔案全解析
include 設定插入點 include 字元處理 include 定義錯誤碼 include 浮點數處理 include 檔案輸入 輸出 include 引數化輸入 輸出 include 資料流輸入 輸出 include 定義各種資料型別最值常量 include 定義本地化函式 include ...