#!/usr/bin/perl -wT #---------------------------------------------------------------------- # e-smith manager functions: navigation # # copyright (C) 2002 Mitel Networks Corporation # # 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 # # Technical support for this program is available from Mitel Networks # Please visit our web site www.e-smith.com for details. #---------------------------------------------------------------------- package esmith; use strict; use CGI ':no_xhtml', ':all'; use CGI::Carp qw(fatalsToBrowser); use esmith::cgi; use esmith::config; use esmith::ConfigDB; use esmith::util; use esmith::I18N; use esmith::db; sub determineGroup; sub showNavigation; sub logmeout; 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 # Use the one script for navigation and noframes my $NO_FRAMES = ($0 =~ /noframes/); my %conf; tie %conf, 'esmith::config'; my %accounts; tie %accounts, 'esmith::config', '/home/e-smith/db/accounts'; my $q = new CGI; showNavigation ($q); logmeout($q); exit (0); #------------------------------------------------------ # subroutine to print logout #------------------------------------------------------ sub logmeout { my $user = $ENV{'REMOTE_USER'}; print < $user Logout EOF } #------------------------------------------------------ # subroutine to determine which group a user belongs to #------------------------------------------------------ sub determineGroup { my ($user) = shift; # Group file for authentication my $group_file = '/etc/group'; open ( GF, $group_file ) or die "Cannot open group file: $group_file: $!\n"; # list of groups this user belongs to my @groupList; while () { if (/[:,]$user\b/) { my ($groupName, undef) = split(/:/); push @groupList, $groupName; } } close GF; return @groupList; } #------------------------------------------------------------ # subroutine to display navigation bar #------------------------------------------------------------ sub showNavigation { my $q = shift; my $acctName = $ENV{'REMOTE_USER'}; my @adminpanels; my $UserAlias = $conf{UserPanelAlias} || 'user'; my $availablePanels = db_get_prop(\%accounts, $acctName, 'AdminPanels') || ''; push (@adminpanels, split (/,/, $availablePanels, -1)); my $globalPanels = db_get_prop(\%accounts, 'globalUP', 'AdminPanels') || ''; push (@adminpanels, split (/,/, $globalPanels, -1)); foreach (determineGroup($acctName), 'shared') { my $gpanel = db_get_prop(\%accounts, $_, 'AdminPanels') || ''; push (@adminpanels, split (/,/, $gpanel, -1)); } # Use this variable throughout to keep track of files # list of just the files my $c = "1"; my @files = (); my %files_hash = (); #----------------------------------------------------- # Determine the directory where the functions are kept #----------------------------------------------------- my $navigation_ignore = "(\.\.?|navigation|noframes|online-manual|(internal|pleasewait)(-.*)?)"; 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 = (); use constant NAVIGATIONDIR => '/home/e-smith/db/navigation'; use constant WEBFUNCTIONS => '/etc/e-smith/web/functions'; my $i18n = new esmith::I18N; my $language = $i18n->preferredLanguage( $ENV{HTTP_ACCEPT_LANGUAGE} ); my $navinfo = NAVIGATIONDIR . "/navigation.$language"; my $navdb = esmith::ConfigDB->open_ro( $navinfo ) or die "Couldn't open $navinfo\n"; # Check the navdb for anything with a UrlPath, which means that it doesn't # have a cgi file to be picked up by the above code. Ideally, only pages # that exist should be in the db, but that's not the case. Anything # without a cgi file will have to remove themselves on uninstall from the # navigation dbs. foreach my $rec ($navdb->get_all) { if ($rec->prop('UrlPath')) { $files_hash{$rec->{key}} = $cgidir; } } foreach my $file (keys %files_hash) { my $heading = 'Unknown'; my $description = $file; my $headingWeight = 99999; my $descriptionWeight = 99999; my $urlpath = ''; my $rec = $navdb->get($file); if (defined $rec) { $heading = $rec->prop('Heading'); $description = $rec->prop('Description'); $headingWeight = $rec->prop('HeadingWeight'); $descriptionWeight = $rec->prop('DescriptionWeight'); $urlpath = $rec->prop('UrlPath') || ''; } #-------------------------------------------------- # 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; my @filename = split /\//, $files_hash{$file}; my $path = "/$UserAlias/$filename[scalar @filename - 1]"; push @{ $nav {$heading} {'DESCRIPTIONS'} }, { DESCRIPTION => $description, WEIGHT => $descriptionWeight, FILENAME => $urlpath ? $urlpath : "$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]; if ( $NO_FRAMES ) { esmith::cgi::genNoframesHeader ($q); } else { esmith::cgi::genNavigationHeader ($q, $#sortedheadings); print "\n\n"; } foreach $h (@sortedheadings) { if ( $NO_FRAMES ) { print $q->h2 ($h); } else { print "\n", $q->Tr ($q->td({class => "section"},$q->span({class => "section"}, $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" if ($NO_FRAMES); } unless ( $NO_FRAMES ) { print "\n
\n"; esmith::cgi::genNavigationFooter ($q); } } sub byweight { $esmith::weights [$a] <=> $esmith::weights [$b]; }