View difference between Paste ID: kDXqafxf and
SHOW:
|
|
- or go back to the newest paste.
1 | - | |
1 | + | #!/bin/bash |
2 | # | |
3 | # apt-sources-update | |
4 | # | |
5 | # by travisn000 <travisn000 at gmail.com> | |
6 | # | |
7 | # This program is free software; you can redistribute it and/or modify | |
8 | # it under the terms of the GNU General Public License as published by | |
9 | # the Free Software Foundation; either version 2 of the License, or | |
10 | # (at your option) any later version. | |
11 | # | |
12 | # This program is distributed in the hope that it will be useful, | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | # GNU General Public License for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU General Public License | |
18 | # along with this program; if not, write to the Free Software | |
19 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
20 | # | |
21 | ||
22 | myname=$(basename "$0"); | |
23 | export TEXTDOMAIN=apt-sources-update | |
24 | export TEXTDOMAINDIR="/usr/share/locale" | |
25 | ||
26 | ||
27 | # verbose output for debugging | |
28 | setverbose () { set -xv; } | |
29 | ||
30 | showhelp () { | |
31 | echo -e $" | |
32 | $myname is a utility that will download the latest PCLinuxOS apt | |
33 | sources.list from the main ibiblio server, verify that they | |
34 | have been recently synced to the ibiblio server, and test | |
35 | all updated repositories for download speed. | |
36 | ||
37 | Once testing is completed the user will be given a speed | |
38 | rated list of repositories from which they can select a | |
39 | default repository to use for future software needs. | |
40 | ||
41 | It is meant to be run as a regular user, and will prompt | |
42 | for root permisions before making any changes to the apt | |
43 | sources.list file. This script also requires that zenity | |
44 | is installed so that GUI dialogs are properly displayed. | |
45 | ||
46 | Available console options to override default behavior include:. | |
47 | -a, -age=<time in days> Allowed repo age before FAIL | |
48 | -n, -number=<number of repos> Max number of official repos to keep (fastest) | |
49 | -s, -sources=<url of file> Location of official online sources.list | |
50 | -t, -timeout=<time in seconds> Time to start file download before FAIL | |
51 | -v, -verbose Verbose output for debugging | |
52 | -w, -write Prompt to write new sources.list to /etc/apt (root password) | |
53 | -u, -usage Display sample command line usage, help | |
54 | -h, -help Display this help message | |
55 | " | |
56 | ||
57 | [ -n "$1" ] && exit $1 # only exit if exit status is passed to function | |
58 | } | |
59 | ||
60 | usage () { | |
61 | showhelp | |
62 | echo -e $" | |
63 | Examples: | |
64 | $myname -timeout=3 -age=2 | |
65 | $myname -s http://myserver.org/sources.list | |
66 | $myname -t 2 -a 2 -n 8 -w | |
67 | ||
68 | " | |
69 | exit | |
70 | } | |
71 | ||
72 | ||
73 | # Set script title | |
74 | VERSION=0.3.1 | |
75 | TITLE=$"Repo Speed Test $VERSION" | |
76 | WINDOW_ICON="/usr/share/pixmaps/synaptic.png" | |
77 | ||
78 | TMP_DIR="$HOME/repo-speed-test" | |
79 | TESTFILE="srclist.main.bz2" | |
80 | REPO_BASE_YEAR="2010" | |
81 | TESTFILEDIR="pclinuxos/${REPO_BASE_YEAR}/base/" | |
82 | UPDATED_SOURCESLIST="http://distro.ibiblio.org/pclinuxos/repo${REPO_BASE_YEAR}/sources.list" | |
83 | MEGA_GAMES_REPO="http://ftp.nl.freebsd.org/pub/os/Linux/distr/pclinuxos/megagames/apt/ pclinuxos/${REPO_BASE_YEAR} megagames" | |
84 | TIMEOUT="3" | |
85 | ||
86 | ||
87 | while getopts a:n:t:s:wvuh op | |
88 | do case "$op" in | |
89 | a) REPO_AGE=$(($OPTARG*1));; | |
90 | n) REPOS_MAX=$(($OPTARG*1));; | |
91 | t) TIMEOUT=$(($OPTARG*1));; | |
92 | s) UPDATED_SOURCESLIST="$OPTARG";; | |
93 | w) WRITE_APTSL=0;; | |
94 | v) setverbose;; | |
95 | u) usage;; | |
96 | h|?) showhelp 0;; | |
97 | esac | |
98 | done | |
99 | ||
100 | shift $(( $OPTIND-1 )) | |
101 | [ -n "$1" ] && echo -e $"Extra parameter(s) \"$@\" ignored...\n" | |
102 | ||
103 | if ! cd ~; then | |
104 | echo $"Cannot change directory to your home directory... quitting." | |
105 | exit 1 | |
106 | fi | |
107 | ||
108 | for c in $(echo "/ | # ! = _ ~ :") | |
109 | do if ! [[ "$@" =~ "$c" ]]; then | |
110 | s=$c ; break | |
111 | fi | |
112 | done | |
113 | if [ -z "$s" ]; then | |
114 | echo $"Try again without using all of \"/|#!=_~:\" in your arguments... quitting." | |
115 | exit 1 | |
116 | fi | |
117 | ||
118 | ||
119 | ||
120 | ||
121 | # Check if kdialog exists, if not, use gdialog for some dialogs. | |
122 | # Note: Most dialogs are pure zenity, but zenity does not have the yes/no function :( | |
123 | if [ -f /usr/bin/kdialog ]; then | |
124 | DIALOG=kdialog | |
125 | else | |
126 | DIALOG=gdialog | |
127 | fi | |
128 | ||
129 | ||
130 | if [ ! -e /usr/bin/zenity ]; then | |
131 | $DIALOG --yesno $"Zenity is required to run this script.\n\nWould you like to install it now?" | |
132 | if [ "$?" == "0" ]; then | |
133 | ktsuss synaptic & | |
134 | exit | |
135 | elif [ "$?" == "1" ]; then | |
136 | kdialog --sorry $"Exiting now" | |
137 | exit | |
138 | fi | |
139 | fi | |
140 | ||
141 | ||
142 | # check that package managers are closed | |
143 | for idx in synaptic smart ksmarttray kpackage apt-get | |
144 | do | |
145 | if [ -n "`pidof $idx`" ]; then | |
146 | zenity --window-icon="$WINDOW_ICON" --error --title="$TITLE" --text=$"Please close your package manager '$idx' and then click on the link again.\n\nExiting..." | |
147 | # echo -e "Please close your ${idx} package manager and then try again.\n\nExiting...\n\n" | |
148 | sleep 2 | |
149 | exit 1 | |
150 | fi | |
151 | done | |
152 | ||
153 | ||
154 | # Check if user is logged in as root ..or not ??? | |
155 | if [ "$UID" == "0" ]; then | |
156 | zenity --window-icon="$WINDOW_ICON" --error --title="$TITLE" --text=$"Please <b>DO NOT</b> run this script as root!" | |
157 | showhelp | |
158 | echo -e $"\nPlease use this command as normal user, not root." | |
159 | exit 1 | |
160 | fi | |
161 | ||
162 | ||
163 | ||
164 | ||
165 | ||
166 | ||
167 | ############################################# | |
168 | ## Execution starts here ## | |
169 | ############################################# | |
170 | ||
171 | ||
172 | aptsl="/etc/apt/sources.list" | |
173 | newaptsl="$TMP_DIR/sources.list.new" | |
174 | atemp="$TMP_DIR/atemp.$$" | |
175 | ||
176 | ||
177 | ||
178 | editsl_file () { | |
179 | exec 9<${aptsl} #$aptsl | |
180 | ||
181 | echo -e $"\n\nLocal repo line(s) found:\n" | |
182 | while read -u 9 r | |
183 | # do if [[ $r =~ $rpm_file ]]; then | |
184 | do if [[ $r =~ $rpm_local ]]; then | |
185 | echo -e "$r\n" | |
186 | zenity --window-icon="$WINDOW_ICON" --question --text=$"The following local repository exists:\n$r\n\nWould you like to keep it?" | |
187 | if [ "$?" = "0" ]; then | |
188 | if ( echo $r | grep ^[[:space:]]*# ); then | |
189 | echo -e "${r}\n">>$newaptsl | |
190 | else | |
191 | echo -e "# ${r}\n">>$newaptsl | |
192 | fi | |
193 | echo -e $"\n..successfully recovered; you may reactivate using Synaptic\n" | |
194 | fi | |
195 | fi | |
196 | done | |
197 | exec 9<&- | |
198 | } ###### end editsl_file ###### | |
199 | ||
200 | ||
201 | editsl_pass () { | |
202 | exec 9<${aptsl} | |
203 | ||
204 | echo -e $"\n\nPASS repo line found:\n" | |
205 | while read -u 9 r | |
206 | do if [[ $r =~ $rpm_pass ]]; then | |
207 | echo -e "$r\n" | |
208 | zenity --window-icon="$WINDOW_ICON" --question --text=$"The following pass repository exists:\n$r\n\nWould you like to keep it?" | |
209 | if [ "$?" = "0" ]; then | |
210 | if ( echo $r | grep ^[[:space:]]*"#" ); then | |
211 | echo -e "${r}\n">>$newaptsl | |
212 | else | |
213 | echo -e "# ${r}\n">>$newaptsl | |
214 | fi | |
215 | echo -e $"\n..successfully recovered; you may reactivate using Synaptic\n" | |
216 | fi | |
217 | ||
218 | fi | |
219 | done | |
220 | exec 9<&- | |
221 | } ###### end editsl_pass ###### | |
222 | ||
223 | ||
224 | ||
225 | makesl () { | |
226 | head=$"# Package repository URL's | |
227 | ||
228 | # Signed repositories have a [<key>] where <key> is the name of the key | |
229 | # as it appears in vendors.list. If you remove it, no digital signature check | |
230 | # will be made. | |
231 | " | |
232 | ||
233 | ||
234 | kde_section="kde4" | |
235 | ||
236 | ||
237 | #if [ -d /usr/share/kde4 ]; then kde_section="kde4" ; fi | |
238 | #if [ `rpm -qa kdebase4|wc -l` -gt 0 ];then kde_section="kde4" ; fi | |
239 | ||
240 | dsx="pclinuxos/${REPO_BASE_YEAR} main updates nonfree games ${kde_section}" | |
241 | ||
242 | ||
243 | ||
244 | # echo -e "\nIf your network connection is not active, please" | |
245 | # read -p "activate it now, then press Enter to continue. " | |
246 | zenity --window-icon="$WINDOW_ICON" --info --title="$TITLE" --text=$"If your network connection is not active, please\nactivate it now, then press OK to continue. " | |
247 | if [ "$?" != "0" ]; then | |
248 | zenity --window-icon="$WINDOW_ICON" --error --title="$TITLE" --text=$"Operation Canceled! \n\nExiting $myname... " | |
249 | exit 1 | |
250 | fi | |
251 | ||
252 | ||
253 | echo -e $"\nRetrieving updated apt sources.list...\n" | |
254 | ||
255 | rm -fR $TMP_DIR &>/dev/null | |
256 | mkdir -p $TMP_DIR | |
257 | wget --directory-prefix=$TMP_DIR $UPDATED_SOURCESLIST 2>&1 \ | |
258 | | sed -u 's/.*\ \([0-9]\+%\)\ \+\([0-9.]\+\ [KMB\/s]\+\)$/\1\n# Downloading \2/' \ | |
259 | | zenity --window-icon="$WINDOW_ICON" --progress --auto-close --title="$TITLE" --text=$"Downloading updated apt sources.list file..." | |
260 | #| zenity --window-icon="$WINDOW_ICON" --progress --pulsate --auto-close --title="$TITLE" --text=$"Downloading updated apt sources.list file..." | |
261 | ||
262 | ||
263 | ||
264 | if [ -f $TMP_DIR/sources.list ]; then | |
265 | ||
266 | zenity --window-icon="$WINDOW_ICON" --info --title="$TITLE" --text=$"Connection successful.. \nRetrieved new sources.list file. " | |
267 | ||
268 | # repo list with NO line breaks | |
269 | # REPOSLIST="" | |
270 | # for url in `grep rpm.*p:// $TMP_DIR/sources.list | sed -e 's@^[# \t]*rpm @@' | cut -d" " -f1`; do REPOSLIST="$REPOSLIST $url "; done; | |
271 | ||
272 | # repo list with line breaks | |
273 | REPOSLIST=( `grep rpm.*:/ $TMP_DIR/sources.list | sed -e 's@^[# \t]*rpm @@' | cut -d" " -f1` ) | |
274 | # echo ${REPOSLIST[@]} | |
275 | ||
276 | else | |
277 | zenity --window-icon="$WINDOW_ICON" --error --title="$TITLE" --text=$"Unable to retrieve new sources.list file. \n\n Verify internet connection and try again. " | |
278 | exit 1 | |
279 | fi | |
280 | ||
281 | ||
282 | ans="" | |
283 | # while ! [[ $ans == [0-9] || $ans == [0-9][0-9] ]]; do | |
284 | # read -p"Enter acceptable repo sync age (0-99 days): " ans | |
285 | # done | |
286 | [[ "$REPO_AGE" =~ ^[0-9]+$ ]] && ans=$REPO_AGE || ans=$(zenity --window-icon="$WINDOW_ICON" --scale --title="$TITLE" --text=$"Select acceptable repo sync age in days.. " --min-value=1 --max-value=10 --value=5 --step 1) | |
287 | if [ "$?" != "0" ]; then | |
288 | zenity --window-icon="$WINDOW_ICON" --error --title="$TITLE" --text=$"Operation Canceled! \n\nExiting $myname... " | |
289 | exit 1 | |
290 | fi | |
291 | ||
292 | ||
293 | DATE_OLD=$(date --date "now - $ans days" +%Y%m%d) #; echo $DATE_OLD | |
294 | GOODLIST="" | |
295 | BADLIST="" | |
296 | REPOCOUNT=${#REPOSLIST[@]} | |
297 | ||
298 | ||
299 | ||
300 | echo -e $"\nTesting repo sync age and download speeds..\n" | |
301 | rm -f $TMP_DIR/repo_goodlist.txt | |
302 | rm -f $TMP_DIR/repo_badlist.txt | |
303 | cd $TMP_DIR | |
304 | #for REPO in ${REPOSLIST[@]} ; do | |
305 | for (( i=0; i<${REPOCOUNT}; i++ )); do | |
306 | the_progress=$((100*${i}/${REPOCOUNT})) | |
307 | URL="${REPOSLIST[$i]}${TESTFILEDIR}${TESTFILE}" | |
308 | GETSPEED=$(curl --max-time ${TIMEOUT} --time-cond ${DATE_OLD} --silent --write-out %{speed_download} -O ${URL}) | |
309 | # GETTIME=$(curl --max-time ${TIMEOUT} --time-cond ${DATE_OLD} --silent --write-out %{total_time} -O ${URL}) | |
310 | GETSPEED=$( echo $GETSPEED| cut -d"." -f1 ) #make integer | |
311 | ||
312 | # if [ "$GETTIME" == "0.000" ]; then | |
313 | if [ "$GETSPEED" == "0" ]; then | |
314 | echo $"# REPO: ${REPOSLIST[$i]}\nSTATUS: FAILED" | |
315 | echo "${REPOSLIST[$i]}" >> $TMP_DIR/repo_badlist.txt | |
316 | echo "$the_progress" | |
317 | else | |
318 | echo $"# REPO: ${REPOSLIST[$i]}\nSPEED: $GETSPEED bytes/second" | |
319 | echo "$GETSPEED ${REPOSLIST[$i]}" >> $TMP_DIR/repo_goodlist.txt | |
320 | echo "$the_progress" | |
321 | fi | |
322 | done | zenity --window-icon="$WINDOW_ICON" --progress --auto-close --title="$TITLE" --text=$"Starting repo speed test..." --width=400 | |
323 | # --pulsate | |
324 | ||
325 | rm -f $TMP_DIR/$TESTFILE | |
326 | ||
327 | REPO_SELECTION=$(sort -nr $TMP_DIR/repo_goodlist.txt | | |
328 | awk -F" " '{print $2,"\n",$1}' | | |
329 | zenity --window-icon="$WINDOW_ICON" --list --title="$TITLE" \ | |
330 | --column=$" Repo URL" --column $"bytes/second" \ | |
331 | --text=$"Select your preferred repo from the list below.\n\n(Ordered fastest to slowest - please do <b>NOT</b> use ibiblio.org)" --width=750 ) | |
332 | ||
333 | if [ "$REPO_SELECTION" == "" ]; then zenity --window-icon="$WINDOW_ICON" --error --title="$TITLE" --text=$"Operation Canceled! \n\nExiting $myname... "; exit; fi | |
334 | ||
335 | ||
336 | ||
337 | finalrepolist=( `cat $TMP_DIR/repo_goodlist.txt | sort -nr | cut -d" " -f2` ) | |
338 | ||
339 | ||
340 | if [ -f $TMP_DIR/repo_badlist.txt ] ; then | |
341 | echo | |
342 | echo -e $"\nThe following mirrors timed out, are out of date, or are not valid :\n" | |
343 | cat $TMP_DIR/repo_badlist.txt; | |
344 | sleep 2 | |
345 | fi | |
346 | ||
347 | ||
348 | echo -e $"\nPCLinuxOS official repositories: \n(ordered by speed-test results, fastest to slowest)" | |
349 | echo -e $"(average download speed in bytes/seconds for ~500 KB file) \n\n" | |
350 | sort -nr $TMP_DIR/repo_goodlist.txt | awk -F" " '{print $1," \t",$2}' | |
351 | ||
352 | ||
353 | if [ "$finalrepolist" != "" ]; then | |
354 | ||
355 | # find item in array | |
356 | bash__is_in_array () { | |
357 | haystack=( "$@" ) | |
358 | haystack_size=( "${#haystack[@]}" ) | |
359 | needle=${haystack[$((${haystack_size}-1))]} | |
360 | for ((i=0;i<$(($haystack_size-1));i++)); do | |
361 | h=${haystack[${i}]}; | |
362 | [ $h = $needle ] && return $i | |
363 | done | |
364 | } | |
365 | ||
366 | bash__is_in_array "${finalrepolist[@]}" $REPO_SELECTION | |
367 | n=$? | |
368 | ||
369 | ||
370 | active_repo="${finalrepolist[$n]}" | |
371 | echo -e $"\n\n Activating $active_repo" | |
372 | echo -e $" Creating $aptsl\n" | |
373 | ||
374 | ||
375 | [[ "$REPOS_MAX" =~ ^[0-9]+$ ]] && list_length=$REPOS_MAX || list_length=$(zenity --window-icon="$WINDOW_ICON" --scale --title="$TITLE" --text=$"Select number of online repositories to keep: " --min-value=1 --max-value=${#finalrepolist[@]} --value=5 --step 1) | |
376 | if [ "$?" != "0" ]; then | |
377 | zenity --window-icon="$WINDOW_ICON" --error --title="$TITLE" --text=$"Operation Canceled! \n\nExiting $myname... " | |
378 | exit 1 | |
379 | fi | |
380 | ||
381 | # write sources.list.new header | |
382 | echo "$head" > $newaptsl | |
383 | ||
384 | # add user selected online repo first (top of the repo list) | |
385 | echo -e "rpm ${finalrepolist[$n]} $dsx\n" >> $newaptsl | |
386 | ||
387 | # ask for enable megagames | |
388 | zenity --window-icon="$WINDOW_ICON" --question --text=$"If you want to enable the repo for megames?" --title="$TITLE" | |
389 | if [ "$?" = "0" ]; then | |
390 | # add megagames repo next | |
391 | echo -e "rpm ${MEGA_GAMES_REPO}\n" >> $newaptsl | |
392 | else | |
393 | echo -e "# rpm ${MEGA_GAMES_REPO}\n" >> $newaptsl | |
394 | fi | |
395 | ||
396 | rs="# rpm"; | |
397 | ||
398 | # write sources.list.new local / pass repositories | |
399 | rpm_local="rpm.*file:/|rpm.*tp://localhost|rpm.*tp://192.168.|rpm.*tp://10.|rpm.*tp://172.16." | |
400 | egrep -q "$rpm_local" ${aptsl} && editsl_file | |
401 | ||
402 | rpm_pass="@" | |
403 | # rpm_pass="rpm.*@" | |
404 | egrep -q "$rpm_pass" ${aptsl} && editsl_pass | |
405 | ||
406 | # write sources.list.new online repositories | |
407 | for (( r=0; r<${list_length}; r++ )); do | |
408 | if [ "$r" != "$n" ]; then # do not add user selected online repo.. it was already added above | |
409 | echo -e "$rs ${finalrepolist[$r]} $dsx\n" >> $newaptsl | |
410 | fi | |
411 | done | |
412 | else | |
413 | echo -e $"\nUnable to contact any PCLinuxOS software repository \(REQUIRED\). \n\nExiting.. please verify your network connection and try again.\n\n" | |
414 | zenity --window-icon="$WINDOW_ICON" --error --title="$TITLE" --text=$"\nUnable to contact any PCLinuxOS software repository \(REQUIRED\). \n\nExiting.. please verify your network connection and try again.\n" | |
415 | sleep 3 | |
416 | exit 1 | |
417 | fi | |
418 | ||
419 | } ###### end makesl ###### | |
420 | ||
421 | ||
422 | ||
423 | ||
424 | ||
425 | ||
426 | if ! [ -f "$aptsl" ]; then | |
427 | echo -e $"Can\'t find ${aptsl} \n\nExiting... " | |
428 | zenity --window-icon="$WINDOW_ICON" --error --title="$TITLE" --text=$"Can\'t find ${aptsl} \n\nExiting... " | |
429 | exit 1 | |
430 | fi | |
431 | ||
432 | root_script=backup-n-overwrite-sources.sh | |
433 | ||
434 | makesl && cat > $TMP_DIR/$root_script <<EOF | |
435 | #!/bin/bash | |
436 | # REQUIRES ROOT PRIVLIGES | |
437 | ||
438 | if [ \$UID -ne 0 ]; then | |
439 | echo -e $"\nPlease use this script as root.\n" | |
440 | exit 1 | |
441 | fi | |
442 | ||
443 | if [ -f "$aptsl" ]; then | |
444 | cp -f --backup $aptsl ${aptsl}.old #2>/dev/null | |
445 | aptslbk=\$? | |
446 | else | |
447 | aptslbk=999 | |
448 | fi | |
449 | ||
450 | [ "\$aptslbk" != "999" ] && force=1 | |
451 | [ -n "\$force" -a -f ${aptsl}.old ] && cp -f --backup=off $TMP_DIR/sources.list.new $aptsl 2>/dev/null | |
452 | ||
453 | # -r => launch synaptic with repository selection dialog open | |
454 | #( synaptic -r &>/dev/null )& | |
455 | synaptic -r | |
456 | ||
457 | echo -e \$(basename "\$0") complete..; | |
458 | ||
459 | EOF | |
460 | ||
461 | chmod 755 $TMP_DIR/$root_script | |
462 | ||
463 | [[ "$WRITE_APTSL" == "0" ]] && zenity --window-icon="$WINDOW_ICON" --question --text=$"The repo speed test has completed and | |
464 | a new apt sources.list has been saved to your home directory. | |
465 | ||
466 | Would you like to overwrite your current sources.list file? | |
467 | (a back up copy of the current file will be made)" | |
468 | if [ "$?" = "0" ]; then | |
469 | ||
470 | cd $TMP_DIR | |
471 | mysu=`which gksu 2>/dev/null` || mysu=`which kdesu 2>/dev/null` && $mysu "./$root_script" | |
472 | cd ~ | |
473 | zenity --window-icon="$WINDOW_ICON" --question --text=$"Would you like to remove the repo-speed-test working directory from your home folder?" | |
474 | if [ "$?" = "0" ]; then | |
475 | rm -fR $TMP_DIR &>/dev/null | |
476 | fi | |
477 | fi | |
478 | ||
479 | [[ "$WRITE_APTSL" != "0" ]] && zenity --window-icon="$WINDOW_ICON" --warning --text=$"The repo speed test has completed and a new apt sources.list \nhas been saved to your home directory.\n\nTo activate it you must copy it to the /etc/apt directory." | |
480 | ||
481 | echo $"${myname} is now finished." | |
482 | echo; echo; | |
483 | ||
484 | sleep 1 |