Guest User

upd

a guest
Jan 25th, 2025
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 11.10 KB | Source Code | 0 0
  1. #!/bin/bash
  2.  
  3. VERSION=2.31
  4.  
  5. ALIASES="/usr/local/etc/upd/upd_${USER}.aliases"
  6. PRG='upd'
  7.  
  8. distver="`sed -r 's/^.*://' /etc/system-release-cpe`"
  9. dist="fc$distver"
  10. baseurl='https://koji.fedoraproject.org/koji'
  11.  
  12. PACKAGER='yum'
  13. type -p dnf &>/dev/null && PACKAGER='dnf'
  14.  
  15. complete='
  16.    BEGIN {
  17.     gsub("[*+.]", "\\\\&", pkg);
  18.    }
  19.    
  20.    $0 ~ pkg {
  21.     link=$0;
  22.     sub("^.*href=\"", "", link);
  23.     sub("\".*$", "", link);
  24.     while (1) {
  25.         getline;
  26.         if ($0 ~ /\/tr/) {
  27.         ok=0;
  28.         break;
  29.         }
  30.         if ($0 ~ /complete/) {
  31.         ok=1;
  32.         break;
  33.         }
  34.     }
  35.     if (ok) print(link);
  36.     exit ok;
  37.    }
  38. '
  39.  
  40. resolve='
  41.    function add(e,
  42.             i) {
  43.     for(i in s) {
  44.         if (e==s[i]) {
  45.         return;
  46.         }
  47.     }
  48.     s[++ptr]=e;
  49.    }
  50.  
  51.    function exadd(e,
  52.             i) {
  53.     for(i in exs) {
  54.         if (e==exs[i]) {
  55.         return;
  56.         }
  57.     }
  58.     exs[++exptr]=e;
  59.    }
  60.  
  61.    BEGIN {
  62.     ptr=0;
  63.     idx=0;
  64.     exptr=0;
  65.     exflag=0;
  66.     keys=split(params, keywords);
  67.     if (!keys) {
  68.         exit;
  69.     }
  70.     for (i in keywords) {
  71.         temp=keywords[i];
  72.         if (temp=="-x" || temp=="--exclude") {
  73.         exflag=1;
  74.         continue;
  75.         }
  76.         if (exflag) {
  77.         exflag=0;
  78.         if (substr(temp, 1, 1)!="-") {
  79.             exadd(temp);
  80.             continue;
  81.         }
  82.         }
  83.         add(temp);
  84.     }
  85.     if (!aliases_exist) {
  86.         exit
  87.     }
  88.    }
  89.  
  90.    {
  91.     if ($0 ~ /^[ \t]*(#|$)/) {
  92.         next;
  93.     }
  94.     if (NF<2) {
  95.         next;
  96.     }
  97.     if (idx) {
  98.         for (i in ali) {
  99.         if ($1==ali[i]) {
  100.             next;
  101.         }
  102.         }
  103.     }
  104.     ali[++idx]=$1;
  105.     ali_pars[idx, 1]=8;
  106.     for (i=2; i<=NF; i++) {
  107.         ali_pars[idx, i]=$i;
  108.     }
  109.    }
  110.  
  111.    END {
  112.     if (aliases_exist) {
  113.         i=1;
  114.         while (i<=ptr) {
  115.         for (j in ali) {
  116.             if (s[i]==ali[j]) {
  117.             if (ali_pars[j, 1]) {
  118.                 delete s[i];
  119.                 for (aliidx in ali_pars) {
  120.                 if (split(aliidx, ix, /\034/)!=2) {
  121.                     continue
  122.                 };
  123.                 if (ix[1]!=j) {
  124.                     continue;
  125.                 }
  126.                 k=ix[2];
  127.                 if (k==1) {
  128.                     ali_pars[j, 1]--;
  129.                 } else {
  130.                     add(ali_pars[j, k]);
  131.                 }
  132.                 }
  133.             }
  134.             break;
  135.             }
  136.         }
  137.         i++;
  138.         }
  139.         for (j in ali) {
  140.         ali_pars[j, 1]=8;
  141.         }
  142.         i=1;
  143.         while (i<=exptr) {
  144.         for (j in ali) {
  145.             if (exs[i]==ali[j]) {
  146.             if (ali_pars[j, 1]) {
  147.                 delete exs[i];
  148.                 for (aliidx in ali_pars) {
  149.                 if (split(aliidx, ix, /\034/)!=2) {
  150.                     continue
  151.                 };
  152.                 if (ix[1]!=j) {
  153.                     continue;
  154.                 }
  155.                 k=ix[2];
  156.                 if (k==1) {
  157.                     ali_pars[j, 1]--;
  158.                 } else {
  159.                     exadd(ali_pars[j, k]);
  160.                 }
  161.                 }
  162.             }
  163.             break;
  164.             }
  165.         }
  166.         i++;
  167.         }
  168.     }
  169.     if (exptr) {
  170.         l=asort(exs);
  171.     }
  172.     if (ptr) {
  173.         printed=0;
  174.         j=asort(s);
  175.         for (i=1; i<=j; i++) {
  176.         exflag=0;
  177.         for (k=1; k<=l; k++) {
  178.             if (exs[k]==s[i]) {
  179.             exflag=1;
  180.             break;
  181.             }
  182.         }
  183.         if (!exflag) {
  184.             printf("%s\n", s[i]);
  185.             printed=1;
  186.         }
  187.         }
  188.         if (!printed) {
  189.         printf("\n");
  190.         }
  191.     } else {
  192.         printf("\n");
  193.     }
  194.    }
  195. '
  196.  
  197. list_to_query='
  198.    function packagenamearch(s,
  199.                 arr, arch, name) {
  200.     split(s, arr, dst);
  201.     name=arr[1];
  202.     sub(/-[^-]+-[^-]+$/, "", name);
  203.     arch=arr[2];
  204.     sub(/\.rpm$/, "", arch);
  205.     sub(/.*\./, "", arch);
  206.     return name "." arch;
  207.    }
  208.  
  209.    function is_element(x, a,
  210.                 i) {
  211.     for (i in a) {
  212.         if (a[i]==x) return 1;
  213.     }
  214.     return 0;
  215.    }
  216.  
  217.    BEGIN {
  218.     i=0;
  219.     dst="fc(" distver-1 "|" distver ")";
  220.     query="";
  221.     urllist="";
  222.    }
  223.  
  224.    /\.rpm.*download/ {
  225.     reply=$0;
  226.     sub(/<[^>]*>/, "");
  227.     pknamearch=$1;
  228.     package[i]=pknamearch;
  229.     sub("^.*info</a>", "", reply);
  230.     sub(/.[^"]*"/, "", reply);
  231.     sub(/"[^"]*$/, "", reply);
  232.     purl[i]=reply;
  233.     pknamearch=packagenamearch(pknamearch);
  234.     temp=pknamearch;
  235.     sub(/^.*\./, "", temp);
  236.     if (temp !~ /x86_64|i[3-6]86|noarch/) {
  237.         next
  238.     };
  239.     pknoversion[i]=pknamearch;
  240.     query=query " " pknamearch;
  241.     i++;
  242.    }
  243.  
  244.    END {
  245.     if (!length(query)) {
  246.         printf("message E \"Empty query list:\" \"%s\" 1>&2\n", param1);
  247.         exit(0);
  248.     }
  249.     cmd="rpm -q" query " | grep -vF \"not installed\" | sort -rV";
  250.     temp=RS;
  251.     RS="\0";
  252.     cmd | getline installed;
  253.     RS=temp;
  254.     if (!length(installed)) {
  255.         printf("message W \"Not installed\" \"%s\" 1>&2\n", param1);
  256.         exit(0);
  257.     }
  258.     oldpnamearch="";
  259.     split(installed, inst);
  260.     j=0;
  261.     k=0;
  262.     for (idx in inst) {
  263.         reply=inst[idx];
  264.         pnamearch=packagenamearch(reply);
  265.         if (pnamearch != oldpnamearch) {
  266.         for (i in pknoversion) {
  267.             if (pnamearch == pknoversion[i]) {
  268.             packagei=package[i];
  269.             sub(/\.[^.]*$/, "", packagei);
  270.             if (reply==packagei) {
  271.                 msg[++j]=reply "/x";
  272.             } else {
  273.                 split(reply, arr_reply, "\\." dst "\\.");
  274.                 split(packagei, arr_packagei, "\\." dst "\\.", separator);
  275.                 cmd="{ echo \"" arr_reply[1] "\"; echo \"" arr_packagei[1] "\"; } | sort -V";
  276.                 temp=RS;
  277.                 RS="\0";
  278.                 cmd | getline sortedline;
  279.                 RS=temp;
  280.                 split(sortedline, sorted);
  281.                 if (reply==sorted[1] separator[1] arr_packagei[2]) {
  282.                 if (!is_element(purl[i], aurl)) {
  283.                     aurl[++k]=purl[i];
  284.                     msg[++j]=packagei "/u";
  285.                 }
  286.                 } else {
  287.                 msg[++j]=reply "/n";
  288.                 }
  289.             }
  290.             break;
  291.             }
  292.         }
  293.         }
  294.         oldpnamearch=pnamearch;
  295.     }
  296.     for (i=k; i>=1; i--) {
  297.         urllist=urllist aurl[i] " ";
  298.     }
  299.     if (length(urllist)) {
  300.         printf("urllist+=\"%s\"\n", urllist);
  301.     }
  302.     for (i=j; i>=1; i--) {
  303.         if (split(msg[i], m, /\//) == 2) {
  304.         switch (m[2]) {
  305.             case "u": {
  306.             printf("message \"Update:\" \"%s\"\n", m[1]);
  307.             break;
  308.             }
  309.             case "x": {
  310.             printf("message W \"Up to date\" \"%s\"\n", m[1]);
  311.             break;
  312.             }
  313.             case "n": {
  314.             printf("message W \"Up to date\" \"%s\" \"(newer installed)\"\n", m[1]);
  315.             break;
  316.             }
  317.         }
  318.         } else {
  319.         printf("message W \"h/h:\" \"%s\"\n", m[1]);
  320.         }
  321.     }
  322.     exit(0);
  323.    }
  324. '
  325.  
  326. message() {
  327.     case "$1" in
  328.     W|w)
  329.         [ $nowarn = 1 ] && return 0
  330.         echo -ne '\x1b[33;1mW:\x1b[m '
  331.         shift
  332.         ;;
  333.     E|e)
  334.         echo -ne '\x1b[31;1mE:\x1b[m '
  335.         shift
  336.         ;;
  337.     esac
  338.     echo -n "$1 "
  339.     shift
  340.     echo -ne "\x1b[1m$1\x1b[m "
  341.     shift
  342.     echo "$*"
  343. }
  344.  
  345. debug() {
  346.     echo -e "\x1b[32;1m$@\x1b[m"
  347. }
  348.  
  349. gettime() {
  350.     echo $((`date '+%s%N'`/1000000))
  351. }
  352.  
  353. tdebug() {
  354.     echo -e "\x1b[32;1m$((`gettime`-t0))\\t$@\x1b[m"
  355. }
  356.  
  357. package1() {
  358.     [ -z "$1" ] && return 0
  359.     pattern="`sed 's/ /%20/g; s/\\+/%2b/g;' <<<\"$1\"`"
  360.     url="$baseurl/search?match=exact&type=package&terms=$pattern"
  361.     if ! list="`wget -t3 -T25 -l1 -O - \"$url\" 2>/dev/null`"; then
  362.     echo "message E 'Error in GET repository' 1>&2"
  363.     echo 'e=1'
  364.     return 1
  365.     fi
  366.     pattern="`sed 's/[*+.]/\\\\&/g' <<<\"$1\"`"
  367.     packages="`grep -E \"<a [^>]*>.*$pattern.*$dist</a>\" <<<\"$list\" |
  368.     sed -r 's:^.*<a [^>]*>::; s:</a>.*$::' | sort -Vr`"
  369.     ((norc)) && packages="`grep -v '^.*-.*rc' <<<\"$packages\"`"
  370.     if [ -z "$packages" ]; then
  371.     echo "message W 'Not in the repository:' '$1' 1>&2"
  372.     return 0
  373.     fi
  374.     for i in $packages; do
  375.     url="`awk -v \"pkg=$i\" \"$complete\" <<<\"$list\"`"
  376.     if [ ! -z "$url" ]; then
  377.         url="$baseurl/$url"
  378.         break
  379.     fi
  380.     done
  381.     if [ -z "$url" ]; then
  382.     echo "message W 'Not in the repository:' '$1' 1>&2"
  383.     return 0
  384.     fi
  385.     if ! list="`wget -t3 -T15 -l1 -O - \"$url\" 2>/dev/null`"; then
  386.     echo "message E 'Error in GET repository' '$1' 1>&2"
  387.     return 0
  388.     fi
  389.     awk -v distver=$distver -v param1="$1" "$list_to_query" <<<"$list"
  390.     return 0
  391. }
  392.  
  393. run() {
  394.     if [ ! -z "$1" -a ! -z "$2" ]; then
  395.     if [ $EUID -eq 0 ]; then
  396.         $PACKAGER "$1" $2
  397.         sync
  398.     else
  399.         i=3
  400.         while [ $i -gt 0 ]; do
  401.         echo -n 'root '
  402.         su - -c "$PACKAGER $1 $2; sync" && break
  403.         ((i--))
  404.         done
  405.         if [ $i -eq 0 ]; then
  406.         message E 'Authentication failure' 1>&2
  407.         return 1
  408.         fi
  409.     fi
  410.     fi
  411.     return 0
  412. }
  413.  
  414. erase_kernel() {
  415.     curr_ver="`uname -r`"
  416.     message 'Current kernel release:' "$curr_ver"
  417.     m='Available kernel'
  418.     spaces='                                           '
  419.     spaces="${spaces:0:${#m}+3}"
  420.     kvers=''
  421.     i=0
  422.     j=0
  423.     while read; do
  424.     if [ x"$REPLY" = x"$curr_ver" ] || [ $i -eq 0 ]; then
  425.         kv="\\x1b[1m${REPLY}\\x1b[m"
  426.     else
  427.         kv="\\x1b[34;1m${REPLY}\\x1b[m"
  428.         [ $j -gt 0 ] && kvers+='\|'
  429.         kvers+="${REPLY//./\\.}"
  430.         ((j++))
  431.     fi
  432.     if [ $i -eq 0 ]; then
  433.         kernels="$kv"
  434.     else
  435.         kernels+="\\n$spaces$kv"
  436.     fi
  437.     ((i++))
  438.     done < <(rpm -q kernel{,-PAE}{,-core} | sed 's/^[^[:digit:]]*//; /^$/ d;' | sort -Vru)
  439.     s=''
  440.     [ $i -gt 1 ] && s='s'
  441.     echo -e "$m$s: $kernels"
  442.     if [ $j -eq 0 ]; then
  443.     message W 'Nothing to do' 1>&2
  444.     return 0
  445.     fi
  446.     pkglist="`rpm -qa kernel\* | grep \"$kvers\" | grep -v headers | xargs -r echo`"
  447.     if [ -z "$kvers" ] || [ -z "$pkglist" ]; then
  448.     message W 'Nothing to do' 1>&2
  449.     return 1
  450.     fi
  451.     run remove "$pkglist" || return 1
  452.     return 0
  453. }
  454.  
  455. version() {
  456.     echo "v$VERSION"
  457. }
  458.  
  459. help() {
  460.     echo -e '\t\x1b[1mupd\x1b[m [-h|--help] [-v|--version] [-k] [-w|--no-warning] [-n|--norc] [[-x|--exclude] \x1b[4mpackage\x1b[m] ...'
  461. }
  462.  
  463. DLCLIENT='wget'
  464. PARALLEL='parallel'
  465. FAST='aria2c -x 5 -k 2M'
  466. # FAST='curl --retry 20 --parallel --parallel-max 5 -O'
  467. if type -p "${FAST%% *}" &>/dev/null; then
  468.     DLCLIENT="$FAST"
  469. else
  470.     message W 'Missing' "${FAST%% *}" 'accelerated download client' 1>&2
  471. fi
  472. if type -p "$PARALLEL" &>/dev/null; then
  473.     P_EXIST=1           # 1, DEBUG: 0
  474. else
  475.     P_EXIST=0
  476.     message W 'Missing' "'$PARALLEL'" 'utility' 1>&2
  477. fi
  478. if [ $# -eq 0 ]; then
  479.     help 1>&2
  480.     exit 1
  481. fi
  482. erase=0
  483. index=0
  484. h=0
  485. v=0
  486. norc=0
  487. nowarn=0
  488. aliases_exist=0
  489. [ -r "$ALIASES" ] && aliases_exist=1
  490. while read; do
  491.     case "$REPLY" in
  492.     -k)
  493.         erase=1
  494.         ;;
  495.     -n|--norc)
  496.         norc=1
  497.         ;;
  498.     -kn|-nk)
  499.         erase=1
  500.         norc=1
  501.         ;;
  502.     -v|--version)
  503.         v=1
  504.         ;;
  505.     -h|--help)
  506.         h=1
  507.         ;;
  508.     -hv|-vh)
  509.         h=1
  510.         v=1
  511.         ;;
  512.     -w|--no-warning)
  513.         nowarn=1
  514.         ;;
  515.     *)
  516.         param[index++]="$REPLY"
  517.         ;;
  518.     esac
  519. done < <(awk -v aliases_exist="$aliases_exist" -v params="$*" "$resolve" "$ALIASES")
  520. if ((h | v)); then
  521.     ((h)) && help
  522.     ((v)) && version
  523.     exit 0
  524. fi
  525. if [ `pgrep -cx "$PRG"` -gt 1 ]; then
  526.     message E 'Updater' "$PRG" 'running yet!' 1>&2
  527.     exit 1
  528. fi
  529. message `uptime | sed -r 's/^.*(up)([^,]*),.*$/\1: \2/'`
  530. if [ $erase -eq 1 ]; then
  531.     erase_kernel || exit 1
  532. fi
  533. urllist=''
  534. e=0
  535. while read; do
  536.     eval "$REPLY"
  537. done < <(
  538.     if [ $P_EXIST -eq 1 ]; then
  539.     export SHELL="`type -p bash`"
  540.     export -f package1 debug
  541.     export norc baseurl dist complete distver list_to_query
  542.     for ((index=0; index<${#param[@]}; index++)); do
  543.         echo "${param[index]}"
  544.     done | "$PARALLEL" -j 200% -k package1 '{}'
  545.     else
  546.     for ((index=0; index<${#param[@]}; index++)); do
  547.         package1 "${param[index]}" || break
  548.     done
  549.     fi
  550. )
  551. unset param
  552. [ $e -ne 0 ] && exit 1
  553. [ -z "$urllist" ] && exit 0
  554. read -rest 0.1
  555. read -ren2 -p $'-----------------------------------\nIs this OK? [y/N] '
  556. echo
  557. [ x"${REPLY,}" != x'y' ] && exit 1
  558. TEMPDIR="/var/tmp/upd-packages.$USER"
  559. rm -Rf "$TEMPDIR"
  560. mkdir "$TEMPDIR" || exit 1
  561. cd "$TEMPDIR"
  562. if ! xargs -n1 $DLCLIENT <<<"$urllist"; then
  563.     rm -Rf "$TEMPDIR"
  564.     message E 'Packages download failed' 1>&2
  565.     exit 1
  566. fi
  567. run update "`ls -1d $TEMPDIR/*.rpm | tr '\n' ' '`" || exit 1
  568. exit 0
  569.  
Advertisement
Add Comment
Please, Sign In to add comment