P3:檔案系統
概述
你在蜥蜴軍團的掩護被揭穿了,你被揭露為雙重間諜並被驅逐出去!是的都很“詹姆斯·邦德”,如果你自己這麼說的話,那是多麼大膽的地下直升機逃生……但是你感到很幸運能帶著你的皮膚逃脫。(從字面上看……他們會用你做一套“人體服”!)現在你又回到了“外部”,你的任務是建立一個方案來允許剩餘的阻力仍在蜥蜴軍團中的戰士可以秘密地將資訊傳回你的組織,而不需要籌集懷疑最近,蜥蜴軍團的成員發現了PC經典遊戲“DOOM”,它已經成為在總部為它建造新的MOD,所以你的團隊決定使用這個標題的MOD作為用於排氣的車輛。透過將加密位元埋在紋理和其他遊戲資料塊中,資訊可以隱藏在無害的“WAD”(所有資料在哪裡)檔案中。
在這個專案中,您將使用FUSE(userspace中的filesystem)實現一個使用者空間檔案系統守護程序API訪問WAD格式的資料,WAD格式是許多經典PC遊戲(包括DOOM)中使用的標準和Hexen)。在這個關鍵的早期原型中,您的任務是實現對的讀寫訪問WAD檔案中的檔案和目錄作為概念證明。因此,您需要實現read和在基於FUSE的程式中為檔案和目錄編寫功能。作為您的戰友,我們將提供WAD樣本檔案,以展示您的功能實施(抵抗力量指望著你!)抵抗力量利用大學課程作為掩護標準操作,因此您將透過Canvas提交專案。
結構
該專案分為三個主要部分:
1) 開發一個用於讀取和寫入WAD檔案的庫,並從中建立目錄和檔案結構。2) 實現一個使用者空間守護程序(透過FUSE),以便在安裝後訪問目錄結構。3) 透過導航裝載的目錄、檢查名稱和檔案內容來測試您的實現,以及新增自己的目錄和檔案。雖然具體實現可能有所不同,但守護程序的引數必須與本文件中列出的引數相匹配,並且目錄結構、命名和檔案內容必須透過檔案系統正確呈現。檔案格式WAD檔案格式包含三個部分的資訊:提供基本佈局資訊的標題,描述檔案中元素的描述符和包含資料本身的塊。注意:所有數字都是小的Endian格式,在適用的情況下,以位元組為單位指定!自從爬行動物商店它在記憶體中的變數也是小Endian格式的,不需要執行任何位元組順序反轉在讀取或寫入資料時,但這仍然是需要了解的重要資訊。檔案頭標頭包含檔案魔力、描述符計數和描述符在檔案中的位置(偏移量):代 寫COP4600 檔案系統實現細節wad檔案的魔力通常是ASCII,並且總是以字尾“wad”(例如,“IWAD”或“PWAD”)結尾。同樣重要的是要注意描述符列表,從描述符指示的位置開始偏移量總是位於WAD檔案的末尾。
描述符
檔案的描述符包含有關WAD檔案中元素的資訊——檔案偏移量、長度和名稱某些元素將具有特定的命名約定,以區別於常規內容資料夾。這些“標記”元素將被守護程序解釋為目錄,並且應該顯示相應地在檔案系統中(見下文)。
腫塊
WAD格式中的元素儲存為描述符所描述的“塊”。這些結塊會在檔案系統中由守護程序表示為可以開啟、讀取和關閉的單個檔案。您不能寫入現有的塊,但您將建立空檔案,其塊將為您所擁有寫信給。
標記元素
WAD檔案中有兩種主要型別的標記元素,每種標記元素都應解釋為目錄。型別包括對映標記和名稱空間標記。地圖示記名稱的格式為“E#M#”,其中#表示一個十進位制數字(例如“E1M9”)。它們後面跟著十(10)個地圖元素描述符。接下來的10個描述符的元素應該是放置在具有地圖名稱的目錄中。對映標記目錄不能有檔案或目錄新增到它們中名稱空間標記成對出現。名稱空間的開頭用描述符標記,該描述符的名稱具有字尾“_START”(例如“F1_START”),其結尾用描述符標記,該描述符的名稱具有字尾“_END(例如“F1_END”)。位於開頭和結尾之間的元素的任何描述符名稱空間的標記應放置在具有名稱空間名稱的目錄中(例如,“F1”)。名稱空間標記的名稱(不包括字尾)永遠不會超過兩個字元。這些將是您將負責建立的目錄型別。
例如,在描述符列表中,以下描述符按順序應產生此組織:圖書館
您的庫將包含一個類來表示WAD資料,如本節所述。
Wad類
Wad類用於表示Wad資料,應具有以下功能。所有路徑的根WAD中的資料應為“/”,每個目錄應以“/”分隔(例如,“/F/F1/LOLWUT”)。公共靜態Wad*loadW(常量字串和路徑)物件分配器;動態建立Wad物件,並將Wad檔案資料從路徑載入到記憶體中。呼叫方必須使用delete關鍵字解除分配記憶體。
公共字串getMagic()返回此WAD資料的魔力。
public bool isContent(const字串和路徑)如果path表示內容(資料),則返回true,否則返回false。public bool isDirectory(const字串和路徑)如果path表示目錄,則返回true,否則返回false。public int getSize(const字串和路徑)如果path表示內容,則返回其資料中的位元組數;否則,返回-1。public int getContents(const string&path,char*buffer,int length,int offset=0)如果路徑表示內容,則將盡可能多的可用位元組(最大長度)的內容資料複製到預先存在的緩衝區中。如果提供了偏移量,則應從內容中的該位元組開始複製資料。退換商品複製到緩衝區的位元組數,如果路徑不表示內容(例如,如果它表示目錄),則為-1。public int getDirectory(const string&path,vector<string>*目錄)若path表示一個目錄,那個麼將立即包含的元素的條目放在目錄中。元素應按照與WAD檔案中相同的順序放置在目錄中。返回的數量目錄中的元素,或者-1,如果路徑不表示目錄(例如,如果它表示內容)。偏移長度名稱
0 0 F_START
0 0 F1_啟動
67500 0 E1M1
67500 1380件東西
68880 6650 LINEDEFS
75532 19440側定義
94972 1868個頂點
96840 8784段
105624 948名檢查員
106572 6608個節點
113180 2210個扇區
115392904拒絕
116296 6922塊圖
42 9001 LOLWUT
0 0 F1_END
0 0結束
E1M1
東西
LINEDEFS
SIDEDEFS
頂點
SEGS
SSECTORS
節點
扇區
拒絕
塊圖
LOLWUT
目錄結構
public void createDirectory(const字串和路徑)路徑包括要建立的新目錄的名稱。如果給定有效路徑,則建立一個新目錄在路徑處使用名稱空間標記。這兩個新的名稱空間標記將新增到“_END”之前其父目錄的標記。無法在地圖示記內建立新目錄。
public void createFile(const字串和路徑)路徑包括要建立的新檔案的名稱。如果給定有效路徑,則在路徑處建立一個空檔案,偏移量和長度為0。檔案將在“_END”標記之前新增到描述符列表中的父目錄。無法在地圖示記內建立新檔案。
public int writeToFile(const string&path,const char*buffer,int length,int offset=0)如果給定一個空檔案的有效路徑,則增大檔案大小並生成塊偏移量,然後寫入長度量從緩衝區到檔案的塊資料的位元組數。如果提供了偏移量,則應從該偏移量開始寫入資料塊內容中的位元組。返回從緩衝區複製的位元組數,如果路徑不表示內容,則返回-1(例如,如果它表示一個目錄)。
精靈命令和引數
您的守護程序應該具有名稱wadfs,並且應該至少接受三個引數——單執行緒標誌“-s”、目標WAD檔案和裝載目錄。例如,這個命令應該掛載TINY。WAD在/home/retilian/mountdir…$ ./wadfs-s TINY。WAD/home/retilian/mountdir$
…這應該是由於執行ls命令來顯示其部分內容:
$ls/home/retilian/mountdir/F/F1-al總計0
drwxrwxrwx。2根1970年1月1日0。
drwxrwxrwx。2根
drwxrwxrwx。2根
1970年1月1日。。
1970年1月1日E1M1
-rwxrwxrwx。2根9001 1970年1月1日LOLWUT您的守護程式應該在後臺執行。不要硬編碼除錯(-d)或前臺(-f)標誌!我們將使用以下命令解除安裝您的檔案系統:
$fusermount-u/home/retilian/mountdir額外信貸
您可能會注意到,在使用守護程序進行測試時,您在中建立的檔案的大小有一個上限您的檔案系統可以是。您的任務是配置庫和守護程序,以便能夠建立檔案系統中的大檔案(例如,使用“cp”複製到200KB的映像檔案中)。執行您的除錯模式下的守護程序(-d)可能會提示您某些呼叫的行為。注意:如果檔案或目錄是在根目錄中建立的,它將被放置在描述符列表,而不是在“_END”名稱空間標記之前
帶保險絲的建築
FUSE是一個使用者空間檔案系統API,由Linux核心直接支援。它允許使用者空間程式
要向核心提供有關核心無法自行解釋的檔案系統的資訊。
安裝和設定
要使用FUSE庫,您需要在Reptilian中安裝它,並更改FUSE許可權:
$sudo apt-install libfuse dev-fuse
$sudo chmod 666/dev/fuse
注意:如果重新啟動虛擬機器,則需要重新新增FUSE許可權,因為它們將被重置!
生成指令
為了使用FUSE庫系統構建程式,您需要將檔案偏移位指定為64和
識別FUSE版本。我們建議指定FUSE版本26(儘管這是可選的):
$g++-D_FILE_OFFSET_BITS=64-DFUSE_USE_VERSION=26 myproggy.cpp-o myproggy-lfuse
提交的資料
您將在本專案結束時提交以下內容:
Canvas上的手冊頁格式的報告(p3.txt),包括未列出的放映影片的連結
Canvas上libWad庫和wadfs守護程序的壓縮tar存檔(wad.tar.gz)
彙報
您的報告將解釋您是如何實現守護程序的,包括您的通用體系結構/程式
結構它必須包括如何將WAD檔案元素表示為目錄結構的說明
記憶體中,以及執行時守護程序如何使用此結構。它將包括
關於如何執行測試以及任何已知錯誤的描述。報告不應超過600
單詞,涵蓋專案的所有相關方面,並以專業的方式組織和格式化——這不是
備忘檔案和目錄要求您的守護程序必須至少實現以下檔案系統功能才能提供讀寫功能
通道
1) 正在檢索檔案和目錄屬性
2) 從現有檔案中讀取,並寫入新檔案
3) 從現有目錄中讀取,並寫入新目錄
檔案和目錄應具有完全的讀取、寫入和執行許可權。至少使用以下六個保險絲回撥函式來實現上述要求:get_attr、mknod、mkdir、讀取、寫入和讀取dir
強烈建議密切關注此pdf底部的連結資源,以幫助您FUSE實現。對檔案系統的所有更改(如目錄和檔案建立)都必須在
安裝和拆卸。要構建庫和守護程序,我們將執行以下命令:
$tar zxvf wad.tar.gz
$cd libWad
製作
$cd。。
$cd wadfs
製作
$cd。。
要執行您的守護程式,我們將執行以下命令:
$ ./wadfs/wadfs somewadfile.wad/some/mount/目錄
要使用您的庫構建另一個程式,我們將執行以下命令:
$c++-o程式名稱原始檔.cpp-L/libWad-lWad