1 # SPDX-License-Identifier: GPL-2.0-or-later OR MIT
6 # tar_print_member "date.txt" "It's $(date +"%Y")"
10 __tar_print_padding
() {
11 dd if=/dev
/zero bs
=1 count
=$1 2>/dev
/null
17 local mtime
="${3:-$(date +%s)}"
21 local size
=${#content}
25 local groupname
="root"
27 # 100 byte of padding bytes, using 0x01 since the shell does not tolerate null bytes in strings
28 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'
30 # validate name (strip leading slash if present)
33 # truncate string header values to their maximum length
36 username
=${username:0:32}
37 groupname
=${groupname:0:32}
39 # construct header part before checksum field
40 local header1
="${name}${pad:0:$((100 - ${#name}))}"
41 header1
="${header1}$(printf '%07d\1' $mode)"
42 header1
="${header1}$(printf '%07o\1' $uid)"
43 header1
="${header1}$(printf '%07o\1' $gid)"
44 header1
="${header1}$(printf '%011o\1' $size)"
45 header1
="${header1}$(printf '%011o\1' $mtime)"
47 # construct header part after checksum field
48 local header2
="$(printf '%d' $type)"
49 header2
="${header2}${link}${pad:0:$((100 - ${#link}))}"
50 header2
="${header2}ustar ${pad:0:1}"
51 header2
="${header2}${username}${pad:0:$((32 - ${#username}))}"
52 header2
="${header2}${groupname}${pad:0:$((32 - ${#groupname}))}"
54 # calculate checksum over header fields
56 for byte
in $
(printf '%s%8s%s' "$header1" "" "$header2" |
tr '\1' '\0' |
hexdump -ve '1/1 "%u "'); do
57 checksum
=$
((checksum
+ byte
))
60 # print member header, padded to 512 byte
61 printf '%s%06o\0 %s' "$header1" $checksum "$header2" |
tr '\1' '\0'
62 __tar_print_padding
183
64 # print content data, padded to multiple of 512 byte
65 printf "%s" "$content"
66 __tar_print_padding $
((512 - (size
% 512)))
70 __tar_print_padding
1024