$versions{'store_admin_actions.pl'} = '06.6.00.0000';

#######################################################################
# This file contains the action logic for the store admin program
#######################################################################
#
# AgoraCart and all associated files, except where noted, are
# Copyright 2001 to Present jointly by K-Factor Technologies, Inc.
# and by C E Mayo (aka Mister Ed) at AgoraCart.com & K-Factor.net
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This copyright notice may not be removed or altered in any way.
#
#######################################################################

sub upcase {
local ($string) = @_;
$string =~ tr/a-z/A-Z/;
return $string;
}

#######################################################################

sub downcase {
local ($string) = @_;
$string =~ tr/A-Z/a-z/;
return $string;
}

#######################################################################

sub register_extension {
local ( $name, $description, $version ) = @_;
local ($continue) = q{};
codehook( 'register-manager-extension' );
if ( $continue eq 'no' ) { return; }
$manager_ext_desc{$name}    = $description;
$manager_ext_version{$name} = $version;
}

#######################################################################

sub register_menu {
# link the incoming POST info to a subroutine to process it
local ( $name, $action_subroutine, $module, $description ) = @_;
local ($continue) = q{};
codehook( 'register-manager-menu-item' );
if ( $continue eq 'no' ) { return; }
if ( $description eq '' ) {
$description = $action_subroutine;
$description =~ s/\_/\ /g;
}
$menu_items{$name}        = $action_subroutine;
$menu_items_module{$name} = $module;
$menu_items_desc{$name}   = $description;
}

#######################################################################

sub std_action_process_login {
    if ( $in{'username'} eq "$username" && $in{'password'} eq "$password" ) {
        update_ip_ok();
        if ( ( $mc_use_cookie_login =~ /yes/ ) && ( $mc_have_cookie =~ /no/ ) ) {
            $other_welcome_message .= qq{<br><br><FONT COLOR=RED>$mgr_cookies_not_found</FONT>};
        }
        elsif ( $mc_use_cookie_login !~ /yes/ ) {
            $other_welcome_message .= qq{<br><br><FONT COLOR=RED>$mgr_cookies_not_enabled</FONT>};
        }
    }
    else {
        require_supporting_libraries( __FILE__, __LINE__, "$mgrcoredir/login_page_mgr.pl" );
        $mc_login_err = $mgr_session_user_mismatch_error;
        display_login($mc_login_err);
        call_exit();
    }
}

#######################################################################

sub update_ip_ok {
local (@lines);
#added by Mister Ed July 2009
if ( !( $in{'invoiceviewertrigger'} || $in{'packingviewertrigger'} ) ) {
# advance previous session IDs
$in{'mgr_seshun'}     = "$mgr_seshun";
$mc_12back_session_id = "$mc_11back_session_id";
$mc_11back_session_id = "$mc_10back_session_id";
$mc_10back_session_id = "$mc_9back_session_id";
$mc_9back_session_id  = "$mc_8back_session_id";
$mc_8back_session_id  = "$mc_7back_session_id";
$mc_7back_session_id  = "$mc_6back_session_id";
$mc_6back_session_id  = "$mc_5back_session_id";
$mc_5back_session_id  = "$mc_4back_session_id";
$mc_4back_session_id  = "$mc_3back_session_id";
$mc_3back_session_id  = "$mc_2back_session_id";
$mc_2back_session_id  = "$mc_prev_session_id";
$mc_prev_session_id   = "$mc_session_id";
$mc_session_id        = "$in{'mgr_seshun'}";
}
open( FILE, "<$ip_file" );
@lines = (<FILE>);
close(FILE);
#added by Mister Ed July 2009
$lines[0] =
"\$ok_ip=\"$ENV{'REMOTE_ADDR'}\"; \$mc_session_id=\"$mc_session_id\"; \$mc_prev_session_id = \"$mc_prev_session_id\"; \$mc_2back_session_id = \"$mc_2back_session_id\"; \$mc_3back_session_id = \"$mc_3back_session_id\"; \$mc_4back_session_id = \"$mc_4back_session_id\"; \$mc_5back_session_id = \"$mc_5back_session_id\"; \$mc_6back_session_id = \"$mc_6back_session_id\"; \$mc_7back_session_id = \"$mc_7back_session_id\"; \$mc_8back_session_id = \"$mc_8back_session_id\"; \$mc_9back_session_id = \"$mc_9back_session_id\"; \$mc_10back_session_id = \"$mc_10back_session_id\"; \$mc_11back_session_id = \"$mc_11back_session_id\"; \$mc_12back_session_id = \"$mc_12back_session_id\"; 1;\n"
;    # always first line
open( FILE, ">$ip_file" )
|| my_die( "Can't Open ip_file, check "
. q|permissions for the "files" directory| );
foreach $inx (@lines) {
print( FILE $inx );
}
close(FILE);
}

#######################################################################

sub my_escape {    #escape out chars used in qq stuff
local ($logic) = @_;
$logic =~ s/\\/\\\\/g;
$logic =~ s/\$/\\\$/g;
$logic =~ s/\@/\\\@/g;
$logic =~ s/\"/\\\"/g;
$logic =~ s/\'/\\\'/g;
$logic =~ s/\#/\\\#/g;    # Blocks response from PayPal
$logic =~ s/\+/\\\+/g;    # Used as the space character
$logic =~ s/\&/\\\&/g;    # Used as the new variable delimiter
$logic =~ s/\%/\\\%/g;    # Used as the hex character delimiter
$logic =~ s/\?/\\\?/g;    # Used as the begin variable delimiter
#delete control-M (^M)
$logic =~ s/\r//g;
return $logic;
}

#######################################################################

sub action_commando {    # simulate "telnet" command line executions
local ($result) = q{};
if ( $in{'command'} ne '' ) {    #perform the command
# Untaint everything.
$in{'command'} =~ /([^\n]+)/;
$zcommand = $1;
$result   = `$zcommand`;
}
# this is a combo edit/results screen
print &$manager_page_header( 'COMMANDO!', '', '', '', '' );
print <<ENDOFTEXT;
<center>
<table width=665 border=0 cellpadding=2>
<tr>
<td><br></td>
</tr>
<tr>
<td colspan="2" class="sub_header"><center><font face="Arial, Helvetica, sans-serif" size=+2><b>Commando - Unix / Linux Shell</b></font></center></td>
</tr>
<tr>
<td><br></td>
</tr>
<tr>
<td colspan="2">
This is the most dangerous part of the manager. &nbsp;Unless you have
a specific reason to be here then don't be! &nbsp;It allows Unix
commands to be entered and their results to be posted below. &nbsp;If
a command returns with no results, it is possible there was an error.
&nbsp;To display errors, you can redirect STDERR to STDOUT by
placing  "2>&1" after the command.
<br><br>BE VERY CAREFUL HERE!<br><br>
<form action="manager.cgi" method="post"><input type="hidden" name="mgr_seshun" value="$in{'mgr_seshun'}">
Command: <input type="TEXT" name="command" size=60 maxsize=120>
<input type="hidden" name="commando" value="yes">
<input type="submit" name="submitcommando" value="Execute Command">
</form>
<hr width=665>
</td>
</tr>
<tr>
<td colspan="2">
<table width=665 border=0 BGCOLOR="F0F0F0"><tr><td>
<pre>$zcommand <br><br>$result</pre>
</td></tr></table>
</td>
</tr>
</table>
ENDOFTEXT
print &$manager_page_footer;
}

#######################################################################

sub init_convert_menu_item {
    local ( $str, @lines, @my_items );
    local ( $kount, $inx, $action, $display, $procname, $junk );
    my $temp_manager_cgi_version = "$versions{'manager.cgi'}";
    $temp_manager_cgi_version =~ s/Gold//i;
    my $ht_menu = q{};

    # used on edit/add product screens
    $manager_banner_main =
    '<font color=green>AgoraCart </font><font color=gold>Route 66</font>'
    . " - Store Manager ver. $temp_manager_cgi_version";

    # used at login screen & standard headers
    $manager_banner =
    '<div align=center><font size=+2><em><font color=green>AgoraCart </font>'
    . '<font color=gold>Route 66</font></em></font></div>';

    $str = qq~<div class="container-fluid">\n<div class="row">\n~;
    $str .= $ht_menu;
    $kount = 0;
    foreach $inx (sort(keys %top_menu)) {
        $action = $top_menu{$inx};
        $display = $top_menu_name{$inx};
        ($procname,$junk) = split(/\=/,$action,2);
        if ($menu_items_disabled{$procname} eq '') {
            $str .= qq~\n<a href="manager.cgi?mgr_seshun=$mgr_seshun&$action">$display</a>&nbsp;&nbsp;~;
            $kount++;
            if ($kount == $mc_max_top_menu_items) {
                $kount = 0;
                $str .= "\n<br>";
            }
        }
    }
    if (substr($str,-6) ne "<br>") {
        $str .= "\n<br>";
    }
    $str .= '</div>';
    $manager_menu = $str;
}

#######################################################################

sub encryptit {

    local ( $mytime, $salt, $my_ans );
    local ($pass) = @_;

    $mytime = time();
    $mytime = "$mytime";

    # not secure enough for an OS, but fine for
    # something run once in a while
    $salt = substr( $mytime, length($mytime) - 2, 2 );
    $my_ans = crypt( $mytime, $salt );

    # now get the new salt for encryption ...
    $salt = substr( $my_ans, length($my_ans) - 2, 2 );
    $my_ans = crypt( $pass, $salt );

    return ($my_ans);
}

#######################################################################
# only used in multi-manager add-on for multiple mgr sessions/access & ACLs

sub eval_store_settings {

    local ( $error_list, $item, $err_count );
    $error_list = q{};
    $err_count  = 0;

    &load_store_settings();

    foreach $zitem ( sort( keys %store_settings ) ) {
        $item = $store_settings{$zitem};
        $item =~ /([^\xFF]*)/;
        $item = $1;
        eval($item);
        if ( $@ ne '' ) {
            $error_list .= "Error loading \"$zitem\" settings:<br>$@<br><br>\n";
            $err_count++;
        }
        else {
            $error_list .= "Loaded settings \"$zitem\" OK<br>\n";
        }
    }
    if ( $err_count == 0 ) {
        return q{};
    }
    else {
        return $error_list;
    }

}

#######################################################################

sub load_store_settings {

    local ( $junk, $name, $stuff );

    {
        open( SETTINGS, "$mgr_user_settings_path" ) || my_die("Can't Open $mgr_user_settings_path");
        local $/ = undef;
        $everything = <SETTINGS>;
        close(SETTINGS);
    }

    undef(%store_settings);

    while ( $everything =~ /#:#: end/i ) {
        ( $junk, $everything ) = split( /#:#:#: start /i, $everything, 2 );
        #    ($name,$everything) = split(/( settings)([^\n]+)(\n)/i,$everything,2);
        ( $name,  $everything ) = split( / settings/i,  $everything, 2 );
        ( $junk,  $everything ) = split( /\n/i,         $everything, 2 );
        ( $stuff, $everything ) = split( /#:#:#: end/i, $everything, 2 );
        $name =~ tr/a-z/A-Z/;
        $store_settings{$name} = $stuff;
    }

    # and by default we need to set the MAIN vars
    $store_settings{'MAIN'} =~ /([^\xFF]*)/;
    $temp = $1;
    eval($temp);
    $mc_path_for_cookie = $sc_path_for_cookie . "/$mgrdirname";

}

#######################################################################

sub save_store_settings {

    my ( $myset, $item, $zitem ) = q{};

    get_file_lock("$mgr_user_settings_path.lockfile");
    open( SETTINGS, ">$mgr_user_settings_path" ) || my_die("Can't Open $mgr_user_settings_path");

    $myset = "## This file contains the user specific variables\n";
    $myset .= "## necessary for AgoraCart to operate\n\n";

    print( SETTINGS $myset );

    foreach $zitem ( sort( keys %store_settings ) ) {
        $item = $zitem;
        $item =~ tr/a-z/A-Z/;
        print( SETTINGS "#:#:#: start $item settings\n" );
        print( SETTINGS $store_settings{$zitem} );
        print( SETTINGS "#:#:#: end $item settings\n" );
    }

    print( SETTINGS "#\n1\;\n" );
    close(SETTINGS);

    release_file_lock("$mgr_user_settings_path.lockfile");

}

#######################################################################

sub update_store_settings {

    my ( $item, $stuff ) = @_;
    $item =~ tr/a-z/A-Z/;

    &load_store_settings();

    $store_settings{$item} = $stuff;

    &save_store_settings();    # need save them all!
}

#######################################################################

sub action_htaccess_settings {
local ( $my_message, $my_ans, $my_str, $junk, $pwd, $old_path );
    $old_path  = $ENV{"PATH"};
    $ENV{"PATH"} = "/bin:/usr/bin";
    $pwd  = `pwd`;
    if ( length($pwd) < 4 ) {  #sanity check ... use our name to get path
        ( $pwd, $junk ) = ( /\/$mgrdirname/, $ENV{'SCRIPT_FILENAME'}, 2 );
    }
    chomp($pwd);
    $my_file = $pwd . "/$mgrdirname/manager.access";
    $my_file =~ s/\/$mgrdirname\/manager\.cgi//ig;
    $my_str = qq!#
#Options All
AuthType "Basic"
AuthName "Protected Access"
AuthUserFile $my_file
<Limit GET>
require valid-user
</Limit>
!;

    open( PSETTINGS, "> $mgrdir/.htaccess" );
    print( PSETTINGS $my_str );
    close(PSETTINGS);
    chmod $mgr_perms_mode, "$mgrdir/.htaccess";

    $username = $in{'username'};
    $password = $in{'password'};
    $stuff = $username . ':' . &encryptit($password) . "   \n";
    open( PSETTINGS, "> $mgrdir/manager.access" );
    print( PSETTINGS $stuff );
    close(PSETTINGS);
    chmod $mgr_perms_mode, "$mgrdir/manager.access";

    init_convert_menu_item();
    welcome_screen();
}

#######################################################################

sub clear_order_log {
    local ( $logfile, $count );
    require "$mgr_user_settings_path";
    $logfile = "$sc_logs_dir/$sc_order_log_name";
    $count   = $in{'bytes'};
    if ( $count > 0 ) {
        get_file_lock("$logfile.lockfile");

        open( LOGFILE, "$logfile" ) || print q{};
        read( LOGFILE, $stuff, 999999 );
        close(LOGFILE);

        $stuff = substr( $stuff, $count, 9999999 );
        unlink($logfile);
        open( LOGFILE, ">$logfile" ) || print q{};
        print( LOGFILE $stuff );
        close(LOGFILE);

        release_file_lock("$logfile.lockfile");
    }
    init_convert_menu_item();
    display_order_log();
}

#######################################################################

# Added by Mister Ed (K-Factor Technologies, Inc) 10/17/2003
sub my_stripout {
    local ($logic) = @_;
    $logic =~ s/\`//g;
    $logic =~ s/\\//g;
    $logic =~ s/\$//g;
    $logic =~ s/\@//g;
    $logic =~ s/\%//g;
    $logic =~ s/\n//g;
    $logic =~ s/\#/\\\#/g;
    $logic =~ s/\"/\\\"/g;
    $logic =~ s/\'/\\\'/g;
    $logic =~ s/\&/\\\&/g;
    $logic =~ s/\?/\\\?/g;
    #delete control-M (^M)
    $logic =~ s/\r//g;
    return $logic;
}

#######################################################################

sub str_encode {    # encode a string for cgi or other purposes
    my ($str)   = @_;
    my ($mypat) = '[\x00-\x1F"\x27#%/+;<>=?\x7F-\xFF]';
    $str =~ s/($mypat)/sprintf("%%%02x",unpack('c',$1))/ge;
    $str =~ tr/ /+/;
    return $str;
}

#######################################################################

sub str_decode {    # decode a string for cgi or other purposes
    my ($str) = @_;
    $str =~ tr/+/ /;
    $str =~ s/%(..)/pack("c",hex($1))/ge;
    return $str;
}

#######################################################################

sub update_adminfile_settings {

    local ( $file, $stuff ) = @_;
    local %shipadmin_file_settings = ();
    $shipadmin_file_settings{$file} = $stuff;
    local ( $item, $zitem );

    get_file_lock("$file.lockfile");
    open( MYADMINFILE, ">$file" ) || my_die("Can't Open $file -- During Admin Settings Update");
    foreach $zitem ( sort( keys %shipadmin_file_settings ) ) {
        $item = $zitem;
        print( MYADMINFILE $shipadmin_file_settings{$zitem} );
    }
    close(MYADMINFILE);
    release_file_lock("$file.lockfile");

}

#######################################################################
# Uses GET and grabs contents of a non-API file or page at a https URL
# username and passwords are not supported for sites/areas involving htaccess, etc.

sub simple_secure_URL_file_getter {

    my $url = shift;
    if ( ( $url =~ /^https\:\/\/agoracart\.com\//i ) || ( $url =~ /^https\:\/\/www\.agoracart\.com\//i ) ) {
        my $ua = LWP::UserAgent->new( ssl_opts => { verify_hostname => "0", }, protocols_allowed => ["https"] );
        my $req = HTTP::Request->new(GET => $url);
        my $res = $ua->request($req);
        my $content = $res->content;
        return $content;
    }
    return '';
}

#######################################################################
# gets binary file

sub get_file_to_install_pro_file {

    my ($local_filename) = shift;
    my $browser = LWP::UserAgent->new( ssl_opts => { verify_hostname => "0", }, protocols_allowed => ["https"] );
    my $req = HTTP::Request->new( GET => "https://agoracart.com/$mgr_install_source_file_path" );
    my $response = $browser->request($req);
    my $downloaded_file = $response->content();
    if ( $downloaded_file ) {
        my $msg = "Can't Open $local_filename";
        open( UPLOADNEWFILE, ">./$local_filename" ) || die $msg;
        binmode UPLOADNEWFILE;
        print( UPLOADNEWFILE $downloaded_file );
        close(UPLOADNEWFILE);
    }
}

#######################################################################

1;
