]>
git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/pakfire/lib/functions.pl
3 require "/opt/pakfire/etc/pakfire.conf" ;
4 require "/var/ipfire/general-functions.pl" ;
21 my %pakfiresettings = ();
22 & General
:: readhash
( "${General::swroot}/pakfire/settings" , \
%pakfiresettings );
32 system ( "logger -t pakfire \" $log \" " ) if " $log " ;
36 & Pakfire
:: message
( "Usage: pakfire <install|remove> <pak(s)>" );
37 & Pakfire
:: message
( " <update> - Contacts the servers for new lists of paks." );
38 & Pakfire
:: message
( " <upgrade> - Installs the latest version of all paks." );
39 & Pakfire
:: message
( " <list> - Outputs a short list with all available paks." );
40 & Pakfire
:: message
( "" );
47 $p = Net
:: Ping
-> new ();
48 if ( $p -> ping ( $host )) {
49 logger
( "PING INFO: $host is alive" );
52 logger
( "PING INFO: $host is unreachable" );
61 my ( @server , $host , $proto , $file , $allok , $i );
63 logger
( "DOWNLOAD STARTED: $getfile " ) unless ( $bfile =~ /^counter\?.*/ );
65 $bfile = basename
( " $getfile " );
68 while (( $allok == 0 ) && $i < 5 ) {
71 if ( " $gethost " eq "" ) {
72 @server = selectmirror
();
75 $file = " $server [2]/ $getfile " ;
81 $proto = "HTTP" unless $proto ;
83 unless ( $bfile =~ /^counter\?.*/ ) {
84 logger
( "DOWNLOAD INFO: Host: $host ( $proto ) - File: $file " );
85 #message("DOWNLOAD INFO: Loading $bfile from ($proto) $host...");
88 my $ua = LWP
:: UserAgent
-> new ;
89 $ua -> agent ( "Pakfire/ $Conf ::version" );
93 & General
:: readhash
( "${General::swroot}/proxy/advanced/settings" , \
%proxysettings );
95 if ( $proxysettings { 'UPSTREAM_PROXY' }) {
96 logger
( "DOWNLOAD INFO: Upstream proxy: \" $proxysettings {'UPSTREAM_PROXY'} \" " ) unless ( $bfile =~ /^counter\?.*/ );
97 if ( $proxysettings { 'UPSTREAM_USER' }) {
98 $ua -> proxy ( "http" , "http:// $proxysettings {'UPSTREAM_USER'}: $proxysettings {'UPSTREAM_PASSWORD'}@" . " $proxysettings {'UPSTREAM_PROXY'}/" );
99 logger
( "DOWNLOAD INFO: Logging in with: \" $proxysettings {'UPSTREAM_USER'} \" - \" $proxysettings {'UPSTREAM_PASSWORD'} \" " ) unless ( $bfile =~ /^counter\?.*/ );
101 $ua -> proxy ( "http" , "http:// $proxysettings {'UPSTREAM_PROXY'}/" );
106 my $url = "http:// $host / $file " ;
109 unless ( $bfile =~ /^counter\?.*/ ) {
110 my $result = $ua -> head ( $url );
111 my $remote_headers = $result -> headers ;
112 $total_size = $remote_headers -> content_length ;
113 logger
( "DOWNLOAD INFO: $file has size of $total_size bytes" );
115 $response = $ua -> get ( $url , ':content_cb' => \
& callback
);
118 $response = $ua -> get ( $url );
121 my $code = $response -> code ();
122 my $log = $response -> status_line ;
123 logger
( "DOWNLOAD INFO: HTTP-Status-Code: $code - $log " );
125 if ( $code eq "500" ) {
126 message
( "Giving up: There was no chance to get the file \" $getfile \" from any available server. \n There was an error on the way. Please fix it." );
130 if ( $response -> is_success ) {
131 if ( open ( FILE
, "> $Conf ::tmpdir/ $bfile " )) {
132 print FILE
$final_data ;
134 unless ( $bfile =~ /^counter\?.*/ ) { # Don't check out counterfile cause it's empty
135 logger
( "DOWNLOAD INFO: File received. Start checking signature..." );
136 if ( system ( "gpg --verify \" $Conf ::tmpdir/ $bfile \" &>/dev/null" ) eq 0 ) {
137 logger
( "DOWNLOAD INFO: Signature of $bfile is fine." );
138 move
( " $Conf ::tmpdir/ $bfile " , " $Conf ::cachedir/ $bfile " );
140 message
( "DOWNLOAD ERROR: The downloaded file ( $file ) wasn't verified by IPFire.org. Sorry - Exiting..." );
144 logger
( "DOWNLOAD FINISHED: $file " ) unless ( $bfile =~ /^counter\?.*/ );
148 logger
( "DOWNLOAD ERROR: Could not open $Conf ::cachedir/ $bfile for writing." );
151 logger
( "DOWNLOAD ERROR: $log " );
154 message
( "DOWNLOAD ERROR: There was no chance to get the file \" $getfile \" from any available server. \n May be you should run \" pakfire update \" to get some new servers." );
161 logger
( "MIRROR: Trying to get a mirror list." );
163 fetchfile
( " $Conf ::version/lists/server-list.db" , " $Conf ::mainserver" );
164 move
( " $Conf ::cachedir/server-list.db" , " $Conf ::dbdir/lists/server-list.db" );
168 ### Check if there is a current server list and read it.
169 # If there is no list try to get one.
171 while (!( open ( FILE
, "< $Conf ::dbdir/lists/server-list.db" )) && ( $count lt 5 )) {
176 message
( "MIRROR ERROR: Could not find or download a server list" );
182 ### Count the number of the servers in the list
186 if ( " $_ " =~ /.*;.*;.*;/ ) {
191 logger
( "MIRROR INFO: $scount servers found in list" );
193 ### Choose a random server and test if it is online
194 # If the check fails try a new server.
195 # This will never give up.
198 while ( $found == 0 ) {
199 $server = int ( rand ( $scount ) + 1 );
201 my ( $line , $proto , $path , $host );
203 foreach $line ( @newlines ) {
205 if ( $servers eq $server ) {
206 @templine = split ( /\;/ , $line );
207 $proto = $templine [ 0 ];
208 $host = $templine [ 1 ];
209 $path = $templine [ 2 ];
210 if ( pinghost
( " $host " )) {
212 return ( $proto , $host , $path );
220 ### Update the database if the file is older than one day.
221 # If you pass &Pakfire::dbgetlist(force) the list will be downloaded.
222 # Usage is always with an argument.
228 if ( - e
" $Conf ::dbdir/lists/packages_list.db" ) {
229 my @stat = stat ( " $Conf ::dbdir/lists/packages_list.db" );
231 $age = $time - $stat [ 9 ];
237 if (( " $age " gt 86400 ) || ( " $force " eq "force" )) {
239 fetchfile
( "lists/packages_list.db" , "" );
240 move
( " $Conf ::cachedir/packages_list.db" , " $Conf ::dbdir/lists/packages_list.db" );
245 ### This subroutine lists the packages.
246 # You may also pass a filter: &Pakfire::dblist(filter)
247 # Usage is always with two arguments.
248 # filter may be: all, notinstalled, installed
256 my ( $name , $version , $release );
259 ### Make sure that the list is not outdated.
260 dbgetlist
( "noforce" );
262 open ( FILE
, "< $Conf ::dbdir/lists/packages_list.db" );
266 if ( " $filter " eq "upgrade" ) {
267 opendir ( DIR
, " $Conf ::dbdir/meta" );
268 my @files = readdir ( DIR
);
270 foreach $file ( @files ) {
271 next if ( $file eq "." );
272 next if ( $file eq ".." );
273 open ( FILE
, "< $Conf ::dbdir/meta/ $file " );
276 foreach $line ( @meta ) {
277 @templine = split ( /\: / , $line );
278 if ( " $templine [0]" eq "Name" ) {
279 $name = $templine [ 1 ];
281 } elsif ( " $templine [0]" eq "ProgVersion" ) {
282 $version = $templine [ 1 ];
284 } elsif ( " $templine [0]" eq "Release" ) {
285 $release = $templine [ 1 ];
289 foreach $prog ( @db ) {
290 @templine = split ( /\;/ , $prog );
291 if (( " $name " eq " $templine [0]" ) && ( " $release " < " $templine [2]" )) {
292 push ( @updatepaks , $name );
293 if ( " $forweb " eq "forweb" ) {
294 print "<option value= \" $name \" >Update: $name -- Version: $version -> $templine [1] -- Release: $release -> $templine [2]</option> \n " ;
296 print "Update: $name \n Version: $version -> $templine [1] \n Release: $release -> $templine [2] \n\n " ;
305 foreach $line ( sort @db ) {
306 next unless ( $line =~ /.*;.*;.*;/ );
307 @templine = split ( /\;/ , $line );
308 if ( " $filter " eq "notinstalled" ) {
309 next if ( - e
" $Conf ::dbdir/installed/meta- $templine [0]" );
310 } elsif ( " $filter " eq "installed" ) {
311 next unless ( - e
" $Conf ::dbdir/installed/meta- $templine [0]" );
313 if ( " $forweb " eq "forweb" ) {
314 print "<option value= \" $templine [0] \" > $templine [0]- $templine [1]- $templine [2]</option> \n " ;
316 print "Name: $templine [0] \n ProgVersion: $templine [1] \n Release: $templine [2] \n\n " ;
328 message
( "## Resolving dependencies for $pak ..." );
330 open ( FILE
, "< $Conf ::dbdir/meta/meta- $pak " );
335 my ( @templine , @deps , @tempdeps , @all );
336 foreach $line ( @file ) {
337 @templine = split ( /\: / , $line );
338 if ( " $templine [0]" eq "Dependencies" ) {
339 @deps = split ( / / , $templine [ 1 ]);
345 my $return = & isinstalled
( $_ );
347 message
( "### Dependency is already installed: $_ " );
349 message
( "### Need to install dependency: $_ " );
356 foreach ( @tempdeps ) {
358 my @newdeps = resolvedeps
( " $_ " );
360 unless (( $_ eq " " ) || ( $_ eq "" )) {
361 my $return = & isinstalled
( $_ );
363 message
( "### Dependency is already installed: $_ " );
365 message
( "### Need to install dependency: $_ " );
380 if ( " $dir " eq "meta" ) {
381 $path = " $Conf ::dbdir/meta" ;
382 } elsif ( " $dir " eq "tmp" ) {
383 $path = " $Conf ::tmpdir" ;
387 my @files = readdir ( DIR
);
390 unless (( $_ eq "." ) || ( $_ eq ".." )) {
399 unless ( - e
" $Conf ::dbdir/meta/meta- $pak " ) {
400 fetchfile
( "meta/meta- $pak " , "" );
401 move
( " $Conf ::cachedir/meta- $pak " , " $Conf ::dbdir/meta/meta- $pak " );
404 open ( FILE
, "< $Conf ::dbdir/meta/meta- $pak " );
408 open ( FILE
, "> $Conf ::dbdir/meta/meta- $pak " );
411 $string =~ s/\r\n/\n/g ;
423 open ( FILE
, "< $Conf ::dbdir/meta/meta- $pak " );
429 foreach $line ( @file ) {
430 @templine = split ( /\: / , $line );
431 if ( " $templine [0]" eq "Size" ) {
444 my $file = getpak
( " $pak " , "noforce" );
446 logger
( "DECRYPT STARTED: $pak " );
447 my $return = system ( "cd $Conf ::tmpdir/ && gpg -d < $Conf ::cachedir/ $file | tar x &>/dev/null" );
449 logger
( "DECRYPT FINISHED: $pak - Status: $return " );
450 if ( $return != 0 ) { exit 1 ; }
459 open ( FILE
, "< $Conf ::dbdir/meta/meta- $pak " );
466 foreach $line ( @file ) {
467 @templine = split ( /\: / , $line );
468 if ( " $templine [0]" eq "File" ) {
470 $file = $templine [ 1 ];
475 message
( "No filename given in meta-file. Please phone the developers." );
479 unless ( " $force " eq "force" ) {
480 if ( - e
" $Conf ::cachedir/ $file " ) {
485 fetchfile
( "paks/ $file " , "" );
492 message
( "################################################################################" );
493 message
( "# --> Installing: $pak " );
494 message
( "################################################################################" );
498 my $return = system ( "cd $Conf ::tmpdir && NAME= $pak ./install.sh >> $Conf ::logdir/install- $pak .log 2>&1" );
500 if ( $pakfiresettings { 'UUID' } ne "off" ) {
501 fetchfile
( "cgi-bin/counter?ver= $Conf ::version&uuid= $Conf ::uuid&ipak= $pak &return= $return " , " $Conf ::mainserver" );
504 move
( " $Conf ::tmpdir/ROOTFILES" , " $Conf ::dbdir/rootfiles/ $pak " );
506 copy
( " $Conf ::dbdir/meta/meta- $pak " , " $Conf ::dbdir/installed/" );
507 message
( "Setup completed. Congratulations!" );
508 message
( "################################################################################" );
510 message
( "Setup returned: $return . Sorry. Please search our forum to find a solution for this problem." );
518 if ( open ( FILE
, "< $Conf ::dbdir/installed/meta- $pak " ) ) {
529 message
( "We are going to upgrade: $pak " );
533 my $return = system ( "cd $Conf ::tmpdir && NAME= $pak ./update.sh >> $Conf ::logdir/update- $pak .log 2>&1" );
535 if ( $pakfiresettings { 'UUID' } ne "off" ) {
536 fetchfile
( "cgi-bin/counter?ver= $Conf ::version&uuid= $Conf ::uuid&upak= $pak &return= $return " , " $Conf ::mainserver" );
539 move
( " $Conf ::tmpdir/ROOTFILES" , " $Conf ::dbdir/rootfiles/ $pak " );
541 copy
( " $Conf ::dbdir/meta/meta- $pak " , " $Conf ::dbdir/installed/" );
542 message
( "Upgrade completed. Congratulations!" );
544 message
( "Setup returned: $return . Sorry. Please search our forum to find a solution for this problem." );
553 message
( "We are going to uninstall: $pak " );
557 my $return = system ( "cd $Conf ::tmpdir && NAME= $pak ./uninstall.sh >> $Conf ::logdir/uninstall- $pak .log 2>&1" );
559 if ( $pakfiresettings { 'UUID' } ne "off" ) {
560 fetchfile
( "cgi-bin/counter?ver= $Conf ::version&uuid= $Conf ::uuid&dpak= $pak &return= $return " , " $Conf ::mainserver" );
563 open ( FILE
, "< $Conf ::dbdir/rootfiles/ $pak " );
566 message
( "Removing files..." );
570 system ( "echo \" Removing: $line \" >> $Conf ::logdir/uninstall- $pak .log 2>&1" );
571 system ( "cd / && rm -rf $line >> $Conf ::logdir/uninstall- $pak .log 2>&1" );
573 unlink ( " $Conf ::dbdir/rootfiles/ $pak " );
574 unlink ( " $Conf ::dbdir/installed/meta- $pak " );
575 message
( "Finished removing files!" );
577 message
( "Uninstall completed. Congratulations!" );
579 message
( "Setup returned: $return . Sorry. Please search our forum to find a solution for this problem." );
587 $size = $size / 1024 ;
591 $size = ( $size / 1024 );
596 $size = sprintf ( "%.2f" , $size );
597 my $string = " $size $unit " ;
602 unless ( - e
" $Conf ::dbdir/uuid" ) {
603 open ( FILE
, "</proc/sys/kernel/random/uuid" );
607 open ( FILE
, "> $Conf ::dbdir/uuid" );
616 if ( $pakfiresettings { 'UUID' } ne "off" ) {
617 unless ( " $Conf ::uuid" ) {
618 $Conf :: uuid
= `cat $Conf ::dbdir/uuid` ;
620 logger
( "Sending my uuid: $Conf ::uuid" );
621 fetchfile
( "cgi-bin/counter?ver= $Conf ::version&uuid= $Conf ::uuid" , " $Conf ::mainserver" );
622 system ( "rm -f $Conf ::tmpdir/counter* 2>/dev/null" );
627 logger
( "CRYPTO INFO: Checking GnuPG Database" );
628 my $myid = "64D96617" ; # Our own gpg-key
629 my $trustid = "65D0FD58" ; # Id of CaCert
630 my $ret = system ( "gpg --list-keys | grep -q $myid " );
631 unless ( " $ret " eq "0" ) {
632 message
( "CRYPTO WARN: The GnuPG isn't configured corectly. Trying now to fix this." );
633 message
( "CRYPTO WARN: It's normal to see this on first execution." );
634 system ( "gpg --keyserver wwwkeys.de.pgp.net --always-trust --recv-key $myid &>> $Conf ::logdir/gnupg-database.log" );
635 system ( "gpg --keyserver wwwkeys.de.pgp.net --always-trust --recv-key $trustid &>> $Conf ::logdir/gnupg-database.log" );
637 logger
( "CRYPTO INFO: Database is okay" );
642 my ( $data , $response , $protocol ) = @_ ;
643 $final_data .= $data ;
644 print progress_bar
( length ( $final_data ), $total_size , 25 , '=' );
648 my ( $got , $total , $width , $char ) = @_ ;
650 $width ||= 25 ; $char ||= '=' ;
651 my $num_width = length $total ;
652 my $len_bfile = length $bfile ;
653 if ( " $len_bfile " >= "12" ) {
654 $show_bfile = substr ( $bfile , 0 , 12 ). "..." ;
656 $show_bfile = $bfile ;
658 sprintf " $show_bfile [%-${width}s] Got %${num_width}s bytes of %s (%.2f%%) \r " , $char x
(( $width - 1 )* $got /$total). '>', $got, $total, 100*$got/ + $total ;