Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2024
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/sh
  2.  
  3. print_padding() {
  4.     [ $1 -eq 0 ] || dd if=/dev/zero bs=$1 count=1 2>/dev/null
  5. }
  6.  
  7. make_tar_member() {
  8.     local name=$1
  9.     local content=$2
  10.     local mode=644
  11.     local uid=1000
  12.     local gid=1000
  13.     local size=${#content}
  14.     local mtime=$(date +%s -r "/tmp/t/$name")
  15.     local type=0
  16.     local link=""
  17.     local username="jow"
  18.     local groupname="jow"
  19.  
  20.     # 100 byte of padding bytes, using 0x01 since the shell does not tolate null bytes in strings
  21.     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'
  22.  
  23.     # truncate string header values to their maximum length
  24.     name=${name:0:100}
  25.     link=${link:0:100}
  26.     username=${username:0:32}
  27.     groupname=${groupname:0:32}
  28.  
  29.     # construct header part before checksum field
  30.     local header1="${name}${pad:0:$((100 - ${#name}))}"
  31.     header1="${header1}$(printf '%07d\1' $mode)"
  32.     header1="${header1}$(printf '%07o\1' $uid)"
  33.     header1="${header1}$(printf '%07o\1' $gid)"
  34.     header1="${header1}$(printf '%011o\1' $size)"
  35.     header1="${header1}$(printf '%011o\1' $mtime)"
  36.  
  37.     # construct header part after checksum field
  38.     local header2="$(printf '%d' $type)"
  39.     header2="${header2}${link}${pad:0:$((100 - ${#link}))}"
  40.     header2="${header2}ustar  ${pad:0:1}"
  41.     header2="${header2}${username}${pad:0:$((32 - ${#username}))}"
  42.     header2="${header2}${groupname}${pad:0:$((32 - ${#groupname}))}"
  43.  
  44.     # calculate checksum over header fields
  45.     local checksum=0
  46.     for byte in $(printf '%s%8s%s' "$header1" "" "$header2" | tr '\1' '\0' | hexdump -ve '1/1 "%u "'); do
  47.         checksum=$((checksum + byte))
  48.     done
  49.  
  50.     # print member header, padded to 512 byte
  51.     printf '%s%06o\0 %s' "$header1" $checksum "$header2" | tr '\1' '\0'
  52.     print_padding 183
  53.  
  54.     # print content data, padded to multiple of 512 byte
  55.     printf "%s" "$content"
  56.     print_padding $((512 - (size % 512)))
  57. }
  58.  
  59.  
  60. {
  61.     make_tar_member "example.txt" "Hello there"
  62.     make_tar_member "example-2.txt" "Blah blah"
  63.  
  64.     # alternatively, instead of printing the trailing padding, run a `tar -c ...` here
  65.     print_padding 1024
  66. } | gzip > /tmp/test.tar.gz
  67.  
  68.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement