aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <yalhcru@gmail.com>2020-07-07 00:19:37 -0400
committerB. Watson <yalhcru@gmail.com>2020-07-07 00:19:37 -0400
commit1d45642186e0eb862726a768067db65bc540181f (patch)
treed921b7fcfaf3a2dccc049169965aba7d4fd367e1
parent70cbc92d783d609235e3415be07a7fb6337f2c11 (diff)
downloadmisc-scripts-1d45642186e0eb862726a768067db65bc540181f.tar.gz
Add slacksrc
-rwxr-xr-xslacksrc257
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/*