mkaptsrc: Use `local' for tracking paintedness of tags.
[distorted-bits] / fetch-unpack-archive
1 #! /bin/sh
2 ###
3 ### Fetch an archive, and unpack it into a directory in a safe manner.
4
5 set -e
6
7 ## Parse the command line.
8 case $# in
9 3) ;;
10 *) echo >&2 "usage: $0 DIR LABEL URL"; exit 1 ;;
11 esac
12 dir=$1 label=$2 url=$3
13 cd "$dir"
14
15 ## Fetch the archive.
16 rm -rf tmp; mkdir tmp
17 curl -s -o tmp/"$label.tar.gz" "$url"
18
19 ## Check the archive for unpleasantness. The GNU and FreeBSD versions of
20 ## tar(1) do something vaguely sensible with `..' components in the pathnames
21 ## of archive members. (Specifically, FreeBSD simply ignores the affected
22 ## members; GNU strips leading components in a bizarre way.) But OpenBSD
23 ## gets a special security award for cheerily following the `..' components.
24 ## So we have to do this complicated laundering thing.
25 ##
26 ## The archive ought to unpack everything into a single directory and not
27 ## contain anythig weird. So check. Actually, this won't catch newlines in
28 ## member names, so we'll have to be careful about those. The regular
29 ## expression insists that everything be in a single directory identified by
30 ## the LABEL, and that the rest of the name contains no two adjacent dots.
31 ## We use the LABEL as part of an ERE, so it ought not contain bad things.
32 if
33 tar tzf tmp/"$label.tar.gz" |
34 grep -Ev "^$label/([^.]+|\.[^.])*$" >&2
35 then
36 echo >&2 "$0: archive has bad member pathnames"
37 exit 1
38 fi
39
40 ## Unpack the archive now that we know it's safe.
41 (cd tmp; tar xzf "$label.tar.gz")
42
43 ## Replace any existing tree with the new one.
44 rm -rf "$label"
45 mv tmp/"$label" .
46 rm -rf tmp