LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware
User Name
Password
Slackware This Forum is for the discussion of Slackware Linux.

Notices


Reply
  Search this Thread
Old 12-27-2007, 09:04 PM   #16
Lufbery
Senior Member
 
Registered: Aug 2006
Location: Harrisburg, PA
Distribution: Slackware 64 14.2
Posts: 1,180

Original Poster
Blog Entries: 29

Rep: Reputation: 135Reputation: 135

Alan,

Thanks for your posts. I particularly appreciate the comments. As I stated above, I'm just learning.

Your script does pretty much what I was looking for: a list of updated packages.

Slackupdate looks pretty good. The web page says that it supports Slackware 8.1! But, the script itself looks like it was updated this past week.

Regards, and thanks again.

-Drew
 
Old 12-28-2007, 02:14 AM   #17
acummings
Member
 
Registered: Jul 2004
Distribution: Slackware
Posts: 615

Rep: Reputation: 50
PS I'll brush up on hash then finish the Perl script I started.

For interval checking (to discover if the changelog has changed) this next can't be beat.

(BTW, wget likely could do this too if could figure out what option(s) to use with wget).

(Herein this here post is the netizen nettique nice way to check the changelog every so often to see if changelog has changed)

for it uses next to no bandwidth and it is very fast it only runs for a split second and it's done.

There's no transfer of any file.

It uses ftp to check the file date of the changelog and compare against a stored date.

I had been snooping via www about Perl 5.10 is out/released when I just ran across a cool (Perl script) utility.

http://www.cpan.org/scripts/index.html

There under networking or www

http://www.cpan.org/authors/id/J/JH/JHERRERO/scripts/

check_ftp

al@AB60R:~$ check_ftp add

al@AB60R:~$ cd .check_ftp
al@AB60R:~/.check_ftp$ pwd
/home/al/.check_ftp
al@AB60R:~/.check_ftp$ ls -la
<snipped>
-rw-r--r-- 1 al users 1912 2007-12-28 00:35 .conf

al@AB60R:~/.check_ftp$ cat .conf
<snipped>
WARNING Do not use the same site name more than once! WARNING
WARNING WARNING
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING

<SITE sw12_upds>
HOST = slackware.mirrors.tds.net
MAIL = email@no_domain.com
USER = anonymous
PASSWORD = email@no_domain.com
DIRECTORY = pub/slackware/slackware-12.0
FILE = ChangeLog.txt
</SITE>


al@AB60R:~/.check_ftp$ check_ftp


al@AB60R:~/.check_ftp$ ls -la
total 16
drwx------ 2 al users 4096 2007-12-28 00:37 ./
drwx--x--x 43 al users 4096 2007-12-28 00:28 ../
-rw-r--r-- 1 al users 1912 2007-12-28 00:35 .conf
-rw-r--r-- 1 al users 70 2007-12-28 00:37 sw12_upds


al@AB60R:~/.check_ftp$ cat sw12_upds
-rw-r--r-- 1 ftp ftp 174420 Dec 24 21:57 ChangeLog.txt

-------

It needs the Mail::Send Perl module onboard in order for check_ftp to run:

root@AB60R:~# cpan2tgz --pkgdir /usr/src/sw_pkg Mail::Send

As root, I use a Slack pkg named cpan2tgz it's available on the internet. That above command gets Mail::Send installed as a Slack pkg AND I have Slack pkg of it outputs to the pkgdir (for use on other machines).

--
Alan.
 
Old 12-28-2007, 03:52 PM   #18
acummings
Member
 
Registered: Jul 2004
Distribution: Slackware
Posts: 615

Rep: Reputation: 50
Today I just discovered that check_ftp uses my (I don't have a domain) localdomain or localhost when attempting to send email outbound.

This isn't going to work since valid domain smtp servers won't accept from a non domain (they can't be an open relay for spammers).

So, you would need to either 1. direct the email to your localhost using a user email address on your localhost (keeps the email from trying to go out to anywhere else)

Or 2. do what I did. Run:

check_ftp add

Then do not enter an email address (defaults to STDOUT)

messages thus will print to screen instead of being emailed.

Whenever the ChangeLog.txt has been changed (the changelog changes whenever new updates happen) the output message will say so.

--
Alan.
 
Old 12-28-2007, 04:42 PM   #19
BCarey
Senior Member
 
Registered: Oct 2005
Location: New Mexico
Distribution: Slackware
Posts: 1,639

Rep: Reputation: Disabled
Quote:
Originally Posted by acummings View Post
Gotcha on the /extra

Will incorporate into a later version. May parse changelog then instead of list mirror server's dir contents. Hey, right now, I run it on my machine -- it's fast -- only a second or two of run time and it's done.

Why does Pat keep the changelog so big? It's still got Slack 11 on it too. Or, is it for all of the "stable" and currently security update supported versions of Slackware?

(changelog) It's a huge file to be pumping across the www every time someone wants to check on Slack 12 patches (reason to join the security updates emailing list, I guess).



Yes. It had a bug in that section too. But not now; I fixed it.

More help comments included now. Re labled/named some section(s). Hopefully more clarity exist now of what is happening when.

Code:
#!/usr/bin/perl

use warnings;
use strict;
# use diagnostics;

# 12-26-2007 unfinished. See at bottom of code for yet to do
# reports whether or not any new (not yet installed) Slackware
# patches/updates are available
# compares a mirror server's updates with /var/log/packages

my $url = 'ftp://slackware.mirrors.tds.net/pub/slackware/slackware-12.0/patches/packages';

my $pid;
my $upd_pkgs;
$pid = open $upd_pkgs, "-|", "lynx", "-dump", "$url" or die "cant fork: $!\n";
print "pid is: $pid\n";
my @patches;
while (<$upd_pkgs>) {
next unless /slack.+patches$/i .. /eof/; # range operator
s#^.+slackware-12.0/patches/packages/##;
s#\.tgz##;
# print unless /\d.+patches$|\.asc|\.txt/;
push @patches, $_ unless /\d.+patches$|\.asc|\.txt/;
} # got patches file names in the @patches array

# next section strips the numeric part of patch file names
# which leaves us with only the leading  alpha and dashes
# up to but not including any of the digits

# begin of alpha_only (number, numeric not allowed)
my $apend;
my @dashes;
my @dashes2;
foreach ( @patches ) {
@dashes = split(/-/, $_);
$apend .= $dashes[0];
$apend .= '-';
$apend .= $dashes[1];
if ( $apend =~ s/-\d.+$// ) {
push @dashes2, $apend;
# print $apend, "hi1\n"; # pkg name leading alpha and dashes
$apend = '';
} else {
$apend .= '-';
$apend .= $dashes[2];
$apend =~ s/-\d.+$//;
# print $apend, "hi2\n"; # pkg name leading alpha and dashes
push @dashes2, $apend;
$apend = '';
}
} # got alpha_only and dashes in the @dashes2 array
# end of alpha_only

# print @dashes2, "\n";
print "Patches on mirror server:\n";
print @patches; # mirror server's patches print to screen
print "\n---\n\n";

my $pid2;
my $sys_pkgs;
$pid2 = open $sys_pkgs, "-|", "find", "/var/log/packages" or die "cant fork: $!\n";
print "pid is: $pid2\n";
my @sys_pkg_list;
while (<$sys_pkgs>) {
next if /packages$/;
s#/var/log/packages/##;
push @sys_pkg_list, $_;
} # got /var/log/packages into the @sys_pkg_list array
@sys_pkg_list = sort { $a cmp $b } @sys_pkg_list;
# and we now have a sorted or ordered list

# next, using the alpha_only and dashes (@dashes2 array) we
# compare each with each that's in the @sys_pkg_list array
# @alpha_matches array gets items from /var/log/packages
# that have a match on the mirror server
# though the digit portion may or may
# not match at this point in the game
# thus the array name of matches via alpha or alpha_matches
my @alpha_matches;
foreach my $x (@sys_pkg_list) {
    foreach (@dashes2) {
#        print $x if $x =~ /^$_-\d/;
# make sure is followed by a dash digit not a dash alpha
# thus the -\d (dash digit) in the next regex
        push @alpha_matches, $x if $x =~ /^$_-\d/;
    }
} # @alpha_matches tells us, irrespective of version number,
# which pkgs exist on both our sys and on the mirror server
# IOW @patches and @alpha_matches should each now be holding
# the same pkg name contents though version #'s may not match

# next, the need to discern and report about yes/no version
# differences between sys pkgs and mirror server patches
# (hint -- we'll likely use a hash since hash keys must be
#  unique)  IOW version matches will be gone and the only
# remaining will be an "either -- or" that is either yes
# new updates exist or no all our pkgs currently up to date
# if yes, it will list which pkgs updates but if no then it
# will say "Your sys pkgs are currently 100% up to date there
# are no new updates for your sys on the mirror server".

# until we resume coding, for now, we'll just print @alpha_matches
# matches via alpha which exist on our sys print to screen
print "From sys the pkg matches via alpha to patches:\n";
print @alpha_matches, "\n";
# end
--
Alan
I may be missing some subtlety of your code, but you should be able to replace the entire "Here 1" section with
Code:
#code not tested
my @dashes2 = map {s/-\d.*$//} @patches;
Brian
 
Old 12-29-2007, 12:53 AM   #20
acummings
Member
 
Registered: Jul 2004
Distribution: Slackware
Posts: 615

Rep: Reputation: 50
I haven't sufficiently learned map yet. But I had guessed there was a way to do it using map.

What's with the long string of 1's ?? as per my console output when I tested it enclosed near the bottom of this post.

I could modify my code so as to make use of your code. But I'm confused by the long string of 1's printed out from the @dashes2 array???

Code:
# got patches file names in the @patches array

# next section strips the numeric part of patch file names
# which leaves us with only the leading  alpha and dashes
# up to but not including any of the digits

# begin of alpha_only (number, numeric not allowed)
my @dashes2 = map {s/-\d.+$//} @patches;
# got alpha_only and dashes in the @dashes2 array
# end of alpha_only

print @dashes2, "\n";
print "Patches on mirror server:\n";
print @patches; # mirror server's patches print to screen
print "\n---\n\n";
----------

I tested it. It puts a long string of 1's into @dashes2

@patches gets the dash-digits removed

In a roundabout way it does what I wanted though I wanted @patches to remain unchanged or untouched and I wanted @patches contents transferred to @dashes2 but with the dash-digits removed from @dashes2

al@AB60R:~$ slak_updck2b
pid is: 3717
111111111111111111111111111
Patches on mirror server:
bind
cairo
cups
gimp
glibc-zoneinfo
<snipped>

--
Alan.
 
Old 12-29-2007, 10:38 AM   #21
BCarey
Senior Member
 
Registered: Oct 2005
Location: New Mexico
Distribution: Slackware
Posts: 1,639

Rep: Reputation: Disabled
Sorry, try
Code:
my @dashes2 = map {s/-\d.*$//;$_} @patches;
The "1" is because the substitution was successful. So it is basically reporting that it was able to perform the substitution, rather than giving you back the result. Adding the additional "line" to the block returns the result of the substitution.

Brian
 
Old 12-29-2007, 10:45 AM   #22
BCarey
Senior Member
 
Registered: Oct 2005
Location: New Mexico
Distribution: Slackware
Posts: 1,639

Rep: Reputation: Disabled
A better way, which will leave your original array undisturbed, make it easier to modify in the future, make it easier to understand, and make it easier to debug, would be
Code:
sub GetPackageName {
        my $string = shift;
        $string =~ s/-\d.*$//;
        return $string;
}
my @dashes2 = map {GetPackageName($_)} @packages;
Brian
 
Old 12-29-2007, 11:57 AM   #23
BCarey
Senior Member
 
Registered: Oct 2005
Location: New Mexico
Distribution: Slackware
Posts: 1,639

Rep: Reputation: Disabled
Here's a version which will give you a hash with package names as keys and version number as values, with an example of how you might use the hash:

Code:
sub GetPackageInfo {
        my $string = shift;
        my ($package_name, $version) = $string =~ m/(.*)-(\d[^-]*)-.*$/;
        return ($package_name, $version);
}
my %version = map {GetPackageInfo($_)} @packages;
foreach (sort keys %version) {
    print "Package Name: $_\nVersion: $version{$_}\n";
}
Brian
 
Old 12-29-2007, 03:43 PM   #24
BCarey
Senior Member
 
Registered: Oct 2005
Location: New Mexico
Distribution: Slackware
Posts: 1,639

Rep: Reputation: Disabled
OK, this is my last one (once you get going, you know...).

This version compares all the patches and extra packages with those installed on the system and prints out when they are different. Problems arise primarily with extra, especially if there is a package in extra which is also in the main tree. So for example it will "fail" on kernel-generic because the ChangeLog shows a 2.6.18 version in the /extra directory, and it compares that to the 2.6.21 from the /a series (which should be installed on a vanilla system) and reports a "new" version.

Anyway, slackpkg is the way to go for this (it's sophisticated and has been well-tested), but for the sake of learning:

Code:
#!/usr/bin/perl

use strict;
use LWP::Simple;

my $url = 'ftp://ftp.slackware.com/pub/slackware/slackware-12.0/ChangeLog.txt';
my $change_log = get $url
  or die "Could not download ChangeLog";
my @change_log = split "\n", $change_log;

my @installed_packages = `ls /var/log/packages`;

my (%installed_version, %latest_version, %package_location, %installed_build, %latest_build);

sub GetPackageInfo {
        my $string = shift;
        my ($package_name, $version) = $string =~ m/(.*)-(\d[^-]*)-.*$/;
        return ($package_name, $version);
}

for my $line (@change_log) {
        next unless ($line =~ m:^patches/:) || ($line =~ m:^extra/:);
        my ($package_location, $package_file_name) = $line =~ m:^(.*/.*/)(.*)$:;
        my ($package_name, $package_version) = GetPackageInfo($package_file_name
);
        next if $latest_version{$package_name};
        $latest_version{$package_name} = $package_version;
        $package_location{$package_name} = $package_location;
}

%installed_version = map {GetPackageInfo($_)} @installed_packages;

for (sort keys %latest_version) {
        next unless $installed_version{$_};
        if ($installed_version{$_} ne $latest_version{$_}) {
                print "New version of $_ available:\nInstalled: $installed_version{$_}\nAvailable: $latest_version{$_}\nLocation: $package_location{$_}\n";
        }
}
Brian

Last edited by BCarey; 12-29-2007 at 09:53 PM.
 
Old 12-30-2007, 12:38 AM   #25
acummings
Member
 
Registered: Jul 2004
Distribution: Slackware
Posts: 615

Rep: Reputation: 50
Two thirds to three quarters or more of that changelog is Slackware 11.0 version; only what's left or the remainder of said changelog is Slackware 12.0

for my $line (@change_log) {
last if /^Released as Slackware 12/; # not parse 11.0 changelog
-----------------------

Such last if line (above) (stops parse of 11.0 changelog)

next (snippet's last line) is snippet from changelog (Slack 11.0) where got your "updated" kernel from /extra

Thu Feb 15 14:43:45 CST 2007
a/cxxlibs-6.0.8-i486-2.tgz: Replaced libstdc++.so.6.0.8 with the version built
by gcc-4.1.2. Pruned some ancient libs unlikely to be used by anyone.
a/pkgtools-11.0.9-noarch-3.tgz: Moved X related files into x11-skel.
a/kernel-generic-2.6.18.6-i486-1.tgz: Moved from /extra.
--------------------------------

Some of your code went only a little over my head. It's late now but I would like ask a few questions about portions of your code.

I used the mirror switch of wget; and it doesn't download the changelog again unless the changelog has changed.

(if you want to try what I did) For now, need be in your home dir and do

$ mkdir .slak_updck

(2 text files, changelog and wget log will be kept there)

Then run the below code and it will only download the changelog once

From then on, it parses the updated wget log and it will only download the changelog again only if the changelog has changed. (speedier, saves bandwidth, the mirrors like us more) :-)

note hard coded paths (2 of them) to my home folder

Perl doesn't expand ~/.slak_updck/dl_log.txt

I don't know how to do that without hard code the path in Perl.

For some reason it's getting "use of uninitialized value" errors from in your part of the code -- but it didn't do this before until I came along -- I suspect it has something to do with my lexical filehandle -- but I don't know the cause, not yet.

Code:
#!/usr/bin/perl

use strict;
use warnings;

system("wget -m -nd -P.slak_updck ftp://slackware.mirrors.tds.net/pub/slackware/slackware-12.0/ChangeLog.txt -o ~/.slak_updck/dl_log.txt");
my $new_updates;
my $downl_log = '/home/al/.slak_updck/dl_log.txt'; # path to wget log (dl_log.txt)

open my $logfil, "<", $downl_log or die "cant open $downl_log: $!";
while ( <$logfil> ) {

print if /RETR ChangeLog.txt/;
$new_updates = 'newstuff' if /RETR ChangeLog.txt/;
last if /RETR ChangeLog.txt/;
}
close($logfil) or die "Could not close input: $!";

my $chnglogfil = '/home/al/.slak_updck/ChangeLog.txt'; # path to ChangeLog.txt


if ( $new_updates ) {
print $new_updates, " on mirror\n\n";
open my $change_log, '<', $chnglogfil or die "could not open '$chnglogfil' $!";

my @change_log = do { local $/; <$change_log> }; # Slurp

print @change_log, "\n";

# print "yesir\n" if $new_updates;

# __END__

# my @change_log = split "\n", $change_log;

my @installed_packages = `ls /var/log/packages`;

my (%installed_version, %latest_version, %package_location, %installed_build, %latest_build);

sub GetPackageInfo {
        my $string = shift;
        my ($package_name, $version, $build) = $string =~ m/(.*)-(\d[^-]*)-.*$/;
        return ($package_name, $version);
}

for my $line (@change_log) {
        last if /^Released as Slackware 12/; # not parse 11.0 changelog
        next unless ($line =~ m:^patches/:) || ($line =~ m:^extra/:);
        my ($package_location, $package_file_name) = $line =~ m:^(.*/.*/)(.*)$:;
        my ($package_name, $package_version) = GetPackageInfo($package_file_name
);
        next if $latest_version{$package_name};
        $latest_version{$package_name} = $package_version;
        $package_location{$package_name} = $package_location;
}

%installed_version = map {GetPackageInfo($_)} @installed_packages;

for (sort keys %latest_version) {
        next unless $installed_version{$_};
        if ($installed_version{$_} ne $latest_version{$_}) {
                print "New version of $_ available:\nInstalled: $installed_version{$_}\nAvailable: $latest_version{$_}\nLocation: $package_location{$_}\n";
        }
}

} else {
print "no new updates on mirror server\n";
}
# end
--
Alan.
 
Old 12-30-2007, 12:49 AM   #26
acummings
Member
 
Registered: Jul 2004
Distribution: Slackware
Posts: 615

Rep: Reputation: 50
Oh. Duh.

I wrapped all of your code in an if else

if ("wget log informs us new updates do exist"){
DL and save to disk the changelog
then run all the Perl code
} else {
# do nothing whatsoever except
print "no new updates on mirror server\N";
------------------------------------

wrapped in the if did changed the scope

I wonder if such change in scope is what is causing the

"uninitialized value in list operator" errors.
--

It's very late here. Tomorrow is another day. Thanks.

--
Alan.
 
Old 01-02-2008, 10:39 AM   #27
BCarey
Senior Member
 
Registered: Oct 2005
Location: New Mexico
Distribution: Slackware
Posts: 1,639

Rep: Reputation: Disabled
Here's a better way to process the ChangeLog:
Code:
use List::MoreUtils qw/first_index/;
my $release_announce_index = first_index {m/Released as Slackware 12/} @change_log;
$#change_log = $release_announce_index - 1;
my @package_lines_from_change_log = grep {m:^patches/: || m:^extra/:} change_log;
my @latest_packages = map {s:^.*/.*/::;$_} @package_lines_from_change_log;
my %latest_version = map {GetPackageInfo($_)} @latest_packages;
No looping and taking advantage of optimized commands like map a grep.

Brian
 
Old 01-02-2008, 01:09 PM   #28
Alien_Hominid
Senior Member
 
Registered: Oct 2005
Location: Lithuania
Distribution: Hybrid
Posts: 2,247

Rep: Reputation: 53
Can smth similar applied to Current?
 
Old 01-02-2008, 10:13 PM   #29
BCarey
Senior Member
 
Registered: Oct 2005
Location: New Mexico
Distribution: Slackware
Posts: 1,639

Rep: Reputation: Disabled
Quote:
Originally Posted by Alien_Hominid View Post
Can smth similar applied to Current?
Sure, why not. But again, we're just playing with perl, here. slackpkg will do this for you, and it is much more sophisticated and well tested.

Brian
 
Old 01-02-2008, 11:17 PM   #30
Alien_Hominid
Senior Member
 
Registered: Oct 2005
Location: Lithuania
Distribution: Hybrid
Posts: 2,247

Rep: Reputation: 53
Ok, I'll take a look it. Just didn't know that such tool, which knows whether the packgage was split into several others or some others were merged, exists. The only automated way in current for me was comparing package trees when having full install.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how to save a list of installed packages and install these packages later mandavi Ubuntu 5 09-07-2009 11:36 AM
website comparing packages between different linux distros? dozer Linux - General 3 11-11-2006 08:44 AM
Sort installed packages by # of dependant packages installed brianez21 Debian 1 01-18-2006 05:06 PM
Comparing RPM packages against Redhat repository bundaburg Linux - Security 1 08-02-2005 04:56 PM
RPM is saying installed packages aren't installed ticky87 Linux - Newbie 4 07-26-2004 01:17 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware

All times are GMT -5. The time now is 07:04 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration