#!/bin/bash # ppa2pup # convert an Ubuntu PPA repo file, into a Puppy compatible repo file. TMPDIR=/tmp/pkg/${whoami} # @TODO1 - fix last few fields of package entries (should contain the supported ubuntu distro, not current system) if [ -z "$PGP_VERIFY_CMD" ]; then if [ ! -z `which gpgv` ]; then PGP_VERIFY_CMD="$(which gpgv)" elif [ ! -z `gpg` ]; then PGP_VERIFY_CMD="$(which gpgv2)" elif [ ! -z `gpg` ]; then PGP_VERIFY_CMD="$(which gpg) --verify" else echo "ppa2pup: No pgp verify command" 1>&2 fi fi . /etc/DISTRO_SPECS if [ -d ~/.packages/repo ]; then REPO_DIR=`realpath ~/.packages/repo` || \ REPO_DIR=`readlink ~/.packages/repo` || \ REPO_DIR=~/.packages/repo elif [ -d /var/packages/repo ]; then REPO_DIR=/var/packages/repo else REPO_DIR=~/.packages fi #if [ "$DISTRO_BINARY_COMPAT" != "ubuntu" ] && [ "$DISTRO_BINARY_COMPAT" != "debian" ];then # echo "Sorry, you must be running a .deb compatible Puppy Linux" # echo "to use this tool. Your Puppy is based on '$DISTRO_BINARY_COMPAT'" # exit 1 #fi if [ ! "$1" ] || [ "$1" = "-h" ] || [ "$1" = "-help" ] then echo "This script creates a Puppy-compatible repo file from a PPA or Debian repo." echo echo "For Launchpad PPA repos:" echo echo " Usage: ppa2pup ppa:/ [debian|ubuntu] [bionic|stretch|artful|etc] [main|all|contrib|non-free|etc]" echo echo "Examples:" echo echo " ppa2pup ppa:team-xbmc/ppa" echo echo " ppa2pup ppa:team-xbmc/ppa ubuntu bionic" echo echo " ppa2pup ppa:team-xbmc/ppa ubuntu artful" echo echo " ppa2pup ppa:team-xbmc/ppa debian stretch" echo echo echo "For other third-party Debian repos:" echo echo " Usage: ppa2pup http://site.com/[debian|ubuntu]/ [stretch|bionic|etc] [main|contrib|non-free|etc]" echo echo "Examples:" echo echo " ppa2pup http://rpms.litespeedtech.com/debian/" echo echo " ppa2pup http://rpms.litespeedtech.com/debian/ stretch main" echo echo " ppa2pup http://repo.steampowered.com/steam/ precise steam" echo echo " ppa2pup http://http.kali.org/kali/ kali-bleeding-edge main contrib non-free" echo echo "NOTE: Any ommitted distro names or versions will be guessed." echo exit 1 fi RELEASE_DIR=/tmp/ppa_release # create a dir to work in #mkdir -p /tmp/ppa_pkgs mkdir -p "$RELEASE_DIR" # remove any old files #rm /tmp/ppa_pkgs/* 2>/dev/null #rm -rf "$RELEASE_DIR"/* 2>/dev/null # we need to find the correct Packages.gz for the distro (debian/ubuntu), # distro version (stretch/bionic/etc), and architecture (i386/amd64) if [ -z "$SOURCES_LIST_OPT__arch" ]; then arch='i386' case $(uname -m) in i*86) arch='i386' ;; *64) arch='amd64' ;; esac else arch="$SOURCES_LIST_OPT__arch" fi if [[ "$1" =~ 'ppa:' ]] then # we got a 'PPA' URL, lets parse it and get the Packages.gz ppaname="${1/*\//}" username="${1/\/*/}" username="${username//ppa:/}" ppaname="${ppaname//ppa:/}" # get username, but strip special chars PPA_NAME="${username//[-_:]/}" distro=${2:-$DISTRO_BINARY_COMPAT} distro_ver=${3:-$DISTRO_COMPAT_VERSION} repo_name="$distro_ver-$PPA_NAME" repo_filename="Packages-$distro-$distro_ver-${PPA_NAME}" repo_stream=${4:-main} repo_stream2='' repo_stream3='' repo_stream4='' [ "$5" != '' ] && repo_stream2=${5} [ "$6" != '' ] && repo_stream3=${6} [ "$7" != '' ] && repo_stream4=${7} URL=http://ppa.launchpad.net/${username}/${ppaname}/${distro}/dists/${distro_ver}/${repo_stream}/binary-${arch}/Packages.gz repo_url=http://ppa.launchpad.net/${username}/${ppaname}/${distro}/ elif [[ "$1" =~ 'http://' ]] || [[ "$1" =~ 'https://' ]];then # we got a Debian repo source URL, lets parse it and get the Packages.gz distro=${DISTRO_BINARY_COMPAT} distro_ver=${2:-$DISTRO_COMPAT_VERSION} repo_url=$(echo $1 | sed -e 's#/$##g')/ repo_stream=${3:-main} repo_stream2='' repo_stream3='' repo_stream4='' [ "$4" != '' ] && repo_stream2=${4} [ "$5" != '' ] && repo_stream3=${5} [ "$6" != '' ] && repo_stream4=${6} URL=$(echo $1 | sed -e 's#/$##g')/dists/${distro_ver}/${repo_stream}/binary-${arch}/Packages.gz ARCH_PATH="/binary-${arch}/Packages.gz" else # didnt get ppa:foo/bar, exit with usage $0 -h exit 1 fi # if we didn't get the name from the ppa:foo/bar style URL if [[ ! "$1" =~ 'ppa:' ]] then # check if this repo is already installed (find its name in Pkg sources files) if [ -z "$repo_url" ]; then PPA_NAME="$(grep -m1 "^${distro_ver}-${stream:-main}|" /root/.pkg/sources-all | cut -f1 -d'|' 2>/dev/null)" else PPA_NAME="$(grep "^${distro_ver}-${stream:-main}|" /root/.pkg/sources-all | grep -m1 "$repo_url" | cut -f1 -d'|' 2>/dev/null)" if [ -z "$PPA_NAME" ]; then PPA_NAME="$(grep "^${distro_ver}-${stream:-main}-" /root/.pkg/sources-all | grep -m1 "$repo_url" | cut -f1 -d'|' 2>/dev/null)" fi fi # get repo name and filename if [ "$PPA_NAME" = "" ];then echo read -e -p "Enter a repo name, such as '${distro_ver}-${stream:-main}': " -i "${distro_ver}-${stream:-main}" PPA_NAME fi # replace any spaces or underscores with dashes, all lower case PPA_NAME="$( echo "${PPA_NAME// /-}" | tr '_' '-' | tr '[:upper:]' '[:lower:]' )" repo_name="$PPA_NAME" repo_filename="Packages-$distro-${PPA_NAME}" fi PACKAGES_GZ="ppa_Packages.gz" PACKAGES_GZ_PATH="$RELEASE_DIR/$PACKAGES_GZ" PACKAGES_PATH="$RELEASE_DIR/${PACKAGES_GZ%.*}" #Remove extension for stream in $repo_stream $repo_stream2 $repo_stream3 $repo_stream4 do [ "$stream" = '' ] && continue rm /"$PACKAGES_PATH" "$PACKAGES_GZ_PATH" 2>/dev/null download_failed=false download_url=${URL//$repo_stream/$stream} wget --quiet $download_url -O "$PACKAGES_GZ_PATH" 1>/dev/null \ || download_failed=true if [ ! -f "$PACKAGES_GZ_PATH" ] || [ $download_failed = true ];then echo echo "ERROR: the PPA repo '$repo_name' not found for $distro $distro_ver:" echo echo " $download_url" echo echo "You could try a different version of the repo." echo $0 -h exit 1 fi gunzip "$PACKAGES_GZ_PATH" # if Packages file is empty, dont create a repo for it if [ -z "$PACKAGES_PATH" ] || [ ! -s "$PACKAGES_PATH" ];then continue fi if [ ! -z "$SOURCES_LIST_OPT__signed_by" ]; then meta_url=${download_url//$ARCH_PATH/} "$RELEASE_DIR" mkdir -p "$RELEASE_DIR/$repo_name" rm -f "$RELEASE_DIR/$repo_name/*" 2>/dev/null meta_download_failed=false wget --quiet "${meta_url}/Release" -O "$RELEASE_DIR/$repo_name/Release" 1>/dev/null && \ wget --quiet"${meta_url}/Release.gpg" -O "$RELEASE_DIR/$repo_name/Release.gpg" 1>/dev/null || \ meta_download_failed=true if [ "$meta_download_failed" = false ]; then if ( cd $RELEASE_DIR/$repo_name; $PGP_VERIFY_CMD --keyring "$SOURCES_LIST_OPT__signed_by" Release.pgp Release ); then pgp_verified=maybe ReleaseFile="$RELEASE_DIR/$repo_name/InRelease" else pgp_verified=false fi else meta_download_failed=false wget --quiet "${meta_url}/InRelease" -O "$RELEASE_DIR/$repo_name/InRelease" 1>/dev/null \ || meta_download_failed=true if [ "$meta_download_failed" = false ]; then if ( cd $RELEASE_DIR/$repo_name; $PGP_VERIFY_CMD --keyring "$SOURCES_LIST_OPT__signed_by" InRelease ); then pgp_verified=maybe ReleaseFile="$RELEASE_DIR/$repo_name/InRelease" else pgp_verified=false fi fi fi if [ "$pgp_verified" = false ]; then if [ ! -z "$SOURCES_LIST_OPT__Trusted" ] && [ "$SOURCES_LIST_OPT__Trusted" = yes ]; then FAIL_CLASS=WARNING else FAIL_CLASS=ERROR fi echo echo "$FAIL_CLASS: could not verify pgp signature of Release/InRelease file" echo echo " ${meta_url}" if [ ! "$SOURCES_LIST_OPT__Trusted" ]; then #Maybe should exit if this exit 1 fi fi if [ SOURCES_LIST_OPT__Allow_Insecure = yes ]; then hash_function=( sha256sum md5sum sha1sum none ) elif [ "$SOURCES_LIST_OPT__allow_weak" = yes ]; then hash_function=( sha256sum md5sum sha1sum ) else hash_function=( sha256sum ) fi for a_hash_fn in "${hash_function[@]}"; then case "$a_hash_fn" in sha256sum) fsum="$(sha256sum "$file_path" | cut -f1 -d' ')" if [ $(grep -m -c "$fsum" "$ReleaseFile" ) -gt 0 ]; then break fi ;; md5sum) fsum="$(md5sum "$file_path" | cut -f1 -d' ')" if [ $(grep -m -c "$fsum" "$ReleaseFile" ) -gt 0 ]; then echo "WARNING: weak checksum for $repo_name" break fi ;; sha1sum) fsum="$(sha1sum "$file_path" | cut -f1 -d' ')" if [ $(grep -m -c "$fsum" "$ReleaseFile" ) -gt 0 ]; then echo "WARNING: weak checksum for $repo_name" break fi ;; none) fsum="$(md5sum "$file_path" | cut -f1 -d' ')" echo "WARNING: repo metadata unverified" break ;; fi fi echo echo "Found URL:" echo echo " $download_url" echo echo "Repo to create:" echo " $repo_name" echo echo "Repo file to create:" echo " $REPO_DIR/$repo_filename" echo rm /tmp/$repo_filename $REPO_DIR/$repo_filename &>/dev/null #---------------New AWK Version------------------------------------------- cat "$PACKAGES_PATH" | awk -v PKGOS="$distro" -v PKGOSVER="$distro_ver" -v REPOFNM="$repo_filename" \ 'function fixdepends(s, a,p,sout) { split(s,a,",") for (p in a) { gsub(/[ \t]*\(.*\)|[ \t]\|.*|:any/,"",a[p]) sout = sout "," a[p] } sub(/^,/,"",sout) ; return sout; } /^Package:/ { sub(/^Package: /,""); PKG=$0; } /^Version:/ { sub(/^Version: /,""); PKGVER=$0; } /^Filename:/ { sub(/^Filename: /,""); PKGPATH=$0; sub(/\/[^\/]*$/,"",PKGPATH); sub(/.*\//,""); PKGFILE=$0; } /^Priority:/ { sub(/^Priority: /,""); PKGPRIO=$0; } /^Section:/ { sub(/^Section: /,""); PKGSECTION=$0; } /^Installed-Size:/ { sub(/^Installed-Size: /,""); PKGSIZE=$0; } /^MD5sum:/ { sub(/^MD5sum: /,""); PKGMD5=$0; } /^SHA1:/ { sub(/^SHA1: /,""); SHA1=$0; } /^SHA256:/ { sub(/^SHA256: /,""); SHA256=$0; } /^Depends:/ { sub(/^Depends: /,""); PKGDEP=fixdepends($0) "," PKGDEP; } /^Pre-Depends:/ { sub(/^Pre-Depends: /,""); PKGDEP=fixdepends($0) "," PKGDEP; } /^Description:/ { sub(/^Description: /,""); PKGINFO=substr($0,1,200); } /^$/ { print PKG "_" PKGVER "|" PKG "|" PKGVER "||" PKGSECTION "|" PKGSIZE "|" PKGPATH "|" PKGFILE "|" PKGDEP "|" PKGINFO "|" PKGOS "|" PKGOSVER "|" PKGMD5 "|" SHA1 "|" SHA256 "|" PKGPRIO "|" REPOFNM ; PKG=""; PKGVER=""; PKGSECTION=""; PKGSIZE=""; PKGFILE=""; PKGPATH=""; PKGDEP=""; PKGINFO=""; PKGPRIO=""; PKGMD5=""; SHA1=""; SHA256=""; PKGDEP=""; } ' > /tmp/$repo_filename # sort & move the repo file sort -u /tmp/$repo_filename > /tmp/${repo_filename}_sorted 2>/dev/null if [ ! -f /tmp/${repo_filename}_sorted ];then echo "Error: Repo file not created!" exit 1 fi #mv /tmp/${repo_filename}_sorted $REPO_DIR/$repo_filename set -x cut -d'|' -f1-12 /tmp/${repo_filename}_sorted > $REPO_DIR/$repo_filename [ -z "$PKGS_DIR" ] && export PKGS_DIR="$(realpath "${HOME}/.packages")" [ -z "$HASHES_DIR" ] && export HASHES_DIR="$PKGS_DIR/hashes" && mkdir -p "$HASHES_DIR" cut -d'|' -f1,2,7,8,13 /tmp/${repo_filename}_sorted > "$HASHES_DIR/${repo_filename//Packages/PKG_SUMS}" cut -d'|' -f1,2,7,8,13,14,15 /tmp/${repo_filename}_sorted | sort -d -k 4 > /tmp/${repo_filename}_sorted_md5 awk -F '|' '{print $5 "|" $3 "|" $4}' /tmp/${repo_filename}_sorted_md5 > "$HASHES_DIR/${repo_filename//Packages/MD5}" #cut -d'|' -f4,5 /tmp/${repo_filename}_sorted_md5 > "$HASHES_DIR/${repo_filename//Packages/SHA1}" cut -d'|' -f4,7 /tmp/${repo_filename}_sorted_md5 > "$HASHES_DIR/${repo_filename//Packages/SHA256}" set +x echo "Success! File created." echo fallback_repos="$(pkg repo-list | grep -v $repo_name | tr '\n' ' ')" repo_entry="$repo_name|deb|$repo_filename|$repo_url||||$fallback_repos" # if already added to ~/.pkg/sources[-all], remove it if [ "$(cat ~/.pkg/sources | grep -m1 "^$repo_name|")" != "" ] || \ [ "$(cat ~/.pkg/sources-all | grep -m1 "^$repo_name|")" != "" ];then cat ~/.pkg/sources | grep -v "^$repo_name|" > /tmp/pkgsources cat ~/.pkg/sources-all | grep -v "^$repo_name|" > /tmp/pkgsources-all mv /tmp/pkgsources ~/.pkg/sources mv /tmp/pkgsources-all ~/.pkg/sources-all fi # add repo entry to ~/.pkg/sources pkg add-source "$repo_entry" echo # refresh list of available repos pkg update-sources echo echo "Repo info:" pkg repo-info $repo_name echo if [ "$(cat ~/.pkg/sources | grep -m1 "^$repo_name|")" != "" ];then echo "Success! Repo added and available to use." echo echo "To use this repo, simply type the following and hit ENTER:" echo " pkg repo $repo_name" echo fi done exit 0