A simple file system and a CLI tool designed for educational purposes and experimental use.
JSDAT-1 is a custom file system with the following on-disk layout:
+-----------------------------------+
| Boot Area (4096 bytes) | - Space for bootloader
+-----------------------------------+
| Superblock (512 bytes) | - Filesystem metadata
+-----------------------------------+
| FSEntries (n x 128 bytes) | - Directory entries
+-----------------------------------+
| FAT (n x 4 bytes) | - File Allocation Table
+-----------------------------------+
| Data Area (n x sector size) | - Actual file content
+-----------------------------------+
1. Install Go
- Linux: use your distro's package manager or follow the instructions at https://go.dev/dl/
# Fedora sudo dnf install golang # Ubuntu/Debian sudo apt install golang-go
- macOS: install via Homebrew or download from https://go.dev/dl/
brew install go
- Windows: download and run the installer from https://go.dev/dl/
2. Build
Inside the project directory run:
go buildThis produces a datotekomat binary (or datotekomat.exe on Windows) in the current directory.
3. Run
Either invoke it directly:
./datotekomat # Linux/macOS
.\datotekomat.exe # WindowsOr move it somewhere on your PATH (e.g. /usr/local/bin on Linux/macOS) to call it as just datotekomat from anywhere.
| Parameter | Default | Flag |
|---|---|---|
| TotalSectors | 8 | -ус |
| BytesPerSector | 16 | -бпс |
| TotalFSEntries | 4 | -уст |
| Label | "ЈСДАТ-1" | -етк |
датотекомат [global options] <command> [command flags/arguments]
| Flag | Description |
|---|---|
-п |
Show help |
-в |
Verbose output |
-издање |
Show version |
-пв |
Use deterministic test timestamps |
датотекомат фмт <path>
датотекомат -в фмт -ус 1024 -бпс 512 -уст 64 -етк "МОЈ_СД" myfs.imgFlags for фмт:
| Flag | Description | Default |
|---|---|---|
-ус <n> |
Total sectors | 8 |
-бпс <n> |
Bytes per sector | 16 |
-уст <n> |
Total filesystem entries | 4 |
-етк <str> |
Filesystem label | "ЈСДАТ-1" |
датотекомат осб myfs.imgдатотекомат кпу <local_file> <internal_path> <fs_file>
датотекомат кпу hello.txt / myfs.img
датотекомат кпу data.bin /подаци myfs.imgдатотекомат кпс <internal_path> <external_path> <fs_file>
датотекомат кпс /hello.txt ./extracted.txt myfs.imgкпс only opens plain TYPE_FILE entries; for encrypted entries use кшс.
Prompts twice for a passphrase, derives a 32-byte key with scrypt
(N=32768, r=8, p=1), encrypts with XChaCha20-Poly1305, and stores the
self-describing blob inside fs_file as a TYPE_ENCRYPTED (0x04) entry.
датотекомат кшу <local_file> <internal_path> <fs_file>
датотекомат кшу secret.txt / myfs.img
# → Лозинка за шифровање: ******
# → Поновите лозинку: ******Requires BytesPerSector >= 512, format the image with -бпс 512 or
larger. No -л flag, no DATOTEKOMAT_LOZINKA environment variable: the
prompt is the only way to supply a passphrase, to keep secrets out of
shell history and the ps listing.
Prompts once for the passphrase. CRC32 of the on-disk blob is checked before AEAD decryption so corruption is distinguishable from a wrong passphrase.
датотекомат кшс <internal_path> <external_path> <fs_file>
датотекомат кшс /secret.txt ./out.txt myfs.img
# → Лозинка за дешифровање: ******See ENCRYPTION.md for the exact on-disk layout and a golden
test vector you can use to port the decoder to another language.
For a step-by-step live demo (format, plain vs encrypted copy, verify on
disk), see ../test/setup.txt.
датотекомат лс <path> <fs_file>
датотекомат лс / myfs.imgдатотекомат стабло <path> <fs_file>
датотекомат стабло / myfs.imgExample output:
/ (8.00Б)
├── систем/ (4.00Б)
│ └── kernel.bin (512.00Б)
└── подаци/ (4.00Б)
└── config.txt (32.00Б)
датотекомат пнј <existing_path> <new_name> <fs_file>
датотекомат пнј /old.txt new.txt myfs.imgдатотекомат обш <path> <fs_file>
датотекомат обш /hello.txt myfs.imgдатотекомат нпфас <path> <fs_file>
датотекомат нпфас /подаци myfs.imgдатотекомат прист <path> <mode> <fs_file>
датотекомат прист /hello.txt 750 myfs.imgдатотекомат иб <path> <uid:gid> <fs_file>
датотекомат иб /hello.txt 1000:1000 myfs.imgдатотекомат вежи <destination> <link_name> <fs_file>
датотекомат вежи /hello.txt /пречица myfs.imgдатотекомат упдч <bootloader_file> <fs_file>
датотекомат упдч boot.bin myfs.imgдатотекомат етк <new_label> <fs_file>
датотекомат етк "MY_FS" myfs.imgдатотекомат врм <path> <label> <time> <fs_file>
датотекомат врм /hello.txt н 15.01.2025-10:30:00 myfs.imgLabels: н (created), и (modified), п (accessed).
Time format: dd.mm.yyyy-hh:mm:ss.
# Create a filesystem with custom parameters
датотекомат -в фмт -ус 1024 -бпс 512 -уст 100 myfs.img
# Create directory structure
датотекомат нпфас /систем myfs.img
датотекомат нпфас /подаци myfs.img
# Copy files in
датотекомат кпу kernel.bin /систем myfs.img
датотекомат кпу config.txt /подаци myfs.img
# List contents
датотекомат лс / myfs.img
# Show tree view
датотекомат стабло / myfs.img
# Add bootloader
датотекомат упдч boot.bin myfs.img
# Inspect the filesystem
датотекомат осб myfs.img- Files (0x01): Regular files with data
- Folders (0x02): Directories containing other entries
- Links (0x03): Symbolic links pointing to other entries
- Encrypted files (0x04): XChaCha20-Poly1305 + scrypt blobs;
managed by
кшу/кшс, listed with the prefixш. The FSEntry'sSizeandChecksumdescribe the on-disk blob, not the plaintext. All other commands (лс,обш,пнј,прист,иб,врм) work without a passphrase since they only touch metadata.
- Name: 62 bytes (up to 31 UTF-8 characters or 62 ASCII characters)
- Permissions: Unix-style rwx for user, group, and world
- Ownership: UID (2 bytes) and GID (2 bytes)
- Timestamps: Creation, modification, and access times (14 bytes each)
- Checksum: CRC32 for data integrity verification
- Size: File size in bytes (uint32)
- Max file size: min(~4 GB, TotalSectors x BytesPerSector)
- Max filename: 62 bytes (62 ASCII chars or ~31 UTF-8 chars);
?is reserved - Max sectors: ~4 billion (uint32), practically much less
- Folders must be empty before deletion; root folder cannot be deleted
- One FSEntry consumed per file, folder, link, or encrypted file
- No fragmentation management, journaling, or compression
- Encryption is selective (per-file, like eCryptfs), not whole-volume.
Filenames, sizes, timestamps and permissions remain visible, see
threat model in
ENCRYPTION.md. Encryption requiresBytesPerSector >= 512. - No atomicity guarantee across superblock / FAT / FSEntry writes
(pre-existing for
кпу/кшу): a crash mid-copy may leave a small inconsistency. Nofsckis shipped.
- Simple structure, great for learning filesystem concepts
- Fully configurable sector size and entry count
- Self-contained in a single file, portable across platforms
- Dedicated boot area for custom bootloaders
- CRC32 checksums for detecting data corruption
- Unix-style permissions with user/group/world
- Native UTF-8 filename support
- Symbolic link support
Једноставан систем датотека и алат за командну линију намењен образовним и експерименталним потребама.
ЈСДАТ-1 је прилагођени систем датотека са следећим распоредом на диску:
+-----------------------------------+
| Подизач (4096 бајтова) | - Простор за подизач система
+-----------------------------------+
| Супер-блок (512 бајтова) | - Метаподаци система датотека
+-----------------------------------+
| СД ставке (н x 128 бајтова) | - Ставке фасцикли
+-----------------------------------+
| ТДД (н x 4 бајта) | - Табела доделе датотека
+-----------------------------------+
| Податковна област (н x сектор) | - Стварни садржај датотека
+-----------------------------------+
1. Инсталација Go-а
- Linux: преко управника пакета дистрибуције или пратећи упутства са https://go.dev/dl/
# Федора sudo dnf install golang # Убунту/Дебијан sudo apt install golang-go
- macOS: преко Homebrew-а или преузимањем са https://go.dev/dl/
brew install go
- Windows: преузети и покренути инсталациони програм са https://go.dev/dl/
2. Градња
У директоријуму пројекта покренути:
go buildРезултат је извршна датотека datotekomat (или datotekomat.exe на Windows-у) у тренутном директоријуму.
3. Покретање
Директно из директоријума:
./datotekomat # Linux/macOS
.\datotekomat.exe # WindowsИли преместити у путању претраге (PATH). Нпр. /usr/local/bin на Linux/macOS ради позивања са било ког места као datotekomat.
| Параметар | Подразумевано | Заставица |
|---|---|---|
| Укупно сектора | 8 | -ус |
| Бајтова по сектору | 16 | -бпс |
| Укупно СД ставки | 4 | -уст |
| Етикета | "ЈСДАТ-1" | -етк |
датотекомат [опције] <наредба> [заставице/аргументи наредбе]
| Заставица | Опис |
|---|---|
-п |
Приказ помоћи |
-в |
Више појединости током рада |
-издање |
Приказ издања |
-пв |
Коришћење пробних временских ознака |
датотекомат фмт <путања>
датотекомат -в фмт -ус 1024 -бпс 512 -уст 64 -етк "МОЈ_СД" мојсд.слкЗаставице за фмт:
| Заставица | Опис | Подразумевано |
|---|---|---|
-ус <н> |
Укупно сектора | 8 |
-бпс <н> |
Бајтова по сектору | 16 |
-уст <н> |
Укупно ставки система датотека | 4 |
-етк <низ> |
Етикета система датотека | "ЈСДАТ-1" |
датотекомат осб мојсд.слкдатотекомат кпу <локална_датотека> <унутрашња_путања> <систем_датотека>
датотекомат кпу здраво.ткт / мојсд.слк
датотекомат кпу подаци.бин /подаци мојсд.слкдатотекомат кпс <унутрашња_путања> <спољна_путања> <систем_датотека>
датотекомат кпс /здраво.ткт ./извучено.ткт мојсд.слкПоднаредба кпс отвара само обичне TYPE_FILE ставке, за шифроване користите кшс.
Двапут пита за лозинку, изводи 32-бајтни кључ scrypt-ом (N=32768, r=8,
p=1), шифрује XChaCha20-Poly1305 и складишти самоописни блок у
систем_датотека као СД ставку типа TYPE_ENCRYPTED (0x04).
датотекомат кшу <локална_датотека> <унутрашња_путања> <систем_датотека>
датотекомат кшу тајна.ткт / мојсд.слк
# → Лозинка за шифровање: ******
# → Поновите лозинку: ******Захтева бајтова по сектору >= 512, форматирајте са -бпс 512 или већим.
Интерактивни упит је једини начин уноса лозинке зарад веће безбедности.
Једном пита за лозинку. CRC32 блока се проверава пре дешифровања, тако да се оштећење разликује од погрешне лозинке.
датотекомат кшс <унутрашња_путања> <спољна_путања> <систем_датотека>
датотекомат кшс /тајна.ткт ./отворено.ткт мојсд.слк
# → Лозинка за дешифровање: ******Тачан распоред бајтова на диску и златни тест вектор описани су у
ENCRYPTION.md, довољно за пренос декодера у други језик.
За живи приказ корак по корак (форматирање, обична и шифрована датотека,
провера на диску) погледајте ../test/setup.txt.
датотекомат лс <путања> <систем_датотека>
датотекомат лс / мојсд.слкдатотекомат стабло <путања> <систем_датотека>
датотекомат стабло / мојсд.слкПример излаза:
/ (8.00Б)
├── систем/ (4.00Б)
│ └── језгро.бин (512.00Б)
└── подаци/ (4.00Б)
└── подешавања.ткт (32.00Б)
датотекомат пнј <постојећа_путања> <нови_назив> <систем_датотека>
датотекомат пнј /старо.ткт ново.ткт мојсд.слкдатотекомат обш <путања> <систем_датотека>
датотекомат обш /здраво.ткт мојсд.слкдатотекомат нпфас <путања> <систем_датотека>
датотекомат нпфас /подаци мојсд.слкдатотекомат прист <путања> <овлашћење> <систем_датотека>
датотекомат прист /здраво.ткт 750 мојсд.слкдатотекомат иб <путања> <иб_корисника:иб_групе> <систем_датотека>
датотекомат иб /здраво.ткт 1000:1000 мојсд.слкдатотекомат вежи <одредиште> <назив_везе> <систем_датотека>
датотекомат вежи /здраво.ткт /пречица мојсд.слкдатотекомат упдч <датотека_подизача> <систем_датотека>
датотекомат упдч подизач.бин мојсд.слкдатотекомат етк <нова_етикета> <систем_датотека>
датотекомат етк "МОЈ_СД" мојсд.слкдатотекомат врм <путања> <ознака> <време> <систем_датотека>
датотекомат врм /здраво.ткт н 15.01.2025-10:30:00 мојсд.слкОзнаке: н (настанак), и (измена), п (приступ).
Формат времена: дд.мм.гггг-чч:мм:сс.
# Стварање система датотека са прилагођеним параметрима
датотекомат -в фмт -ус 1024 -бпс 512 -уст 100 мојсд.слк
# Стварање структуре фасцикли
датотекомат нпфас /систем мојсд.слк
датотекомат нпфас /подаци мојсд.слк
# Копирање датотека унутар
датотекомат кпу језгро.бин /систем мојсд.слк
датотекомат кпу подешавања.ткт /подаци мојсд.слк
# Листање садржаја
датотекомат лс / мојсд.слк
# Приказ стабла
датотекомат стабло / мојсд.слк
# Упис подизача система
датотекомат упдч подизач.бин мојсд.слк
# Преглед система датотека
датотекомат осб мојсд.слк- Датотеке (0x01): Обичне датотеке са подацима
- Фасцикле (0x02): Фасцикле које садрже друге ставке
- Везе (0x03): Симболичке везе ка другим ставкама
- Шифроване датотеке (0x04): XChaCha20-Poly1305 + scrypt блокови;
њима управљају наредбе
кшуикшс, а у листингу су означене саш. ПољаSizeиChecksumу СД ставци описују блок на диску, не отворени текст. Остале наредбе (лс,обш,пнј,прист,иб,врм) раде без лозинке јер додирују само метаподатке.
- Назив: 62 бајтова (до 31 UTF-8 знак или 62 ASCII знака)
- Овлашћења: чпш (читање, писање, извршавање) за корисника, групу и остале
- Власништво: ИБ корисника (2 бајта) и ИБ групе (2 бајта)
- Временске ознаке: настанак, измена и приступ (14 бајтова свака)
- Контролни збир: CRC32 за проверу целовитости
- Величина: величина у бајтовима (uint32)
- Највећа датотека: мин(~4 ГБ, укупно сектора x бајтова по сектору)
- Највећи назив: 62 бајтова (62 ASCII знака или ~31 UTF-8 знак);
?је резервисан - Највише сектора: ~4 милијарде (uint32), практично знатно мање
- Фасцикле морају бити празне пре брисања; коренска фасцикла не може бити обрисана
- Једна СД ставка по датотеци, фасцикли, вези или шифрованој датотеци
- Без управљања фрагментацијом, журнала или компресије
- Шифровање је селективно (на нивоу датотеке, попут eCryptfs-а), не
целог тома. Називи, величине, временске ознаке и овлашћења остају
видљиви. Шифровање захтева
Бајтова по сектору >= 512. - Без гаранције атомичности упис(а) супер-блока / ТДД / СД ставке
(важи и за
кпуи закшу): пад у току копирања може оставити малу неконзистентност.fsckалат није у понуди.
- Једноставна структура, одлична за учење о системима датотека
- Потпуно подесива величина сектора и броја ставки
- Самосадржана у једној датотеци, преносива на различите платформе
- Наменски простор за подизач система
- CRC32 контролни збирови за откривање оштећења података
- Овлашћења по узору на Јуникс (корисник/група/остали)
- Изворна подршка за UTF-8 називе датотека
- Подршка за симболичке везе