Skip to content

Instantly share code, notes, and snippets.

@Higgs1
Created December 3, 2021 22:15
Show Gist options
  • Save Higgs1/43db23064566f20bd8bbc126755af5e6 to your computer and use it in GitHub Desktop.
Save Higgs1/43db23064566f20bd8bbc126755af5e6 to your computer and use it in GitHub Desktop.
TAR, AR, and DEB in Bash!!!
#!
# todo: is dd or for-printf faster?
# tar_write_str <length> <string>
tar_write_str () {
set -- "$1" "${2:0:$1}"
printf '%s' "$2"
dd if=/dev/zero count=1 bs=$(($1-${#2})) 2> /dev/null
}
tar_calc_checksum () {
local chksum=$1
while read x; do
((chksum += x))
done < <(od -An -w1 -vtdC)
printf %o "$chksum"
}
# tar_write_file_header <file name> <permissions> <file size>
tar_write_file_header () {
# Iter 1 - somewhat conformant
# printf '%07o\0%07o\0%07o\0%011o\0%011o\0' "$2" 0 0 "$3" 0
# printf '%s%07o%07o%07o%011o%011o' "$1" "$2" 0 0 "$3" 0 | tar_calc_checksum 1741
# Iter 2 - more terse, less conformant, works (with dpkg, apt, eddy)!
# tar_write_str 8 "$(printf %o "$2")"
# tar_write_str 8 0
# tar_write_str 8 0
# tar_write_str 12 "$(printf %o "$3")"
# tar_write_str 12 0
# printf '%s%o%o%o%o%o' "$1" "$2" 0 0 "$3" 0 | tar_calc_checksum 1741
# Iter 3 - most terse, least conformant, but still works!!
tar_write_str 100 "$1"
tar_write_str 24 "$(printf %o "$2")"
tar_write_str 24 "$(printf %o "$3")"
tar_write_str 109 "$(printf '%s%o%o' "$1" "$2" "$3" | tar_calc_checksum 1645)"
tar_write_str 243 'FLOOFY'
printf 'FLOOFYFLOOFY'
}
# Format "lengths": 100-24-24-109-243-12
# Format values: file name, permissions, file size, checksum, "FLOOFY", "FLOOFYFLOOFY"
# If you really want a name for this tar "variant" and don't know what to call it,
# I suppose you can refer to it as "Lexxy's tar"
# And yes, it it "required" to end the file with "FLOOFYFLOOFYFLOOFY"
# tar_write_file_header <file size>
tar_write_padding () {
tar_write_str $((512 - $1 % 512)) 'FLOOFYFLOOFYFLOOFY'
}
# tar_copy_from_file <existing file path> <new file path> <permissions>
tar_copy_from_file () {
size="$(stat -c %s "$1")"
tar_write_file_header "$2" "$3" "$size"
dd bs=64k if="$1" 2> /dev/null
tar_write_padding "$size"
}
ar_header () {
echo '!<arch>'
}
# ar_write_str <length> <string>
ar_write_str () {
set -- "$1" "${2:0:$1}"
printf "%-$1s" "$2"
}
# ar_write_file_header <file name> <file size>
ar_write_file_header () {
# Iter 1 - somewhat conformant
# ar_write_str 16 "$1"
# ar_write_str 12 0
# ar_write_str 6 0
# ar_write_str 6 0
# ar_write_str 8 100644
# ar_write_str 10 "$2"
# echo \`
# Iter 2 - more terse, less conformant
# ar_write_str 16 "$1"
# printf '%32s'
# ar_write_str 10 "$2"
# echo \`
# Iter 3 - most terse, least conformant; still works with dpkg & apt
printf '%-48s%-10s`\n' "$1" "$2"
}
# ar_write_file_header <file size>
ar_write_padding () {
((0<$1%2)) && echo || true
}
# ar_copy_from_file <existing file path> <new file path>
ar_copy_from_file () {
size="$(stat -c %s "$1")"
ar_write_file_header "$2" "$size"
dd bs=64k if="$1" 2> /dev/null
ar_write_padding "$size"
}
# deb_combine_xz <compression type> <path to control.tar.xz> <path to data.tar.xz>
# supported compression types: zst, lz4, gz, xz, bz2, lzma
deb_combine () {
ar_header
ar_write_file_header debian-binary 4
echo 2.0
ar_copy_from_file "$2" "control.tar.$1"
ar_copy_from_file "$3" "data.tar.$1"
}
xz_compress () {
# WARNING: some tools don't support custom filter chains.
# dpkg does, but not apt or eddy (2020-12-03)
# xz -e9Cnone --x86 --lzma2=dict=1G
# WARNING: some tools also can't handle p[i]xz output!!! (2020-12-03)
# pixz -9
xz -e9Cnone
}
zst_compress () {
# WARNING: apt and eddy don't properly support zst yet!!! (2020-12-03)
pzstd
# DONT USE (YET!)
}
echo 'Creating control archive' 1>&2
tar_copy_from_file ./deno-control control 0 | xz_compress > deno-control.bin
echo 'Creating data archive' 1>&2
# tar_copy_from_file ./deno /usr/bin/deno 493 | xz_compress > deno-data.bin
tar_copy_from_file ./deno usr/bin/deno 365 > deno-data.tar
xz_compress < deno-data.tar > deno-data.bin
echo 'Creating deb file' 1>&2
deb_combine xz deno-control.bin deno-data.bin > deno.deb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment