]> git.ipfire.org Git - ipfire-2.x.git/blame - src/pakfire/lib/functions.pl
DHCP Webseite angepasst damit beim speichern auch die rc links gesetzt werden
[ipfire-2.x.git] / src / pakfire / lib / functions.pl
CommitLineData
1bd42c89
MT
1#!/usr/bin/perl -w
2
3require "/opt/pakfire/etc/pakfire.conf";
4b122800 4require "/var/ipfire/general-functions.pl";
1bd42c89
MT
5
6use File::Basename;
7use File::Copy;
8use LWP::UserAgent;
4d504812 9use HTTP::Response;
1bd42c89
MT
10use Net::Ping;
11
12package Pakfire;
13
4b122800
MT
14my %pakfiresettings = ();
15&General::readhash("${General::swroot}/pakfire/settings", \%pakfiresettings);
16
1bd42c89
MT
17sub message {
18 my $message = shift;
19 print "$message\n";
20 logger("$message");
21}
22
23sub logger {
24 my $log = shift;
25 system("logger -t pakfire \"$log\"");
26}
27
5b2a12ff
MT
28sub usage {
29 &Pakfire::message("Usage: pakfire <install|remove> <pak(s)>");
30 &Pakfire::message(" <update> - Contacts the servers for new lists of paks.");
99e6df8e 31 &Pakfire::message(" <upgrade> - Installs the latest version of all paks.");
5b2a12ff 32 &Pakfire::message(" <list> - Outputs a short list with all available paks.");
99e6df8e 33 &Pakfire::message("");
5b2a12ff
MT
34 exit 1;
35}
36
1bd42c89
MT
37sub pinghost {
38 my $host = shift;
39
40 $p = Net::Ping->new();
41 if ($p->ping($host)) {
42 logger("$host is alive.");
43 return 1;
44 } else {
45 logger("$host is dead.");
46 return 0;
47 }
48 $p->close();
49}
50
51sub fetchfile {
4d504812
MT
52 my $getfile = shift;
53 my $gethost = shift;
54 my (@server, $host, $proto, $file, $allok, $i);
1bd42c89
MT
55
56 use File::Basename;
4d504812 57 $bfile = basename("$getfile");
1bd42c89 58
4d504812
MT
59 $i = 0;
60 while (($allok == 0) && $i < 5) {
61 $i++;
62
63 if ("$gethost" eq "") {
64 @server = selectmirror();
65 $proto = $server[0];
66 $host = $server[1];
67 $file = "$server[2]/$getfile";
1bd42c89 68 } else {
4d504812 69 $host = $gethost;
afabe9f7 70 $file = $getfile;
1bd42c89 71 }
4d504812
MT
72
73 $proto = "HTTP" unless $proto;
74
75 logger("Trying to get $file from $host ($proto).");
1bd42c89 76
4d504812
MT
77 my $ua = LWP::UserAgent->new;
78 $ua->agent("Pakfire/$Conf::version");
afabe9f7 79 $ua->timeout(5);
4b122800
MT
80
81 my %proxysettings=();
82 &General::readhash("${General::swroot}/proxy/advanced/settings", \%proxysettings);
83
99e6df8e 84 if ($proxysettings{'UPSTREAM_PROXY'}) {
4b122800 85 if ($proxysettings{'UPSTREAM_USER'}) {
99e6df8e 86 $ua->proxy("http","http://$proxysettings{'UPSTREAM_USER'}:$proxysettings{'UPSTREAM_PASSWORD'}@"."$proxysettings{'UPSTREAM_PROXY'}/");
4b122800 87 } else {
99e6df8e 88 $ua->proxy("http","http://$proxysettings{'UPSTREAM_PROXY'}/");
4b122800
MT
89 }
90 }
4d504812
MT
91
92 my $response = $ua->get("http://$host/$file");
93
4b122800
MT
94 my $code = $response->code();
95 my $log = $response->status_line;
96 logger("HTTP-Status-Code: $code - $log");
97
98 if ( $code eq "500" ) {
99 message("Giving up: There was no chance to get teh file \"$getfile\" from any available server.\nThere was an error on the way. Please fix it.");
100 return 1;
101 }
102
4d504812 103 if ($response->is_success) {
4d504812
MT
104 if (open(FILE, ">$Conf::cachedir/$bfile")) {
105 print FILE $response->content;
106 close(FILE);
4b122800 107 logger("Download successfully done from $host (file: $file).");
4d504812
MT
108 $allok = 1;
109 return 0;
110 } else {
111 logger("Could not open $Conf::cachedir/$bfile for writing.");
112 }
113 } else {
4d504812
MT
114 logger("Download $file failed from $host ($proto): $log");
115 }
1bd42c89 116 }
4d504812
MT
117 message("Giving up: There was no chance to get the file \"$getfile\" from any available server.\nMay be you should run \"pakfire update\" to get some new servers.");
118 return 1;
1bd42c89
MT
119}
120
121sub getmirrors {
122 use File::Copy;
123
124 logger("Try to get a mirror list.");
125
126 fetchfile("lists/$Conf::version-server-list", "$Conf::mainserver");
127 move("$Conf::cachedir/$Conf::version-server-list", "$Conf::dbdir/lists/$Conf::version-server-list");
128}
129
130sub selectmirror {
131 ### Check if there is a current server list and read it.
132 # If there is no list try to get one.
133 my $count = 0;
134 while (!(open(FILE, "<$Conf::dbdir/lists/$Conf::version-server-list")) && ($count lt 5)) {
135 $count++;
136 getmirrors();
137 }
138 if ($count == 5) {
139 message("Could not find or download a server list.");
140 exit 1;
141 }
142 my @lines = <FILE>;
143 close(FILE);
144
145 ### Count the number of the servers in the list
146 my $scount = 0;
147 foreach (@lines) {
148 $scount++;
149 }
150 logger("$scount servers found in list.");
151
152 ### Choose a random server and test if it is online
153 # If the check fails try a new server.
154 # This will never give up.
155 my $found = 0;
156 my $servers = 0;
157 while ($found == 0) {
158 $server = int(rand($scount) + 1);
159 $servers = 0;
160 my ($line, $proto, $path, $host);
161 my @templine;
162 foreach $line (@lines) {
163 $servers++;
164 if ($servers eq $server) {
165 @templine = split(/\;/, $line);
166 $proto = $templine[0];
167 $host = $templine[1];
168 $path = $templine[2];
a08c3a2e 169 if (pinghost("$host")) {
1bd42c89
MT
170 $found = 1;
171 return ($proto, $host, $path);
172 }
173 }
174 }
4d504812 175 }
1bd42c89
MT
176}
177
178sub dbgetlist {
179 ### Update the database if the file is older than one day.
180 # If you pass &Pakfire::dbgetlist(force) the list will be downloaded.
181 # Usage is always with an argument.
182 my $force = shift;
183 my $age;
184
185 use File::Copy;
186
187 if ( -e "$Conf::dbdir/lists/packages_list.db" ) {
188 my @stat = stat("$Conf::dbdir/lists/packages_list.db");
189 my $time = time();
190 $age = $time - $stat[9];
191 } else {
192 # Force an update.
193 $age = "86401";
194 }
195
196 if (("$age" gt 86400) || ("$force" eq "force")) {
5b2a12ff 197 #cleanup();
1bd42c89
MT
198 fetchfile("lists/packages_list.db", "");
199 move("$Conf::cachedir/packages_list.db", "$Conf::dbdir/lists/packages_list.db");
200 }
201}
202
203sub dblist {
204 ### This subroutine lists the packages.
205 # You may also pass a filter: &Pakfire::dblist(filter)
206 # Usage is always with two arguments.
207 # filter may be: all, notinstalled, installed
208 my $filter = shift;
209 my $forweb = shift;
4b122800 210 my @meta;
99e6df8e 211 my @updatepaks;
4b122800
MT
212 my $file;
213 my $line;
214 my $prog;
215 my ($name, $version, $release);
216 my @templine;
1bd42c89
MT
217
218 ### Make sure that the list is not outdated.
219 dbgetlist("noforce");
220
221 open(FILE, "<$Conf::dbdir/lists/packages_list.db");
222 my @db = <FILE>;
223 close(FILE);
4b122800
MT
224
225 if ("$filter" eq "upgrade") {
226 opendir(DIR,"$Conf::dbdir/meta");
227 my @files = readdir(DIR);
228 closedir(DIR);
229 foreach $file (@files) {
230 next if ( $file eq "." );
231 next if ( $file eq ".." );
232 open(FILE, "<$Conf::dbdir/meta/$file");
233 @meta = <FILE>;
234 close(FILE);
235 foreach $line (@meta) {
236 @templine = split(/\: /,$line);
237 if ("$templine[0]" eq "Name") {
238 $name = $templine[1];
239 chomp($name);
240 } elsif ("$templine[0]" eq "ProgVersion") {
241 $version = $templine[1];
242 chomp($version);
243 } elsif ("$templine[0]" eq "Release") {
244 $release = $templine[1];
245 chomp($release);
246 }
247 }
248 foreach $prog (@db) {
249 @templine = split(/\;/,$prog);
250 if (("$name" eq "$templine[0]") && ("$release" < "$templine[2]" )) {
99e6df8e 251 push(@updatepaks,$name);
4b122800
MT
252 if ("$forweb" eq "forweb") {
253 print "<option value=\"$name\">Update: $name -- Version: $version -> $templine[1] -- Release: $release -> $templine[2]</option>\n";
254 } else {
255 print "Update: $name\nVersion: $version -> $templine[1]\nRelease: $release -> $templine[2]\n\n";
256 }
257 }
258 }
5b2a12ff 259 }
99e6df8e 260 return @updatepaks;
4b122800
MT
261 } else {
262 my $line;
263 my @templine;
264 foreach $line (sort @db) {
265 @templine = split(/\;/,$line);
266 if ("$filter" eq "notinstalled") {
267 next if ( -e "$Conf::dbdir/installed/meta-$templine[0]" );
268 } elsif ("$filter" eq "installed") {
269 next unless ( -e "$Conf::dbdir/installed/meta-$templine[0]" );
270 }
271 if ("$forweb" eq "forweb") {
272 print "<option value=\"$templine[0]\">$templine[0]-$templine[1]-$templine[2]</option>\n";
273 } else {
274 print "Name: $templine[0]\nProgVersion: $templine[1]\nRelease: $templine[2]\n\n";
275 }
1bd42c89
MT
276 }
277 }
278}
279
280sub resolvedeps {
281 my $pak = shift;
282
283 getmetafile("$pak");
284
285 message("\n## Resolving dependencies for $pak...");
286
287 open(FILE, "<$Conf::dbdir/meta/meta-$pak");
288 my @file = <FILE>;
289 close(FILE);
290
291 my $line;
292 my (@templine, @deps, @tempdeps);
293 foreach $line (@file) {
294 @templine = split(/\: /,$line);
295 if ("$templine[0]" eq "Dependencies") {
296 @deps = split(/ /, $templine[1]);
297 }
298 }
299 chomp (@deps);
300 foreach (@deps) {
301 if ($_) {
302 message("### Found dependency: $_");
303 push(@tempdeps,$_);
304 }
305 }
306
307 #my @tempdeps = @deps;
308 foreach (@tempdeps) {
309 if ($_) {
310 my @newdeps = resolvedeps("$_");
311 foreach(@newdeps) {
312 unless (($_ eq " ") || ($_ eq "")) {
313 message("### Found dependency: $_");
314 push(@deps,$_);
315 }
316 }
317 }
318 }
319 chomp (@deps);
320 return @deps;
321}
322
323sub cleanup {
324 my $dir = shift;
325 my $path;
326
327 if ( "$dir" eq "meta" ) {
328 $path = "$Conf::dbdir/meta";
329 } elsif ( "$dir" eq "tmp" ) {
330 $path = "$Conf::tmpdir";
331 }
332 chdir("$path");
333 opendir(DIR,".");
334 my @files = readdir(DIR);
335 closedir(DIR);
336 foreach (@files) {
337 unless (($_ eq ".") || ($_ eq "..")) {
338 system("rm -rf $_");
339 }
340 }
341}
342
343sub getmetafile {
344 my $pak = shift;
345
346 logger("Going to download meta-$pak.");
347
348 unless ( -e "$Conf::dbdir/meta/meta-$pak") {
349 fetchfile("meta/meta-$pak", "");
350 move("$Conf::cachedir/meta-$pak", "$Conf::dbdir/meta/meta-$pak");
351 }
352
353 open(FILE, "<$Conf::dbdir/meta/meta-$pak");
354 my @line = <FILE>;
355 close(FILE);
356
357 open(FILE, ">$Conf::dbdir/meta/meta-$pak");
358 foreach (@line) {
359 my $string = $_;
360 $string =~ s/\r\n/\n/g;
361 print FILE $string;
362 }
363 close(FILE);
364 return 1;
365}
366
367sub getsize {
368 my $pak = shift;
369
370 getmetafile("$pak");
371
372 open(FILE, "<$Conf::dbdir/meta/meta-$pak");
373 my @file = <FILE>;
374 close(FILE);
375
376 my $line;
377 my @templine;
378 foreach $line (@file) {
379 @templine = split(/\: /,$line);
380 if ("$templine[0]" eq "Size") {
381 chomp($templine[1]);
382 return $templine[1];
383 }
384 }
4b122800 385 return 0;
1bd42c89
MT
386}
387
388sub decryptpak {
389 my $pak = shift;
390
391 cleanup("tmp");
392
393 my $file = getpak("$pak", "noforce");
394
99e6df8e
MT
395 my $return = system("cd $Conf::tmpdir/ && gpg -d < $Conf::cachedir/$file | tar x >/dev/null 2>&1");
396 $return %= 255;
1bd42c89 397 logger("Decryption process returned the following: $return");
cde0e116 398 if ($return != 0) { exit 1; }
1bd42c89
MT
399}
400
401sub getpak {
402 my $pak = shift;
403 my $force = shift;
404
405 getmetafile("$pak");
406
407 open(FILE, "<$Conf::dbdir/meta/meta-$pak");
408 my @file = <FILE>;
409 close(FILE);
410
411 my $line;
412 my $file;
413 my @templine;
414 foreach $line (@file) {
415 @templine = split(/\: /,$line);
416 if ("$templine[0]" eq "File") {
417 chomp($templine[1]);
418 $file = $templine[1];
419 }
420 }
421
422 unless ($file) {
423 message("No filename given in meta-file. Please phone the developers.");
424 exit 1;
425 }
426
1bd42c89
MT
427 unless ( "$force" eq "force" ) {
428 if ( -e "$Conf::cachedir/$file" ) {
1bd42c89
MT
429 return $file;
430 }
431 }
432
433 fetchfile("paks/$file", "");
434 return $file;
435}
436
437sub setuppak {
438 my $pak = shift;
439
440 message("We are going to install: $pak");
441
442 decryptpak("$pak");
443
99e6df8e 444 my $return = system("cd $Conf::tmpdir && NAME=$pak ./install.sh >> $Conf::logdir/install-$pak.log 2>&1");
cde0e116 445 $return %= 255;
1bd42c89
MT
446 if ($return == 0) {
447 move("$Conf::tmpdir/ROOTFILES", "$Conf::dbdir/rootfiles/$pak");
448 cleanup("tmp");
4d504812 449 copy("$Conf::dbdir/meta/meta-$pak","$Conf::dbdir/installed/");
1bd42c89
MT
450 message("Setup completed. Congratulations!");
451 } else {
452 message("Setup returned: $return. Sorry. Please search our forum to find a solution for this problem.");
453 exit $return;
454 }
a08c3a2e 455 return $return;
1bd42c89
MT
456}
457
99e6df8e 458sub upgradepak {
1bd42c89
MT
459 my $pak = shift;
460
99e6df8e 461 message("We are going to upgrade: $pak");
1bd42c89
MT
462
463 decryptpak("$pak");
464
99e6df8e
MT
465 my $return = system("cd $Conf::tmpdir && NAME=$pak ./update.sh >> $Conf::logdir/update-$pak.log 2>&1");
466 $return %= 255;
1bd42c89
MT
467 if ($return == 0) {
468 move("$Conf::tmpdir/ROOTFILES", "$Conf::dbdir/rootfiles/$pak");
469 cleanup("tmp");
99e6df8e
MT
470 copy("$Conf::dbdir/meta/meta-$pak","$Conf::dbdir/installed/");
471 message("Upgrade completed. Congratulations!");
1bd42c89
MT
472 } else {
473 message("Setup returned: $return. Sorry. Please search our forum to find a solution for this problem.");
474 exit $return;
475 }
8e58bd37 476 return $return;
1bd42c89
MT
477}
478
479sub removepak {
480 my $pak = shift;
481
482 message("We are going to uninstall: $pak");
483
484 decryptpak("$pak");
485
99e6df8e
MT
486 my $return = system("cd $Conf::tmpdir && NAME=$pak ./uninstall.sh >> $Conf::logdir/uninstall-$pak.log 2>&1");
487 $return %= 255;
1bd42c89
MT
488 if ($return == 0) {
489 open(FILE, "<$Conf::dbdir/rootfiles/$pak");
490 my @file = <FILE>;
491 close(FILE);
492 foreach (@file) {
493 my $line = $_;
494 chomp($line);
495 system("echo \"Removing: $line\" >> $Conf::logdir/uninstall-$pak.log 2>&1");
496 system("cd / && rm -rf $line >> $Conf::logdir/uninstall-$pak.log 2>&1");
497 }
498 unlink("$Conf::dbdir/rootfiles/$pak");
499 cleanup("tmp");
500 message("Uninstall completed. Congratulations!");
501 } else {
502 message("Setup returned: $return. Sorry. Please search our forum to find a solution for this problem.");
503 exit $return;
504 }
8e58bd37 505 return $return;
1bd42c89
MT
506}
507
508sub beautifysize {
509 my $size = shift;
a08c3a2e
MT
510 $size = $size / 1024;
511 my $unit;
1bd42c89
MT
512
513 if ($size > 1023) {
a08c3a2e
MT
514 $size = ($size / 1024);
515 $unit = "MB";
1bd42c89 516 } else {
a08c3a2e 517 $unit = "KB";
1bd42c89 518 }
a08c3a2e
MT
519 $size = sprintf("%.2f" , $size);
520 my $string = "$size $unit";
521 return $string;
1bd42c89
MT
522}
523
8e58bd37
MT
524sub makeuuid {
525 unless ( -e "$Conf::dbdir/uuid" ) {
8e58bd37
MT
526 open(FILE, "</proc/sys/kernel/random/uuid");
527 my @line = <FILE>;
528 close(FILE);
529
530 open(FILE, ">$Conf::dbdir/uuid");
531 foreach (@line) {
532 print FILE $_;
533 }
534 close(FILE);
535 }
536}
537
538sub senduuid {
99e6df8e 539 if ($pakfiresettings{'UUID'} ne "off") {
4b122800
MT
540 unless("$Conf::uuid") {
541 $Conf::uuid = `cat $Conf::dbdir/uuid`;
542 }
543 logger("Sending my uuid: $Conf::uuid");
544 fetchfile("cgi-bin/counter?ver=$Conf::version&uuid=$Conf::uuid", "$Conf::mainserver");
545 system("rm -f $Conf::cachedir/counter* 2>/dev/null");
8e58bd37 546 }
8e58bd37 547}
1bd42c89 548
5b2a12ff
MT
549sub lock {
550 my $status = shift;
551 if ("$status" eq "on") {
552 system("touch /opt/pakfire/pakfire.lock");
553 system("chmod 777 /opt/pakfire/pakfire.lock");
554 logger("Created lock");
555 } else {
556 if (system("rm -f /opt/pakfire/pakfire.lock >/dev/null 2>&1")) {
557 logger("Successfully removed lock.");
558 } else {
559 logger("Couldn't remove lock.");
560 }
561 }
562 return 0;
563}
564
cde0e116
MT
565sub checkcryptodb {
566 my $myid = "64D96617"; # Our own gpg-key
567 my $trustid = "65D0FD58"; # Id of CaCert
568 my $ret = system("gpg --list-keys | grep -q $myid");
569 unless ( "$ret" eq "0" ) {
570 message("The GnuPG isn't configured corectly. Trying now to fix this.");
571 system("gpg --keyserver wwwkeys.de.pgp.net --always-trust --recv-key $myid");
572 system("gpg --keyserver wwwkeys.de.pgp.net --always-trust --recv-key $trustid");
573 }
574}
575
1bd42c89 5761;