home *** CD-ROM | disk | FTP | other *** search
- package Debian::Defoma::Common;
-
- use strict;
- use POSIX;
- use Exporter;
- use FileHandle;
-
- use vars qw(@EXPORT @EXPORT_OK @ISA $ROOTDIR $DEFOMA_TEST_DIR
- $DEFAULT_PACKAGE $DEFAULT_CATEGORY);
-
- my ($Scriptdir, $Substruledir, $Homedir, $Lockfile, $Quiet, $Error, $Verbose,
- $Debug, $Userspace, @Scriptdirs, $Locale, $Login);
- my ($Defoma_Test_Dir, $Rootdir);
- my $Version = "0.10.0";
- my @Args;
- my @Options;
-
- BEGIN {
- @ISA = qw(Exporter);
- @EXPORT = qw(&printm &printw &printe &printv &printd &add_hash_list
- &parse_hints_start
- &parse_hints_cut &parse_hints_cut_except &parse_hints_build
- &parse_hints_subhints &parse_hints_subhints_inherit
- &get_xencoding &get_charset
- &weight_a2i &weight_ascii2integer
- &get_xlfd_of_font
- &app_readfile &app_writefile &app_symlink &app_unlink
- $DEFOMA_TEST_DIR $ROOTDIR
- &DEFOMA_TEST_DIR &ROOTDIR &USERSPACE &HOMEDIR &LOCALE
- &SCRIPTDIR &SUBSTRULEDIR &LOCKFILE &ERROR
- &SCRIPTDIRS &VERSION &ARGS &USERLOGIN &OPTIONS
- );
- @EXPORT_OK = qw(&mylock ®ister_id_object ®ister_subst_object
- &get_id_object &get_subst_object &get_system_categories
- &get_files &diff_files &arg_check &arg_check_category
- &readfile &writefile
- $DEFAULT_PACKAGE $DEFAULT_CATEGORY
- );
-
- $Quiet = 0;
- $Error = 0;
- $Verbose = 0;
- $Debug = 0;
- $Userspace = 0;
-
- my @unknown = ();
-
- @Args = @ARGV;
-
- while (@ARGV > 0 && $ARGV[0] =~ /^-/ && $ARGV[0] !~ /^--/) {
- my $options = shift(@ARGV);
- $options =~ s/^-//;
-
- my %h = (q => \$Quiet, t => \$Error, v => \$Verbose, d => \$Debug,
- u => \$Userspace);
-
- foreach my $option (split(//, $options)) {
- if (my $s = $h{$option}) {
- $$s = 1;
- push(@Options, '-' . $option);
- } else {
- push(@unknown, '-' . $option);
- }
- }
- }
-
- $Error = 1 - $Error;
-
- unshift(@ARGV, @unknown);
-
- $Defoma_Test_Dir = $DEFOMA_TEST_DIR = '';
- if ($Debug) {
- if (exists($ENV{'DEFOMA_TEST_DIR'})) {
- $Defoma_Test_Dir = $DEFOMA_TEST_DIR = $ENV{'DEFOMA_TEST_DIR'};
- }
-
- push(@Scriptdirs, "$DEFOMA_TEST_DIR/usr/local/share/defoma/scripts");
- }
-
- push(@Scriptdirs, "$DEFOMA_TEST_DIR/usr/share/defoma/scripts");
-
- if (exists($ENV{'LC_ALL'})) {
- $Locale = $ENV{'LC_ALL'};
- } elsif (exists($ENV{'LANG'})) {
- $Locale = $ENV{'LANG'};
- } else {
- $Locale = '';
- }
-
- $Homedir = '';
- if ($Userspace) {
- my @l = getpwuid($<);
- $Homedir = "$DEFOMA_TEST_DIR$l[7]";
- $Login = $l[0];
- $Rootdir = $ROOTDIR = "$Homedir/.defoma";
- } else {
- $Rootdir = $ROOTDIR = "$DEFOMA_TEST_DIR/var/lib/defoma";
- }
-
- $Substruledir = "$DEFOMA_TEST_DIR/etc/defoma";
- $Scriptdir = "$ROOTDIR/scripts";
- $Lockfile = "$ROOTDIR/locked";
-
- $DEFAULT_PACKAGE = $DEFAULT_CATEGORY = '';
- }
-
- sub OPTIONS {
- return @Options;
- }
-
- sub ARGS {
- return @Args;
- }
-
- sub DEFOMA_TEST_DIR {
- return $Defoma_Test_Dir;
- }
-
- sub ROOTDIR {
- return $Rootdir;
- }
-
- sub SCRIPTDIR {
- return $Scriptdir;
- }
-
- sub SCRIPTDIRS {
- return @Scriptdirs;
- }
-
- sub SUBSTRULEDIR {
- return $Substruledir;
- }
-
- sub HOMEDIR {
- return $Homedir;
- }
-
- sub LOCKFILE {
- return $Lockfile;
- }
-
- sub QUIET {
- return $Quiet;
- }
-
- sub ERROR {
- return $Error;
- }
-
- sub LOCALE {
- return $Locale;
- }
-
- sub USERSPACE {
- return $Userspace;
- }
-
- sub VERSION {
- return $Version;
- }
-
- sub USERLOGIN {
- return $Login;
- }
-
- sub printd {
- return unless ($Debug);
- my @c = caller(0);
-
- print STDERR $c[3], " at line ", $c[2], " in ", $c[1], ": ", @_, "\n";
- }
-
- sub printm {
- return if ($Quiet);
-
- print STDERR @_, "\n";
- }
-
- my $CALLERLEVEL = 0;
-
- sub printw {
- print "W: ", @_, "\n";
- }
-
- sub printe {
- print "E: ", @_, "\n";
- }
-
-
- sub printee {
- my @c = caller($CALLERLEVEL);
- $CALLERLEVEL = 0;
-
- print STDERR $c[3], " at line ", $c[2], " in ", $c[1], ": ", @_, "\n";
- }
-
- sub printv {
- return unless ($Verbose);
-
- print @_, "\n";
- }
-
- sub get_files {
- my $pattern = shift;
- my $directory = shift;
- my $i;
- my @caches = ();
- my @list;
-
- opendir(D, $directory) || return ();
- @list = readdir(D);
- closedir(D);
-
- foreach $i (@list) {
- if ($i =~ /$pattern/) {
- push(@caches, $i);
- }
- }
-
- return @caches;
- }
-
- sub diff_files {
- my $file1 = shift;
- my $file2 = shift;
-
- return 1 if ((-s $file1) != (-s $file2));
-
- my $err = system("/usr/bin/cmp", "-s", $file1, $file2);
- return $err;
- }
-
- sub arg_check {
- my @b = @_;
- while (@_ > 0) {
- my $s = shift;
- if ($s =~ /[ \t]/ || $s eq '') {
- $CALLERLEVEL = 2;
- printee "(", join(', ', @b), "): Illegal argument.";
- return 0;
- }
- }
-
- return 1;
- }
-
- sub arg_check_category {
- while (@_ > 0) {
- my $s = shift;
- if ($s !~ /^[A-Za-z0-9-]+$/) {
- $CALLERLEVEL = 2;
- printee "'$s': Illegal Category name.";
- return 0 ;
- }
- }
-
- return 1;
- }
-
- sub add_hash_list {
- my $hashptr = shift;
- my $key = shift;
- my $str = shift;
-
- if (exists($hashptr->{$key})) {
- $hashptr->{$key} .= ' ';
- } else {
- $hashptr->{$key} = '';
- }
-
- $hashptr->{$key} .= $str;
- }
-
- sub mylock {
- my $flag = 0;
- my $op = shift;
- my $bg = (@_ > 0) ? shift(@_) : '';
-
- if (USERSPACE) {
- mkdir(ROOTDIR) unless (-d ROOTDIR);
- mkdir(SCRIPTDIR) unless (-d SCRIPTDIR);
-
- if ((-e ROOTDIR && ! -d ROOTDIR) || -l ROOTDIR) {
- printe("Defoma-root-dir " . ROOTDIR . " is occupied.");
- exit ERROR;
- }
- if ((-e SCRIPTDIR && ! -d SCRIPTDIR) || -l SCRIPTDIR) {
- printe("Script-dir " . SCRIPTDIR . " is occupied.");
- exit ERROR;
- }
- }
-
- if ($op == 0) {
- unlink($Lockfile);
- } elsif ($op == 1) {
- symlink("locknow", $Lockfile) && return 0;
-
- printe("$Lockfile exists.");
- unless (USERSPACE) {
- printe("Another defoma process seems running, or you aren't root.");
- printe("If you are root and defoma process isn't running undoubtedly,");
- printe("it is possible that defoma might have aborted.");
- printe("Please run defoma-reconfigure -f to fix its broken status.");
- exit ERROR;
- } else {
- printe("Another defoma process seems running, or defoma might ".
- "have aborted.");
- printe("Please run defoma-user reconfigure to fix its broken status.");
- exit ERROR;
- }
- }
- }
-
- sub get_system_categories {
- # update defoma-reconfigure too.
- return ('x-postscript', 'postscript', 'xfont', 'pspreview', 'obsoleted');
- }
-
- ###### IdObject And SubstObject
-
- my %IdObject = ();
-
- sub register_id_object {
- my $o = shift;
- my $pkg = shift;
- my $suffix = shift;
-
- $IdObject{"$pkg/$suffix"} = $o;
- }
-
- sub get_id_object {
- my $pkg = shift;
- my $suffix = shift;
-
- if (exists($IdObject{"$pkg/$suffix"})) {
- return $IdObject{"$pkg/$suffix"};
- }
-
- return '';
- }
-
- sub clear_id_object {
- %IdObject = ();
- }
-
- my %SubstObject = ();
-
- sub register_subst_object {
- my $o = shift;
- my $rulename = shift;
-
- $SubstObject{$rulename} = $o;
- }
-
- sub get_subst_object {
- my $rulename = shift;
-
- if (exists($SubstObject{$rulename})) {
- return $SubstObject{$rulename};
- }
-
- return '';
- }
-
- sub clear_subst_object {
- %SubstObject = ();
- }
-
- ###### Parsehints
-
- sub parse_hints_start {
- my $ret = {};
- my $key = '';
- my $addflag = 0;
-
- foreach my $item (@_) {
- if ($item =~ /^--(.*)/) {
- if ($key && $addflag == 0) {
- $ret->{$key} = '';
- }
- $key = $1;
- $addflag = 0;
- } elsif ($key) {
- $addflag = 1;
- add_hash_list($ret, $key, $item);
- }
- }
-
- if ($key && $addflag == 0) {
- $ret->{$key} = '';
- }
-
- return $ret;
- }
-
- sub parse_hints_subhints {
- my $parsed = shift;
- my $subnum = shift;
- my $ret = {};
-
- $subnum = '' if ($subnum == 0);
-
- foreach my $k (keys(%{$parsed})) {
- if ($k =~ /(.*[^0-9-])-?$subnum$/) {
- $ret->{$1} = $parsed->{$k};
- }
- }
-
- return $ret;
- }
-
- sub parse_hints_subhints_inherit {
- my $parsed = shift;
- my $subnum = shift;
-
- my $ret = parse_hints_subhints($parsed, $subnum);
-
- return $ret if ($subnum == 0 || ! exists($parsed->{Inherit}));
-
- my @l = split(' ', $parsed->{Inherit});
-
- foreach my $k (@l) {
- unless (exists($ret->{$k})) {
- $ret->{$k} = $parsed->{$k};
- }
- }
-
- return $ret;
- }
-
- sub parse_hints_cut {
- my $parsed = shift;
- my $key;
-
- foreach $key (@_) {
- if (exists($parsed->{$key})) {
- delete($parsed->{$key});
- }
- }
- }
-
- sub parse_hints_cut_except {
- my $parsed = shift;
- my $key;
- my @l = keys(%{$parsed});
-
- foreach $key (@l) {
- unless (grep($_ eq $key, @_)) {
- delete($parsed->{$key});
- }
- }
- }
-
- sub parse_hints_build {
- my $parsed = shift;
- my $key;
- my @keys = keys(%{$parsed});
- my @ret = ();
-
- foreach $key (@keys) {
- push(@ret, '--' . $key);
- push(@ret, split(' ', $parsed->{$key}));
- }
-
- return @ret;
- }
-
- ###### File Handler ######
-
- sub readfile {
- my $file = shift;
- my $fh = new FileHandle($file, "r");
- my @ret = ();
-
- if (defined($fh)) {
- while (<$fh>) {
- chomp($_);
- push(@ret, $_);
- }
-
- $fh->close();
- }
-
- return @ret;
- }
-
- sub writefile {
- my $file = shift;
- my $fh = new FileHandle($file, "w");
-
- if (defined($fh)) {
- while (@_) {
- $fh->print(shift, "\n");
- }
-
- $fh->close();
- }
- }
-
- sub app_readfile {
- my $file = shift;
-
- return readfile("$Rootdir/$DEFAULT_PACKAGE.d/$file");
- }
-
- sub app_writefile {
- my $file = shift;
-
- return writefile("$Rootdir/$DEFAULT_PACKAGE.d/$file", @_);
- }
-
- sub app_symlink {
- my $src = shift;
- my $dest = shift;
-
- return symlink($src, "$Rootdir/$DEFAULT_PACKAGE.d/$dest");
- }
-
- sub app_unlink {
- my $file = shift;
-
- return unlink("$Rootdir/$DEFAULT_PACKAGE.d/$file");
- }
-
- ###### DataFile Handler ######
-
- my @XencData;
-
- sub read_csetenc_xenc_data {
- my $dir = shift;
- $dir .= "/csetenc-xenc.data2";
-
- unless (@XencData) {
- my @file = readfile($dir);
-
- while (@file) {
- my $a = shift(@file);
-
- next if ($a =~ /^\#/);
-
- my @l = split(/[ \t]+/, $a);
- next if (@l < 3);
-
- $l[0] =~ s/\*/\.\*/g;
- $l[0] =~ s/\?/\./g;
-
- $l[1] =~ s/\*/\.\*/g;
- $l[1] =~ s/\?/\./g;
-
- my $p = [];
- $p->[0] = $l[0];
- $p->[1] = $l[1];
- $p->[2] = $l[2];
-
- push(@XencData, $p);
- }
- }
- }
-
- sub get_xencoding {
- my $charset = shift;;
- my $encoding = shift || '';
-
- unless (@XencData) {
- read_csetenc_xenc_data("$DEFOMA_TEST_DIR/etc/defoma");
- read_csetenc_xenc_data("$DEFOMA_TEST_DIR/usr/share/defoma");
- }
-
- foreach my $i (@XencData) {
- if ($charset =~ /^($i->[0])$/ && $encoding =~ /^($i->[1])$/) {
- if ($i->[2] eq 'ignore' || $i->[2] eq 'none') {
- return '';
- } else {
- return $i->[2];
- }
- }
- }
-
- return '';
- }
-
- my @X2C;
-
- sub read_xenc_cset_file {
- my $dir = shift;
- $dir .= "/xenc-cset.data";
-
- my $i;
- my @l;
- my @file = readfile($dir);
-
- while (@file) {
- my $a = shift(@file);
-
- next if ($a =~ /^\#/);
-
- @l = split(' ', $a);
- if (@l >= 2) {
- $l[0] =~ s/\./\\./g;
- $l[0] =~ s/\*/\.*/g;
- $l[0] =~ s/\?/\./g;
-
- push(@X2C, $l[0], $l[1]);
- }
- }
- }
-
- sub get_charset {
- my $xfont = shift;
- my $i;
-
- unless (@X2C) {
- read_xenc_cset_file("$DEFOMA_TEST_DIR/etc/defoma");
- read_xenc_cset_file("$DEFOMA_TEST_DIR/usr/share/defoma");
- }
-
- $xfont =~ /([^-]+-[^-]+)$/;
- my $xenc = $1;
-
- for ($i = 0; $i < @X2C; $i += 2) {
- return $X2C[$i + 1] if ($xenc =~ /^($X2C[$i])$/);
- }
-
- return '';
- }
-
- ###### Weight -> Numeric ######
-
- my %Weight2Numeric = ( Medium => 0,
- Regular => 0,
- Normal => 0,
- Book => 0,
- UltraBold => 4,
- Ultrabold => 4,
- ExtraBold => 3,
- Extrabold => 3,
- Bold => 2,
- Semibold => 1,
- DemiBold => 1,
- Demibold => 1,
- ExtraLight => -3,
- Extralight => -3,
- Light => -2,
- SemiLight => -1,
- Semilight => -1);
-
- sub weight_a2i {
- my $weight = shift;
-
- return 0 unless ($weight);
-
- exists($Weight2Numeric{$weight}) && return $Weight2Numeric{$weight};
-
- $weight =~ tr/A-Z/a-z/;
- my @l = keys(%Weight2Numeric);
- foreach my $k (@l) {
- my $j = $k;
- $j =~ tr/A-Z/a-z/;
-
- return $Weight2Numeric{$k} if ($j eq $weight);
- }
-
- return 0;
- }
-
- sub weight_ascii2integer {
- return weight_a2i(@_);
- }
-
- ###### get XLFD from x-ttcidfont-conf database ######
-
- my ($XId, $XId2);
-
- sub get_xlfd_of_font {
- my $font = shift;
- my %op = @_;
-
- my $level = $op{level} || '';
- my $face = $op{face};
-
- unless ($XId) {
- my $pkg = 'x-ttcidfont-conf';
- $XId = &Debian::Defoma::Id::defoma_id_open_cache('', $pkg);
- $XId2 = &Debian::Defoma::Id::defoma_id_open_cache('sub', $pkg);
- return () unless ($XId && $XId2);
- }
-
- my @ret;
- my @l = &Debian::Defoma::Id::defoma_id_grep_cache($XId, 'real',
- font => $font);
- foreach my $i (@l) {
- next if ($XId->{2}->[$i] ne 'SrI');
-
- my @hints = split(' ', $XId->{7}->[$i]);
- my $ttcap = shift(@hints);
-
- if (defined($face)) {
- next if ($ttcap !~ /fn=$face/ && $ttcap !~ /:$face:/);
- }
-
- if ($level eq 'min') {
- next if ($ttcap =~ /ds=y/ || $ttcap =~ /ai=/);
- }
-
- push(@ret, $XId->{0}->[$i]);
- }
-
- if ($level eq 'max') {
- @l = &Debian::Defoma::Id::defoma_id_grep_cache($XId2, 'real',
- font => $font);
- foreach my $i (@l) {
- next if ($XId2->{2}->[$i] ne 'SrI');
-
- my @hints = split(' ', $XId2->{7}->[$i]);
- my $ttcap = shift(@hints);
-
- if (defined($face)) {
- next if ($ttcap !~ /fn=$face/ && $ttcap !~ /:$face:/);
- }
-
- push(@ret, $XId2->{0}->[$i]);
- }
- }
-
- return @ret;
- }
-
- package Debian::Defoma::Configure;
- use strict;
- #no strict 'subs';
- use POSIX;
- use File::Copy;
-
- use vars qw(@ISA $DEFAULT_PACKAGE $DEFAULT_CATEGORY
- @ACCEPT_CATEGORIES $APPINFO);
-
- use Debian::Defoma::Common;
- import Debian::Defoma::Common qw($DEFAULT_CATEGORY $DEFAULT_PACKAGE
- &get_files &diff_files &readfile &writefile);
-
-
- my %AppInfo = ();
- my %Initialized = ();
- my %Categories = ();
- my @DefaultPackage = ();
- my @DefaultCategory = ();
- my %OriginalScripts;
- my %RootScripts;
- my %FontTouchTime;
- my $UpdateTime;
-
- sub read_status_cache {
- my $rootdir = shift;
-
- %FontTouchTime = ();
- $UpdateTime = 0;
-
- my @file = readfile($rootdir . "/status-cache");
-
- while (@file) {
- my @l = split(' ', shift(@file));
-
- my $mode = shift(@l);
-
- if ($mode eq 'font-last-modified') {
- $FontTouchTime{$l[0]} = $l[1];
- } elsif ($mode eq 'app-ignore') {
- hash_app_info($l[0], 'ignore_category', $l[1], undef);
- } elsif ($mode eq 'app-subdirs') {
- push_app_info($l[0], 'subdirs', $l[1]);
- } elsif ($mode eq 'app-links') {
- push_app_info($l[0], 'links', $l[1].' '.$l[2]);
- } elsif ($mode eq 'defoma-last-run') {
- $UpdateTime = $l[0];
- }
- }
- }
-
- sub write_status_cache {
- my $time = time();
- my @file = ();
-
- foreach my $fobj (values(%Debian::Defoma::Font::Fobjs)) {
- my $c = $fobj->{category};
- my $t = ($fobj->{updated} || ! $FontTouchTime{$c}) ?
- $time : $FontTouchTime{$c};
-
- push(@file, "font-last-modified $c $t");
- }
-
- foreach my $app (keys(%AppInfo)) {
- if ($AppInfo{$app}->{ignore_category}) {
- foreach my $i (keys(%{$AppInfo{$app}->{ignore_category}})) {
- push(@file, "app-ignore $app $i");
- }
- }
- if ($AppInfo{$app}->{subdirs}) {
- foreach my $d (@{$AppInfo{$app}->{subdirs}}) {
- push(@file, "app-subdirs $app $d") if ($d ne '');
- }
- }
- if ($AppInfo{$app}->{links}) {
- foreach my $l (@{$AppInfo{$app}->{links}}) {
- push(@file, "app-links $app $l") if ($l ne '');
- }
- }
- }
-
- push(@file, "defoma-last-run $time");
-
- writefile(ROOTDIR . "/status-cache", @file);
- }
-
- sub set_app_info {
- my $app = shift;
- my $key = shift;
- my $value = shift;
-
- unless (exists($AppInfo{$app})) {
- $AppInfo{$app} = {};
- }
-
- $AppInfo{$app}->{$key} = $value;
- }
-
- sub push_app_info {
- my $app = shift;
- my $key = shift;
-
- unless (exists($AppInfo{$app})) {
- $AppInfo{$app} = {};
- }
-
- unless (exists($AppInfo{$app}->{$key})) {
- $AppInfo{$app}->{$key} = [];
- }
-
- push(@{$AppInfo{$app}->{$key}}, @_);
- }
-
- sub hash_app_info {
- my $app = shift;
- my $key = shift;
- my $hkey = shift;
- my $hvalue = shift;
-
- unless (exists($AppInfo{$app})) {
- $AppInfo{$app} = {};
- }
-
- unless (exists($AppInfo{$app}->{$key})) {
- $AppInfo{$app}->{$key} = {};
- }
-
- $AppInfo{$app}->{$key}->{$hkey} = $hvalue;
- }
-
- sub set_app_categories {
- my $app = shift;
-
- foreach my $i (@_) {
- $Categories{$i} = [] unless (exists($Categories{$i}));
- if ($app eq 'x-ttcidfont-conf' || $app eq 'psfontmgr') {
- unshift(@{$Categories{$i}}, $app);
- } else {
- push(@{$Categories{$i}}, $app);
- }
- }
-
- push_app_info($app, 'category', @_);
- }
-
- sub clear_app_info {
- my $app = shift;
-
- if (defined($app)) {
- delete($AppInfo{$app});
- } else {
- %AppInfo = ();
- }
- }
-
- sub get_app_info {
- my $app = shift;
-
- return $AppInfo{$app};
- }
-
- sub get_status {
- my $fonttouchtime = shift;
- my $updatetime = shift;
-
- %{$fonttouchtime} = %FontTouchTime;
- $$updatetime = $UpdateTime;
- }
-
- sub diff_scripts {
- foreach my $app (keys(%OriginalScripts), keys(%RootScripts)) {
- next if (exists($AppInfo{$app}->{script_change}));
-
- if (! $RootScripts{$app} && $OriginalScripts{$app}) {
- set_app_info($app, 'script_change', 'new');
- } elsif ($RootScripts{$app} && ! $OriginalScripts{$app}) {
- set_app_info($app, 'script_change', 'obsoleted');
- set_app_info($app, 'ignoreall', 1);
- printw("$app is already removed. ".
- "It is recommended to run defoma-app purge $app.");
- } else {
- if (diff_files($RootScripts{$app}, $OriginalScripts{$app})) {
- set_app_info($app, 'script_change', 'updated');
- set_app_info($app, 'ignoreall', 1);
- } else {
- set_app_info($app, 'script_change', 'same');
- }
- }
- }
-
- return 0;
- }
-
- sub init_scripts {
- # Check out /usr/share/defoma/scripts
-
- my $pat = (USERSPACE) ? "\\.udefoma\$" : "\\.defoma\$";
- my @scripts;
- my $script;
-
- %OriginalScripts = ();
-
- foreach my $dir (SCRIPTDIRS) {
- next unless (-d $dir);
-
- @scripts = get_files($pat, $dir);
-
- foreach $script (@scripts) {
- my $app = $script;
- $app =~ s/$pat//;
-
- unless (exists($OriginalScripts{$app})) {
- $OriginalScripts{$app} = "$dir/$script";
- }
- }
- }
-
- %RootScripts = ();
-
- @scripts = get_files($pat, SCRIPTDIR);
-
- foreach $script (@scripts) {
- my $app = $script;
- $app =~ s/$pat//;
-
- $RootScripts{$app} = SCRIPTDIR ."/$script";
- }
- }
-
- sub update_script {
- my $app = shift;
-
- my $suffix = (USERSPACE) ? "udefoma" : "defoma";
-
- unless (copy($OriginalScripts{$app}, SCRIPTDIR . "/$app.$suffix")) {
- printe("Failed to copy " . $OriginalScripts{$app} . "to " .
- SCRIPTDIR . ".");
- set_app_info($app, 'error', 1);
-
- return 1;
- }
-
- mkdir(ROOTDIR . "/$app.d");
-
- unless (-d ROOTDIR . "/$app.d") {
- printe("Failed to create application directory: " . ROOTDIR . ".");
- set_app_info($app, 'error', 1);
-
- return 1;
- }
-
- return 0;
- }
-
- sub remove_script {
- my $app = shift;
-
- my $suffix = (USERSPACE) ? "udefoma" : "defoma";
-
- unlink(SCRIPTDIR . "/$app.$suffix");
- }
-
- sub purge_script {
- my $app = shift;
-
- remove_script($app);
-
- rrm("$app.d") if (compare_version_app($app, "0.10") >= 0);
-
- links_purge($app);
-
- clear_app_info($app);
- }
-
- sub load_scripts {
- my $updateapp = shift || '';
-
- foreach my $app (keys(%AppInfo)) {
- if ($AppInfo{$app}->{script_change} eq 'new' && $app eq $updateapp) {
- # new script
- next if (update_script($app));
- }
-
- my $suffix = (USERSPACE) ? "udefoma" : "defoma";
- my $script = SCRIPTDIR . "/$app.$suffix";
-
- next unless (-f $script);
-
- @ACCEPT_CATEGORIES = ();
- undef $APPINFO;
- $APPINFO = {};
-
- eval('require($script);');
- if ($@) {
- printe("Unable to load: $script because:\n$@");
- set_app_info($app, 'error', 1);
- }
-
- if (compare_version_app($app, VERSION) > 0) {
- printe("$app.$suffix requires defoma ", $AppInfo{$app}->{require},
- " or later version while the installed version is ",
- VERSION, ".");
- set_app_info($app, 'error', 1);
-
- next;
- }
-
- if ($AppInfo{$app}->{script_change} eq 'new' && $app eq $updateapp &&
- compare_version_app($app, "0.10") >= 0) {
- # new script
- subdirs_update($app) && next;
- links_update($app) && next;
- }
-
- set_app_categories($app, @ACCEPT_CATEGORIES);
- # set_app_info($app, 'info', $APPINFO);
- }
- }
-
- sub init {
- read_status_cache(ROOTDIR);
-
- init_scripts();
-
- diff_scripts();
- }
-
- sub init2 {
- load_scripts(@_);
- write_status_cache();
- }
-
- sub term {
- my @list = keys(%Initialized);
- my ($i, $c, $a);
-
- foreach $i (@list) {
- $i =~ /(.*)\/(.*)/;
- $c = $1;
- $a = $2;
-
- push(@DefaultPackage, $DEFAULT_PACKAGE);
- push(@DefaultCategory, $DEFAULT_CATEGORY);
-
- $DEFAULT_PACKAGE = $a;
- $DEFAULT_CATEGORY = $c;
-
- $a =~ s/[^a-zA-Z0-9]/_/g;
- $c =~ s/[^a-zA-Z0-9]/_/g;
-
- eval("${a}::${c}('term')");
- printw("In ${a}::${c}('term'): ", $@) if ($@);
-
- $DEFAULT_PACKAGE = pop(@DefaultPackage);
- $DEFAULT_CATEGORY = pop(@DefaultCategory);
- }
-
- write_status_cache();
-
- foreach my $app (keys(%AppInfo)) {
- if ($AppInfo{$app}->{error}) {
- remove_script($app);
-
- printe("$app was excluded from configuration due to the error " .
- "in the header.");
- printe("Please perform the following things.");
- printe(" (1) run defoma-app purge $app.");
- printe(" (2) upgrade $app and/or defoma.");
- printe(" (3) run defoma-app update $app.");
- }
- }
-
- return 0;
- }
-
- sub subdirs_update {
- my $app = shift;
- my $pkgdir = ROOTDIR . "/$app.d";
-
- if ($APPINFO->{subdirs}) {
- if ($AppInfo{$app}->{subdirs}) {
- foreach my $dir (@{$AppInfo{$app}->{subdirs}}) {
- unless (grep($_ eq $dir, @{$APPINFO->{subdirs}})) {
- # obsoleted subdirectory
- rrm("$app.d/$dir");
- $dir = '';
- }
- }
- }
-
- foreach my $dir (@{$APPINFO->{subdirs}}) {
- if ($dir =~ /^\// || $dir =~ /\.\./) {
- printe("Illegal app subdirs: $pkgdir/$dir. ");
- set_app_info($app, 'error', 1);
- return 1;
- }
- unless (-d "$pkgdir/$dir") {
- # new subdirectory
- if (mkdirp("$pkgdir/$dir")) {
- printe("$pkgdir/$dir: mkdir failed. ");
- set_app_info($app, 'error', 1);
- return 1;
- }
-
- push_app_info($app, 'subdirs', $dir);
- }
- }
- } elsif ($AppInfo{$app}->{subdirs}) {
- foreach my $dir (@{$AppInfo{$app}->{subdirs}}) {
- # obsoleted subdirectory
- rrm("$app.d/$dir");
- $dir = '';
- }
- }
- }
-
- sub links_update {
- my $app = shift;
- my $pkgdir = ROOTDIR . "/$app.d";
-
- if ($APPINFO->{links}) {
- if ($AppInfo{$app}->{links}) {
- foreach my $links (@{$AppInfo{$app}->{links}}) {
- unless (grep($_ eq $links, @{$APPINFO->{links}})) {
- # obsoleted link
- my @l = split(' ', $links);
- unlink(DEFOMA_TEST_DIR . $l[1]);
- $links = '';
- }
- }
- }
-
- foreach my $links (@{$APPINFO->{links}}) {
- next if ($AppInfo{$app}->{links} &&
- grep($_ eq $links, @{$AppInfo{$app}->{links}}));
- # new link
-
- my @l = split(' ', $links);
-
- unless (@l == 2) {
- printe("$app contains illegal links in the header.");
- next;
- }
-
- my $src = $l[0];
- my $dest = DEFOMA_TEST_DIR . "$l[1]";
-
- if ($dest !~ /^\// || index($dest, ROOTDIR) != -1 ||
- $src =~ /^\// || $src =~ /\.\./) {
- printe("Illegal app links: $dest -> $pkgdir/$src. ");
- set_app_info($app, 'error', 1);
- return 1;
- }
-
- unless (symlink("$pkgdir/$src", $dest)) {
- printe("$dest -> $pkgdir/$src: symlink failed. ");
- set_app_info($app, 'error', 1);
- return 1;
- }
-
- push_app_info($app, 'links', $links);
- }
- } elsif ($AppInfo{$app}->{links}) {
- links_purge($app);
- }
- }
-
- sub links_purge {
- my $app = shift;
-
- if ($AppInfo{$app}->{links}) {
- foreach my $links (@{$AppInfo{$app}->{links}}) {
- my @l = split(' ', $links);
- unlink(DEFOMA_TEST_DIR . $l[1]);
- $links = '';
- }
- }
- }
-
- sub call_1 {
- my $fobj = shift;
- my $app = shift;
- my $com = shift;
- my $category = shift;
- my $font = shift;
-
- return 0 if ($AppInfo{$app}->{ignoreall});
- return 0 if ($AppInfo{$app}->{ignore_category} &&
- exists($AppInfo{$app}->{ignore_category}->{$category}));
-
- push(@DefaultPackage, $DEFAULT_PACKAGE);
- push(@DefaultCategory, $DEFAULT_CATEGORY);
-
- $DEFAULT_PACKAGE = $app;
- $DEFAULT_CATEGORY = $category;
-
- my $appi = $app;
- $appi =~ s/[^a-zA-Z0-9]/_/g;
- my $ctgi = $category;
- $ctgi =~ s/[^a-zA-Z0-9]/_/g;
-
- unless (exists($Initialized{"$category/$app"})) {
- $Initialized{"$category/$app"} = '';
- eval("${appi}::${ctgi}('init')");
- printw("In ${appi}::${ctgi}('init'): ", $@) if ($@);
- }
-
- my $ret = eval("${appi}::${ctgi}(\$com, \$font, \@_)");
- printw("In ${appi}::${ctgi}('$com', '$font', ...): ", $@) if ($@);
-
- $DEFAULT_PACKAGE = pop(@DefaultPackage);
- $DEFAULT_CATEGORY = pop(@DefaultCategory);
-
- if ($fobj && $com eq 'unregister') {
- if ($fobj->remove_failed($font, $app)) {
- return 0;
- }
- }
-
- if ($ret && $fobj && $com eq 'register') {
- $fobj->add_failed($font, $app, $ret);
- printv("$font: failed to register for package $app, status($ret).");
- }
-
- return $ret;
- }
-
- sub call_m {
- my $fobj = shift;
- my $com = shift;
- my $category = shift;
- my $font = shift;
-
- return unless (exists($Categories{$category}));
-
- foreach my $app (@{$Categories{$category}}) {
- call_1($fobj, $app, $com, $category, $font, @_);
- }
-
- return 0;
- }
-
- sub rrm {
- my $dir = shift;
- my $cwd = getcwd();
-
- chdir(ROOTDIR);
- return 1 unless (ROOTDIR eq getcwd());
- return 1 if ($dir =~ /^\// || $dir =~ /\.\./);
-
- system("/bin/rm", "-r", $dir) if (-e $dir);
-
- chdir($cwd);
-
- return 0;
- }
-
- sub mkdirp {
- my $dir = shift;
-
- my $dirs = '';
- foreach my $d (split('/', $dir)) {
- $dirs .= "/" . $d;
- next if (-d $dirs);
-
- mkdir($dirs) || return 1;
- }
-
- return 0;
- }
-
- sub compare_version {
- my @v1 = split(/\./, shift);
- my @v2 = split(/\./, shift);
-
- while (@v1 > 0 || @v2 > 0) {
- my $vv1 = (@v1 > 0) ? shift(@v1) : 0;
- my $vv2 = (@v2 > 0) ? shift(@v2) : 0;
-
- return -1 if ($vv1 < $vv2);
- return 1 if ($vv1 > $vv2);
- }
-
- return 0;
- }
-
- sub compare_version_app {
- my $app = shift;
-
- my $v = ($AppInfo{$app} && $AppInfo{$app}->{require}) ?
- $AppInfo{$app}->{require} : 0;
-
- return compare_version($v, shift);
- }
-
- sub get_app_categories {
- my $app = shift;
-
- return () unless (exists($AppInfo{$app}) &&
- exists($AppInfo{$app}->{category}));
- return @{$AppInfo{$app}->{category}};
- }
-
- sub get_apps {
- return keys(%AppInfo);
- }
-
- 1;
-