#!/usr/bin/perl -wT #---------------------------------------------------------------------- # user manager functions: noframes # # Copyright (c) 2001 Daniel van Raay # # 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #---------------------------------------------------------------------- package esmith; use strict; use CGI ':all'; use CGI::Carp qw(fatalsToBrowser); use esmith::cgi; use esmith::config; use esmith::util; use esmith::db; use esmith::AccountsDB; sub showNavigation ($); sub byweight; BEGIN { # Clear PATH and related environment variables so that calls to # external programs do not cause results to be tainted. See # "perlsec" manual page for details. $ENV {'PATH'} = ''; $ENV {'SHELL'} = '/bin/bash'; delete $ENV {'ENV'}; } esmith::util::setRealToEffective (); $CGI::POST_MAX=1024 * 100; # max 100K posts $CGI::DISABLE_UPLOADS = 1; # no uploads my %conf; tie %conf, 'esmith::config'; my %accounts; tie %accounts, 'esmith::config', '/home/e-smith/db/accounts'; my $a = esmith::AccountsDB->open_ro || die "Error opening AccountsDB\n"; my $q = new CGI; showNavigation ($q); exit (0); #------------------------------------------------------------ # subroutine to display navigation bar #------------------------------------------------------------ sub showNavigation ($) { my $q = shift; esmith::cgi::genNoframesHeader ($q); my $acctName = $ENV{'REMOTE_USER'}; my $user = $a->get($acctName) || die "User $acctName not found in AccountsDB\n"; my $availablePanels = $user->prop('AdminPanels') || ''; foreach ($a->user_group_list($acctName)){ my $group = $a->get($_) || die "Group $_ not found in AccountsDB\n"; $availablePanels .= ','.$group->prop('AdminPanels') || ''; } my $glob = $a->get('globalUP'); my $globalPanels = $glob->prop('AdminPanels') || ''; my @adminpanels; if ( defined ($availablePanels) && defined ($globalPanels) ) { @adminpanels = ((split (/,/, $availablePanels, -1)),(split (/,/, $globalPanels, -1))); } elsif ( defined ($globalPanels) ) { @adminpanels = split (/,/, $globalPanels, -1); } elsif ( defined ($availablePanels) ) { @adminpanels = split (/,/, $availablePanels, -1); } # Use this variable throughout to keep track of files # list of just the files my @files = (); my %files_hash = (); #----------------------------------------------------- # Determine the directory where the functions are kept # match available panels with delegated panels to this user #----------------------------------------------------- my $cgidir = '/etc/e-smith/web/panels/user/cgi-bin/'; if (opendir (DIR, $cgidir)) { @files = grep (!/^(\..*|userpanel-navigation|userpanel-noframes|userpanel-initial|pleasewait)$/, readdir (DIR)); closedir (DIR); } else { warn "Can't open directory $cgidir\n"; } foreach my $file (@files) { foreach my $adminpanel (@adminpanels) { if ( $file eq $adminpanel ) { $files_hash{$file} = $cgidir; } } } #-------------------------------------------------- # For each script, extract the description and category # information. Build up an associative array mapping headings # to heading structures. Each heading structure contains the # total weight for the heading, the number of times the heading # has been encountered, and another associative array mapping # descriptions to description structures. Each description # structure contains the filename of the particular cgi script # and a weight. #-------------------------------------------------- my %nav = (); foreach my $file (keys %files_hash) { #-------------------------------------------------- # extract heading, description and weight information # from CGI script #-------------------------------------------------- my $heading = "Unknown"; my $headingWeight = 0; my $description = "Unknown"; my $descriptionWeight = 0; unless (open (RD, "$files_hash{$file}/$file")) { warn "Can't open file $files_hash{$file}/$file: $!\n"; next; } while () { if (/^\s*#\s*heading\s*:\s*(.+?)\s*$/) { $heading = $1; } if (/^\s*#\s*description\s*:\s*(.+?)\s*$/) { $description = $1; } if (/^\s*#\s*navigation\s*:\s*(\d+?)\s+(\d+?)\s*$/) { $headingWeight = $1; $descriptionWeight = $2; } last if ($heading ne "Unknown" && $headingWeight && $description ne "Unknown" && $descriptionWeight); } close RD; #-------------------------------------------------- # add heading, description and weight information to data structure #-------------------------------------------------- unless (exists $nav {$heading}) { $nav {$heading} = { COUNT => 0, WEIGHT => 0, DESCRIPTIONS => [] }; } $nav {$heading} {'COUNT'} ++; $nav {$heading} {'WEIGHT'} += $headingWeight; # Check for manager panel, and assign the appropriate # cgi-bin prefix for the links. # Grab the last 2 directories by splitting for '/'s and # then concatenating the last 2 # probably a better way, but I don't know it. my @filename = split /\//, $files_hash{$file}; my $path = "/user-manager/$filename[scalar @filename - 1]"; push @{ $nav {$heading} {'DESCRIPTIONS'} }, { DESCRIPTION => $description, WEIGHT => $descriptionWeight, FILENAME => "$path/$file", CGIPATH => $path }; } #-------------------------------------------------- # generate list of headings sorted by average weight #-------------------------------------------------- my @unsortedheadings = keys %nav; my $h; local @esmith::weights = (); foreach $h (@unsortedheadings) { push (@esmith::weights, ($nav {$h} {'WEIGHT'} / $nav {$h} {'COUNT'})); } my @sortedheadings = @unsortedheadings [sort byweight $[..$#unsortedheadings]; foreach $h (@sortedheadings) { print $q->h2 ($h); #-------------------------------------------------- # generate list of descriptions sorted by weight #-------------------------------------------------- my @unsorteddescriptions = @{ $nav {$h} {'DESCRIPTIONS'} }; my $d; @esmith::weights = (); foreach $d (@unsorteddescriptions) { push (@esmith::weights, $d->{'WEIGHT'}); } my @indices = sort byweight $[..$#unsorteddescriptions; print "\n"; } esmith::cgi::genNavigationFooter ($q); } sub byweight { $esmith::weights [$a] <=> $esmith::weights [$b]; }