-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Helio Machado
committed
Aug 18, 2017
1 parent
c1cbdae
commit 72d04d6
Showing
2 changed files
with
85 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# qdtar | ||
|
||
A `qdtar` archive is a slightly modified `tar` archive, used to pack the root filesystem in the Qisda ES600 e-reader upgrades. The file name used for these archives is `rootfs.img`, even if it has nothing to do with a disk image. | ||
|
||
*** | ||
|
||
The file format is simple: a header of 978 bytes whose contents are completely ignored, prepended to a normal `tar` archive. | ||
|
||
The [executable found on the firmware](busybox) zero-fills the header when creating a new archive. However, the archives found in official firmware upgrade packages used a different approach: | ||
|
||
* The first 970 bytes of the header were filled with a copy of the first 970 bytes of the `tar` file. | ||
* The next 8 bytes were used to store the magic number (`QDTAR1.0`). | ||
|
||
I suspect that the filling of the header with a copy of the first bytes of the `tar` file is a mistake made by the developer of the packer app. Probably the original code shifts the data on a buffer by copying it to the new offset without taking care of zeroing the contents of the header. The other possibility (more conspiranoid) is that copying the first bytes of the `tar` archive will fool a normal decompression utility. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#!/bin/sh | ||
|
||
magic="QDTAR1.0" | ||
|
||
|
||
usage() { | ||
echo "Usage: $0 <mode> <input> <output>" | ||
echo | ||
echo " -p, --pack pack the input file" | ||
echo " -u, --unpack unpack the input file" | ||
echo | ||
echo "Example: $0 --unpack rootfs.img rootfs.tar" | ||
exit 1 | ||
} | ||
|
||
|
||
pack() { | ||
# Function arguments. | ||
input="$1"; output="$2"; | ||
|
||
# Offset 0, length 970: header fill. | ||
dd if="$input" of="$output" bs=970 count=1 | ||
status=$((status + $?)) | ||
|
||
# Offset 970, length 8: magic number. | ||
printf "$magic" | dd of="$output" bs=970 seek=1 | ||
status=$((status + $?)) | ||
|
||
# Offset 978, until EOF: tar file. | ||
dd if="$input" of="$output" bs=978 seek=1 | ||
status=$((status + $?)) | ||
|
||
return $status | ||
} | ||
|
||
|
||
unpack() { | ||
# Function arguments. | ||
input="$1"; output="$2" | ||
|
||
# Warn the user if the magic number is wrong. | ||
if [[ "$(dd if="$input" bs=1 skip=970 count=8)" != "$magic" ]]; then | ||
echo "warning: the magic number is not '$magic'" | ||
fi | ||
|
||
# Extract the tar file. | ||
dd if="$input" of="$output" bs=978 skip=1 | ||
} | ||
|
||
|
||
# Check the number of arguments. | ||
[[ $# != 3 ]] && usage | ||
|
||
# If the output file exists, ask before overwriting. | ||
if test -f "$2"; then | ||
read -p "Output file already exists. Overwrite? [y/N]: " answer | ||
[[ "$answer" != "y" ]] && [[ "$answer" != "Y" ]] && exit 1 | ||
fi | ||
|
||
# Operation mode selection. | ||
case "$1" in | ||
-u|--unpack) log="$(unpack "$1" "$2" 2>&1)";; | ||
-p|--pack) log="$(pack "$1" "$2" 2>&1)";; | ||
*) usage;; | ||
esac | ||
|
||
# Log dump in case of error. | ||
if [[ $? > 0 ]]; then | ||
echo "$log" | ||
fi |