#!/usr/bin/perl -w # $Id: get_latest_kernel.txt,v 1.1 2009-09-17 11:47:03 bagder Exp $ # Copyright (C) 2006 Fredrik Ax # # get_latest_kernel.pl is free software; you may redistributed it and/or modify # it under the terms of the GNU General Public License, Version 2 or later. # ############################################################################### # Defaults my $baseurl= 'http://www.kernel.org/pub/linux/kernel/'; my $basever= '2.6'; ### No need to change anything below this ##################################### use strict; use HTML::TreeBuilder; use WWW::Curl::easy; my $showprog= 1; for my $arg (@ARGV) { if($arg =~ m/[0-9]+\.[0-9]+$/) { $basever= $arg; } elsif($arg eq '--no-progress') { $showprog= 0; } else { die "\nUSAGE: $0 [--no-progress] []\n\n(base version defaults to '2.6')\n\n"; } } my $body= ''; my $tot= my $prog= 0; my $code= 0; my $curl = WWW::Curl::easy->new(); $code+= $curl->setopt(CURLOPT_WRITEFUNCTION, \&tovar ); $code+= $curl->setopt(CURLOPT_FAILONERROR, 0); $code+= $curl->setopt(CURLOPT_FILE, \$body); $code+= $curl->setopt(CURLOPT_SSL_VERIFYPEER, 0); $code+= $curl->setopt(CURLOPT_SSL_VERIFYHOST, 0); $code+= $curl->setopt(CURLOPT_NOPROGRESS, 1); $code+= $curl->setopt(CURLOPT_VERBOSE, 0); $code+= $curl->setopt(CURLOPT_HEADER, 0); $code+= $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length(shift) } ); # ignore headers $code+= $curl->setopt(CURLOPT_URL, "${baseurl}v$basever/"); die 'Failed to initialize curl' if $code != 0; $curl->perform(); my $tree = HTML::TreeBuilder->new(); $tree->parse($body); my $lver= ''; for my $a ($tree->look_down('_tag', 'a', sub { defined($_[0]->attr('href')) && $_[0]->attr('href') =~ m/^LATEST-IS-/ } )) { $a->attr('href') =~ m/^LATEST-IS-(.*)/ or die 'Internal Error'; $lver= $1; last; } die "\nCould not find latest kernel of major version $basever!\n\n" unless length($lver); print "Looking for linux-$lver.tar.bz2 or linux-$lver.tar.gz ...\n"; my $kernel= ''; for my $a ($tree->look_down('_tag', 'a', sub { defined($_[0]->attr('href')) && $_[0]->attr('href') =~ m/^linux-$lver\.tar\.(bz2|gz)$/i } )) { $a->attr('href') =~ m/^linux-$lver\.tar\.(bz2|gz)$/i or die 'Internal Error 2'; $kernel= "linux-$lver.tar.$1"; last if $1 =~ m/^bz2/i; } die "\nCould not find linux-$lver.tar.bz2 or linux-$lver.tar.gz!\n\n" unless length($kernel); print "Downloading ${baseurl}v$basever/$kernel...\n"; open(TBZ2, ">$kernel") or die "\nopen: $!\n\n"; binmode TBZ2; if($showprog) { $code+= $curl->setopt(CURLOPT_HEADERFUNCTION, \&get_tot ); # get content-length from headers $code+= $curl->setopt(CURLOPT_WRITEFUNCTION, \&tofile_prog); $|= 1; } else { $code+= $curl->setopt(CURLOPT_WRITEFUNCTION, \&tofile); } $code+= $curl->setopt(CURLOPT_FILE, *TBZ2); $code+= $curl->setopt(CURLOPT_URL, "${baseurl}v$basever/$kernel"); die 'Failed to initialize curl' if $code != 0; $curl->perform(); close TBZ2; print "\n"; exit 0; # Call-back functions sub tovar { my ($data,$pointer)=@_; ${$pointer}.= $data; return length($data); } sub tofile { return syswrite($_[1], $_[0]); } sub tofile_prog { my $res= syswrite($_[1], $_[0]); return 0 unless defined $res; $prog+= $res; print "\r$prog", $tot ? (" / $tot bytes (".int(100*$prog/$tot)."%)") : ' bytes'; return $res; } sub get_tot { return length($_[0]) if $tot; $tot= $1 if $_[0] =~ m/content-length:\s*([0-9]+)\s*$/i; return length($_[0]); }