452 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			452 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/local/bin/perl
 | 
						|
# ==================================================================
 | 
						|
# Gossamer Links - enhanced directory management system
 | 
						|
#
 | 
						|
#   Website  : http://gossamer-threads.com/
 | 
						|
#   Support  : http://gossamer-threads.com/scripts/support/
 | 
						|
#   CVS Info : 087,071,086,086,085      
 | 
						|
#   Revision : $Id: setup.cgi,v 1.89 2009/05/08 19:56:50 brewt Exp $
 | 
						|
#
 | 
						|
# Copyright (c) 2001 Gossamer Threads Inc.  All Rights Reserved.
 | 
						|
# Redistribution in part or in whole strictly prohibited. Please
 | 
						|
# see LICENSE file for full details.
 | 
						|
# ==================================================================
 | 
						|
 | 
						|
use strict;
 | 
						|
use lib '/var/home/slowtwitch/slowtwitch.com/cgi-bin/articles/admin';
 | 
						|
use Links qw/$IN $CFG $DB %STASH/;
 | 
						|
use Links::SQL;
 | 
						|
 | 
						|
$| = 1;
 | 
						|
local $SIG{__DIE__} = \&Links::fatal;
 | 
						|
Links::init('/var/home/slowtwitch/slowtwitch.com/cgi-bin/articles/admin');
 | 
						|
Links::init_admin();
 | 
						|
 | 
						|
main();
 | 
						|
 | 
						|
sub main {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Main admin loop, displays html pages and other admin tasks.
 | 
						|
#
 | 
						|
 | 
						|
# Make sure we are only run from the web.
 | 
						|
    if (! defined $ENV{REQUEST_METHOD}) {
 | 
						|
        print "\nThis script can only be accessed from your browser.\n\n";
 | 
						|
        if ($CFG->{admin_root_url}) {
 | 
						|
            print "Try visiting:\n\t$CFG->{admin_root_url}/setup.cgi\n\n";
 | 
						|
        }
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
# If we don't have anything to do, and aren't setup yet, go to setup_first template.
 | 
						|
    if (! $IN->param('do') and ! $CFG->{setup}) {
 | 
						|
        $IN->param('do', 'page');
 | 
						|
        $IN->param('page', 'setup_first.html');
 | 
						|
    }
 | 
						|
 | 
						|
# If we can't find the admin templates, perhaps the path is screwed, try to
 | 
						|
# reset it.
 | 
						|
    if (! -e "$CFG->{admin_root_path}/templates/admin") {
 | 
						|
        die 'Configured admin path does not appear to be valid!';
 | 
						|
    }
 | 
						|
# Otherwise do the command or display the setup frameset.
 | 
						|
    my $action = $IN->param('do') || 'disp_home';
 | 
						|
    no strict 'refs';   my %subs = %{__PACKAGE__ . "::"}; use strict 'refs';
 | 
						|
 | 
						|
    if (exists $subs{$action}) {
 | 
						|
        $subs{$action}->();
 | 
						|
    }
 | 
						|
    elsif ($action eq 'page') {
 | 
						|
        Links::admin_page();
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        die "Invalid Request: '$action'";
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
sub setup_sql {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Change the sql server information.
 | 
						|
#
 | 
						|
    my ($host, $port, $output, $action, $ret);
 | 
						|
 | 
						|
    $action = $IN->param('action');
 | 
						|
    print $IN->header();
 | 
						|
    if ($action !~ /^create|overwrite|load$/) {
 | 
						|
        return Links::admin_page('setup_sql.html', [ $IN, { error => "Invalid action: '$action'" }]);
 | 
						|
    }
 | 
						|
 | 
						|
    $host = $IN->param('host');
 | 
						|
    ($host =~ s/\:(\d+)$//) and ($port = $1);
 | 
						|
 | 
						|
    my $prefix = $IN->param('prefix');
 | 
						|
    $prefix =~ /^\w*$/ or return Links::admin_page('setup_sql.html', [ $IN, { error => "Invalid prefix: '$prefix'. Can only be letters, numbers and underscore." } ]);
 | 
						|
 | 
						|
    $DB->prefix($prefix);
 | 
						|
    $ret = $DB->set_connect({
 | 
						|
        driver     => scalar $IN->param('driver'),
 | 
						|
        host       => $host,
 | 
						|
        port       => $port,
 | 
						|
        database   => scalar $IN->param('database'),
 | 
						|
        login      => scalar $IN->param('login'),
 | 
						|
        password   => scalar $IN->param('password'),
 | 
						|
        RaiseError => 0,
 | 
						|
        PrintError => 0
 | 
						|
    });
 | 
						|
    if (! defined $ret) {
 | 
						|
        return Links::admin_page('setup_sql.html', [$IN, { error => $GT::SQL::error }]);
 | 
						|
    }
 | 
						|
    if ($action eq 'create') {
 | 
						|
        $output = Links::SQL::tables('check');
 | 
						|
    }
 | 
						|
    elsif ($action eq 'overwrite') {
 | 
						|
        $output = Links::SQL::tables('force');
 | 
						|
# Create the admin user.
 | 
						|
        my $db   = $DB->table('Users');
 | 
						|
        my $pass = join '', map { chr(65 + rand 57) } 1 .. 8;
 | 
						|
        $db->insert({ Username => 'admin', Password => $pass, Email => $CFG->{db_admin_email}, ReceiveMail => 'No', Status => 'Administrator' });
 | 
						|
    }
 | 
						|
    elsif ($action eq 'load') {
 | 
						|
        $output = Links::SQL::load_from_sql();
 | 
						|
    }
 | 
						|
    Links::admin_page('setup_sql.html', [$IN, { message_pre => $output }]);
 | 
						|
}
 | 
						|
 | 
						|
sub setup_path {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Set the path information.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
    if ($IN->param('reset_defaults')) {
 | 
						|
        $CFG->default_path(0);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        _update_cfg();
 | 
						|
        if ($IN->param('update_others')) {
 | 
						|
            $CFG->{build_images_url}    = "$CFG->{build_root_url}/images";
 | 
						|
            $CFG->{build_css_url}       = "$CFG->{build_root_url}/links.css";
 | 
						|
            $CFG->{build_new_path}      = "$CFG->{build_root_path}/New";
 | 
						|
            $CFG->{build_new_url}       = "$CFG->{build_root_url}/New";
 | 
						|
            $CFG->{build_cool_path}     = "$CFG->{build_root_path}/Cool";
 | 
						|
            $CFG->{build_cool_url}      = "$CFG->{build_root_url}/Cool";
 | 
						|
            $CFG->{build_ratings_path}  = "$CFG->{build_root_path}/Ratings";
 | 
						|
            $CFG->{build_ratings_url}   = "$CFG->{build_root_url}/Ratings";
 | 
						|
            $CFG->{build_detail_path}   = "$CFG->{build_root_path}/Detailed";
 | 
						|
            $CFG->{build_detail_url}    = "$CFG->{build_root_url}/Detailed";
 | 
						|
        }
 | 
						|
    }
 | 
						|
    $CFG->save();
 | 
						|
    Links::admin_page('setup_path.html', [$IN, { message => "All paths and URL's have been updated successfully." }]);
 | 
						|
}
 | 
						|
 | 
						|
sub setup_build {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Set the build information.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
    if ($IN->param('reset_defaults')) {
 | 
						|
        $CFG->default_build(1);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        _update_cfg();
 | 
						|
    }
 | 
						|
 | 
						|
    $CFG->save();
 | 
						|
    Links::admin_page('setup_build.html', [$IN, { message => "All build options have been updated successfully." }]);
 | 
						|
}
 | 
						|
 | 
						|
sub setup_user {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Set the user information.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
    if ($IN->param('reset_defaults')) {
 | 
						|
        $CFG->default_user(1);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        _update_cfg();
 | 
						|
    }
 | 
						|
    $CFG->save();
 | 
						|
    Links::admin_page('setup_user.html', [$IN, { message => "All user options have been updated successfully." }]);
 | 
						|
}
 | 
						|
 | 
						|
sub setup_email {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Set the email information.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
    if ($IN->param('db_mail_path') and $IN->param('db_smtp_server')) {
 | 
						|
        Links::admin_page('setup_email.html', [$IN, { message => "You can not specify both an SMTP server and a path to sendmail!" }]);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if ($IN->param('reset_defaults')) {
 | 
						|
        $CFG->default_email(1);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        _update_cfg();
 | 
						|
    }
 | 
						|
    $CFG->save();
 | 
						|
    Links::admin_page('setup_email.html', [$IN, { message => "All email options have been updated successfully." }]);
 | 
						|
}
 | 
						|
 | 
						|
sub setup_search {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Set the email information.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
    if ($IN->param('reset_defaults')) {
 | 
						|
        $CFG->default_search(1);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        _update_cfg();
 | 
						|
    }
 | 
						|
    $CFG->save();
 | 
						|
    Links::admin_page('setup_search.html', [$IN, { message => "All search options have been updated successfully." }]);
 | 
						|
}
 | 
						|
 | 
						|
sub setup_review {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Set the review information.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
    if ($IN->param('reset_defaults')) {
 | 
						|
        $CFG->default_review(1);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        _update_cfg();
 | 
						|
    }
 | 
						|
    $CFG->save();
 | 
						|
    Links::admin_page('setup_review.html', [$IN, { message => "All review options have been updated successfully. " }]);
 | 
						|
}
 | 
						|
 | 
						|
sub setup_date {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Set the date information.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
    if ($IN->param('reset_defaults')) {
 | 
						|
        $CFG->default_date(1);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        _update_cfg();
 | 
						|
    }
 | 
						|
    $CFG->save();
 | 
						|
 | 
						|
# Reload the date module.
 | 
						|
    delete $STASH{date_loaded};
 | 
						|
    Links::init_date;
 | 
						|
    Links::admin_page('setup_date.html', [$IN, { message => "All date options have been updated successfully." }]);
 | 
						|
}
 | 
						|
 | 
						|
sub setup_misc {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Set the misc information.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
    if ($IN->param('reset_defaults')) {
 | 
						|
        $CFG->default_misc(1);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        _update_cfg();
 | 
						|
    }
 | 
						|
    $CFG->save();
 | 
						|
    Links::admin_page('setup_misc.html', [$IN, { message => "All misc options have been updated successfully." }]);
 | 
						|
}
 | 
						|
 | 
						|
sub setup_pass {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Creates the .htaccess/.htpasswd file.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
    my $htpasswd = $CFG->{admin_root_path} . "/.htpasswd";
 | 
						|
    my $htaccess = $CFG->{admin_root_path} . "/.htaccess";
 | 
						|
    unless (-w $htaccess and -w $htpasswd) {
 | 
						|
        Links::admin_page('setup_pass.html', [$IN, { error => "Sorry, but we don't have write access to the htaccess files: '$htaccess' and '$htpasswd'." }]);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    my $username  = $IN->param('admin_username');
 | 
						|
    my $password  = $IN->param('admin_password');
 | 
						|
    my $password2 = $IN->param('admin_password_confirm');
 | 
						|
    my $to_delete = $IN->param('delete') ? $IN->param('delete_user') : $username;
 | 
						|
 | 
						|
    if ($password and $password ne $password2) {
 | 
						|
        Links::admin_page('setup_pass.html', [$IN, { error => "Your passwords do not match." }]);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    my $fh = \do { local *FH; *FH };
 | 
						|
    open $fh, "< $htpasswd" or die "Unable to open '$htpasswd': $!";
 | 
						|
    my @lines = <$fh>;
 | 
						|
    close $fh;
 | 
						|
    @lines = grep ! /^\Q$to_delete\E:/, @lines if $to_delete;
 | 
						|
 | 
						|
    if ($username and $password) {
 | 
						|
        require GT::MD5::Crypt;
 | 
						|
        my $salt = join '', ('A' .. 'Z', 0 .. 9, 'a' .. 'z', '.', '/')[map rand 64, 1 .. 8];
 | 
						|
        my $crypted = GT::MD5::Crypt::apache_md5_crypt($password, $salt);
 | 
						|
        push @lines, "$username:$crypted\n";
 | 
						|
    }
 | 
						|
 | 
						|
    if (@lines and -z $htaccess) {
 | 
						|
        _create_htaccess($htaccess, $htpasswd);
 | 
						|
    }
 | 
						|
    elsif (!@lines and -s $htaccess) {
 | 
						|
        open $fh, "> $htaccess";
 | 
						|
        close $fh;
 | 
						|
    }
 | 
						|
 | 
						|
    open $fh, "> $htpasswd" or die "Unable to open '$htpasswd': $!";
 | 
						|
    print $fh @lines if @lines;
 | 
						|
    close $fh;
 | 
						|
 | 
						|
    Links::admin_page('setup_pass.html', [$IN, { message => "Your directory is now password protected. The next screen you visit, you should be prompted for a password." } ]);
 | 
						|
}
 | 
						|
 | 
						|
sub _create_htaccess {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Creates the htaccess file.
 | 
						|
#
 | 
						|
    my ($htaccess, $htpasswd) = @_;
 | 
						|
    open HTAC, "> $htaccess" or die "Unable to open '$htaccess': $!";
 | 
						|
    print HTAC <<HTACCESS;
 | 
						|
AuthUserFile   $htpasswd
 | 
						|
AuthGroupFile  /dev/null
 | 
						|
AuthType       Basic
 | 
						|
AuthName       Protected
 | 
						|
 | 
						|
require valid-user
 | 
						|
HTACCESS
 | 
						|
    close HTAC;
 | 
						|
}
 | 
						|
 | 
						|
sub init_setup {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Sets the mysql information.
 | 
						|
#
 | 
						|
    my ($host, $port, $overwrite);
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
# Test the ability to create a def file.
 | 
						|
    unless (open TEST, "> $CFG->{admin_root_path}/defs/database.def") {
 | 
						|
        return Links::admin_page('setup_second.html', [$IN, { error => <<HTML }]);
 | 
						|
Unable to create our def file in $CFG->{admin_root_path}/defs/. <br />
 | 
						|
Please make sure this directory exists, and is writeable by the server. <br />
 | 
						|
If this is the wrong directory, you will need to manually set the directory <br />
 | 
						|
in Links::Config::Data. Error was: $!
 | 
						|
HTML
 | 
						|
    }
 | 
						|
    close TEST;
 | 
						|
    unlink "$CFG->{admin_root_path}/defs/database.def";
 | 
						|
 | 
						|
# Set the connection info.
 | 
						|
    $overwrite = $IN->param('overwrite') ? 'force' : 'check';
 | 
						|
    $host = $IN->param('host');
 | 
						|
    ($host =~ s/\:(\d+)$//) and ($port = $1);
 | 
						|
 | 
						|
    my $prefix = $IN->param('prefix');
 | 
						|
    $prefix =~ /^\w*$/ or return Links::admin_page('setup_sql.html', [ $IN, { error => "Invalid prefix: '$prefix'. Can only be letters, numbers and underscore." } ]);
 | 
						|
 | 
						|
    $DB->prefix($prefix);
 | 
						|
    my $ret = $DB->set_connect({
 | 
						|
        driver     => scalar $IN->param('driver'),
 | 
						|
        host       => $host,
 | 
						|
        port       => $port,
 | 
						|
        database   => scalar $IN->param('database'),
 | 
						|
        login      => scalar $IN->param('login'),
 | 
						|
        password   => scalar $IN->param('password'),
 | 
						|
        RaiseError => 0,
 | 
						|
        PrintError => 0
 | 
						|
    });
 | 
						|
    if (! defined $ret) {
 | 
						|
        return Links::admin_page('setup_second.html', [$IN, { error => $GT::SQL::error }]);
 | 
						|
    }
 | 
						|
# Now let's create the tables.
 | 
						|
    eval { local $SIG{__DIE__}; require Links::SQL; };
 | 
						|
    if ($@) { return Links::admin_page('setup_second.html', [ $IN, { error => "Unable to load Links::SQL module: $@\n" }]); }
 | 
						|
 | 
						|
    my $output = Links::SQL::tables($overwrite);
 | 
						|
 | 
						|
# Update other paths and URL's.
 | 
						|
    $CFG->{build_css_url}       = "$CFG->{build_root_url}/links.css";
 | 
						|
    $CFG->{build_new_path}      = "$CFG->{build_root_path}/New";
 | 
						|
    $CFG->{build_new_url}       = "$CFG->{build_root_url}/New";
 | 
						|
    $CFG->{build_cool_path}     = "$CFG->{build_root_path}/Cool";
 | 
						|
    $CFG->{build_cool_url}      = "$CFG->{build_root_url}/Cool";
 | 
						|
    $CFG->{build_ratings_path}  = "$CFG->{build_root_path}/Ratings";
 | 
						|
    $CFG->{build_ratings_url}   = "$CFG->{build_root_url}/Ratings";
 | 
						|
    $CFG->{build_detail_path}   = "$CFG->{build_root_path}/Detailed";
 | 
						|
    $CFG->{build_detail_url}    = "$CFG->{build_root_url}/Detailed";
 | 
						|
    $CFG->{build_images_url}    = "$CFG->{build_root_url}/images";
 | 
						|
 | 
						|
# Create the admin user.
 | 
						|
    my $db   = $DB->table('Users');
 | 
						|
    my $pass = $db->random_pass;
 | 
						|
    $db->insert({ Username => 'admin', Password => $pass, Email => $CFG->{db_admin_email}, ReceiveMail => 'No', Status => 'Administrator' });
 | 
						|
 | 
						|
# And lets set sensible defaults for the rest of the config vars.
 | 
						|
    $CFG->create_defaults();
 | 
						|
 | 
						|
# And save the config.
 | 
						|
    $CFG->save();
 | 
						|
    Links::admin_page('setup_third.html', [ $IN, { message => "The data tables have been setup: <pre>$output</pre>" } ]);
 | 
						|
}
 | 
						|
 | 
						|
sub disp_home {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Display the home page.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
    Links::admin_page('setup.html', $IN);
 | 
						|
}
 | 
						|
 | 
						|
sub reset_setup {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Sets the cfg->{setup} to 0, and prints out the setup_first page.
 | 
						|
#
 | 
						|
    print $IN->header();
 | 
						|
 | 
						|
    $CFG->{setup} = 0;
 | 
						|
    $CFG->save;
 | 
						|
    Links::admin_page('setup_first.html', $IN);
 | 
						|
}
 | 
						|
 | 
						|
sub _update_cfg {
 | 
						|
# ------------------------------------------------------------------
 | 
						|
# Updates the config based on the form input.
 | 
						|
#
 | 
						|
    for my $param ($IN->param) {
 | 
						|
        next unless exists $CFG->{$param};
 | 
						|
        my $val = $IN->param($param);
 | 
						|
        if ($val eq 'custom' and my $custom = $IN->param("${param}_custom")) {
 | 
						|
            $CFG->{$param} = $custom;
 | 
						|
        }
 | 
						|
        elsif (ref $CFG->{$param} eq 'ARRAY') {
 | 
						|
            my @val = split /\s*[,\n]\s*/, $val;
 | 
						|
            $CFG->{$param} = \@val;
 | 
						|
        }
 | 
						|
        elsif (ref $CFG->{$param} eq 'HASH') {
 | 
						|
            my $h = {};
 | 
						|
            my @pairs = split /\s*[,\n]\s*/, $val;
 | 
						|
            foreach my $pair (@pairs) {
 | 
						|
                my ($k, $v) = split /\s*=>?\s*/, $pair;
 | 
						|
                $h->{$k} = $v;
 | 
						|
            }
 | 
						|
            $CFG->{$param} = $h;
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            $CFG->{$param} = $val;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |