diff options
author | B. Watson <yalhcru@gmail.com> | 2020-07-07 00:19:37 -0400 |
---|---|---|
committer | B. Watson <yalhcru@gmail.com> | 2020-07-07 00:19:37 -0400 |
commit | 1d45642186e0eb862726a768067db65bc540181f (patch) | |
tree | d921b7fcfaf3a2dccc049169965aba7d4fd367e1 | |
parent | 70cbc92d783d609235e3415be07a7fb6337f2c11 (diff) | |
download | misc-scripts-1d45642186e0eb862726a768067db65bc540181f.tar.gz |
Add slacksrc
-rwxr-xr-x | slacksrc | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/slacksrc b/slacksrc new file mode 100755 index 0000000..4cc6d19 --- /dev/null +++ b/slacksrc @@ -0,0 +1,257 @@ +#!/bin/bash + +# slacksrc - wget the slackware source for a Slackware package. +# B. Watson (yalhcru@gmail.com) + +# I thought this would be a quicky one-liner (or anyway less than 10 +# lines), but it's grown into a monster. + +set -e + +DEFAULTMIRROR="http://ftp.slackware.com/pub/slackware" +MIRROR="${MIRROR:-$DEFAULTMIRROR}" +TMP="${TMP:-/tmp}" +CACHEDIR="$HOME/.slacksrc" +FILELIST="$CACHEDIR/FILE_LIST" +TMPFILE="$TMP/slacksrc.$RANDOM.$$" +SELF="$( echo $0 | sed 's,.*/,,' )" + +# everyone's favorite perl function +die() { + echo -n "$SELF: " 1>&2 + if [ -n "$@" ]; then + echo "$@" 1>&2 + else + echo "internal error, contact author" 1>&2 + fi + rm -f "$TMPFILE" + exit 1 +} + +# /etc/slackware-version sometimes contains extra stuff past the +# actual version number (for Slack 9.0, it says 9.0.0, and I remember +# at least one old version with a name in parentheses). So sed out +# everything but major.minor. This will still be wrong on a -current +# system, but anyone running -current is smart enough to read and +# edit this script. +SLACKVER="$( \ + sed \ + 's,slackware \+\([0-9]\+\.[0-9]\+\).*$,\1,i' \ + /etc/slackware-version 2>/dev/null || \ + echo Not-Slackware )" + +if [ -z "$1" ] || [ "$1" == "--help" ]; then + exec perldoc $0 + + # This never actually runs. + cat <<EOF +=pod + +=head1 NAME + +slacksrc - download source directory of an official Slackware package + +=head1 SYNOPSIS + +slacksrc [-o] [slack_ver] [series]/package + +=head1 DESCRIPTION + +Downloads the source directory of an official Slackware package with wget. + +By default, the latest version from patches/source/ is downloaded. If +you need the original release version source, use the B<-o> option. + +Default Slackware version is determined by looking at +/etc/slackware-version, if the B<slack_ver> argument isn't given. + +The slack_ver argument can be any slackware from 3.3 to +the present, including current (although current can't be +autodetected, since /etc/slackware-version never actually +says 'current'). Not all mirrors carry all old Slackware +versions. If you're looking for really old sources, the mirror at +ftp://ftp.heanet.ie/mirrors/ftp.slackware.com/pub/slackware/ goes all +the way back to Slackware 1.0.1, although this script only works on +3.3 and newer (3.3 was the first version with FILELIST.TXT). + +The package name is matched against FILE_LIST from the server. If only +one match is found, the source for that package is downloaded and saved +in a subdirectory of the current directory (named after the package). If +multiple matches are found, they are listed, but nothing is downloaded. + +If the package name is a full name, like bash-4.2.037-x86_64-1 (possibly +with a .t?z extension), the version/build/arch/extension will be removed. +Likewise if the name is a full pathname (beginning with e.g. /var/log), +the directory name will be removed. For this reason, there is NO guarantee +that the source will match any version number provided. + +Searching is done with grep, so the package name can be a regex. The list +entries look like 'a/pkgname/', so you can do: + + a/foo - all packages in a/ series beginning with 'foo' + a/foo/ - exact match, foo package in a/ series + /foo/ - exact match in any series + foo.*bar - any series, matching the (unanchored!) regex + +Because the list contains a trailing slash, you can't use $ to anchor the +end of the match (just match the / instead). + +The environment variable MIRROR can be set to the Slackware mirror site +to use. This should be the URL of the top level of the mirror. You can +copy the URLs from http://mirrors.slackware.com/mirrorlist/ (only http: +or ftp: mirrors though, rsync not supported). Default mirror is + +The FILE_LIST file is cached at I<~/.slacksrc/FILE_LIST-<slack_ver>>. +There's not a lot of error checking. If things go wrong, check the contents +of the cache file or just rm it and try again. + +If you want to mirror all the Slackware source (for all packages), this +is the wrong tool for the job. Use rsync or wget instead. If you're +looking for the source to a 3rd-party package (from slackbuilds.org or +slacky.eu maybe), you're using the wrong tool again. + +=head1 AUTHOR AND COPYRIGHT + +This is slacksrc v0.1 by B. Watson (yalhcru@gmail.com). +Released under the WTFPL: do WTF you want with this. See +http://www.wtfpl.net/txt/copying/. + +=cut +EOF + exit 0 +fi + +if [ -z "$HOME" ]; then + die "HOME not set. Please fix this and try again." +fi + +if [ "$1" = "-o" ]; then + PATCHES=no + shift +fi + +if [ "$2" != "" ]; then + SLACKVER="$1" + shift +fi + +if [ "$SLACKVER" = "Not-Slackware" ]; then + die "This ain't Slackware, you'll have to tell me the Slack version you want" +fi + +FILELIST="$FILELIST-$SLACKVER" + +PKG="$1" +TOPDIR=$MIRROR/slackware-$SLACKVER +SRCDIR=$TOPDIR/source + +if ! wget -q --spider "$TOPDIR"; then + die "$TOPDIR not found on server, are you sure $SLACKVER is a valid version?" +fi + +# Remove local dir name. Only works with absolute paths (relative +# paths are assumed to be the package series, sorry) +PKG="$( echo "$PKG" | sed 's,^/.*/,,' )" + +# Remove .tgz/txz/tar extension +PKG="$( echo "$PKG" | sed 's,\.\(t.z\|tar\)$,,' )" + +# Remove version/arch/build. Since we can't know whether the input +# *has* a version-arch-build, we can't use the standard cut|rev stuff +# to remove it. So we use some heuristics that might one day need to +# change (particularly, new arches might need to be added to the list). +PKG="$( echo "$PKG" | sed 's,-[^-]\+-\(x86_64\|i.86\|arm\|s390\|ppc\|ppc64\)-[0-9][^-]*$,,' )" + +# The sed|sort below extracts only the first 2 directory name components +# after the source/. Earlier slack versions didn't list directories in +# FILELIST.TXT (only the files in them) or else we could simplify this. +# Basically, we have something like ./source/a/less/SlackBuild, and we +# keep only the a/less/ part (note the trailing slash). +if [ ! -s $FILELIST ]; then + mkdir -p $CACHEDIR + wget -O- $TOPDIR/FILELIST.TXT | \ + sed -n 's,.*\./source/\([^/]\+/[^/]\+/\).*$,\1,p' | \ + sort -u > $FILELIST + +#TODO: handle extra/ somehow +#wget -O $FILELIST.tmp $TOPDIR/FILELIST.TXT +fi + +rm -f $TMPFILE + +# The files in $FILELIST have trailing slashes, sed them out. +grep "$PKG" $FILELIST | sed 's,/$,,' > $TMPFILE + +LINES=$( wc -l $TMPFILE | cut -d' ' -f1 ) + +URL="" +case "$LINES" in + 0) die "Can't find any packages matching '$PKG' in $FILELIST" + ;; + 1) URL="$SRCDIR/$( cat $TMPFILE )/" + ;; + *) echo "Ambiguous match, '$PKG' matches:" + echo + cat $TMPFILE + echo + ;; +esac + +rm -f $TMPFILE +if [ -z "$URL" ]; then + die "Couldn't determine source URL" +fi + +PKGDIR=$( echo "$URL" | sed 's,.*/\([^/]\+\)/,\1,' ) + +if [ -e "$PKGDIR" ]; then + die "Directory '$PKGDIR' already exists, move or remove it first" +fi + +# 20200706 bkw: see if there's a patches/, use that if found. +PATCHURL="$( echo "$URL" | sed "s,source/[^/]*/\([^/]*\)/,patches/source/\1/," )" + +#echo "Original source dir URL: $URL" +#echo "Patch source dir URL: $PATCHURL" + +if [ "$PATCHES" = "no" ]; then + echo "-o option given, not looking in /patches!" +else + if wget -q --spider "$PATCHURL"; then + echo "Patch URL exists, using it" + URL="$PATCHURL" + else + echo "Patch URL doesn't exist, using original source" + fi +fi + +echo $URL + +# Unfortunately, the Slackware mirrors don't all have the same dir +# structure (/pub/slackware vs. /pub/Linux/slackware, etc). We have +# to count the leading directories so we can tell wget how many dirs +# to strip off. The shell isn't really suited to this, but I don't wanna +# rewrite in a real language. + +# In English... the first sed expression removes the +# proto://hostname. The 2nd removes the final directory name +# (e.g. /bash/), and the third replaces the slashes in the remaining +# part, with newlines (ASCII 0x0a). So we get one dir name per line, +# which is exactly what "wc -l" will count for us. +CUTDIRS=$( echo "$URL" | \ + sed -e 's,^[a-z]\+://[^/]\+/,,' \ + -e 's,/[^/]\+/$,,' \ + -e 's,/,\x0a,g' | \ + wc -l ) + +# wget will retrieve the server-generated index files (index.html??C=D;O=D +# and friends), so reject them with -R. The -l10 might be overkill (it's +# the recursion level limit), but it won't hurt anything. +wget -q -r -l10 -nH -np -R'index.html*' --cut-dirs=$CUTDIRS "$URL" + +# The icing on the cake: make the SlackBuild executable. +chmod 0755 $PKGDIR/*SlackBuild 2>/dev/null || true + +echo +echo "Files saved to ./$PKGDIR:" +ls -ld $PKGDIR/* |