Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- print_padding() {
- [ $1 -eq 0 ] || dd if=/dev/zero bs=$1 count=1 2>/dev/null
- }
- make_tar_member() {
- local name=$1
- local content=$2
- local mode=644
- local uid=1000
- local gid=1000
- local size=${#content}
- local mtime=$(date +%s -r "/tmp/t/$name")
- local type=0
- local link=""
- local username="jow"
- local groupname="jow"
- # 100 byte of padding bytes, using 0x01 since the shell does not tolate null bytes in strings
- local pad=$'\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1'
- # truncate string header values to their maximum length
- name=${name:0:100}
- link=${link:0:100}
- username=${username:0:32}
- groupname=${groupname:0:32}
- # construct header part before checksum field
- local header1="${name}${pad:0:$((100 - ${#name}))}"
- header1="${header1}$(printf '%07d\1' $mode)"
- header1="${header1}$(printf '%07o\1' $uid)"
- header1="${header1}$(printf '%07o\1' $gid)"
- header1="${header1}$(printf '%011o\1' $size)"
- header1="${header1}$(printf '%011o\1' $mtime)"
- # construct header part after checksum field
- local header2="$(printf '%d' $type)"
- header2="${header2}${link}${pad:0:$((100 - ${#link}))}"
- header2="${header2}ustar ${pad:0:1}"
- header2="${header2}${username}${pad:0:$((32 - ${#username}))}"
- header2="${header2}${groupname}${pad:0:$((32 - ${#groupname}))}"
- # calculate checksum over header fields
- local checksum=0
- for byte in $(printf '%s%8s%s' "$header1" "" "$header2" | tr '\1' '\0' | hexdump -ve '1/1 "%u "'); do
- checksum=$((checksum + byte))
- done
- # print member header, padded to 512 byte
- printf '%s%06o\0 %s' "$header1" $checksum "$header2" | tr '\1' '\0'
- print_padding 183
- # print content data, padded to multiple of 512 byte
- printf "%s" "$content"
- print_padding $((512 - (size % 512)))
- }
- {
- make_tar_member "example.txt" "Hello there"
- make_tar_member "example-2.txt" "Blah blah"
- # alternatively, instead of printing the trailing padding, run a `tar -c ...` here
- print_padding 1024
- } | gzip > /tmp/test.tar.gz
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement