From 29f8b91814577ca094538c5c55b3014998057e69 Mon Sep 17 00:00:00 2001 From: lovelywcm Date: Sun, 18 Apr 2010 07:14:09 +0000 Subject: [PATCH] bW9yZSByb2J1c3QgZXJyb3IgaGFuZGluZwo= --- sendGFWList.sh | 68 ++++++++++++++++++++++++++------------------- validateChecksum.pl | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 28 deletions(-) create mode 100755 validateChecksum.pl diff --git a/sendGFWList.sh b/sendGFWList.sh index a19f45a..b05d36f 100755 --- a/sendGFWList.sh +++ b/sendGFWList.sh @@ -29,17 +29,17 @@ ################################################################################ # dependence -for cmd in sed date base64 gawk svn git perl +for cmd in sed date base64 gawk svn git perl file do which $cmd &> /dev/null; if [ $? -ne 0 ]; then - echo "Depends on $cmd, please install it first."; + echo "Error: depends on $cmd, please install it first."; exit 1; fi done # get formated author and log information -log=$(svn log -r BASE:HEAD) && +log=$(svn log -r BASE:HEAD) || exit 1; log=$(echo $log | gawk -v RS='------------------------------------------------------------------------'\ 'NR > 2 { if (NF > 10) printf "%s:%s;", $3, $NF; }' ) && @@ -55,7 +55,7 @@ do # discard used string log=${log#*:}; else # log, decode it - temp=$( echo ${log%%;*} | base64 -d); + temp=$( echo ${log%%;*} | base64 -d ); convertedLog+=$temp; convertedLog+="\n"; log=${log#*;}; @@ -63,54 +63,66 @@ do ((i++)); done -# modified by others, commit to local git repository. +# modified by others, commit to local git repository if [ "$convertedLog" != "" ]; then - svn update && + git diff > temp.patch && - # save local modification - [ -n "$(git diff)" ] && git diff > temp.patch; + svn update || exit 1; - base64 -d gfwlist.txt > list.txt && - echo -e $convertedLog | git commit -a -F - ; + base64 -d gfwlist.txt > list.txt && ./validateChecksum.pl list.txt; + if [ $? -ne 0 ]; then + echo "Error: gfwlist.txt from svn is invalid!"; + echo "It must be a download error or somebody made a mistake."; + echo "Please check with the last committer or report to maintainers group."; + exit 1; + fi + + echo -e $convertedLog | git commit -a -F - && - # apply local modification [ -s temp.patch ] && git apply temp.patch && - rm temp.patch; + rm temp.patch && + + # remove (if exist) empty temp.patch + [ ! -s temp.patch -a -e temp.patch ] && rm temp.patch; fi if [ "$(git diff)" == "" ]; then - echo "list.txt not modified."; + echo "Info: list.txt not modified."; exit 0; fi if [ "$*" == "" ]; then - echo "Empty log, please say something about this modification."; + echo "Error: empty log, please say something about this modification."; exit 1; fi -# make sure the list doesn't contain unicode chars -file list.txt | grep ASCII 1> /dev/null || -( - echo "List contains non-ASCII characters, please remove them." && +if [ "$(file list.txt)" != "list.txt: ASCII text" ]; then + echo "Error: list.txt, please make sure:"; + echo "1. there is no non-ASCII characters;"; + echo "2. configure your text editor to use unix style line break."; exit 1; -) && +fi # update date and checksum -sed -i s/"Last Modified:.*$"/"Last Modified: $(date -R -r list.txt)"/ list.txt && +sed -i s/"Last Modified:.*$"/"Last Modified: $(date -Rr list.txt)"/ list.txt && ./addChecksum.pl list.txt && -# save self change to git. exit directly if conflicting. +# save local changes to git & svn +# if conflict or network problem occurs: do nothing & throw error message git commit -a -m "$*" && - -# commit to remote svn server -base64 list.txt > gfwlist.txt && ( - # "svn ci" and "git commit" are atomic operations + base64 list.txt > gfwlist.txt && + + # may be running under Windows + Cygwin? + # convert dos new line to unix style, old mac style ignored + sed -i 's/\r$//g' gfwlist.txt && + + # may be failed because of connection/authentication problems svn ci gfwlist.txt -m $( echo "$*" | base64 -w 0) || - # "svn ci" may be failed because of connection problems. + + # "svn ci" and "git commit" are atomic operations git reset HEAD^ 1> /dev/null; ) && -# BASE++, HEAD++, if committed. +# BASE++ if committed svn update 1> /dev/null; - diff --git a/validateChecksum.pl b/validateChecksum.pl new file mode 100755 index 0000000..a0efbf9 --- /dev/null +++ b/validateChecksum.pl @@ -0,0 +1,55 @@ +#!/usr/bin/perl + +############################################################################# +# This is a reference script to validate the checksum in downloadable # +# subscription. This performs the same validation as Adblock Plus when it # +# downloads the subscription. # +# # +# To validate a subscription file, run the script like this: # +# # +# perl validateChecksum.pl subscription.txt # +# # +# Note: your subscription file should be saved in UTF-8 encoding, otherwise # +# the validation result might be incorrect. # +# # +# 20100418: Stolen from ABP with minor modification for AutoProxy project # +############################################################################# + +use strict; +use warnings; +use Digest::MD5 qw(md5_base64); + +die "Usage: $^X $0 subscription.txt\n" unless @ARGV; + +my $file = $ARGV[0]; +my $data = readFile($file); + +# Normalize data +$data =~ s/\r//g; +$data =~ s/\n+/\n/g; + +# Extract checksum + +# Remove checksum +$data =~ s/^\s*!\s*checksum[\s\-:]+([\w\+\/=]+).*\n//mi; +my $checksum = $1; +die "Error: couldn't find a checksum in the file\n" unless $checksum; + +# Calculate new checksum +my $checksumExpected = md5_base64($data); + +# Compare checksums +die "Error: invalid checksum\n" unless $checksum eq $checksumExpected; + +sub readFile +{ + my $file = shift; + + open(local *FILE, "<", $file) || die "Error: could not read file '$file'"; + binmode(FILE); + local $/; + my $result = ; + close(FILE); + + return $result; +}