24 |
# ^M <--------- extra empty line |
# ^M <--------- extra empty line |
25 |
# -----------------------------29995809218093749221856446032--^M |
# -----------------------------29995809218093749221856446032--^M |
26 |
|
|
|
# Beware: bashism $'\r' is used to handle ^M |
|
|
|
|
27 |
file=/tmp/$$-$RANDOM |
file=/tmp/$$-$RANDOM |
28 |
|
|
29 |
|
CR=`printf '\r'` |
30 |
|
|
31 |
# CGI output must start with at least empty line (or headers) |
# CGI output must start with at least empty line (or headers) |
32 |
printf '\r\n' |
printf '\r\n' |
33 |
|
|
34 |
IFS=$'\r' |
IFS="$CR" |
35 |
read -r delim_line |
read -r delim_line |
36 |
|
IFS="" |
|
IFS='' |
|
|
delim_line="${delim_line}--"$'\r' |
|
37 |
|
|
38 |
while read -r line; do |
while read -r line; do |
39 |
test "$line" = '' && break |
test x"$line" = x"" && break |
40 |
test "$line" = $'\r' && break |
test x"$line" = x"$CR" && break |
41 |
done |
done |
42 |
|
|
43 |
# This will not work well for binary files: bash 3.2 is upset |
cat >"$file" |
|
# by reading NUL bytes and loses chunks of data. |
|
|
# If you are not bothered by having junk appended to the uploaded file, |
|
|
# consider using simple "cat >file" instead of the entire |
|
|
# fragment below. |
|
44 |
|
|
45 |
while read -r line; do |
# We need to delete the tail of "\r\ndelim_line--\r\n" |
46 |
|
tail_len=$((${#delim_line} + 6)) |
47 |
|
|
48 |
|
# Get and check file size |
49 |
|
filesize=`stat -c"%s" "$file"` |
50 |
|
test "$filesize" -lt "$tail_len" && exit 1 |
51 |
|
|
52 |
|
# Check that tail is correct |
53 |
|
dd if="$file" skip=$((filesize - tail_len)) bs=1 count=1000 >"$file.tail" 2>/dev/null |
54 |
|
printf "\r\n%s--\r\n" "$delim_line" >"$file.tail.expected" |
55 |
|
if ! diff -q "$file.tail" "$file.tail.expected" >/dev/null; then |
56 |
|
printf "<html>\n<body>\nMalformed file upload" |
57 |
|
exit 1 |
58 |
|
fi |
59 |
|
rm "$file.tail" |
60 |
|
rm "$file.tail.expected" |
61 |
|
|
62 |
|
# Truncate the file |
63 |
|
dd of="$file" seek=$((filesize - tail_len)) bs=1 count=0 >/dev/null 2>/dev/null |
64 |
|
|
65 |
while test "$line" = $'\r'; do |
printf "<html>\n<body>\nFile upload has been accepted" |
|
read -r line |
|
|
test "$line" = "$delim_line" && { |
|
|
# Aha! Empty line + delimiter! All done |
|
|
cat <<EOF |
|
|
<html> |
|
|
<body> |
|
|
File upload has been accepted |
|
|
EOF |
|
|
exit 0 |
|
|
} |
|
|
# Empty line + NOT delimiter. Save empty line, |
|
|
# and go check next line |
|
|
printf "%s\n" $'\r' -vC >&3 |
|
|
done |
|
|
# Not empty line - just save |
|
|
printf "%s\n" "$line" -vC >&3 |
|
|
done 3>"$file" |
|
|
|
|
|
cat <<EOF |
|
|
<html> |
|
|
<body> |
|
|
File upload was not terminated with '$delim_line' - ??! |
|
|
EOF |
|