Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- VERSION=2.31
- ALIASES="/usr/local/etc/upd/upd_${USER}.aliases"
- PRG='upd'
- distver="`sed -r 's/^.*://' /etc/system-release-cpe`"
- dist="fc$distver"
- baseurl='https://koji.fedoraproject.org/koji'
- PACKAGER='yum'
- type -p dnf &>/dev/null && PACKAGER='dnf'
- complete='
- BEGIN {
- gsub("[*+.]", "\\\\&", pkg);
- }
- $0 ~ pkg {
- link=$0;
- sub("^.*href=\"", "", link);
- sub("\".*$", "", link);
- while (1) {
- getline;
- if ($0 ~ /\/tr/) {
- ok=0;
- break;
- }
- if ($0 ~ /complete/) {
- ok=1;
- break;
- }
- }
- if (ok) print(link);
- exit ok;
- }
- '
- resolve='
- function add(e,
- i) {
- for(i in s) {
- if (e==s[i]) {
- return;
- }
- }
- s[++ptr]=e;
- }
- function exadd(e,
- i) {
- for(i in exs) {
- if (e==exs[i]) {
- return;
- }
- }
- exs[++exptr]=e;
- }
- BEGIN {
- ptr=0;
- idx=0;
- exptr=0;
- exflag=0;
- keys=split(params, keywords);
- if (!keys) {
- exit;
- }
- for (i in keywords) {
- temp=keywords[i];
- if (temp=="-x" || temp=="--exclude") {
- exflag=1;
- continue;
- }
- if (exflag) {
- exflag=0;
- if (substr(temp, 1, 1)!="-") {
- exadd(temp);
- continue;
- }
- }
- add(temp);
- }
- if (!aliases_exist) {
- exit
- }
- }
- {
- if ($0 ~ /^[ \t]*(#|$)/) {
- next;
- }
- if (NF<2) {
- next;
- }
- if (idx) {
- for (i in ali) {
- if ($1==ali[i]) {
- next;
- }
- }
- }
- ali[++idx]=$1;
- ali_pars[idx, 1]=8;
- for (i=2; i<=NF; i++) {
- ali_pars[idx, i]=$i;
- }
- }
- END {
- if (aliases_exist) {
- i=1;
- while (i<=ptr) {
- for (j in ali) {
- if (s[i]==ali[j]) {
- if (ali_pars[j, 1]) {
- delete s[i];
- for (aliidx in ali_pars) {
- if (split(aliidx, ix, /\034/)!=2) {
- continue
- };
- if (ix[1]!=j) {
- continue;
- }
- k=ix[2];
- if (k==1) {
- ali_pars[j, 1]--;
- } else {
- add(ali_pars[j, k]);
- }
- }
- }
- break;
- }
- }
- i++;
- }
- for (j in ali) {
- ali_pars[j, 1]=8;
- }
- i=1;
- while (i<=exptr) {
- for (j in ali) {
- if (exs[i]==ali[j]) {
- if (ali_pars[j, 1]) {
- delete exs[i];
- for (aliidx in ali_pars) {
- if (split(aliidx, ix, /\034/)!=2) {
- continue
- };
- if (ix[1]!=j) {
- continue;
- }
- k=ix[2];
- if (k==1) {
- ali_pars[j, 1]--;
- } else {
- exadd(ali_pars[j, k]);
- }
- }
- }
- break;
- }
- }
- i++;
- }
- }
- if (exptr) {
- l=asort(exs);
- }
- if (ptr) {
- printed=0;
- j=asort(s);
- for (i=1; i<=j; i++) {
- exflag=0;
- for (k=1; k<=l; k++) {
- if (exs[k]==s[i]) {
- exflag=1;
- break;
- }
- }
- if (!exflag) {
- printf("%s\n", s[i]);
- printed=1;
- }
- }
- if (!printed) {
- printf("\n");
- }
- } else {
- printf("\n");
- }
- }
- '
- list_to_query='
- function packagenamearch(s,
- arr, arch, name) {
- split(s, arr, dst);
- name=arr[1];
- sub(/-[^-]+-[^-]+$/, "", name);
- arch=arr[2];
- sub(/\.rpm$/, "", arch);
- sub(/.*\./, "", arch);
- return name "." arch;
- }
- function is_element(x, a,
- i) {
- for (i in a) {
- if (a[i]==x) return 1;
- }
- return 0;
- }
- BEGIN {
- i=0;
- dst="fc(" distver-1 "|" distver ")";
- query="";
- urllist="";
- }
- /\.rpm.*download/ {
- reply=$0;
- sub(/<[^>]*>/, "");
- pknamearch=$1;
- package[i]=pknamearch;
- sub("^.*info</a>", "", reply);
- sub(/.[^"]*"/, "", reply);
- sub(/"[^"]*$/, "", reply);
- purl[i]=reply;
- pknamearch=packagenamearch(pknamearch);
- temp=pknamearch;
- sub(/^.*\./, "", temp);
- if (temp !~ /x86_64|i[3-6]86|noarch/) {
- next
- };
- pknoversion[i]=pknamearch;
- query=query " " pknamearch;
- i++;
- }
- END {
- if (!length(query)) {
- printf("message E \"Empty query list:\" \"%s\" 1>&2\n", param1);
- exit(0);
- }
- cmd="rpm -q" query " | grep -vF \"not installed\" | sort -rV";
- temp=RS;
- RS="\0";
- cmd | getline installed;
- RS=temp;
- if (!length(installed)) {
- printf("message W \"Not installed\" \"%s\" 1>&2\n", param1);
- exit(0);
- }
- oldpnamearch="";
- split(installed, inst);
- j=0;
- k=0;
- for (idx in inst) {
- reply=inst[idx];
- pnamearch=packagenamearch(reply);
- if (pnamearch != oldpnamearch) {
- for (i in pknoversion) {
- if (pnamearch == pknoversion[i]) {
- packagei=package[i];
- sub(/\.[^.]*$/, "", packagei);
- if (reply==packagei) {
- msg[++j]=reply "/x";
- } else {
- split(reply, arr_reply, "\\." dst "\\.");
- split(packagei, arr_packagei, "\\." dst "\\.", separator);
- cmd="{ echo \"" arr_reply[1] "\"; echo \"" arr_packagei[1] "\"; } | sort -V";
- temp=RS;
- RS="\0";
- cmd | getline sortedline;
- RS=temp;
- split(sortedline, sorted);
- if (reply==sorted[1] separator[1] arr_packagei[2]) {
- if (!is_element(purl[i], aurl)) {
- aurl[++k]=purl[i];
- msg[++j]=packagei "/u";
- }
- } else {
- msg[++j]=reply "/n";
- }
- }
- break;
- }
- }
- }
- oldpnamearch=pnamearch;
- }
- for (i=k; i>=1; i--) {
- urllist=urllist aurl[i] " ";
- }
- if (length(urllist)) {
- printf("urllist+=\"%s\"\n", urllist);
- }
- for (i=j; i>=1; i--) {
- if (split(msg[i], m, /\//) == 2) {
- switch (m[2]) {
- case "u": {
- printf("message \"Update:\" \"%s\"\n", m[1]);
- break;
- }
- case "x": {
- printf("message W \"Up to date\" \"%s\"\n", m[1]);
- break;
- }
- case "n": {
- printf("message W \"Up to date\" \"%s\" \"(newer installed)\"\n", m[1]);
- break;
- }
- }
- } else {
- printf("message W \"h/h:\" \"%s\"\n", m[1]);
- }
- }
- exit(0);
- }
- '
- message() {
- case "$1" in
- W|w)
- [ $nowarn = 1 ] && return 0
- echo -ne '\x1b[33;1mW:\x1b[m '
- shift
- ;;
- E|e)
- echo -ne '\x1b[31;1mE:\x1b[m '
- shift
- ;;
- esac
- echo -n "$1 "
- shift
- echo -ne "\x1b[1m$1\x1b[m "
- shift
- echo "$*"
- }
- debug() {
- echo -e "\x1b[32;1m$@\x1b[m"
- }
- gettime() {
- echo $((`date '+%s%N'`/1000000))
- }
- tdebug() {
- echo -e "\x1b[32;1m$((`gettime`-t0))\\t$@\x1b[m"
- }
- package1() {
- [ -z "$1" ] && return 0
- pattern="`sed 's/ /%20/g; s/\\+/%2b/g;' <<<\"$1\"`"
- url="$baseurl/search?match=exact&type=package&terms=$pattern"
- if ! list="`wget -t3 -T25 -l1 -O - \"$url\" 2>/dev/null`"; then
- echo "message E 'Error in GET repository' 1>&2"
- echo 'e=1'
- return 1
- fi
- pattern="`sed 's/[*+.]/\\\\&/g' <<<\"$1\"`"
- packages="`grep -E \"<a [^>]*>.*$pattern.*$dist</a>\" <<<\"$list\" |
- sed -r 's:^.*<a [^>]*>::; s:</a>.*$::' | sort -Vr`"
- ((norc)) && packages="`grep -v '^.*-.*rc' <<<\"$packages\"`"
- if [ -z "$packages" ]; then
- echo "message W 'Not in the repository:' '$1' 1>&2"
- return 0
- fi
- for i in $packages; do
- url="`awk -v \"pkg=$i\" \"$complete\" <<<\"$list\"`"
- if [ ! -z "$url" ]; then
- url="$baseurl/$url"
- break
- fi
- done
- if [ -z "$url" ]; then
- echo "message W 'Not in the repository:' '$1' 1>&2"
- return 0
- fi
- if ! list="`wget -t3 -T15 -l1 -O - \"$url\" 2>/dev/null`"; then
- echo "message E 'Error in GET repository' '$1' 1>&2"
- return 0
- fi
- awk -v distver=$distver -v param1="$1" "$list_to_query" <<<"$list"
- return 0
- }
- run() {
- if [ ! -z "$1" -a ! -z "$2" ]; then
- if [ $EUID -eq 0 ]; then
- $PACKAGER "$1" $2
- sync
- else
- i=3
- while [ $i -gt 0 ]; do
- echo -n 'root '
- su - -c "$PACKAGER $1 $2; sync" && break
- ((i--))
- done
- if [ $i -eq 0 ]; then
- message E 'Authentication failure' 1>&2
- return 1
- fi
- fi
- fi
- return 0
- }
- erase_kernel() {
- curr_ver="`uname -r`"
- message 'Current kernel release:' "$curr_ver"
- m='Available kernel'
- spaces=' '
- spaces="${spaces:0:${#m}+3}"
- kvers=''
- i=0
- j=0
- while read; do
- if [ x"$REPLY" = x"$curr_ver" ] || [ $i -eq 0 ]; then
- kv="\\x1b[1m${REPLY}\\x1b[m"
- else
- kv="\\x1b[34;1m${REPLY}\\x1b[m"
- [ $j -gt 0 ] && kvers+='\|'
- kvers+="${REPLY//./\\.}"
- ((j++))
- fi
- if [ $i -eq 0 ]; then
- kernels="$kv"
- else
- kernels+="\\n$spaces$kv"
- fi
- ((i++))
- done < <(rpm -q kernel{,-PAE}{,-core} | sed 's/^[^[:digit:]]*//; /^$/ d;' | sort -Vru)
- s=''
- [ $i -gt 1 ] && s='s'
- echo -e "$m$s: $kernels"
- if [ $j -eq 0 ]; then
- message W 'Nothing to do' 1>&2
- return 0
- fi
- pkglist="`rpm -qa kernel\* | grep \"$kvers\" | grep -v headers | xargs -r echo`"
- if [ -z "$kvers" ] || [ -z "$pkglist" ]; then
- message W 'Nothing to do' 1>&2
- return 1
- fi
- run remove "$pkglist" || return 1
- return 0
- }
- version() {
- echo "v$VERSION"
- }
- help() {
- echo -e '\t\x1b[1mupd\x1b[m [-h|--help] [-v|--version] [-k] [-w|--no-warning] [-n|--norc] [[-x|--exclude] \x1b[4mpackage\x1b[m] ...'
- }
- DLCLIENT='wget'
- PARALLEL='parallel'
- FAST='aria2c -x 5 -k 2M'
- # FAST='curl --retry 20 --parallel --parallel-max 5 -O'
- if type -p "${FAST%% *}" &>/dev/null; then
- DLCLIENT="$FAST"
- else
- message W 'Missing' "${FAST%% *}" 'accelerated download client' 1>&2
- fi
- if type -p "$PARALLEL" &>/dev/null; then
- P_EXIST=1 # 1, DEBUG: 0
- else
- P_EXIST=0
- message W 'Missing' "'$PARALLEL'" 'utility' 1>&2
- fi
- if [ $# -eq 0 ]; then
- help 1>&2
- exit 1
- fi
- erase=0
- index=0
- h=0
- v=0
- norc=0
- nowarn=0
- aliases_exist=0
- [ -r "$ALIASES" ] && aliases_exist=1
- while read; do
- case "$REPLY" in
- -k)
- erase=1
- ;;
- -n|--norc)
- norc=1
- ;;
- -kn|-nk)
- erase=1
- norc=1
- ;;
- -v|--version)
- v=1
- ;;
- -h|--help)
- h=1
- ;;
- -hv|-vh)
- h=1
- v=1
- ;;
- -w|--no-warning)
- nowarn=1
- ;;
- *)
- param[index++]="$REPLY"
- ;;
- esac
- done < <(awk -v aliases_exist="$aliases_exist" -v params="$*" "$resolve" "$ALIASES")
- if ((h | v)); then
- ((h)) && help
- ((v)) && version
- exit 0
- fi
- if [ `pgrep -cx "$PRG"` -gt 1 ]; then
- message E 'Updater' "$PRG" 'running yet!' 1>&2
- exit 1
- fi
- message `uptime | sed -r 's/^.*(up)([^,]*),.*$/\1: \2/'`
- if [ $erase -eq 1 ]; then
- erase_kernel || exit 1
- fi
- urllist=''
- e=0
- while read; do
- eval "$REPLY"
- done < <(
- if [ $P_EXIST -eq 1 ]; then
- export SHELL="`type -p bash`"
- export -f package1 debug
- export norc baseurl dist complete distver list_to_query
- for ((index=0; index<${#param[@]}; index++)); do
- echo "${param[index]}"
- done | "$PARALLEL" -j 200% -k package1 '{}'
- else
- for ((index=0; index<${#param[@]}; index++)); do
- package1 "${param[index]}" || break
- done
- fi
- )
- unset param
- [ $e -ne 0 ] && exit 1
- [ -z "$urllist" ] && exit 0
- read -rest 0.1
- read -ren2 -p $'-----------------------------------\nIs this OK? [y/N] '
- echo
- [ x"${REPLY,}" != x'y' ] && exit 1
- TEMPDIR="/var/tmp/upd-packages.$USER"
- rm -Rf "$TEMPDIR"
- mkdir "$TEMPDIR" || exit 1
- cd "$TEMPDIR"
- if ! xargs -n1 $DLCLIENT <<<"$urllist"; then
- rm -Rf "$TEMPDIR"
- message E 'Packages download failed' 1>&2
- exit 1
- fi
- run update "`ls -1d $TEMPDIR/*.rpm | tr '\n' ' '`" || exit 1
- exit 0
Advertisement
Add Comment
Please, Sign In to add comment