-
Notifications
You must be signed in to change notification settings - Fork 24
/
privoxy-adblock.sh
executable file
·199 lines (174 loc) · 7.47 KB
/
privoxy-adblock.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/bin/bash
sedcmd=${SEDCMD:-sed}
defaultprivoxydir="/usr/local/etc/privoxy"
defaulturls=("https://easylist-downloads.adblockplus.org/easylist.txt")
#=== FUNCTION ================================================================
# NAME: cleanup
# DESCRIPTION: cleans up after script termination
# PARAMETERS: none
# RETURNS: none
#===============================================================================
function cleanup() {
trap - INT TERM EXIT
[[ -f "${pidfile}" ]] && rm "$pidfile"
exit
}
#=== FUNCTION ================================================================
# NAME: isrunning
# DESCRIPTION: is any previous instance of this script already running
# PARAMETERS: pid file path
# RETURNS: boolean
#===============================================================================
function isrunning() {
pidfile="${1}"
[[ ! -f "${pidfile}" ]] && return 1 #pid file is nonexistent
procpid=$(<"${pidfile}")
[[ -z "${procpid}" ]] && return 1 #pid file contains no pid
# check process list for pid existence and is an instance of this script
[[ ! $(ps -p ${procpid} | grep $(basename ${0})) == "" ]] && value=0 || value=1
return ${value}
}
#=== FUNCTION ================================================================
# NAME: createpidfile
# DESCRIPTION: atomic creation of pid file with no race condition
# PARAMETERS: the pid to put in the file, the filename to use as a lock
# RETURNS: none
#===============================================================================
function createpidfile() {
mypid=${1}
pidfile=${2}
#Close stderr, don't overwrite existing file, shove my pid in the lock file.
$(exec 2>&-; set -o noclobber; echo "$mypid" > "$pidfile")
[[ ! -f "${pidfile}" ]] && exit #Lock file creation failed
procpid=$(<"${pidfile}")
[[ ${mypid} -ne ${procpid} ]] && {
#I'm not the pid in the lock file
# Is the process pid in the lockfile still running?
isrunning "${pidfile}" || {
# No. Kill the pidfile and relaunch
rm "${pidfile}"
$0 $@
}
exit
}
}
#=== FUNCTION ================================================================
# NAME: pidfilename
# DESCRIPTION: create a predictable pid file name, put it in the right inode
# PARAMETERS: none
# RETURNS: path and filename
#===============================================================================
function pidfilename() {
myfile=$(basename "$0" .sh)
whoiam=$(whoami)
mypidfile="/tmp/${myfile}.pid"
[[ "$whoiam" == 'root' ]] && mypidfile="/var/run/$myfile.pid"
echo $mypidfile
}
#=== FUNCTION ================================================================
# NAME: doconvert
# DESCRIPTION: download requested scripts and perform the conversion
# PARAMETERS: privoxy conf dir, list of urls
# RETURNS: none
#===============================================================================
function doconvert() {
privoxydir=$1
urls=$2
for url in ${urls[@]}
do
file=${tempdir}/$(basename ${url})
actionfile=${file%\.*}.script.action
filterfile=${file%\.*}.script.filter
list=$(basename ${file%\.*})
# clean up files
[[ -f "${file}" ]] && rm "${file}"
[[ -f "${actionfile}" ]] && rm "${actionfile}"
[[ -f "${filterfile}" ]] && rm "${filterfile}"
echo "downloading ${url} ..."
wget -t 3 --no-check-certificate -O ${file} "${url}" >${tempdir}/wget-${url//\//#}.log 2>&1
[ "$(grep -E '^.*\[Adblock.*\].*$' ${file})" == "" ] && echo "The list recieved from ${url} isn't an AdblockPlus list. Skipped" && continue
echo "Creating actionfile for ${list} ..."
echo -e "{ +block{${list}} }" > ${actionfile}
$sedcmd '/^!.*/d;1,1 d;/^@@.*/d;/\$.*/d;/#/d;s/\./\\./g;s/\?/\\?/g;s/\*/.*/g;s/(/\\(/g;s/)/\\)/g;s/\[/\\[/g;s/\]/\\]/g;s/\^/[\/\&:\?=_]/g;s/^||/\./g;s/^|/^/g;s/|$/\$/g;/|/d' ${file} >> ${actionfile}
echo "... creating filterfile for ${list} ..."
echo "FILTER: ${list} Tag filter of ${list}" > ${filterfile}
$sedcmd '/^#/!d;s/^##//g;s/^#\(.*\)\[.*\]\[.*\]*/s@<([a-zA-Z0-9]+)\\s+.*id=.?\1.*>.*<\/\\1>@@g/g;s/^#\(.*\)/s@<([a-zA-Z0-9]+)\\s+.*id=.?\1.*>.*<\/\\1>@@g/g;s/^\.\(.*\)/s@<([a-zA-Z0-9]+)\\s+.*class=.?\1.*>.*<\/\\1>@@g/g;s/^a\[\(.*\)\]/s@<a.*\1.*>.*<\/a>@@g/g;s/^\([a-zA-Z0-9]*\)\.\(.*\)\[.*\]\[.*\]*/s@<\1.*class=.?\2.*>.*<\/\1>@@g/g;s/^\([a-zA-Z0-9]*\)#\(.*\):.*[:[^:]]*[^:]*/s@<\1.*id=.?\2.*>.*<\/\1>@@g/g;s/^\([a-zA-Z0-9]*\)#\(.*\)/s@<\1.*id=.?\2.*>.*<\/\1>@@g/g;s/^\[\([a-zA-Z]*\).=\(.*\)\]/s@\1^=\2>@@g/g;s/\^/[\/\&:\?=_]/g;s/\.\([a-zA-Z0-9]\)/\\.\1/g' ${file} >> ${filterfile}
echo "... filterfile created - adding filterfile to actionfile ..."
echo "{ +filter{${list}} }" >> ${actionfile}
echo "*" >> ${actionfile}
echo "... filterfile added ..."
echo "... creating and adding whitlist for urls ..."
echo "{ -block }" >> ${actionfile}
$sedcmd '/^@@.*/!d;s/^@@//g;/\$.*/d;/#/d;s/\./\\./g;s/\?/\\?/g;s/\*/.*/g;s/(/\\(/g;s/)/\\)/g;s/\[/\\[/g;s/\]/\\]/g;s/\^/[\/\&:\?=_]/g;s/^||/\./g;s/^|/^/g;s/|$/\$/g;/|/d' ${file} >> ${actionfile}
echo "... created and added whitelist - creating and adding image handler ..."
echo "{ -block +handle-as-image }" >> ${actionfile}
$sedcmd '/^@@.*/!d;s/^@@//g;/\$.*image.*/!d;s/\$.*image.*//g;/#/d;s/\./\\./g;s/\?/\\?/g;s/\*/.*/g;s/(/\\(/g;s/)/\\)/g;s/\[/\\[/g;s/\]/\\]/g;s/\^/[\/\&:\?=_]/g;s/^||/\./g;s/^|/^/g;s/|$/\$/g;/|/d' ${file} >> ${actionfile}
echo "... created and added image handler ..."
echo "... created actionfile for ${list}."
actionfiledest="${privoxydir}/$(basename ${actionfile})"
echo "... copying ${actionfile} to ${actionfiledest}"
cp "${actionfile}" "${actionfiledest}"
filterfiledest="${privoxydir}/$(basename ${filterfile})"
echo "... copying ${filterfile} to ${filterfiledest}"
cp "${filterfile}" "${filterfiledest}"
done
}
#=== FUNCTION ================================================================
# NAME: usage
# DESCRIPTION: prints command usage
# PARAMETERS: none
# RETURNS: none
#===============================================================================
function usage() {
echo "Usage: ${0} [-d] [-p <privoxy config dir>] [-u <url1>] [-u <url2>]..."
exit 1
}
#=== FUNCTION ================================================================
# NAME: main
# DESCRIPTION: main script entry point
# PARAMETERS: none
# RETURNS: none
#===============================================================================
function main() {
pidfile="$(pidfilename)"
tempfile="$(mktemp -t j.XXX)"
tempdir="$(dirname $tempfile)"
rm ${tempfile}
isrunning "${pidfile}" && {
echo "$(basename ${0}) is already running"
exit 1
}
createpidfile $$ "${pidfile}"
trap 'cleanup' INT TERM EXIT
debug="false"
trap 'logger -t $0 -i -- $USER : $BASH_COMMAND' ERR #log errors regardless
privoxydir=$defaultprivoxydir
urls=( "${defaulturls[@]}" )
while getopts "dp:u:" opt; do
case "${opt}" in
p)
privoxydir=${OPTARG}
;;
u)
urls+=("${OPTARG}")
;;
d)
debug="true"
;;
*)
usage
;;
:)
echo "Option -"$OPTARG" requires an arguemnt." >&2
usage
;;
esac
done
[[ "$debug" == "true" ]] && trap 'logger -t $0 -i -- $USER : $BASH_COMMAND' DEBUG #syslog everything if we're debugging
[[ ! -d "$privoxydir" ]] && usage
[[ "${#urls[@]}" -eq "0" ]] && usage
# perform the operation
doconvert $privoxydir $urls
}
main $@
exit 0