#!/usr/bin/perl

use strict;
push(@INC,'/home/oc/cgi-bin/');
use lib '/home/oc/cgi-bin/';
use lib './';
use OC;
use CGI qw/:standard/;
use CGI::Carp qw(fatalsToBrowser);
use HTML::Template;
use Tie::IxHash;
use Digest::MD5 qw(md5_hex);
use Mail::Sender;

use vars qw/
%CONFIG
$template
%form
%cookie
$self_url
$TITLE
@LINKS
$BODY
@DISPLAYED
$CAN_EDIT
$LOGGED_IN
@NOTE
$NAVIGATION
$USERNAME
$AC_TYPE
$PANEL
/;


sub Initialize {
    %form=();
    my $query=new CGI;
    foreach ($query->param) {
        $form{$_}=$query->param($_);
    }   
    foreach ($query->cookie) {
        $cookie{$_}=$query->cookie($_);
    }
    %CONFIG=%OC::CONFIG;

    $self_url=$CONFIG{account_url};

#    $self_url=$ENV{REQUEST_URI};
#    $self_url=~s/^(.*)\?.*$/$1/;
#    $self_url=~s/^(.*.cgi).*$/$1/;

    @DISPLAYED=();
    @LINKS=();
    $TITLE='';
    $BODY='';
    $PANEL='';
    @NOTE=();
    $NAVIGATION='';
    $LOGGED_IN=0;
    $AC_TYPE='';
}


sub ConnectToDatabase {
    if (!defined $::db) {
      $::db = DBI->connect("DBI:mysql:$CONFIG{db_name}:$CONFIG{db_host}:
        $CONFIG{db_port}",$CONFIG{db_username},$CONFIG{db_password})
        || die "Can't connect to database server: $CONFIG{db_name} $CONFIG{db_host} $CONFIG{db_port}";
    }
    return $::db;
}

sub PrepareSQL {
    my ($str) = (@_);
    $::sth=$::db->prepare($str);
}
 
sub ExecuteSQL {
    $::sth->execute(@_) || die "Could not execute SQL statement";
}

sub SendSQL {
    PrepareSQL(@_); 
    ExecuteSQL();
}

sub FetchSQLData {
    return $::sth->fetchrow_array();
}

sub Note {
    push(@NOTE,$_[0]);
}

sub Output_Notes {
    my $result="<font color=red>";
    foreach (@NOTE) {
        $result.="$_<br>";
    }
    $result.="</font><p>";
    return $result;
}

sub Prepare_Template {
    $template=HTML::Template->new(
	filename=>$_[0],
        die_on_bad_params=>0,
        loop_context_vars=>1,
        global_vars=>0,
        shared_cache=>0,
    );
    $template->param(table_color1=>$CONFIG{color}{table1});
    $template->param(table_color3=>$CONFIG{color}{table3});
}

sub Block_Edit_Link {
    my ($account)=@_;
    if ($CAN_EDIT) {
        return  "<a href='$self_url/$account/admin'><img src='$CONFIG{edit_image}' border=0></a>";
    } else {
        return '';
    }
}

sub Right_Table {
    my $selected=$_[0];
    my $table="<b>Accounts</b>";
    if ($selected eq 'login') {
        $table.=OC::Li("Login");
    } else {
        $table.=OC::Li("<a href='$self_url?cmd=login'>Login</a>");
    }
    if ($selected eq 'lost_password') {
        $table.=OC::Li("Lost password?");
    } else {
        $table.=OC::Li("<a href='$self_url?cmd=lost_password_screen'>Lost password?</a>");
    }
    if ($LOGGED_IN<1 || $selected eq 'get_account') {
        if ($selected eq 'get_account') {
            $table.=OC::Li("Get account");
        } else {
            $table.=OC::Li("<a href='$self_url?request=form'>Get account</a>");
        }
    }
    if ($selected eq 'people') {
        $table.=OC::Li("People at OpenCores");
    } else {
        $table.=OC::Li("<a href='$self_url'>People at OpenCores</a>");
    }
    return $table;
}

sub Admin_Links {
    my $screen=$_[0];
    my %row=();
    $row{name}="Account queue";
    if ($screen ne 'queue') {
        $row{link}="$self_url?cmd=queue";
    }
    push(@LINKS,\%row);
    my %row=();
    $row{name}="Browse accounts";
    if ($screen ne 'browse') {
        $row{link}="$self_url";
    }    
    push(@LINKS,\%row);
}

sub Request_Form {
    $TITLE="Get account";
    $BODY.="<b>Note: account is required only for maintainig your projects and/or 
        writing news and articles. All other feature of OpenCores web are available to
        anyone. Are you sure that you need account?</b><p>";
    $BODY.="Please make sure you provide a valid email address because email with password will 
        be sent to that address. Without password you are unable to login. Also you must provide 
        information why you need account. If you are going to start new project or join an 
        existing one please let as know more about this. <p>";  
    $BODY.=Output_Notes;  
    $BODY.="<table width=100%><tr><td>";
    $BODY.="<form action='$self_url' method=post><table><tr><td>";
    $BODY.="<b>Username</b><br><font size=-1>username you would like to have</font><br>
            <input type=query name=username value='$form{username}' size=40 maxlength=15><p>";
    $BODY.="<b>Full name</b><br><input type=query name=fullname value='$form{fullname}' value='' size=40 maxlength=50><p>";
    $BODY.="<b>Account type</b><br><font size=-1>Note: project maintainers can post news and 
            articles too.</font><br><select name=type>";

    SendSQL("select type,display from account_type");
    while(my @result=FetchSQLData) {
        $BODY.="<option value='$result[0]'>$result[1]</option>";
    }

    $BODY.="</select><p>";
    $BODY.="<b>Email</b><br><font size=-1>be sure that it is valid!</font><br>
            <input type=query name=email value='$form{email}' size=40 maxlength=60><p>";
    $BODY.="<b>Reason why do you need account</b><br>
        <font size=-1>Info about the project you are going to start/join or
        info about <br>articles/news you are going to post.</font><br><textarea name=info wrap=hard rows=7 cols=40>$form{info}</textarea><p>";
    $BODY.="<center><hr noshade size=1><input type=submit name=get_account value='Submit'>";
    $BODY.="</td></tr></table></form></td><td valign=top align=right>";
    my $table=OC::Li("to grab files from CVS");
    $table.=OC::Li("to join discussion in our forums");
    $BODY.=OC::Small_Table("Account is NOT required",$table);
    $BODY.="</td></tr></table>";
    $PANEL.=Right_Table('get_account');
}

sub Request_Result {
    $form{email}=lc($form{email});
    $form{username}=lc($form{username});
    $TITLE="Get account";
    @NOTE=();
    unless ($form{username}=~m/^[A-Z0-9_-]{4,20}$/i) {
        Note("Invalid username '$form{username}'.");
    }
    unless (length($form{fullname})>5) {
        Note("Full name is too short.");
    }
    SendSQL("select count(type) from account_type where type='$form{type}'");
    unless (FetchSQLData>=1) {
        Note("Invalid account type '$form{type}'.");
    }
    unless ($form{email}=~m/^.+\@.+\..+$/i) {
        Note("Invalid email '$form{email}'.");
    }
    PrepareSQL("select count(username) from account where username=?");
    ExecuteSQL($form{username});
    if (FetchSQLData>0 && $form{username} ne '') {
        Note("Account already exists.");
    }
    PrepareSQL("select count(username) from account where email=?");
    ExecuteSQL($form{email});
    if (FetchSQLData>0 && $form{email} ne '') {
        Note("Account with same email address ('$form{email}') already exists.")
    }
    if (length($form{info})<20) {
        Note("Reason is too short.");
    }

    if (scalar(@NOTE)) {
        Request_Form;
    } else {
        PrepareSQL("insert into account (username,fullname,type,email,homepage,info,approved,disabled) values (?,?,?,?,?,?,0,1)");
        ExecuteSQL($form{username},$form{fullname},$form{type},$form{email},$form{homepage},$form{info});
        $BODY.="Request was added to queue. In next 24 hours it will be approved or rejected. You will be informed by email.";
        OC::Mail_Webmaster("Request for account '$form{username}'. Please check http://www.opencores.org/people?cmd=queue");
    }
}

sub Show_Queue {
    if ($AC_TYPE ne 'admin') {
        $BODY.="You are not administrator!!";
        return;
    }
    $TITLE="Account queue";
    $BODY.=Output_Notes;
    $BODY.="Accounts waiting for approval:";

    SendSQL("select id,username,type,fullname,email,homepage,info from account where approved=0");
    my $cnt=0;
    while (my @result=FetchSQLData) {
        $cnt++;
        $BODY.="<form action='$self_url'>";
        $BODY.="Username: $result[1]<br>";
        $BODY.="Type: $result[2]<br>";
        $BODY.="Fullname: $result[3]<br>";
        $BODY.="Email: $result[4]<br>";
        $BODY.="Homepage: $result[5]<br>";
        $BODY.="Reason<br>".${OC::Smart_Reformat(\$result[6])};
        $BODY.="<p>Reject response<br><textarea name=response rows=7 cols=30></textarea><br>";
        $BODY.="<input type=submit name=approve_account value='Approve'> <input type=submit name=reject_account value='Reject'>";
        $BODY.="<input type=hidden name=id value='$result[0]'></form> <hr noshade size=1>";
    }
    unless ($cnt) {
        $BODY.="<ul>No accounts..</ul>";
    }

}

sub Reject_Account {
    if ($AC_TYPE ne 'admin') {
        $BODY.="You are not administrator!!";
        return;
    }
    SendSQL("select username,fullname,type,email,info from account where id=$form{id} and approved=0");
    my @result=FetchSQLData;
    SendSQL("delete from account where id=$form{id}");
    my %mail=();
    $mail{from}="$CONFIG{add_account_from}";
    $mail{to}="$result[3]";
    $mail{subject}="Request rejected";
    $mail{body}="
Hi $result[1],

your request for account '$result[0]'  has been rejected because of the following reason:
$form{response}

OpenCores team
";
    OC::Send_Mail(\%mail);

    Note("Account rejected.. Requester will be informed about this action.");
}

sub Approve_Account {
        if ($AC_TYPE ne 'admin') {
            $BODY.="You are not administrator!!";
            return;
        }
        SendSQL("select username,type,fullname,email,homepage,alias,skils,last_login,created from account where id=$form{id} and approved=0");
        my @result=FetchSQLData;
        SendSQL("select count(username) from account where username='$result[0]' and approved<>0");
        if (FetchSQLData) {
            $BODY.="Username '$result[0]' already approved.. You must reject this account.";
            return;
        }

        my $user_folder=$CONFIG{account_home_folder}."/$result[0]";
        my $pw=substr(md5_hex(time+substr($result[1],0,4)),0,6);
        my $cpw=crypt($pw,substr($result[0],0,2));
        unless(mkdir($user_folder,'493')) {
            Note("Failed to create home folder: $user_folder. Please report this error to webmaster!");
        }
        if ($result[1] eq 'project') {
            if (open(FILE,"$CONFIG{account_config_file}")) {
                my $file="";
                while(my $line=<FILE>) {
                    my @row=split(/:/,$line);
                    if ($row[0] eq $result[0]) {
                        Note("Username already in file $CONFIG{account_config_file}. Please report this error to webmaster!");
                    }
                    $file.="$line";
                }
                close(FILE);
                unless ($file=~m!\n$!) {
                    $file.="\n";
                }
                $file.="$result[0]::n:$user_folder:\n";
                if (open(FILE,">$CONFIG{account_config_file}")) {
                    print FILE $file;
                    close(FILE);
                } else {
                    Note("Failed to save file: $CONFIG{account_config_file}. Please report this to webmasters!");                    
                }
            } else {
                Note("Failed to read file: $CONFIG{account_config_file}. Please report this to webmasters!");
            }
            if (open(FILE,"$CONFIG{password_file}")){
                my $file="";
                while(my $line=<FILE>) {
                    my @row=split(/:/,$line);
	            if ($row[0] eq $result[0]) {
                        Note("Username already in file $CONFIG{password_file}. Please report this error to webmaster!");
                    }
                    $file.="$line";
	        }
                close(FILE);
                unless ($file=~m!\n$!) {
                    $file.="\n";
                }
                $file.="$result[0]:$cpw:$CONFIG{cvs_passwd_junk}\n";
                if (open(FILE,">$CONFIG{password_file}")) {
                    print FILE $file;
                    close(FILE);
                } else {
                    Note("Failed to save file: $CONFIG{password_file}. Please report this to webmasters!");                    
                }
            } else {
                Note("Failed to read file: $CONFIG{password_file}. Please report this to webmasters!");
            }
        }

        PrepareSQL("insert into email_aliases (email,alias) values (?,?)");
        ExecuteSQL($result[3],lc($result[0]).'@opencores.org');
        my $sender=new Mail::Sender{
            smtp=>$CONFIG{mail_sender_smtp},
            from=>$CONFIG{add_account_from},
            cc=>$CONFIG{add_account_cc},
            to=>$result[3],
            subject=>$CONFIG{add_account_subject},
        };

        my $time=time;
        SendSQL("update account set created=$time, password='$cpw', disabled=0,approved=1 where id=$form{id}");


        my $msg='';
        if ($result[1] eq 'project') {
            open(FILE,$CONFIG{greet_file}) or Note("Cannot open file: '$CONFIG{greet_file}'");
        } else {
            open(FILE,$CONFIG{article_greet_file}) or Note("Cannot open file: '$CONFIG{article_greet_file}'");
        }
        while (my $line=<FILE>) {
            $msg.=$line;
        }
        close(FILE);
        $msg=~s/KEY_FULLNAME/$result[2]/g;
        $msg=~s/KEY_USERNAME/$result[0]/g;
        $msg=~s/KEY_PASSWORD/$pw/g;

        if ($sender->MailMsg({msg=>$msg})<0) {
            Note("Error while trying to send email to '$form{email}'. Error: $Mail::Sender::Error");
        }
        Note("<font color=green>Account successfully created. User will be informed about this action</font>");
        
}

sub Browse_Accounts {
    $TITLE="People";
    my %atype=();
    SendSQL("select type,display from account_type");
    while (my @result=FetchSQLData) {
        $atype{$result[0]}=$result[1];
    }
#    $BODY.="<table width=100%><tr><td>";
    $BODY.="<table width=100%>";
    my $cnt=0;
    SendSQL("select username,fullname,type,email from account where last_login>0 and disabled<1 order by username");
    while (my @result=FetchSQLData) {
        if ($cnt % 2==0) {
            $BODY.="<tr>";
        }
        $result[1]=$result[0] unless ($result[1]);
        $BODY.="<td valign=top><b><a href='$self_url/$result[0]'>$result[1]</a></b><br>$atype{$result[2]}<p></td>";
        if ($cnt %2!=0) {
            $BODY.="</tr>";
        }
        $cnt++;
    }
    $BODY.="</table>";
    $PANEL.=Right_Table('people');    
}

sub Display_Account {
    $template->param(no_panel=>1);
    my ($username)=@_;
    SendSQL("select fullname, type, email, homepage, skils, last_login, created, city, state, country from account where username='$username'");
    my ($fullname,$type,$email,$homepage,$skils,$lastlogin,$created,$city,$state,$country);

    unless (($fullname,$type,$email,$homepage,$skils,$lastlogin,$created,$city,$state,$country)=FetchSQLData) {
        Browse_Accounts;
        return;
    }
    my %atype=();
    SendSQL("select type,display from account_type");
    while (my @result=FetchSQLData) {
        $atype{$result[0]}=$result[1];
    }

    $TITLE=$fullname;
    $TITLE=$username unless($TITLE);

    $template->param(page_title=>"people: $TITLE");

    $BODY.="<b>User info</b>".Block_Edit_Link($username)."<p>";
    $BODY.="<table>";
    $BODY.="<tr><td>Username</td><td>$username</td></tr>";
    $BODY.="<tr><td>Full name</td><td>$fullname</td></tr>";
    if ($city ne '') {
        $BODY.="<tr><td>City</td><td>$city</td></tr>";
    }
    if ($state ne '') {
        $BODY.="<tr><td>State</td><td>$state</td></tr>";
    }
    SendSQL("select country from country_codes where code='$country'");
    my $country=FetchSQLData();
    if ($country ne '') {
        $BODY.="<tr><td>Country</td><td>$country</td></tr>";
    }
    $BODY.="<tr><td>Account type</td><td>$atype{$type}</td></tr>";
    $BODY.="<tr><td>Email</td><td>";

    if ($email=~m/.+\@.+\..+/ && !($email=~m/ /)) {
        my $link=OC::Store_Email($email);
        $link=$CONFIG{post_url}."?to=$link";
        $link="<a href='$link'>$email</a>";
        $email=${OC::Filter_Emails(\$link)};
    }
    $BODY.=$email;

    $BODY.="</td></tr>";

    my $hp_link=$homepage;
    $hp_link="http://".$homepage unless ($homepage=~m!^http://!);

    $BODY.="<tr><td>Homepage</td><td><a target='_new' href='$hp_link'>$homepage</a></td></tr>";
    $BODY.="<tr><td>Account created</td><td>".OC::Time_To_Str($created,'nice')."</td></tr>";
    $BODY.="<tr><td>Last login</td><td>".OC::Time_To_Str($lastlogin,'nice')."</td></tr>";
    $BODY.="</table>";
    $skils=${OC::Smart_Reformat(\$skils)};
    if ($skils) {
        $BODY.="<p><b>Skills</b>".Block_Edit_Link($username)."<p>$skils";
    }

    my @project=();
    SendSQL("select project from project_maintainers where username='$username'");
    while (my $result=FetchSQLData) {
        push(@project,$result);
    }
    if (scalar(@project)) {
        $fullname=ucfirst($username) if ($fullname eq '');
        $BODY.="<p><b>Projects of $fullname</b><p>";
        foreach (@project) {
            SendSQL("select display_name,short_desc from project where name='$_'");
            my @result=FetchSQLData();
            $result[1]=${OC::Smart_Reformat(\$result[1])};
            $BODY.="<li><a href='$CONFIG{project_url}/$_'>$result[0]</a><br>$result[1]</li><p>";
        }
    }

    my %news=();
    tie (%news,'Tie::IxHash');
    SendSQL("select id,title from news where author='$username' and status='approved' order by added desc");
    while (my @result=FetchSQLData) {
        $news{$result[0]}=$result[1];
    }
    if (scalar(keys %news)) {
        $BODY.="<p><b>Posted news</b><p>";
        foreach (keys %news) {
            $BODY.="<li><a href='$CONFIG{news_url}?id=$_'>$news{$_}</a></li>";
        }
    }
    
    my %article=();
    SendSQL("select title,id from article where author='$username' and status='approved' order by added desc");
    while (my @result=FetchSQLData) {
        $article{$result[1]}=$result[0];
    }
    if (scalar(keys %article)) {
        $BODY.="<p><b>Posted articles</b><p>";
        foreach (keys %article) {
            $BODY.="<li><a href='$CONFIG{article_url}?cmd=view_article&id=$_'>$article{$_}</a></li>";
        }
    }

}

sub Help {
    my ($username)=@_;
    SendSQL("select type from account where username='$username'");
    my $ac_type=FetchSQLData;
    if ($ac_type eq 'admin') {
        $ac_type='project';
    }
    SendSQL("select display,help from account_type where type='$ac_type'");
    my ($display_type,$help)=FetchSQLData;
    $TITLE="Help";
    $BODY.="Help for account type: $display_type<p>";
    SendSQL("select email from email_aliases where alias='$username\@opencores.org'");
    my $email=FetchSQLData();
    $help=~s/KEY_USERNAME/$username/g;
    $help=~s/KEY_EMAIL/$email/g;
    $help=${OC::Smart_Reformat(\$help)};
    $BODY.=$help;
}

sub Requests {
    my ($username)=@_;
    $TITLE="Requests";

    $BODY.="<b>Project requests</b>";
    SendSQL("select display_name,status,response,added from project_queue where username='$username' order by added desc");
    my $cnt=0;
    while (my @result=FetchSQLData) {
        $BODY.="<p><b>$result[0]</b> - ".OC::Time_To_Str($result[3],'nice')."<br>";
        $BODY.="Status: $result[1]<br>";
        $BODY.="Response: ".${OC::Smart_Reformat(\$result[2])} if ($result[2] ne '');
        $cnt++;
    }
    unless ($cnt) {
        $BODY.="<p>No requests till now";
    }
    
    $BODY.="<p><hr noshade size=1><p>";
    $BODY.="<b>News requests</b>";    
    SendSQL("select title,status,response,added from news where author='$username'  order by added desc");
    my $cnt=0;
    while (my @result=FetchSQLData) {
        $BODY.="<p><b>$result[0]</b> - ".OC::Time_To_Str($result[3],'nice')."<br>";
        $BODY.="Status: $result[1]<br>";
        $BODY.="Response: ".${OC::Smart_Reformat(\$result[2])} if ($result[2] ne '');
        $cnt++;
    }
    unless ($cnt) {
        $BODY.="<p>No requests till now";
    }

    $BODY.="<p><hr noshade size=1><p>";
    $BODY.="<b>Article requests</b>";    
    SendSQL("select title,status,response from article where author='$username'  order by added desc");
    my $cnt=0;
    while (my @result=FetchSQLData) {
        $BODY.="<p><b>$result[0]</b> - ".OC::Time_To_Str($result[3],'nice')."<br>";
        $BODY.="Status: $result[1]<br>";
        $BODY.="Response: ".${OC::Smart_Reformat(\$result[2])} if ($result[2] ne '');
        $cnt++;
    }
    unless ($cnt) {
        $BODY.="<p>No requests till now";
    }

}

sub Admin {
    my ($account)=@_;
    $TITLE="Administration";
    SendSQL("select fullname, type, email, homepage, skils, city, state, country
      from account where username='$account'");
    my ($fullname,$type,$email,$homepage,$skils,$city,$state,$country)=FetchSQLData;
    $BODY.="<table width=100%><tr><td><table><form action='$self_url/$account/admin' method=post>";
    $BODY.="<tr><td>Username</td><td>$account</td></tr>";

    $BODY.="<tr><td>Account type</td><td><select name=type>";

    SendSQL("select type,display from account_type");
    while(my @result=FetchSQLData) {
        my $selected='';
        $selected=' selected ' if ($result[0] eq $type);
        $BODY.="<option $selected value='$result[0]'>$result[1]</option>";
    }

    $BODY.="</select></td></tr>";
    $BODY.="<tr><td>Full name</td><td><input type=query name=fullname value='$fullname'></td></tr>";
    $BODY.="<tr><td>City</td><td><input type=query name=city value='$city'></td></tr>";
    $BODY.="<tr><td>State</td><td><input type=query name=state value='$state'></td></tr>";
    $BODY.="<tr><td>Country</td><td><select name=country>";
    $BODY.="<option value=''>None</option>";
    SendSQL("select code,country from country_codes order by country");
    while(my @result=FetchSQLData) {
        my $selected ="";
        if ($result[0] eq $country) {
            $selected=" selected ";
        }
        $BODY.="<option $selected value='$result[0]'>$result[1]</option>";
    }
    $BODY.="</select></td></tr>";
    $BODY.="<tr><td>Email</td><td><input type=query name=email value='$email'></td></tr>";
    $BODY.="<tr><td>Homepage</td><td><input type=query name=homepage value='$homepage'></td></tr>";
    $BODY.="<tr><td colspan=2>Skills<br><textarea name=skils cols=50 rows=10 wrap=soft>$skils</textarea>
      <center><hr size=1 noshade><input type=hidden name=username value='$account'>
      <input type=submit name=save value='Save'></td></tr>";
    $BODY.="</table></form></td><td valign=top align=right>";

    $BODY.="</td></tr></table>";
}

sub Change_Password_Screen {
    my ($account)=@_;
    $TITLE="Change password";
    $BODY.=Output_Notes."
      <table><form action='$self_url/$account/admin' method=post>";
    $BODY.="<tr><td>Username</td><td>$account</td></tr>";
    $BODY.="<tr><td>Old password</td><td><input type=password name=oldpassword value=''></td></tr>";
    $BODY.="<tr><td>New password</td><td><input type=password name=newpassword value=''></td></tr>";
    $BODY.="<tr><td>Retype password</td><td><input type=password name=retypepassword value=''></td></tr>";
    $BODY.="<tr><td colspan=2><center><hr noshade size=1><input type=submit value='Change'></td></tr>";
    $BODY.="<input type=hidden name=cmd value=new_password></td></tr></table>";
}

sub Change_Password {
    my ($account)=@_;
    @NOTE=();
    my $error=0;
    my $cookie_pass='';
    if (OC::Login($account,$form{oldpassword}) eq '' && $CAN_EDIT) {
        Note("Old password is invalid.");
        $error=1;
    }
    if (length($form{newpassword})<4) {
        Note("New password is too short.");
        $error=1;
    }
    if ($form{newpassword} ne $form{retypepassword}) {
        $error=1;
    }
    if ($error) {
        Note("At least one of passwords is invalid. Change password failed!");
        print header(-type  =>  'text/html',-charset=>'');
    } else {
        Note("<font color=green>Password successfully changed.</font>");
        $cookie_pass=OC::Change_Password($account,$form{newpassword});
        my $cookie1=cookie(
            -name=>"username",
            -value=>$account,
        );
        my $cookie2=cookie( 
            -name=>"password",
            -value=>$cookie_pass,
	);
        print header(
            -cookie=>[$cookie1,$cookie2],
            -type  =>  'text/html',
            -charset=>''
        );
    }
}

sub Save_Account {
    my $username=$USERNAME;
    if ($form{type} eq 'project' || $form{type} eq 'article' ) {
        SendSQL("select type from account where username='$username'");
        if (FetchSQLData eq 'admin') {
            PrepareSQL("update account set fullname=?, email=?, homepage=?, skils=?, 
              city=?, state=?, country=?  where username=?");
            ExecuteSQL($form{fullname},$form{email},$form{homepage},$form{skils},
              $form{city},$form{state},$form{country},$username);
        } else {
            PrepareSQL("update account set fullname=?, email=?, homepage=?, skils=?, type=?, 
              city=?, state=?, country=?  where username=?");
            ExecuteSQL($form{fullname},$form{email},$form{homepage},$form{skils},$form{type},
              $form{city},$form{state},$form{country},$username);
        }

        my $new_file='';
        my $found=0;
        open(FIN,$CONFIG{password_file});
        while(my $line=<FIN>) {
            my ($un,$pw,@junk)=split(/:/,$line);
            if ($un eq $username && $un ne '') {
                if ($form{type} eq 'project') {
                    $new_file.=join(':',($un,$pw,@junk));
                }
                $found=1;
            } else {
                $new_file.=join(':',($un,$pw,@junk));
            }
        }
        if ($form{type} eq 'project' && $found==0) {
            unless($new_file=~m/\n$/) {
                $new_file.="\n";
            }
            SendSQL("select password from account where username='$username'");
            my $crypted_pass=FetchSQLData();
            $new_file.=join(':',($username,$crypted_pass,$CONFIG{cvs_passwd_junk}."\n"));
        }
        close(FIN);
        open(FOUT,">$CONFIG{password_file}");
        print FOUT $new_file;
        close(FOUT);

    } else {
        Note("Cannot save account properties!");
    }
}

sub Create_Links {
    my ($account,$screen)=@_;
    if ($CAN_EDIT && $account) {
        my %row=();
        $row{link}="$self_url/$account/admin" unless ($screen eq 'admin');
        $row{name}="Admin";
        push(@LINKS,\%row);
        my %row=();
        $row{link}="$self_url/$account/admin?cmd=requests" unless ($screen eq 'requests');
        $row{name}="Requests";
        push(@LINKS,\%row);
        my %row=();
        $row{link}="$self_url/$account/admin?cmd=change_password" unless ($screen eq 'change_password');
        $row{name}="Change password";
        push(@LINKS,\%row);
        my %row=();
        $row{link}="$self_url/$account/admin?cmd=help" unless ($screen eq 'help');
        $row{name}="Help";
        push(@LINKS,\%row);
        my %row=();
        $row{link}="$self_url/$account" unless ($screen eq '');
        $row{name}="Home";
        push(@LINKS,\%row);
    }
}

sub Lost_Password_Screen {
    $TITLE.="Lost password";
    $BODY.="<form action='$self_url'>";
    my $email='administration@opencores.org';
    my $link=OC::Store_Email($email);
    $link=$CONFIG{post_url}."?to=$link";
    $link="<a href='$link'>$email</a>";
    $email=${OC::Filter_Emails(\$link)};
    $BODY.="If you lost your password enter username below and you will get new one by email. Incase you didn't set valid email you will have to contact $email.<p>";
    $BODY.=Output_Notes."<table><tr><td>
      Username <input type=query name=username value=''>
      <center><hr size=1 noshade><input type=submit value='Send me new password'>
      <input type=hidden name=cmd value=lost_password></td></tr></table></form>";
    $PANEL.=Right_Table('lost_password');
}

sub Lost_Password {
    PrepareSQL("select username,email,fullname from account where username=?");
    ExecuteSQL($form{username});
    my ($username,$email,$fullname)=FetchSQLData;
    if ($username eq '') {
        Note("Invalid username!");
        return;
    } elsif (!($email=~m/.+\@.+\..+/)) {
        Note("Username exists but email is invalid.. You'll have to contact webmaster!");
    } else {
        my $newpass=substr(md5_hex(time),0,7);
        OC::Change_Password($form{username},$newpass);
        my $sender=new Mail::Sender{
            smtp=>$CONFIG{mail_sender_smtp},
            from=>$CONFIG{add_account_from},
            to=>$email,
 	    subject=>$CONFIG{lost_password_subject},
        };
        my $msg='';
        open(FILE,$CONFIG{lost_password_file});
        while (my $line=<FILE>) {
            $msg.=$line;
        }
        close(FILE);
        $msg=~s/KEY_FULLNAME/$fullname/g;
        $msg=~s/KEY_USERNAME/$form{username}/g;
        $msg=~s/KEY_PASSWORD/$newpass/g;

        if ($sender->MailMsg({msg=>$msg})<0) {
 	    Note("Error while trying to send email to $email: $Mail::Sender::Error");
        } else {
            Note("<font color=green>New password has been set and emailed to $email</font>");
        }

    }
}

sub Login_Screen {
    $TITLE="Login";
    $BODY.="<form action='$self_url' method=post>";
    $BODY.="Please note that you must have cookies enabled in your browser to be able to log in.<p>";
    $BODY.=Output_Notes;
    $BODY.="<table>";
    $BODY.="<tr><td>Username</td><td><input type=query name=username value=''></td></tr>";
    $BODY.="<tr><td>Password</td><td><input type=password name=password value=''></td></tr>";
    $BODY.="<tr><td colspan=2><center><p><hr size=1 noshade><input type=submit value='Login'>
      <input type=hidden name=cmd value='login'></td></tr>";
#    $BODY.="</table></form></td><td align=right valign=top>".Right_Table('login')."</td></tr></table>";
    $BODY.="</table></form>";
    $PANEL.=Right_Table('login');
}

sub Login {
    @NOTE=();
    my ($password,$type)=OC::Login($form{username},$form{password});
    unless ($password) {
        Note("Incorrect login. Please check your username and password.") if ($form{username} ne '' && $form{password} ne '');
        Create_Links($USERNAME);
        Login_Screen;
        my $cookie1=cookie(
            -name=>"username",
            -value=>'',
        );
        my $cookie2=cookie(
            -name=>"password",
            -value=>'',
        );
        print header(
            -cookie=>[$cookie1,$cookie2],
            -type  =>  'text/html',
            -charset=>''
        );
        return;
    } else {
        $USERNAME=$form{username},
        my $cookie1=cookie(
            -name=>"username",
            -value=>$USERNAME,
        );
        my $cookie2=cookie(
            -name=>"password",
            -value=>$password,
        );
        print header(
            -cookie=>[$cookie1,$cookie2],
            -type  =>  'text/html',
            -charset=>''
        );
        my $time=time;
        SendSQL("update account set last_login=$time where username='$USERNAME'");
        $CAN_EDIT=1;
        Create_Links($USERNAME,'');
        Display_Account($form{username});
    }
} 

sub Output {
    $template->param(
        links=>\@LINKS,
        title=>$TITLE,
        body=>$BODY,
#        panel=>$PANEL,
        no_panel=>1,
    );
    print $template->output;
}

sub Info {
    SendSQL("select count(name) from project");
    my $cprj=FetchSQLData;
    SendSQL("select count(username) from account where type<>'project'");
    my $cwriters=FetchSQLData;
    SendSQL("select count(username) from account where type='project'");
    my $cdevelopers=FetchSQLData;
    my $cforums=scalar OC::Get_Mailing_Lists;
    my $body.=OC::Li("$cprj projects");
    $body.=OC::Li("$cwriters news posters");
    $body.=OC::Li("$cdevelopers developers");
    $body.=OC::Li("$cforums mailing lists");
    print $body;
}

sub Main {
    Initialize;
    my ($junk,$account,$cmd)=split(/\//,$ENV{PATH_INFO});
    ConnectToDatabase();
    if ($ARGV[0] eq '-stats') {
        Info;
        exit;
    }
    print header(-type  =>  'text/html',-charset=>'') if ($form{cmd} ne "login" && $form{cmd} ne "new_password");
    if ($ARGV[0] eq '-cc') {
        SendSQL("delete from country_codes");
        open(FILE,"$ARGV[1]") or die("Cannot open file: '$ARGV[1]'");
        while(my $line=<FILE>) {
            my ($code,$country)=split(/ +/,$line,2);
            if (length($code)==2) {
                PrepareSQL("insert into country_codes (country,code) values (?,?)");
                ExecuteSQL($country,$code);
            }
        }
        close(FILE);
    }
    Prepare_Template($CONFIG{tmpl_account_file});
    SendSQL("select username,type from account where username='$account'");
    my @result=FetchSQLData;
    if (OC::Login($cookie{username},$cookie{password}) ne '') {
        $LOGGED_IN=1;
        SendSQL("select type from account where username='$cookie{username}'");
        my $type=FetchSQLData;
        if ($type eq 'admin') {
            $CAN_EDIT=1;
            $AC_TYPE='admin';
        }
    }
    if ($result[0] eq '') {
        if ($form{request} eq 'form') {
            Request_Form;
        } elsif($form{get_account}) {
            Request_Result;
        } elsif($form{cmd} eq 'login_screen') {
            Login_Screen;
        } elsif($form{cmd} eq 'login') {
            Login;
        } elsif($form{cmd} eq 'lost_password_screen') {
            Lost_Password_Screen;
        } elsif($form{cmd} eq 'lost_password') {
            Lost_Password;
            Lost_Password_Screen;
        } elsif ($AC_TYPE eq 'admin' && $form{cmd} eq 'queue') {
            Show_Queue;
            Admin_Links('queue');
        } elsif ($AC_TYPE eq 'admin' && $form{approve_account} ne '') {
            Admin_Links('queue');
            Approve_Account;
            Show_Queue;
        } elsif ($AC_TYPE eq 'admin' && $form{reject_account} ne '') {
            Reject_Account;
            Show_Queue;
            Admin_Links('queue');
        } else {
            Browse_Accounts;
            Admin_Links('browse') if ($AC_TYPE eq 'admin');
        }
        Create_Links;
    } else {
        if ($LOGGED_IN && $result[0] eq $cookie{username}) {
            $CAN_EDIT=1;
            $USERNAME=$cookie{username};
        }
        if ($cmd eq 'admin' && $CAN_EDIT) {
            $template->param(no_panel=>1);
            if ($form{save}) {
                Save_Account;
            }
            if ($form{cmd} eq 'change_password') {
                Create_Links($account,'change_password');
                Change_Password_Screen($account);
            } elsif($form{cmd} eq 'new_password') {
                Create_Links($account,'change_password');
                Change_Password($account);
                Change_Password_Screen($account);
            } elsif($form{cmd} eq 'requests') {
                Create_Links($account,'requests');
                Requests($account);
            } elsif($form{cmd} eq 'help') {
                Create_Links($account,'help');
                Help($account);
            } else {
                Create_Links($account,'admin');
                Admin($account);
            }
        } else {
            Create_Links($account);
            Display_Account($account);
        }
    }
    Output;
}

Main;
