TIP emerge only free software packages(so you don't have non-free dependencies)
From Gentoo Linux Wiki
Contents |
[edit] Rationale
Unlike most of the Linux distributions (Portage doesn't), by default, differentiate free and non-free packages and dependencies. The problem is that even if you know that the package isn't free, the non-free dependencies can be installed. So that's a problem for the ones that care about free software or just want only free software for security reasons.
[edit] Solutions
There are at least 3 solutions to that problem:
- switch to Paludis
- switch to Pkgcore
- use licenses2kill.sh (download) (forums)
- use license-checker (download (homepage)
- use my perl script to mask the non-free packages
[edit] selinux
Selinux support is not present in pkgcore but is present in portage and paludis: from #paludis irc:
selinux is supported far enough that files merged by paludis will be labeled properly
[edit] others
for some others reasons(please add them here) one could want to use portage instead op paludis and pkgcore
[edit] the script
[edit] Features
[edit] Limitations
- others repositories than the main portage tree(overlays,layman),even if you have layman it will work but it will only mask the files from the main portage tree...the reason why it is not supported is because the script would have to go in each eclass directory of each layman repository
- badly written(not object programming)
- you must execute the script after each time you sync portage and remove the old masked packages
- doesn't support the full portage's syntax so when it look inside the perl ebuilds the || is not supported and it fails to classify them as free software cause it finds the artistic license which is not free
[edit] Features
- support for licences that are not inside the ebuild but inside the eclass
[edit] dependencies
- dev-perl/List-MoreUtils
- use File::Find () that is included in perl
- the following files:
[edit] Installation
you must create a folder named files under the directory where is the sctipt and put all the files mentioned above inside in order to make the script run. by the way...don't forget to make the script executable with chmod +x
[edit] how to run the script?
the script output to a file...just give him the name of the file to output to:
./licence-masker ./files/masked_packages.txt
[edit] The script
#!/usr/bin/perl # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' # if 0; #$running_under_some_shell use strict; use warnings; use File::Find (); use List::MoreUtils qw(any none); our $PORTDIR; if ($ENV{PORTDIR}) { $PORTDIR = $ENV{PORTDIR}; } else { $PORTDIR = "/usr/portage/"; } our $LAYMAN = "$PORTDIR/local/layman/"; our $OVERLAY='/usr/overlay/'; our @directories = ($PORTDIR,$LAYMAN,$OVERLAY); our $SETTINGS = "$ENV{HOME}/.portage/"; our @EBUILDS; our %LICENSES; our ($OUTPUT_FILE) = @ARGV; unless (-e $SETTINGS) { print "creating $ENV{HOME}/.portage\n"; mkdir "$ENV{HOME}/.portage"; } our $LICENSE_DIR = "$PORTDIR/licenses/"; our @GLOBAL; my ($key,$value); my $i; my $line2; our $GPL_COMPATIBLE = 'files/gpl_compatible'; our $GPL_INCOMPATIBLE = 'files/gpl_incompatible'; our $DOCUMENTATION = 'files/free_documentation_licenses'; our $FONTS = 'files/licenses_for_fonts'; our $OTHERS = 'files/licenses_for_works_besides_software_and_documentation'; open (GPL_COMPATIBLE , "$GPL_COMPATIBLE"); open (GPL_INCOMPATIBLE , "$GPL_INCOMPATIBLE"); open (DOCUMENTATION , "$DOCUMENTATION"); open (FONTS , "$FONTS"); open (OTHERS , "$OTHERS"); open (OUTPUT_FILE,">>$OUTPUT_FILE"); our @FREE_SOFTWARE; our @PROPRIETARY_SOFTWARE; our $line; my $foreach; unless (@ARGV) { die "usage: ./license_masker Path_to_The_mask_file"; } $line = shift; while ($line = <GPL_COMPATIBLE>){ $line =~ s /\#(.*)//; #wipe out comments $line =~ s /\s+//; #wipe out spaces(the licences are files and there is no space in them...) chomp $line; next if (!$line); #go to the beguining if $line is empty print "$line\n"; push (@FREE_SOFTWARE,$line); } $line = shift; while ($line = <GPL_INCOMPATIBLE>){ $line =~ s /\#(.*)//; #wipe out comments $line =~ s /\s+//; #wipe out spaces(the licences are files and there is no space in them...) chomp $line; next if (!$line); #go to the beguining if $line is empty print "$line\n"; push (@FREE_SOFTWARE,$line); } $line = shift; while ($line = <DOCUMENTATION>){ $line =~ s /\#(.*)//; #wipe out comments $line =~ s /\s+//; #wipe out spaces(the licences are files and there is no space in them...) chomp $line; next if (!$line); #go to the beguining if $line is empty print "$line\n"; push (@FREE_SOFTWARE,$line); } $line = shift; while ($line = <FONTS>){ $line =~ s /\#(.*)//; #wipe out comments $line =~ s /\s+//; #wipe out spaces(the licences are files and there is no space in them...) chomp $line; next if (!$line); #go to the beguining if $line is empty print "$line\n"; push (@FREE_SOFTWARE,$line); } $line = shift; while ($line = <OTHERS>){ $line =~ s /\#(.*)//; #wipe out comments $line =~ s /\s+//; #wipe out spaces(the licences are files and there is no space in them...) chomp $line; next if (!$line); #go to the beguining if $line is empty print "$line\n"; push (@FREE_SOFTWARE,$line); } # %LICENSES = (map { $_ => "FreeSoftware"} @FREE_SOFTWARE ); # my ($key,$value); # while ( ($key, $value) = each %LICENSES) { # print "$key = $value\n"; # } opendir(DIR, $LICENSE_DIR) or die "can’t opendir $LICENSE_DIR: $!"; our @LICENCES_FILES = readdir(DIR); @LICENCES_FILES = File::Spec->no_upwards( @LICENCES_FILES ); %LICENSES = (map { $_ => "Proprietary"} @LICENCES_FILES ); #($key,$value) = shift; while ( ($key, $value) = each %LICENSES) { $LICENSES{$key} = "FreeSoftware" if any { $key eq $_ } @FREE_SOFTWARE; #if $key eq any element of @FREE_SOFTWARE it push the license beeing free software into the hash } # ($key,$value) = shift; while ( ($key, $value) = each %LICENSES) { print 'key/value',"$key, $value\n"; push(@PROPRIETARY_SOFTWARE,$key) if none { $key eq $_ } @FREE_SOFTWARE; #if $key ne any element of @FREE_SOFTWARE it push the license beeing proprietary software into the array } my $proprietary_loop_test; foreach $proprietary_loop_test(@PROPRIETARY_SOFTWARE) { print '@PROPRIETARY_SOFTWARE: ',"$proprietary_loop_test\n"; } # ($key,$value) = shift; while ( ($key, $value) = each %LICENSES) { print "HASH: $key = $value\n"; } #open the dir #push evrything to licences # $LICENCES{"$key"} = "FreeSoftware" if any { !defined($_) } @FREE_SOFTWARE; # Set the variable $File::Find::dont_use_nlink if you're using AFS, # since AFS cheats. # for the convenience of &wanted calls, including -eval statements: use vars qw/*name *dir *prune/; *name = *File::Find::name; *dir = *File::Find::dir; *prune = *File::Find::prune; sub wanted; # Traverse desired filesystems # File::Find::find(\&wanted, @directories); File::Find::find(\&wanted, "$PORTDIR"); sub wanted { my ($dev,$ino,$mode,$nlink,$uid,$gid); (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && /^.*\.ebuild\z/si && push (@EBUILDS,$name); } my $ebuilds; @EBUILDS = map { $EBUILDS[$_] !~ m/local\/layman/ ? $EBUILDS[$_] : () } 0 .. $#EBUILDS; our $LICENSE; our @LICENSE; our $COMBINED; $ebuilds = shift; foreach $ebuilds (@EBUILDS) { open (EBUILDS_FILES ,"$ebuilds"); $line = shift; while ($line = <EBUILDS_FILES>) { # print "$line\n"; $line =~ m /LICENSE="(.*)"/; $LICENSE = $1; } if ($ebuilds and $LICENSE) { print "$ebuilds;$LICENSE\n"; } elsif($ebuilds) { print "$ebuilds do not have a license...mabe look in the eclass\n"; } else { print "array corruption\n"; } push (@LICENSE,$LICENSE); } # @EBUILDS = map { $LICENSE[$_] eq 'GPL-2' ? $EBUILDS[$_] : () } 0 .. $#EBUILDS; @GLOBAL =map { {ebuild => $EBUILDS[$_], license => $LICENSE[$_], freedom => "Proprietary"}}0..$#EBUILDS; $i = shift; my $inherit; our @inherit; my $eclass_license; for $i (0..$#EBUILDS){ unless ($GLOBAL[$i]{license}){ open (EBUILDS_NO_LICENSE ,"$GLOBAL[$i]{ebuild}"); $line = shift; while ($line = <EBUILDS_NO_LICENSE>) { $line =~ s /\#(.*)//; $line =~ m /inherit(.*)/; $inherit = $1; } print "inherit:$GLOBAL[$i]{ebuild}: $inherit\n"; @inherit = split / /,$inherit; $foreach = shift; foreach $foreach(@inherit){ print "inherit2: $foreach \n"; open (ECLASS,"$PORTDIR/eclass/$foreach.eclass"); $line2 = shift; while ($line2 = <ECLASS>) { $line2 =~ s /\#(.*)//; # $1 = shift; if ($line2 =~ m /LICENSE="(.*)"/){ # $line2 =~ m /LICENSE="(.*)"/; $eclass_license = $1; } } } if ($eclass_license) { print "inherit3: $GLOBAL[$i]{ebuild} is $GLOBAL[$i]{license}\n"; $GLOBAL[$i]{license} = $eclass_license; } } } #identify the ebuilds that are free software matching their licences to @FREE_SOFTWARE that contain all the licenses that are free software $i = shift; for $i (0..$#EBUILDS){ # $GLOBAL[$i]{freedom} = "FreeSoftware" if any { $GLOBAL[$i]{license} eq $_ } @FREE_SOFTWARE; $GLOBAL[$i]{freedom} = "FreeSoftware" if none { $GLOBAL[$i]{license} =~ /$_/ } @PROPRIETARY_SOFTWARE; $i++; } $i = shift; for $i (0..$#EBUILDS){ if ($GLOBAL[$i]{license}){ print "GLOBAL: $GLOBAL[$i]{ebuild} ;$GLOBAL[$i]{license}; $GLOBAL[$i]{freedom}\n"; } else { print "GLOBAL: $GLOBAL[$i]{ebuild} has no license...so we assume that it's $GLOBAL[$i]{freedom}\n"; } $i++; } #testing purpose only # my $numbers_of_gpl = grep (/^GPL-2$/, @LICENSE); # our $i = shift; # for $i (reverse 0..($numbers_of_gpl -1)) { # # if ($LICENSE[$i] ne "GPL-2" ){ # # splice (@LICENSE,$i,1); # splice (@EBUILDS,$i,1); # } # else { # $i++; # } # } # ti # for (0..$#EBUILDS) { # if ($LICENSE[$_] eq 'GPL-2') { # print "forlooptest: ",$EBUILDS[$_]; # } # } # the numbers of elements in the array -1 # @ebuilds = # @EBUILDS = map { notall { $LICENSE($_) } @FREE_SOFTWARE ? $EBUILDS[$_] : () } 0 .. $#EBUILDS; # our @EBUILD_FILTERED; # $i = shift; # for $i (0..$#EBUILDS) { # my $filtered_ebuild =$EBUILDS[$i] if any {$LICENSE[$i] eq $_} @FREE_SOFTWARE; # push (@EBUILD_FILTERED,$filtered_ebuild); # } # # @EBUILDS = map {$LICENSE[$_] @FREE_SOFTWARE } # print "No value defined" if notall { defined($_) } @FREE_SOFTWARE; # # my $foreach; # my $PROPRIETARY_LICENSE; # # foreach $foreach (@EBUILDS){ # # open (EBUILDS_FILES_LICENSE ,"$foreach"); # $line = shift; # while ($line = <EBUILDS_FILES_LICENSE>) { # # print "$line\n"; # $line =~ m /LICENSE="(.*)"/; # $PROPRIETARY_LICENSE = $1; # } # if ($PROPRIETARY_LICENSE) { # print "PROPRIETARY: $foreach ; $PROPRIETARY_LICENSE \n"; # } # else { # print "PROPRIETARY: $foreach has no license\n"; # # } # # } $i = shift; for (0..$#GLOBAL) { if ($GLOBAL[$i]{freedom} eq "Proprietary"){ if ($GLOBAL[$i]{license}){ print "PROPRIETARY: $GLOBAL[$i]{ebuild} ;$GLOBAL[$i]{license}; $GLOBAL[$i]{freedom}\n"; my $output = ebuild_transformation($GLOBAL[$i]{ebuild}); print OUTPUT_FILE "$output\n"; } else { print "PROPRIETARY: $GLOBAL[$i]{ebuild} has no license...so we assume that it's $GLOBAL[$i]{freedom}\n"; } } $i++; } sub ebuild_transformation { my ($ebuild_path) = @_; print '@_:',"$ebuild_path\n"; #exemple #/usr/portage/media-fonts/dejavu/dejavu-2.19.ebuild #media-fonts/dejavu-2.19.ebuild #first remocve the /usr/portage: $ebuild_path =~ s/$PORTDIR//; print 'without portdir:',"$ebuild_path\n"; #then remove the .ebuild $ebuild_path =~ s/.ebuild//; print 'without .ebuild:',"$ebuild_path\n"; #$LICENSE[$_] eq 'GPL-2' ? $EBUILDS[$_] : () # $ebuild_path = ($ebuild_path =~ m/^(.*)\/(.*)\/(.*)$/ ? "=$1/$3" : print "error... incorect ebuild path"); if ($ebuild_path =~ m/^(.*)\/(.*)\/(.*)$/){ $ebuild_path = "=$1/$3"; } else { print "error... incorect ebuild path \n"; } print '$ebuild_path: ',"$ebuild_path\n"; return $ebuild_path; } #create a hash of licences with # GPL-2 => FreeSoftware # as-is => Proprietary # nothing => Proprietary # # my $ebuild_numbers_gpl_only = @EBUILDS; # # $i = shift; # for $i (0..($ebuild_numbers_gpl_only - 1)) { # if ($EBUILDS[$i] and $LICENSE[$i]){ # print "onlygpl:","$EBUILDS[$i]"," is ","$LICENSE[$i]\n"; # } # elsif ($EBUILDS[$i]) { # print "warning $EBUILDS[$i] has no license...it muse be in the eclass\n"; # } # else { # print "we have a huge problem:array corruption\n"; # } # # # } # # # # # # ############################################################################################################################## #match for the licence instead of eq because of that: #GPL-2 LGPL-2; Proprietary =>proprietary if there is a proprietary licence in it such as madwifi as-is #|| ( Artistic GPL-2 ); Proprietary =>free because there is a || #split the licences in case there are multiple licences... #problem with the overays inherit...there aren't in the same place... #need to match non free software because of LL-GPL # while ( ($key, $value) = each %LICENSES) { # #push(@PROPRIETARY_SOFTWARE,$key) if none { $value ne $_ } @FREE_SOFTWARE; # push(@PROPRIETARY_SOFTWARE,$key) if none { $key eq $_ } @FREE_SOFTWARE; # } # in order to decide what ebuild is free software we match non free licences... # for instance "atheros-hal || ( BSD GPL-2 )" will match atheros-hal and so it will be identificated as free software # match is used because otherwise we have to parse the syntax such as || and similar # =>problem with ||(GPL PROPRIETARY)
