diff options
author | Jacob Pipkin <d4wnr4z0r@yahoo.com> | 2012-05-08 00:44:49 -0500 |
---|---|---|
committer | Jacob Pipkin <d4wnr4z0r@yahoo.com> | 2012-05-08 00:44:49 -0500 |
commit | b7afd023a8e5ff86f751196984ba87dcb9d451cd (patch) | |
tree | 0e6add668d896be591972c4e7fb2a02b31488770 | |
download | sbotools2-b7afd023a8e5ff86f751196984ba87dcb9d451cd.tar.xz |
initial repo add
-rw-r--r-- | SBO-Lib/Changes | 6 | ||||
-rw-r--r-- | SBO-Lib/MANIFEST | 6 | ||||
-rw-r--r-- | SBO-Lib/Makefile.PL | 12 | ||||
-rw-r--r-- | SBO-Lib/README | 36 | ||||
-rw-r--r-- | SBO-Lib/lib/SBO/.Lib.pm.swp | bin | 0 -> 32768 bytes | |||
-rw-r--r-- | SBO-Lib/lib/SBO/Lib.pm | 580 | ||||
-rw-r--r-- | SBO-Lib/t/SBO-Lib.t | 18 | ||||
-rw-r--r-- | man1/sbocheck.1 | 25 | ||||
-rw-r--r-- | man1/sboconfig.1 | 55 | ||||
-rw-r--r-- | man1/sbofind.1 | 25 | ||||
-rw-r--r-- | man1/sboinstall.1 | 59 | ||||
-rw-r--r-- | man1/sbosnap.1 | 36 | ||||
-rw-r--r-- | man1/sboupgrade.1 | 59 | ||||
-rw-r--r-- | man5/sbotools.conf.5 | 35 | ||||
-rwxr-xr-x | sbocheck | 46 | ||||
-rwxr-xr-x | sboconfig | 119 | ||||
-rwxr-xr-x | sbofind | 85 | ||||
-rwxr-xr-x | sboinstall | 50 | ||||
-rwxr-xr-x | sbosnap | 64 | ||||
-rwxr-xr-x | sboupgrade | 183 |
20 files changed, 1499 insertions, 0 deletions
diff --git a/SBO-Lib/Changes b/SBO-Lib/Changes new file mode 100644 index 0000000..57a96fd --- /dev/null +++ b/SBO-Lib/Changes @@ -0,0 +1,6 @@ +Revision history for Perl extension SBO::Lib. + +0.01 Wed Apr 25 23:13:55 2012 + - original version; created by h2xs 1.23 with options + -X -n SBO::Lib + diff --git a/SBO-Lib/MANIFEST b/SBO-Lib/MANIFEST new file mode 100644 index 0000000..c2cad44 --- /dev/null +++ b/SBO-Lib/MANIFEST @@ -0,0 +1,6 @@ +Changes +Makefile.PL +MANIFEST +README +t/SBO-Lib.t +lib/SBO/Lib.pm diff --git a/SBO-Lib/Makefile.PL b/SBO-Lib/Makefile.PL new file mode 100644 index 0000000..0fcb1d5 --- /dev/null +++ b/SBO-Lib/Makefile.PL @@ -0,0 +1,12 @@ +use 5.012003; +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + NAME => 'SBO::Lib', + VERSION_FROM => 'lib/SBO/Lib.pm', + PREREQ_PM => {'Sort::Versions' => 1.5,'Text::Tabulate' => 1.1.1}, + ($] >= 5.005 ? ## Add these new keywords supported since 5.005 + (ABSTRACT => 'methods, variables, etc for the sbotools pacage', + AUTHOR => 'Jacob Pipkin <j@dawnrazor.net>') : ()), +); diff --git a/SBO-Lib/README b/SBO-Lib/README new file mode 100644 index 0000000..324c6ae --- /dev/null +++ b/SBO-Lib/README @@ -0,0 +1,36 @@ +SBO-Lib version 0.01 +==================== + +SBO::Lib is a library for the sbotools scripts. + +INSTALLATION + +To install this module type the following: + + perl Makefile.PL + make + make test + make install + +DEPENDENCIES + +This module requires these other modules and libraries: + + Sort::Versions => 1.5 + Text::Tabulate => 1.1.1 + +COPYRIGHT AND LICENCE + +DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +Version 2, December 2004 + +Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> + +Everyone is permitted to copy and distribute verbatim or modified +copies of this license document, and changing it is allowed as long +as the name is changed. + +DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/SBO-Lib/lib/SBO/.Lib.pm.swp b/SBO-Lib/lib/SBO/.Lib.pm.swp Binary files differnew file mode 100644 index 0000000..88b9abf --- /dev/null +++ b/SBO-Lib/lib/SBO/.Lib.pm.swp diff --git a/SBO-Lib/lib/SBO/Lib.pm b/SBO-Lib/lib/SBO/Lib.pm new file mode 100644 index 0000000..458df14 --- /dev/null +++ b/SBO-Lib/lib/SBO/Lib.pm @@ -0,0 +1,580 @@ +#!/usr/bin/env perl +# +# sbolib.sh +# shared functions for the sbo_ scripts. +# +# author: Jacob Pipkin <j@dawnrazor.net> +# date: Setting Orange, the 37th day of Discord in the YOLD 3178 +# license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> + +package SBO::Lib 0.1; +my $version = "0.1"; + +require Exporter; + +@ISA = qw(Exporter); +@EXPORT = qw( + script_error + show_version + get_slack_version + check_slackbuilds_txt + fetch_tree + update_tree + get_installed_sbos + get_available_updates + check_sbo_name_validity + do_slack_build + make_clean + make_distclean + do_upgradepkg + get_sbo_location +); + +use warnings FATAL => 'all'; +use strict; +use File::Basename; +use English '-no_match_vars'; +use Tie::File; +use IO::File; +use Sort::Versions; +use Digest::MD5; +use File::Copy; +use File::Path qw(make_path remove_tree); +use Fcntl; + +$UID == 0 or print "This script requires root privileges.\n" and exit(1); + +our $conf_dir = '/etc/sbotools'; +our $conf_file = "$conf_dir/sbotools.conf"; +my @valid_conf_keys = ( + 'NOCLEAN', + 'DISTCLEAN', +# "JOBS", + 'PKG_DIR', + 'SBO_HOME' +); + +our %config; +if (-f $conf_file) { + open my $reader, '<', $conf_file; + my $text = do {local $/; <$reader>}; + %config = $text =~ /^(\w+)=(.*)$/mg; + close($reader); +} +for my $key (keys %config) { + unless ($key ~~ @valid_conf_keys) { + undef $config{$key}; + } +} +for (@valid_conf_keys) { + unless ($_ eq 'SBO_HOME') { + $config{$_} = "FALSE" unless exists $config{$_}; + } else { + $config{$_} = '/usr/sbo' unless exists $config{$_}; + } +} + + +my $distfiles = "$config{SBO_HOME}/distfiles"; +my $slackbuilds_txt = "$config{SBO_HOME}/SLACKBUILDS.TXT"; + +my $name_regex = '\ASLACKBUILD\s+NAME:\s+'; + +# this should be done a bit differently. +# +sub script_error { + unless (exists $_[0]) { + print "A fatal script error has occured. Exiting.\n"; + } else { + print "A fatal script error has occured:\n"; + print "$_[0]\n"; + print "Exiting.\n"; + } + exit(1); +} + +sub show_version { + print "sbotools version $version\n"; + print "licensed under the WTFPL\n"; + print "<http://sam.zoy.org/wtfpl/COPYING>\n"; +} + +sub get_slack_version { + if (-f '/etc/slackware-version') { + open my $slackver, '<', '/etc/slackware-version'; + chomp(my $line = <$slackver>); + close($slackver); + my $slk_version = split_line($line,' ',1); + $slk_version = '13.37' if $slk_version eq '13.37.0'; + return $slk_version; + } +} + +sub check_slackbuilds_txt { + if (-f $slackbuilds_txt) { + return 1; + } else { + print "I am unable to find SLACKBUILDS.TXT.\n"; + print "Perhaps you need to \"sbosnap fetch\"?\n"; + exit(1); + } +} + +sub rsync_sbo_tree { + my $slk_version = get_slack_version(); + my $cmd = 'rsync'; + my @arg = ('-a','--exclude=*.tar.gz','--exclude=*.tar.gz.asc'); + push(@arg,"rsync://slackbuilds.org/slackbuilds/$slk_version/*"); + push(@arg,$config{SBO_HOME}); + system($cmd,@arg); + print "Finished.\n"; + return 1; +} + +sub check_home { + my $sbo_home = $config{SBO_HOME}; + if (-d $sbo_home) { + opendir(my $home_handle,$sbo_home); + while (readdir $home_handle) { + next if /^\.[\.]{0,1}$/; + print "$sbo_home exists and is not empty. Exiting.\n"; + exit(1); + } + } else { + make_path($sbo_home) or print "Unable to create $sbo_home. Exiting.\n" + and exit(1); + } +} + +sub fetch_tree { + check_home(); + print "Pulling SlackBuilds tree...\n"; + rsync_sbo_tree(); +} + +sub update_tree { + check_slackbuilds_txt(); + print "Updating SlackBuilds tree...\n"; + rsync_sbo_tree(); +} + +sub get_installed_sbos { + my @installed; + opendir my $diread, '/var/log/packages'; + while (my $ls = readdir $diread) { + next if $ls =~ /\A\./; + if (index($ls,"SBo") != -1) { + my @split = split(/-/,reverse($ls),4); + my %hash; + $hash{name} = reverse($split[3]); + $hash{version} = reverse($split[2]); + push(@installed,\%hash); + } + } + return @installed; +} + +sub clean_line { + script_error('clean line requires an argument') + unless exists $_[0]; + chomp(my $line = shift); + $line =~ s/[\s"\\]//g; + return $line; +} + +#sub get_available_updates { +# check_slackbuilds_txt(); +# my @updates; +# my @pkg_list = get_installed_sbos(); +# my $sb_txt = IO::File->new($slackbuilds_txt,"r"); +# FIRST: for my $c (keys @pkg_list) { +# my $name = $pkg_list[$c]{name}; +# my $version = $pkg_list[$c]{version}; +# my $regex = qr/$name_regex\Q$name\E\n\z/; +# my $found = "FALSE"; +# SECOND: while (my $line = <$sb_txt>) { +# if ($line =~ $regex) { +# $found = "TRUE"; +# next SECOND; +# } +# if ($found eq "TRUE") { +# if ($line =~ /VERSION/) { +# $found = "FALSE"; +# my @split = split(' ',$line); +# my $sbo_version = clean_line($split[2]); +# if (versioncmp($sbo_version,$version) == 1) { +# my %hash = ( +# name => $name, +# installed => $version, +# update => $sbo_version, +# ); +# push(@updates,\%hash); +# } +# $sb_txt->seek(0,0); +# next FIRST; +# } +# } +# } +# } +# $sb_txt->close; +# return @updates; +#} + +# much nicer version above does not work with perl 5.12, at last on Slackware +# 13.37 - the regex within the SECOND loop (while inside for) will never ever +# match, or at least I couldn't find a way to make it do so. switch which is +# inside which, and it works, so we use this method for now. +# +# iterate over all the lines! +# +sub get_available_updates { + check_slackbuilds_txt(); + my (@updates,$index); + my @pkg_list = get_installed_sbos(); + open my $sb_txt, '<', $slackbuilds_txt; + my $found = 'FALSE'; + FIRST: while (my $line = <$sb_txt>) { + if ($found eq 'TRUE') { + if ($line =~ /VERSION/) { + $found = 'FALSE'; + my $sbo_version = split_line($line,' ',2); + if (versioncmp($sbo_version,$pkg_list[$index]{version}) == 1) { + my %hash = ( + name => $pkg_list[$index]{name}, + installed => $pkg_list[$index]{version}, + update => $sbo_version, + ); + push(@updates,\%hash); + } + } + } else { + SECOND: for my $c (keys @pkg_list) { + my $regex = qr/$name_regex\Q$pkg_list[$c]{name}\E\n\z/; + if ($line =~ $regex) { + $found = 'TRUE'; + $index = $c; + last SECOND; + } + } + } + } + close $sb_txt; + return @updates; +} + +sub check_sbo_name_validity { + script_error('check_sbo_name_validity requires an argument') + unless exists $_[0]; + my $sbo = shift; + check_slackbuilds_txt(); + my $valid = 'FALSE'; + my $regex = qr/$name_regex\Q$sbo\E\n\z/; + open my $sb_txt, '<', $slackbuilds_txt; + FIRST: while (my $line = <$sb_txt>) { + if ($line =~ $regex) { + $valid = 'TRUE'; + last FIRST; + } + } + close($sb_txt); + unless ($valid eq 'TRUE') { + print "$sbo does not exist in the SlackBuilds tree. Exiting.\n"; + exit(1); + } + return 1; +} + +sub get_sbo_location { + script_error('get_sbo_location requires an argument.Exiting.') + unless exists $_[0]; + my $sbo = shift; + check_slackbuilds_txt(); + my $found = 'FALSE'; + my $location; + my $regex = qr/$name_regex\Q$sbo\E\n\z/; + open my $sb_txt, '<', $slackbuilds_txt; + FIRST: while (my $line = <$sb_txt>) { + if ($line =~ $regex) { + $found = 'TRUE'; + next FIRST; + } + if ($found eq 'TRUE') { + if ($line =~ /LOCATION/) { + my $loc_line = split_line($line,' ',2); + $loc_line =~ s#^\./##; + $location = "$config{SBO_HOME}/$loc_line"; + last FIRST; + } + } + } + close($sb_txt); + return $location; +} + +sub split_line { + script_error('split_line requires three arguments') unless exists $_[2]; + my ($line,$pattern,$index) = @_; + if ($pattern eq ' ') { + my @split = split("$pattern",$line); + } else { + my @split = split(/$pattern/,$line); + } + return clean_line($split[$index]); +} + +sub split_equal_one { + script_error("split_equal_one requires an argument") unless exists $_[0]; + return split_line($_[0],'=',1); +} + +sub check_multilib { + return 1 if -f '/etc/profile.d/32dev.sh'; + return; +} + +sub find_download_info { + script_error('find_download_info requires four arguments.') + unless exists $_[3]; + my ($sbo,$location,$type,$x64) = @_; + my @return; + my $regex; + if ($type eq 'download') { + $regex = qr/^DOWNLOAD/; + } elsif ($type eq 'md5sum') { + $regex = qr/^MD5SUM/; + } + if ($x64) { + $regex = qr/${regex}_x86_64=/; + } else { + $regex = qr/$regex=/; + } + my $empty_regex = qr/=""$/; + my $back_regex = qr/\\$/; + my $more = 'FALSE'; + open my $info,'<',"$location/$sbo.info"; + FIRST: while (my $line = <$info>) { + unless ($more eq 'TRUE') { + if ($line =~ $regex) { + last FIRST if $line =~ $empty_regex; + unless ($link eq 'UNSUPPORTED') { + push(@return,split_equal_one($line)); + $more = 'TRUE' if $line =~ $back_regex; + } else { + last FIRST; + } + } + } else { + unless ($line =~ $back_regex) { + $more = 'FALSE'; + last FIRST; + } + $line = clean_line($line); + push(@return,$line); + } + } + close($return); + return @return if exists $return[0]; + return; +} + +# this is a bit wonky - if running a 64-bit system, we have to first see if +# DOWNLOAD_x86_64 is defined, and make sure it's not set to "UNSUPPORTED"; +# then if that doesn't yield anything, go through again pulling the DOWNLOAD +# contents. +# +# would like to think of a better way to handle this. +# +sub get_sbo_downloads { + script_error('get_sbo_downloads requires two arguments.') + unless exists $_[1]; + script_error('get_sbo_downloads given a non-directory.') unless -d $_[1]; + my ($sbo,$location) = @_; + chomp(my $arch = `uname -m`); + my (@links,@md5s); + if ($arch eq 'x86_64') { + my @links = find_download_info($sbo,$location,'download',1); + my @md5s = find_download_info($sbo,$location,'md5sum',1); + } + unless (exists $links[0]) { + my @links = find_download_info($sbo,$location,'download',0); + my @md5s = find_download_info($sbo,$location,'md5sum',0); + } + my @downloads; + for my $c (keys @links) { + my %hash = (link => $links[$c],md5sum => $md5s[$c]); + push (@downloads,\%hash); + } + return @downloads; +} + +sub compute_md5sum { + script_error('compute_md5sum requires an argument.') unless exists $_[0]; + script_error('compute_md5sum argument is not a file.') unless -f $_[0]; + my $filename = shift; + open my $reader, '<', $filename; + my $md5 = Digest::MD5->new; + $md5->addfile($reader); + my $md5sum = $md5->hexdigest; + close($reader); + return $md5sum; +} + +sub get_filename_from_link { + script_error('get_filename_from_link requires an argument') + unless exists $_[0]; + my @split = split('/',reverse($_[0]),2); + chomp(my $filename = $distfiles .'/'. reverse($split[0])); + return $filename; +} + +sub check_distfile { + script_error('check_distfile requires an argument.') unless exists $_[0]; + my $filename = get_filename_from_link($_[0]); + return unless -d $distfiles; + return unless -f $filename; + my $md5sum = compute_md5sum($filename); + return unless $_[1] eq $md5sum; + return 1; +} + +sub get_distfile { + script_error('get_distfile requires an argument') unless exists $_[1]; + my ($link,$expected_md5sum) = @_; + my $filename = get_filename_from_link($link); + mkdir($distfiles) unless -d $distfiles; + chdir($distfiles); + my $out = system("wget $link"); + return unless $out == 0; + my $md5sum = compute_md5sum($filename); + if ($md5sum ne $expected_md5sum) { + print "md5sum failure for $filename.\n"; + exit(1); + } + return 1; +} + +sub get_sbo_version { + script_error('get_sbo_version requires two arguments.') + unless exists $_[1]; + my ($sbo,$location) = @_; + my $version; + open my $info, '<', "$location/$sbo.info"; + my $version_regex = qr/\AVERSION=/; + FIRST: while (my $line = <$info>) { + if ($line =~ $version_regex) { + $version = split_equal_one($line); + last FIRST; + } + } + close($info); + return $version; +} + +sub get_symlink_from_filename { + script_error('get_symlink_from_filename requires two arguments') + unless exists $_[1]; + script_error('get_symlink_from_filename first argument is not a file') + unless -f $_[0]; + my @split = split('/',reverse($_[0]),2); + my $fn = reverse($split[0]); + return "$_[1]/$fn"; +} + +sub check_x32 { + script_error('check_x32 requires two arguments.') unless exists $_[1]; + my ($sbo,$location) = @_; + open my $info,'<',"$location/$sbo.info"; + my $regex = qr/^DOWNLOAD_x86_64/; + FIRST: while (my $line = <$info>) { + if ($line =~ $regex) { + return 1 if index($line,'UNSUPPORTED') != -1; + } + } + return; +} + +sub check_multilib { + return 1 if -f '/etc/profile.d/32dev.sh'; + return; +} + +sub do_slack_build { + script_error('do_slack_build requires two arguments.') unless exists $_[1]; + my ($jobs,$sbo) = @_; + my $sbo_home = $config{SBO_HOME}; + my $location = get_sbo_location($sbo); + my $x32 = check_x32($sbo,$location); + if ($x32) { + if (! check_multilib()) { + print "$sbo is 32-bit only, however, this system does not appear +to be multilib ready\n"; + exit 1 + } + } + my $version = get_sbo_version($sbo,$location); + my @downloads = get_sbo_downloads($sbo,$location); + my @symlinks; + for my $c (keys @downloads) { + my $link = $downloads[$c]{link}; + my $md5sum = $downloads[$c]{md5sum}; + my $filename = get_filename_from_link($link); + unless (check_distfile($link,$md5sum)) { + die unless get_distfile($link,$md5sum); + } + my $symlink = get_symlink_from_filename($filename,$location); + push(@symlinks,$symlink); + symlink($filename,$symlink); + } + chdir($location); + chmod(0755,"$location/$sbo.SlackBuild"); + my $cmd; + if ($x32) { + $cmd = ". /etc/profile.d/32dev.sh && $location/$sbo.SlackBuild"; + } else { + $cmd = "$location/$sbo.SlackBuild"; + } + my $out = system($cmd); + die unless $out == 0; + unlink($_) for (@symlinks); + return $version; +} + +sub make_clean { + script_error('make_clean requires two arguments.') unless exists $_[1]; + my ($sbo,$version) = @_; + print "Cleaning for $sbo-$version...\n"; + remove_tree("/tmp/SBo/$sbo-$version") if -d "/tmp/SBo/$sbo-$version"; + remove_tree("/tmp/SBo/package-$sbo") if -d "/tmp/SBo/package-$sbo"; + return 1; +} + +sub make_distclean { + script_error('make_distclean requires two arguments.') unless exists $_[1]; + my ($sbo,$version) = @_; + make_clean($sbo,$version); + print "Distcleaning for $sbo-$version...\n"; + my $location = get_sbo_location($sbo); + my @downloads = get_sbo_downloads($sbo,$location); + for my $dl (@downloads) { + my $filename = get_filename_from_link($dl); + unlink($filename) if -f $filename; + } + return 1; +} + +sub do_upgradepkg { + script_error('do_upgradepkg requires two arguments.') unless exists $_[1]; + my ($sbo,$version) = @_; + my $pkg; + my $pkg_regex = qr/^(\Q$sbo\E-\Q$version\E-[^-]+-.*_SBo.t[xblg]z)$/; + opendir my $diread, '/tmp/'; + FIRST: while (my $ls = readdir $diread) { + if ($ls =~ $pkg_regex) { + chomp($pkg = "/tmp/$1"); + last FIRST; + } + } + system("/sbin/upgradepkg --reinstall --install-new $pkg"); + return $pkg; +} + diff --git a/SBO-Lib/t/SBO-Lib.t b/SBO-Lib/t/SBO-Lib.t new file mode 100644 index 0000000..1c5866b --- /dev/null +++ b/SBO-Lib/t/SBO-Lib.t @@ -0,0 +1,18 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl SBO-Lib.t' + +######################### + +# change 'tests => 1' to 'tests => last_test_to_print'; + +use strict; +use warnings; + +use Test::More tests => 1; +BEGIN { use_ok('SBO::Lib') }; + +######################### + +# Insert your test code below, the Test::More module is use()ed here so read +# its man page ( perldoc Test::More ) for help writing this test script. + diff --git a/man1/sbocheck.1 b/man1/sbocheck.1 new file mode 100644 index 0000000..ee1463b --- /dev/null +++ b/man1/sbocheck.1 @@ -0,0 +1,25 @@ +.TH sbocheck 1 "Pungenday, the 45th day of Discord in the YOLD 3178" "sbotools 0.1 fnord" dawnrazor.net +.SH NAME +.P +sbocheck - update a local slackbuilds.org tree and check for updates. +.SH SYNAPSES +.P +sbocheck [-v] +.SH DESCRIPTION +.P +sbocheck first updates a previously fetched copy of the slackbuilds.org tree (see sbosnap(1)) and then checks to see if any packages installed from slackbuilds.org slackbuilds have updates, and reports what it finds. +.SH OPTIONS +.P +-v +.RS +Show sbotools version information. +.RE +.SH BUGS +.P +None known, but there may be some. Please report any found to j@dawnrazor.net; patches are always welcome. In the future sbotools may exist in a public git repository and this section may change to reflect that. +.SH SEE ALSO +.P +sboconfig(1), sbofind(1), sboinstall(1), sboupgrade(1), sbosnap(1), sbotools.conf(5) +.SH AUTHOR +.P +Jacob Pipkin <j@dawnrazor.net> diff --git a/man1/sboconfig.1 b/man1/sboconfig.1 new file mode 100644 index 0000000..a52930f --- /dev/null +++ b/man1/sboconfig.1 @@ -0,0 +1,55 @@ +.TH sboconfig 1 "Pungenday, the 45th day of Discord in the YOLD 3178" "sbotools 0.1 fnord" dawnrazor.net +.SH NAME +.P +sboconfig - set sbotools configuration options. +.SH SYNAPSES +.P +sboconfig [-h] [-l] [-c TRUE|FALSE] [-d TRUE|FALSE] [-p /path|FALSE] [-s /path|/usr/sbo] [-v] +.SH DESCRIPTION +.P +sboconfig is a front-end for managing sbotools configuration options. The sbotools.conf(5) file can also be manually edited; any fields not relevant to sbotools configuration will be ignored. Note that more options may be added in the future, so you should not add garbage to the sbotools.conf(5) file. +.SH OPTIONS +.P +-h +.RS +Show help information. +.RE +.P +-l +.RS +List out current configuration options, included unmodified default configuration options (meaning that if a given option is not set in the sbotools.conf(5) file, the default will be shown for that option). +.RE +.P +-c (TRUE|FALSE) +.RS +NOCLEAN: If TRUE, then DO NOT clean working directories after building the SBo. These are the directories where the source is unpacked and compiled, and where the package is put together in, which are under /tmp/SBo. By default, these directories are removed after building an SBo. Setting this option to TRUE causes the working directories to not be cleaned by default. This can be overridden when running sboupgrade(1)/sboinstall(1). +.RE +.P +-d (TRUE|FALSE) +.RS +DISTCLEAN: If TRUE, then DO remove the source code after building the SBo. By default, the source code is not removed, and lives under $SBO_HOME/distfiles, which, by default, is /usr/sbo/distfiles. Setting this option to TRUE causes the source code to be removed by default. This can be overridden when running sboupgrade(1)/sboinstall(1). +.RE +.P +-p (/path|FALSE) +.RS +PKG_DIR: If set to a path, packages will be stored at the given location after building and installing. By default, packages are left where they are deposited by SlackBuilds, which is typically (probably always) /tmp. If PKG_DIR is FALSE and DISTCLEAN is TRUE (either in sbotools.conf(5) or at sboupgrade/sboinstall runtime), the package will be deleted. If this option is set to a path in the filesystem, the package will be stored in that directory, regardless of any DISTCLEAN option. +.RE +.P +-s (/path|/usr/sbo) +.RS +SBO_HOME: If set to a path, this is where the slackbuilds.org tree will live; by default, /usr/sbo will be used. If the tree should live elsewhere, this option can be set to the path where the tree should live. Note that if you set this option after fetching the tree to a different location (such as the default), you will need to fetch the tree again. +.RE +.P +-v +.RS +Show sbotools version information. +.RE +.SH BUGS +.P +None known, but there may be some. Please report any found to j@dawnrazor.net; patches are always welcome. In the future sbotools may exist in a public git repository and this section may change to reflect that. +.SH SEE ALSO +.P +sbocheck(1), sbofind(1), sboinstall(1), sboupgrade(1), sbosnap(1), sbotools.conf(5) +.SH AUTHOR +.P +Jacob Pipkin <j@dawnrazor.net> diff --git a/man1/sbofind.1 b/man1/sbofind.1 new file mode 100644 index 0000000..08c6d3a --- /dev/null +++ b/man1/sbofind.1 @@ -0,0 +1,25 @@ +.TH sbofind 1 "Pungenday, the 45th day of Discord in the YOLD 3178" "sbotools 0.1 fnord" dawnrazor.net +.SH NAME +.P +sbofind - search SlackBuilds for a given name +.SH SYNAPSES +.P +sbofind [-v] search_term +.SH DESCRIPTION +.P +sbofind searches the names of all SlackBuilds for a given term. It reports back any SBos found along with the path for each. This is equivalent to running "cd /usr/ports; make search name=$search_term display=name,path" on a FreeBSD system. For a more general search, the slackbuilds.org site should be consulted, where tags also exist and are included in the searched fields. +.SH OPTIONS +.P +-v +.RS +Show sbotools version information. +.RE +.SH BUGS +.P +None known, but there may be some. Please report any found to j@dawnrazor.net; patches are always welcome. In the future sbotools may exist in a public git repository and this section may change to reflect that. +.SH SEE ALSO +.P +sbocheck(1), sboconfig(1), sboinstall(1), sboupgrade(1), sbosnap(1), sbotools.conf(5) +.SH AUTHOR +.P +Jacob Pipkin <j@dawnrazor.net> diff --git a/man1/sboinstall.1 b/man1/sboinstall.1 new file mode 100644 index 0000000..7572fd3 --- /dev/null +++ b/man1/sboinstall.1 @@ -0,0 +1,59 @@ +.TH sboupgrade 1 "Pungenday, the 45th day of Discord in the YOLD 3178" "sbotools 0.1 fnord" dawnrazor.net +.SH NAME +.P +sboupgrade,sboinstall - install or upgrade SBos +.SH SYNAPSES +.P +sboupgrade [-h] [-v] [-c TRUE|FALSE] [-d TRUE|FALSE] [-f] [-N] [-r] sbo_name (sbo_name) +.SH DESCRIPTION +.P +sboupgrade is used to upgrade packages installed from SBos. sboinstall is equivalent to sboupgrade -N +.SH OPTIONS +.P +-h +.RS +Show help information. +.RE +.P +-c (TRUE|FALSE) +.RS +If TRUE, then DO NOT clean working directories after building the SBo. These are the directories where the source is unpacked and compiled, and where the package is put together in, which are under /tmp/SBo. By default, these directories are removed after building an SBo. This option leaves those directories in place. This can be set as default via the sboconfig(1) command. Also see sbotools.conf(5). This option overrides the default. +.RE +.P +-d (TRUE|FALSE) +.RS +If TRUE, then DO remove the source code after building the SBo. By default, the source code is not removed, and lives under $SBO_HOME/distfiles, which, by default, is /usr/sbo/distfiles; this option can be set as default via the sboconfig(1) command. See also sbotools.conf(5). This option overrides the default. +.RE +.P +-f +.RS +Force an upgrade, even if the installed version is equal to or less than the slackbuilds.org version. +.RE +.P +-N +.RS +Install any new SBos specified. So, if you want to upgrade some things and install new things with the same command, then you would use the -N flag. Note that upgrades are handled prior to new installs. +.RE +.P +-r +.RS +Skip viewing of the README and the yes or no question which accompanies it. Anytime sboupgrade or sboinstall is run, the first thing the command will attempt to do is show you the README for a given SBo and ask whether or not you wish to proceed; this option skips the README and bypasses the question. If multiple SBos are specified, this option bypasses them all. +.RE +.P +-v +.RS +Show sbotools version information. +.RE +.SH BUGS +.P +- Installing 32-bit packages on 64-bit systems is currently unsupported and in some cases impossible. +.P +- It is currently not possible to specify how many concurrent jobs make should run (make's -j flag). +.P +- Probably more that I've missed. Please report any found to j@dawnrazor.net; patches are always welcome. In the future sbotools may exist in a public git repository and this section may change to reflect that. +.SH SEE ALSO +.P +sbocheck(1), sboconfig(1), sbofind(1), sbosnap(1), sbotools.conf(5) +.SH AUTHOR +.P +Jacob Pipkin <j@dawnrazor.net> diff --git a/man1/sbosnap.1 b/man1/sbosnap.1 new file mode 100644 index 0000000..9a15345 --- /dev/null +++ b/man1/sbosnap.1 @@ -0,0 +1,36 @@ +.TH sbosnap 1 "Pungenday, the 45th day of Discord in the YOLD 3178" "sbotools 0.1 fnord" dawnrazor.net +.SH NAME +.P +sbosnap - slackbuilds.org tree fetch and update command. +.SH SYNAPSES +.P +sbosnap [-v] (fetch|update) +.SH DESCRIPTION +.P +sbosnap is used to download and update a local copy of the slackbuilds.org tree, minus the .tar.gz{,.asc} files. Note that sbocheck(1) will also update the tree, and will then also check for updated SBos. rsync is used for both operations. +.SH OPTIONS +.P +fetch +.RS +Download a local copy of the slackbuilds.org tree. The copy will be downloaded to the SBO_HOME setting (see sboconfig(1) and sbotools.conf(5)), which, by default, is /usr/sbo +.RE +.P +update +.RS +Update an previously fetch'd copy of the slackbuilds.org tree. +.RE +.P +-v +.RS +Show sbotools version information. +.RE + +.SH BUGS +.P +None known, but there may be some. Please report any found to j@dawnrazor.net; patches are always welcome. In the future sbotools may exist in a public git repository and this section may change to reflect that. +.SH SEE ALSO +.P +sbocheck(1), sboconfig(1), sbofind(1), sboinstall(1), sboupgrade(1), sbotools.conf(5) +.SH AUTHOR +.P +Jacob Pipkin <j@dawnrazor.net> diff --git a/man1/sboupgrade.1 b/man1/sboupgrade.1 new file mode 100644 index 0000000..7572fd3 --- /dev/null +++ b/man1/sboupgrade.1 @@ -0,0 +1,59 @@ +.TH sboupgrade 1 "Pungenday, the 45th day of Discord in the YOLD 3178" "sbotools 0.1 fnord" dawnrazor.net +.SH NAME +.P +sboupgrade,sboinstall - install or upgrade SBos +.SH SYNAPSES +.P +sboupgrade [-h] [-v] [-c TRUE|FALSE] [-d TRUE|FALSE] [-f] [-N] [-r] sbo_name (sbo_name) +.SH DESCRIPTION +.P +sboupgrade is used to upgrade packages installed from SBos. sboinstall is equivalent to sboupgrade -N +.SH OPTIONS +.P +-h +.RS +Show help information. +.RE +.P +-c (TRUE|FALSE) +.RS +If TRUE, then DO NOT clean working directories after building the SBo. These are the directories where the source is unpacked and compiled, and where the package is put together in, which are under /tmp/SBo. By default, these directories are removed after building an SBo. This option leaves those directories in place. This can be set as default via the sboconfig(1) command. Also see sbotools.conf(5). This option overrides the default. +.RE +.P +-d (TRUE|FALSE) +.RS +If TRUE, then DO remove the source code after building the SBo. By default, the source code is not removed, and lives under $SBO_HOME/distfiles, which, by default, is /usr/sbo/distfiles; this option can be set as default via the sboconfig(1) command. See also sbotools.conf(5). This option overrides the default. +.RE +.P +-f +.RS +Force an upgrade, even if the installed version is equal to or less than the slackbuilds.org version. +.RE +.P +-N +.RS +Install any new SBos specified. So, if you want to upgrade some things and install new things with the same command, then you would use the -N flag. Note that upgrades are handled prior to new installs. +.RE +.P +-r +.RS +Skip viewing of the README and the yes or no question which accompanies it. Anytime sboupgrade or sboinstall is run, the first thing the command will attempt to do is show you the README for a given SBo and ask whether or not you wish to proceed; this option skips the README and bypasses the question. If multiple SBos are specified, this option bypasses them all. +.RE +.P +-v +.RS +Show sbotools version information. +.RE +.SH BUGS +.P +- Installing 32-bit packages on 64-bit systems is currently unsupported and in some cases impossible. +.P +- It is currently not possible to specify how many concurrent jobs make should run (make's -j flag). +.P +- Probably more that I've missed. Please report any found to j@dawnrazor.net; patches are always welcome. In the future sbotools may exist in a public git repository and this section may change to reflect that. +.SH SEE ALSO +.P +sbocheck(1), sboconfig(1), sbofind(1), sbosnap(1), sbotools.conf(5) +.SH AUTHOR +.P +Jacob Pipkin <j@dawnrazor.net> diff --git a/man5/sbotools.conf.5 b/man5/sbotools.conf.5 new file mode 100644 index 0000000..2aebade --- /dev/null +++ b/man5/sbotools.conf.5 @@ -0,0 +1,35 @@ +.TH sbotools.conf 5 "Pungenday, the 45th day of Discord in the YOLD 3178" "sbotools 0.1 fnord" dawnrazor.net +.SH NAME +.P +sbotools.conf - configuration file for sbotools commands. +.SH DESCRIPTION +.P +This file, location at /etc/sbotools/sbotools.conf, contains key=value configuration parameters, and is read by all of the sbotools commands. +.P +The current configuration keys are as follows: +.P +NOCLEAN=(TRUE|FALSE) +.RS +If TRUE, then DO NOT clean working directories after building the SBo. These are the directories where the source is unpacked and compiled, and where the package is put together in, which are under /tmp/SBo. By default, these directories are removed after building an SBo. Setting this option to TRUE causes the working directories to not be cleaned by default. This can be overridden when running sboupgrade(1)/sboinstall(1). +.RE +.P +DISTCLEAN=(TRUE|FALSE) +.RS +If TRUE, then DO remove the source code after building the SBo. By default, the source code is not removed, and lives under $SBO_HOME/distfiles, which, by default, is /usr/sbo/distfiles. Setting this option to TRUE causes the source code to be removed by default. This can be overridden when running sboupgrade(1)/sboinstall(1). +.RE +.P +PKG_DIR=(/path|FALSE) +.RS +If set to a path, packages will be stored at the given location after building and installing. By default, packages are left where they are deposited by SlackBuilds, which is typically (probably always) /tmp. If PKG_DIR is FALSE and DISTCLEAN is TRUE (either in sbotools.conf(5) or at sboupgrade/sboinstall runtime), the package will be deleted. If this option is set to a path in the filesystem, the package will be stored in that directory, regardless of any DISTCLEAN option. +.RE +.P +SBO_HOME=(/path|/usr/sbo) +.RS +If set to a path, this is where the slackbuilds.org tree will live; by default, /usr/sbo will be used. If the tree should live elsewhere, this option can be set to the path where the tree should live. Note that if you set this option after fetching the tree to a different location (such as the default), you will need to fetch the tree again. +.RE +.SH SEE ALSO +.P +sbocheck(1), sboconfig(1), sbofind(1), sboinstall(1), sboupgrade(1), sbosnap(1) +.SH AUTHOR +.P +Jacob Pipkin <j@dawnrazor.net> diff --git a/sbocheck b/sbocheck new file mode 100755 index 0000000..aa952dd --- /dev/null +++ b/sbocheck @@ -0,0 +1,46 @@ +#!/usr/bin/env perl +# +# sbocheck +# script to update the local sbo tree and check for updates +# +# author: Jacob Pipkin <j@dawnrazor.net> +# date: Sweetmorn, the 38th day of Discord in the YOLD 3178 +# license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> + +use SBO::Lib; +use File::Basename; +use Getopt::Std; +use Text::Tabulate; +use warnings FATAL => 'all'; +use strict; + +my %config = %SBO::Lib::config; +my $self = basename($0); + +my %options; +getopts('v',\%options); + +show_version() && exit(0) if (exists $options{v}); + +update_tree(); + +print "Checking for updated SlackBuilds...\n"; +my @updates = get_available_updates(); + +my @listing; +for (keys @updates) { + my $string = "$updates[$_]{name}-$updates[$_]{installed}"; + $string .= " < needs updating (SBo has $updates[$_]{update})\n"; + push(@listing,$string); +} + +if (exists $listing[0]) { + my $tab = new Text::Tabulate(); + $tab->configure(tab => '\s'); + my $output = $tab->format(@listing); + print "\n". $output ."\n"; +} else { + print "\nNo updates available.\n"; +} + +exit(0); diff --git a/sboconfig b/sboconfig new file mode 100755 index 0000000..b440edb --- /dev/null +++ b/sboconfig @@ -0,0 +1,119 @@ +#!/usr/bin/env perl +# +# sboconfig +# script to handle sbotools configuration +# +# author: Jacob Pipkin <j@dawnrazor.net> +# date: Pungenday, the 40th day of Discord in the YOLD 3178 +# license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> + +use strict; +use warnings FATAL => 'all'; +use SBO::Lib; +use File::Basename; +use Getopt::Std; +use File::Copy; +use File::Path qw(make_path); +use Fcntl; + +my %config = %SBO::Lib::config; +my $self = basename($0); + +sub show_usage { + print <<EOF +Usage: $self [options] [arguments] + +Options: + -h: this screen. + -v: version information. + -l: show current options. + +Config options (defaults shown): + -c FALSE: + NOCLEAN: if TRUE, do NOT clean up after building by default. + -d FALSE: + DISTCLEAN: if TRUE, DO clean distfiles by default after building. + -p FALSE: + PKG_DIR: set a directory to store packages in. + -s /usr/sbo: + SBO_HOME: set the SBo directory. + +EOF +# -j FALSE: +# set the -j# option to feed to make. +} + +my %options; +getopts('hvlc:d:p:s:',\%options); + +show_usage() and exit(0) if exists $options{h}; +show_version() and exit(0) if exists $options{v}; + +if (exists $options{l}) { + while (my ($key,$value) = each %config) { + print "$key=$value\n"; + } +} + +show_usage() unless %options; + +my %changes; +$changes{NOCLEAN} = $options{c} if exists $options{c}; +$changes{DISTCLEAN} = $options{d} if exists $options{d}; +$changes{PKG_DIR} = $options{p} if exists $options{p}; +$changes{SBO_HOME} = $options{s} if exists $options{s}; + +my $conf_dir = $SBO::Lib::conf_dir;; +my $conf_file = $SBO::Lib::conf_file; + +sub make_temp_file { + make_path('/tmp/sbotools') unless -d '/tmp/sbotools'; + my $temp_dir = -d '/tmp/sbotools' ? '/tmp/sbotools' : $ENV{TMPDIR} || + $ENV{TEMP}; + my $filename = sprintf "%s/%d-%d-0000", $temp_dir, $$, time; + sysopen my($fh), $filename, O_WRONLY|O_EXCL|O_CREAT; + return ($fh,$filename); +} + +sub config_write { + script_error('config_write requires two arguments.') unless $_[1]; + my ($key,$val) = @_; + if (! -d $conf_dir) { + mkdir($conf_dir) + or print "Unable to create $conf_dir. Exiting.\n" and exit(1); + } + if (-f $conf_file) { + my ($fh,$filename) = make_temp_file(); + open my $reader, '<', $conf_file; + print {$fh} <$reader>; + close($fh); + tie my @temp, 'Tie::File', $filename; + my $has = 'FALSE'; + my $regex = qr/\A\Q$key\E=/; + FIRST: for my $tmpline (@temp) { + if ($tmpline =~ $regex) { + $has = 'TRUE'; + $tmpline = "$key=$val"; + last FIRST; + } + } + untie @temp; + if ($has eq 'FALSE') { + open (my $writer, '>>', $filename); + print {$writer} "$key=$val\n"; + close($writer); + } + move($filename,$conf_file); + } else { + open my $writer, '>', $conf_file; + print {$writer} "$key=$val\n"; + close($writer); + } +} + +while (my ($key,$value) = each %changes) { + print "Setting $key to $value...\n"; + config_write($key,$value); +} + +exit(0); @@ -0,0 +1,85 @@ +#!/usr/bin/env perl +# +# sbofind +# script to locate something in a local SlackBuilds tree. +# +# author: Jacob Pipkin <j@dawnrazor.net> +# date: Boomtime, the 39th day of Discord in the YOLD 3178 +# license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> + +use SBO::Lib; +use File::Basename; +use Getopt::Std; +use Text::Tabulate; +use strict; +use warnings FATAL => 'all'; + +my %config = %SBO::Lib::config; +my $self = basename($0); + +sub show_usage { + print <<EOF +Usage: $self (search_term) + +Options: + -h: this screen. + -v: version information. + +Example: + $self libsexy + +EOF +} + +my %options; +getopts('hv',\%options); + +show_usage() and exit(0) if (exists $options{h}); +show_version() and exit(0) if (exists $options{v}); + +show_usage() and exit(1) unless exists $ARGV[0]; +my $search = $ARGV[0]; + +check_slackbuilds_txt(); + +my (@findings,$name); +my $found = 'FALSE'; +my $regex = qr/NAME:\s.*\Q$search\E.*/; +open my $sb_txt, '<', "$config{SBO_HOME}/SLACKBUILDS.TXT"; +FIRST: while (my $line = <$sb_txt>) { + unless ($found eq 'TRUE') { + if ($line =~ $regex) { + $found = 'TRUE'; + my @split = split(' ',$line); + chomp($name = $split[2]); + next FIRST; + } + } else { + if ($line =~ /LOCATION/) { + $found = 'FALSE'; + my @split = split(' ',$line); + chomp(my $location = $split[2]); + $location =~ s#^\.##; + my %hash = ($name => $config{SBO_HOME} . $location); + push(@findings,\%hash); + } + } +} + +if (exists $findings[0]) { + my @listing; + for my $hash (@findings) { + while (my ($key,$value) = each %{$hash}) { + push(@listing,"SBo: $key\n"); + push(@listing,"Path: $value\n\n"); + } + } + my $tab = new Text::Tabulate(); + $tab->configure(tab => '\s'); + my $output = $tab->format(@listing); + print "\n". $output; +} else { + print "Nothing found for search term: $search\n"; +} + +exit(0); diff --git a/sboinstall b/sboinstall new file mode 100755 index 0000000..087c6d9 --- /dev/null +++ b/sboinstall @@ -0,0 +1,50 @@ +#!/usr/bin/env perl +# +# sboinstall +# script to install a SlackBuild by name +# +# author: Jacob Pipkin <j@dawnrazor.net> +# date: Pungenday, the 40th day of Discord in the YOLD 3178 +# license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> + +use SBO::Lib; +use Getopt::Std; +use File::Basename; +use strict; +use warnings FATAL => 'all'; + +my $self = basename($0); + +sub show_usage { + print <<EOF +Usage: $self [options] sbo + +Options: + -h: this screen. + -v: version information. + -c: do not clean working files/directories after the build. + -d: clean distfiles afterward. + -r: skip viewing of the SBo README. + +EOF +} + +my %options; +getopts('hvcdr',\%options); + +show_usage() and exit(0) if exists $options{h}; +show_version() and exit(0) if exists $options{v}; + +show_usage() and exit(0) unless exists $ARGV[0]; + +unshift(@ARGV,'-c') if exists $options{c}; +unshift(@ARGV,'-d') if exists $options{d}; +unshift(@ARGV,'-r') if exists $options{r}; + +my $string = ''; +for (@ARGV) { + $string .= " $_"; +} + +system("/usr/sbin/sboupgrade -N $string"); +exit(0); @@ -0,0 +1,64 @@ +#!/usr/bin/env perl +# +# sbosnap +# script to pull down / update a local copy of the +# slackbuilds.org tree. +# +# author: Jacob Pipkin <j@dawnrazor.net> +# date: Setting Orange, the 37th day of Discord in the YOLD 3178 +# license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> +# changelog: +# .01: initial creation. + +use SBO::Lib; +use File::Basename; +use Getopt::Std; +use File::Path qw(make_path); +use feature switch; +use warnings FATAL => 'all'; +use strict; + +my %config = %SBO::Lib::config; +my $sbo_home = $config{SBO_HOME}; +my $self = basename($0); + +sub show_usage { + print <<EOF +Usage: $self [options|command] + +Options: + -h: this screen. + -v: version information. + +Commands: + fetch: initialize a local copy of the slackbuilds.org tree. + update: update an existing local copy of the slackbuilds.org tree. + (generally, you may prefer "sbocheck" over "$self update") + +EOF +} + +show_usage() and exit(1) unless exists $ARGV[0]; + +my %options; +getopts('hv',\%options); + +show_usage() and exit(0) if exists $options{h}; +show_version() and exit(0) if exists $options{v}; + +# check for a command and, if found, execute it +# +my $command; +if ($ARGV[0] =~ /fetch|update/) { + $command = $ARGV[0]; +} else { + show_usage(); + exit(1); +} + +given($command) { + when('fetch') { fetch_tree() } + when('update') { update_tree() } +} + +exit(0); diff --git a/sboupgrade b/sboupgrade new file mode 100755 index 0000000..c68d276 --- /dev/null +++ b/sboupgrade @@ -0,0 +1,183 @@ +#!/usr/bin/env perl +# +# sboupgrade +# script to update an installed SlackBuild. +# +# author: Jacob Pipkin <j@dawnrazor.net> +# date: Boomtime, the 39th day of Discord in the YOLD 3178 +# license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> + +use SBO::Lib; +use File::Basename; +use Getopt::Std; +use Text::Tabulate; +use File::Copy; +use strict; +use warnings FATAL => 'all'; + +my %config = %SBO::Lib::config; +my $self = basename($0); + +sub show_usage { + print <<EOF +Usage: $self (options) [package] + +Options: + -h: this screen. + -v: version information. + -c: do not clean working files/directories after the build. + -d: clean distfiles afterward. + -f: force an update, even if the "upgrade" version is the same or lower. + -N: install any new SBo's listed. + -r: skip viewing of the SBo README. + +Example: + $self -d libsexy + $self -ca + +EOF +# -j: specify "-j" setting to make, for SMP systems; overrides conf file. +} + +my %options; +getopts('hvacdfj:Nr',\%options); + + +show_usage() && exit(0) if exists $options{h}; +show_version() && exit(0) if exists $options{v}; +my $noclean = exists $options{c} ? 'FALSE' : $config{NOCLEAN}; +my $distclean = exists $options{d} ? 'TRUE' : $config{DISTCLEAN}; +my $force = exists $options{f} ? 'TRUE' : 'FALSE'; +#my $jobs = exists $options{j} ? $options{j} : $config{JOBS}; +my $jobs = 'FALSE'; +my $install_new = exists $options{N} ? 'TRUE' : 'FALSE'; +my $no_readme = exists $options{r} ? 'TRUE' : 'FALSE'; + +show_usage() and exit(1) unless exists $ARGV[0]; + +for my $sbo_name (@ARGV) { + check_sbo_name_validity($sbo_name); +} + +sub get_readme_path { + script_error('get_readme_path requires an argument.') unless exists $_[0]; + my $sbo = shift; + my $location = get_sbo_location($sbo); + return $location .'/README'; +} + +sub readme_prompt { + script_error('readme_prompt requires an argument.') unless exists $_[0]; + my $sbo = shift; + my $readme_path = get_readme_path($sbo); + open my $readme,'<',$readme_path; + print "\n",<$readme>; + close($readme); + print "\nProceed with $sbo? [yn]: "; + my $test = <STDIN>; + exit(0) unless $test =~ /^[Yy]/; + return 1; +} + +sub process_sbos { + script_error('process_sbos requires an argument.') unless exists $_[0]; + my @todo = @_; + my @failures; + for my $sbo (@todo) { + readme_prompt($sbo) unless $no_readme eq 'TRUE'; + my $version; + eval { + $version = do_slack_build($jobs,$sbo); + }; + if ($@) { + push(@failures,$sbo); + } else { + unless ($distclean eq 'TRUE') { + if ($noclean eq 'FALSE') { + make_clean($sbo,$version); + } + } else { + make_distclean($sbo,$version); + } + my $pkg = do_upgradepkg($sbo,$version); + + unless ($config{PKG_DIR} eq 'FALSE') { + unless (-d $config{PKG_DIR}) { + mkdir($config{PKG_DIR}) or + warn "Unable to create $config{PKG_DIR}\n"; + } + move($pkg,$config{PKG_DIR}) if -d $config{PKG_DIR}; + print "$pkg stored in $config{PKG_DIR}\n"; + } elsif ($distclean eq 'TRUE') { + unlink($pkg); + } + } + } + return @failures; +} + +# this can probably be redone to be faster overall. + +my @updates unless $force eq 'TRUE'; +unless ($force eq 'TRUE') { + my @updates_array = get_available_updates(); + for my $index (keys @updates_array) { + push(@updates,$updates_array[$index]{name}); + } +} + +my @installed = get_installed_sbos(); + +my @todo_upgrade; +unless ($force eq 'TRUE') { + for (@ARGV) { + if ($_ ~~ @updates) { + push(@todo_upgrade,$_); + } + } +} else { + for (@ARGV) { + SECOND: for my $c (keys @installed) { + if ($_ eq $installed[$c]{name}) { + push(@todo_upgrade,$_); + last SECOND; + } + } + } +} + +my @failed; +@failed = process_sbos(@todo_upgrade) if exists $todo_upgrade[0]; + +sub print_failures { + if (exists $failed[0]) { + print "Failures:\n"; + print " $_\n" for (@failed); + exit(1); + } +} + +print_failures() unless $install_new eq 'TRUE'; + +my @todo_install; +my $has = 'FALSE'; +for (@ARGV) { + SECOND: for my $index (keys @installed) { + if ($_ eq $installed[$index]{name}) { + $has = 'TRUE'; + last SECOND; + } + } + unless ($has eq 'TRUE') { + push(@todo_install,$_); + } else { + print "$_ already installed.\n"; + } + $has = 'FALSE'; +} + +@failed = process_sbos(@todo_install) if exists $todo_install[0]; + +print_failures(); + +exit(0); |