#!/usr/bin/perl
## ~---------------------
## ~      取得資料
## ~---------------------
sub getdata{
    if ($ENV{'REQUEST_METHOD'} eq "POST") {
        read(STDIN, $in, $ENV{'CONTENT_LENGTH'});
    }else{
        $in = $ENV{'QUERY_STRING'};
    }
    @pairs = split(/&/,$in);
    foreach $pair(@pairs) {
        ($name,$value) = split(/=/, $pair);
        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; #解碼
        $value =~ s/\,/&#44;/g;                 #取代,號
        $value =~ s/\r\n/<br>/g;                #取代斷行
        if ($FORM{$name} ne ''){
            $FORM{$name} = "$FORM{$name},$value";                    #給予FORM
        }else{
            $FORM{$name} = $value;
        }
    }
}
## ~---------------------
## ~     係統設定 
## ~---------------------
$news_url     = 'news.pl';          ## 程式位置
$data_url     = 'news/data.cgi';         ## 資料庫位置
$sn_url       = 'news/sn.txt';           ## 流水號檔

$out_skin     = 'out.htm' ;         ## 外部樣版
$table_skin   = 'news/table.htm' ;       ## 表格樣版
$data_skin    = 'news/data.htm' ;        ## 內文樣版
$fix_skin     = 'news/fixform.htm' ;     ## 修改用版面
$new_skin     = 'news/admform.htm' ;     ## 新增登出用版面
$adm_skin     = 'news/adm.htm' ;         ## 登入用版面

$id           = 'victor';           ## 管理帳號 
$pass         = '1v9i8c7t7o9r';            ## 管理密碼

####### ---> 樣版關建字設定 <--- #########
$in_key    = '!~in~!';
$table_key = '!~text~!' ;
$url_key   = '!~newsurl~!';
$out_key   = '!~outtitle~!';

$skin_key{'time'}     ='!~time~!';
$skin_key{'text'}     ='!~text~!';
$skin_key{'sn'}       ='!~sn~!';  
$skin_key{'newsurl'}  ='!~newsurl~!';

## ~---------------------
## ~     主要程式 
## ~---------------------
&getdata;      ## 取得資料
&getcookie;    ## 取得Cookie
&setadmcookie; ## 設定ADMCookie 

&load_skin;    ## 載入樣版
if ($FORM{mode} eq 'new' && &c_idps == 1){
    &newnews;
    print "Location: $news_url\n\n";  ## 跳回原頁
    exit;
}elsif($FORM{mode} eq 'log'){
    &shell_adm_log;
    exit;
}elsif($FORM{mode} eq 'fix' && &c_idps == 1){
    &fixnews($FORM{sn});
    print "Location: $news_url\n\n";  ## 跳回原頁
    exit;
}elsif($FORM{mode} eq 'top' && &c_idps == 1){
    &topnews($FORM{sn});
    print "Location: $news_url\n\n";  ## 跳回原頁
    exit;
}elsif($FORM{mode} eq 'del' && &c_idps == 1){
    &delnews($FORM{sn});
    print "Location: $news_url\n\n";  ## 跳回原頁
    exit;
}elsif($FORM{'mode'} eq 'out' && &c_idps == 1){
    $date_gmt = "1987, 1\-1\-1 1:1:1 GMT";
    print "Set-Cookie:id=0; expires=$date_gmt\n";
    print "Set-Cookie:pass=0; expires=$date_gmt\n";
    print "Location: $news_url\n\n";  ## 跳回原頁
    exit;
}elsif($FORM{mode} eq 'adm' && &c_idps == 1){
    &shell_adm;
    exit;
}
if (&c_idps == 1){
    &shell_adm;
    exit;
}
&shell_web;
## ~---------------------
## ~     輸出網頁
## ~---------------------
sub shell_web{
    print "Content-type: text/html; charset=big5\n\n"; ##輸出網頁檔頭
    if ( !( open(GD,"<$data_url") ) ){&error("$data_url 無法讀檔");}
        @gd=<GD>;
    close(GD);
    foreach $gad(@gd){
        ($GD{'text'},$GD{'time'},$GD{'sn'})= split(/,/,$gad) ;
        chomp($time);
        $getdata  = $dataskin;
        foreach $keyi(keys %skin_key){
            $getdata =~ s/$skin_key{$keyi}/$GD{$keyi}/g;
        }
        $datahtml .= $getdata;
    }
    $getout   = $outskin;
    $gettable = $tableskin;
    
    if ($datahtml eq ''){
       $datahtml='<br><div align="center">沒有消息</div><br>';
    }

    $gettable =~ s/$url_key/$news_url/g;
    $gettable =~ s/$table_key/$datahtml/g;
    $getout =~ s/$in_key/$gettable/g;
    $getout =~ s/$out_key/最新消息/g;
    print "$getout";
}
## ~---------------------
## ~     管理模式 
## ~---------------------
sub shell_adm{
    print "Content-type: text/html; charset=big5\n\n"; ##輸出網頁檔頭
    if ( !( open(GD,"<$data_url") ) ){&error("$data_url 無法讀檔");}
        @gd=<GD>;
    close(GD);
    $GD{'newsurl'}=$news_url;
    foreach $gad(@gd){
        ($GD{'text'},$GD{'time'},$GD{'sn'})= split(/,/,$gad) ;
        chomp($GD{'sn'});
        $GD{'text'}=~ s/<br>/\n/gi;
        $getdata  = $fixskin;
        foreach $keyi(keys %skin_key){
            $getdata =~ s/$skin_key{$keyi}/$GD{$keyi}/g;
        }
        $datahtml .= $getdata;
    }
    $getout   = $outskin;
    $gettable = $tableskin;

    if ($datahtml eq ''){
       $datahtml='<br><div align="center">沒有消息</div><br>';
    }
    $gettable =~ s/$table_key/$datahtml/g;
    $gettable ="$newskin$gettable";
    $gettable =~ s/$url_key/$news_url/g;
    $getout =~ s/$in_key/$gettable/g;
    $getout =~ s/$out_key/最新消息/g;
    print "$getout";
}
## ~---------------------
## ~     登入網頁 
## ~---------------------
sub shell_adm_log{
    print "Content-type: text/html; charset=big5\n\n"; ##輸出網頁檔頭
    $getout   = $outskin;
    $getadm   = $admskin;

    $getadm   =~ s/$url_key/$news_url/g;

    $getout =~ s/$in_key/$getadm/g;
    $getout =~ s/$out_key/最新消息/g;
    print "$getout";
}
## ~---------------------
## ~    新增最新消息
## ~---------------------
sub newnews{
    if ( !( open(GD,"<$data_url") ) ){&error("$data_url 無法讀檔");}
        @gd=<GD>;
    close(GD);

    &getsn;
    
    $text  = $FORM{'text'};
    $time  = $FORM{'time'};
    
    $wd = "$text,$time,$sn\n";
    
    unshift(@gd,$wd);
    ## 對檔尾的斷行去除
    $last=pop(@gd); #取出 
    chomp($last);
    push(@gd,$last); #放回
    ## 存回記錄檔
    if ( !( open(SD,">$data_url") ) ){&error("$data_url無法存檔");}
        flock(2,SD);    #鎖檔
        print SD @gd;
        flock(8,SD);    #開鎖
    close(SD);  
    &addsn;
}

## ~---------------------
## ~     刪除留言 
## ~---------------------
sub delnews{
    ## 取得記錄檔
    if ( !( open(GD,"<$data_url") ) ){&error("$data_url無法讀檔");}
        @gd=<GD>;
    close(GD);
    $delsn=$_[0];
    foreach $gad(@gd){
        ($text,$time,$sn)= split(/,/,$gad) ;
        chomp($sn);
        if ($delsn == $sn){
            $gad='';
        }
    }

    ## 存回記錄檔
    if ( !( open(SD,">$data_url") ) ){&error("$data_url無法存檔");}
        flock(2,SD);    #鎖檔
        print SD @gd;
        flock(8,SD);    #開鎖
    close(SD);
}
## ~---------------------
## ~     修改留言
## ~---------------------
sub fixnews{
    ## 取得記錄檔
    if ( !( open(GD,"<$data_url") ) ){&error("$data_url無法讀檔");}
        @gd=<GD>;
    close(GD);
    $fixsn=$_[0];
    foreach $gad(@gd){
        ($text,$time,$sn)= split(/,/,$gad) ;
        chomp($sn);
        if ($fixsn == $sn){
            $gad="$FORM{text},$FORM{time},$sn\n";
        }
    }
    ## 對檔尾的斷行去除
    $last=pop(@gd); #取出
    chomp($last);
    push(@gd,$last); #放回
    ## 存回記錄檔
    if ( !( open(SD,">$data_url") ) ){&error("$data_url無法存檔");}
        flock(2,SD);    #鎖檔
        print SD @gd;
        flock(8,SD);    #開鎖
    close(SD);
}
## ~---------------------
## ~     修改留言
## ~---------------------
sub topnews{
    ## 取得記錄檔
    if ( !( open(GD,"<$data_url") ) ){&error("$data_url無法讀檔");}
        @gd=<GD>;
    close(GD);
    $topsn=$_[0];
    foreach $gad(@gd){
        ($text,$time,$sn)= split(/,/,$gad) ;
        chomp($sn);
        if ($topsn == $sn){
            splice(@gd,$i,1);
            unshift(@gd,"$text,$time,$sn\n");
        }
        $i++;
    }
    ## 對檔尾的斷行去除
    $last=pop(@gd); #取出
    chomp($last);
    push(@gd,$last); #放回
    ## 存回記錄檔
    if ( !( open(SD,">$data_url") ) ){&error("$data_url無法存檔");}
        flock(2,SD);    #鎖檔
        print SD @gd;
        flock(8,SD);    #開鎖
    close(SD);
}
## ~---------------------
## ~     載入樣版 
## ~---------------------
sub load_skin{
    if ( !( open(SKIN,"<$out_skin") ) ){&error("$out_skin 樣版 無法讀取");}
        @gout=<SKIN>;
    close(SKIN);
    if ( !( open(SKIN,"<$table_skin") ) ){&error("$table_skin 樣版 無法讀取");}
        @gtable=<SKIN>;
    close(SKIN);
    if ( !( open(SKIN,"<$data_skin") ) ){&error("$data_skin 樣版 無法讀取");}
        @gdata=<SKIN>;
    close(SKIN);
    if ( !( open(SKIN,"<$fix_skin") ) ){&error("$fix_skin 樣版 無法讀取");}
        @gfix=<SKIN>;
    close(SKIN);
    if ( !( open(SKIN,"<$new_skin") ) ){&error("$new_skin 樣版 無法讀取");}
        @gnew=<SKIN>;
    close(SKIN);
    if ( !( open(SKIN,"<$adm_skin") ) ){&error("$adm_skin 樣版 無法讀取");}
        @gadm=<SKIN>;
    close(SKIN);
    foreach $line(@gout){
        $outskin="$outskin$line";
    }
    foreach $line(@gtable){
        $tableskin="$tableskin$line";
    }
    foreach $line(@gdata){
        $dataskin="$dataskin$line";
    }
    foreach $line(@gfix){
        $fixskin="$fixskin$line";
    }
    foreach $line(@gnew){
        $newskin="$newskin$line";
    }
    foreach $line(@gadm){
        $admskin="$admskin$line";
    }
}
## ~---------------------
## ~     設定ADM的Cookie
## ~---------------------
sub setadmcookie{
    if ($FORM{id} ne '' && $FORM{pass} ne ''){
       print "Set-Cookie:id=$FORM{id};\n";
       print "Set-Cookie:pass=$FORM{pass};\n";
       $COOKIE{id}=$FORM{id};
       $COOKIE{pass}=$FORM{pass};
    }
}
## ~---------------------
## ~     得到Cookie
## ~---------------------
sub getcookie{
    $cookies = $ENV{'HTTP_COOKIE'};
    @pairs = split(/;/,$cookies);  ##取得不同組的cookie
    foreach $pair (@pairs) {
        ($name, $value) = split(/=/, $pair);
        $name =~ s/ //g;
        $COOKIE{$name} = $value;
    }
    if ($FORM{'pass'} ne ''){ $COOKIE{'pass'}=$FORM{'pass'};}
    if ($FORM{'id'} ne ''){ $COOKIE{'id'}=$FORM{'id'};}
}
## ~---------------------
## ~  確認帳號密碼 
## ~---------------------
sub c_idps{
    if(($FORM{id} eq $id && $FORM{pass} eq $pass) ||
       ($COOKIE{id} eq $id && $COOKIE{pass} eq $pass)){
        return 1;
    }else{
        return 0;
    }
}
## ~---------------------
## ~     得到流水號
## ~---------------------
sub getsn{
    if ( !( open(SN,"<$sn_url") ) ){&error("$sn_url無法讀取");}
        $sn=<SN>;
    close(SN);
    ## 流水號檔內容為空 設為0
    if ($sn eq '') {
       $sn=0;
    }
}
## ~---------------------
## ~     遞增流水號
## ~---------------------
sub addsn{
    $sn++;
    if ( !( open(SN,">$sn_url") ) ){&error("$sn_url無法存檔");}
        print SN $sn;
    close(SN);
}
## ~---------------------
## ~     發生錯誤
## ~---------------------
sub error{
    print "Content-type: text/html; charset=big5\n\n"; ##輸出網頁檔頭
    print "發生錯誤 : $_[0]" ;
    exit;
}
