540 lines
18 KiB
Perl
540 lines
18 KiB
Perl
#!/usr/bin/perl
|
|
|
|
BEGIN { use lib '/usr/home/cfg' ; require push_inc ; }
|
|
|
|
require cfg ;
|
|
|
|
use CGI::Carp qw(fatalsToBrowser);
|
|
use CGI;
|
|
use File::Find;
|
|
use File::Path 'rmtree';
|
|
use File::Copy;
|
|
use File::Basename;
|
|
use MIME::Lite;
|
|
use Mail::Sendmail;
|
|
use Date::Calc qw(:all);
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
my ($q) = CGI -> new() ;
|
|
$iaction = $q -> param('iaction') || '' ;
|
|
$idelaction = $q -> param('idelaction') || '' ;
|
|
$izip = $q -> param('izip') || '' ; # quote-Sep-2016
|
|
|
|
if ($izip) { our ($ztype,$zmonth,$zyear) = split(/\-/,$izip) ; }
|
|
|
|
unless ((lc $username eq 'vivian') or ($username eq 'rory')) { print "<<<<<<<<<<<<<<<< UNAUTHORIZED >>>>>>>>>>>>>>>" ; exit ; }
|
|
# unless ($username eq 'rory') { print "<<<<<<<<<<<<<<<< CLOSED FOR MAINTENANCE >>>>>>>>>>>>>>>" ; exit ; }
|
|
|
|
my $uploadspath = "$htmlpath/uploads" ;
|
|
# my $uploadspath = "$htmlpath/uploads_test" ;
|
|
# my $archivezip = "$htmlpath/archives/uploads.zip" ;
|
|
my $archivezipdir = "$htmlpath/archives" ;
|
|
|
|
# our $debug = 1 ;
|
|
|
|
our $to = 'vivian@filmfreight.co.za' ; if ($debug) { $to = 'rory@kre8it.co.za' ; }
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
print "Content-type: text/html\n\n";
|
|
|
|
&today;
|
|
|
|
if ($iaction eq ''){
|
|
&get_uploads ;
|
|
&server_usage ;
|
|
&display_screen1 ;
|
|
}
|
|
|
|
if ($iaction eq 'zip'){
|
|
&get_uploads ;
|
|
&delete_previous_zips ;
|
|
&archive_zip ;
|
|
&send_email ;
|
|
&update_sent ;
|
|
&server_usage ;
|
|
&display_screen1 ;
|
|
}
|
|
|
|
if ($iaction eq 'deluploads'){
|
|
&get_uploads ;
|
|
&delete_uploads ;
|
|
&server_usage ;
|
|
&display_screen1 ;
|
|
}
|
|
|
|
exit ;
|
|
|
|
#--------------------------------------------------------------------------------------------
|
|
|
|
sub get_uploads {
|
|
|
|
&read_uploads_dir("$uploadspath") ;
|
|
# &read_uploads_dir("$uploadspath/journeys") ;
|
|
&process_uploads ;
|
|
|
|
} #--------------------------------------------------------------------------------------------
|
|
|
|
sub update_sent {
|
|
|
|
# if (-e $archivezip) { unlink $archivezip ; }
|
|
|
|
unless ($izip) { return ; }
|
|
|
|
$i{sent_to} = "$to" ;
|
|
$i{send_date} = "$now_ccyy_mm_dd $now_hour:$now_min:$now_sec" ;
|
|
&db_min_upd('uploads_backup',"`month`='$zmonth' AND `year`='$zyear' AND `type`='$ztype'") ;
|
|
|
|
} #--------------------------------------------------------------------------------------------
|
|
|
|
sub read_uploads_dir {
|
|
|
|
my ($path) = @_ ;
|
|
|
|
opendir(DIR,"$path") or die "cant open directory: $path - $!\n";
|
|
|
|
while(defined($folder = readdir(DIR))) {
|
|
if (length $folder > 2) {
|
|
my ($file,$type) = split(/\./,$folder) ;
|
|
|
|
# if ($folder eq 'journeys') { next ; }
|
|
|
|
# print "<br>$path" ;
|
|
|
|
if (-d "$path/$folder"){ # check if directory
|
|
&read_uploads_dir_drill_1("$path/$folder") ;
|
|
}
|
|
|
|
# $ff++;
|
|
# if ($ff == 50) { last ; }
|
|
}
|
|
}
|
|
|
|
closedir(DIR) ;
|
|
|
|
} #--------------------------------------------------------------------------------------------
|
|
|
|
sub read_uploads_dir_drill_1 {
|
|
|
|
my ($path) = @_ ;
|
|
|
|
# print "<br>$path" ;
|
|
|
|
opendir(DIR2, "$path") or die "cant open directory: $path - $!\n";
|
|
|
|
while (defined($folder2 = readdir(DIR2))) {
|
|
|
|
if (length $folder2 > 2) {
|
|
my ($file,$type) = split(/\./,$folder2) ;
|
|
my @file_attributes = stat ("$path/$folder2") ;
|
|
my $file_modified_time_readable = localtime ($file_attributes[9]) ;
|
|
|
|
# print "<br>$folder2 : $file_modified_time_readable" ;
|
|
|
|
my @file_name = split(/\_/,$folder2) ;
|
|
my @date_data = split(/ /,$file_modified_time_readable) ;
|
|
my $year = substr($file_modified_time_readable,-4,4) ;
|
|
|
|
if ($izip) {
|
|
if (($year eq $zyear) and ($zmonth eq $date_data[1]) and ($ztype eq $file_name[0])) {
|
|
push @zip_file_arr, "$path/$folder2" ;
|
|
}
|
|
}
|
|
|
|
# $files_to_zip_hash{$file_name[0]}{$date_data[4]}{$date_data[1]}++ ;
|
|
$files_to_zip_hash{$file_name[0]}{$year}{$date_data[1]}++ ;
|
|
|
|
# for (1 .. 30) {
|
|
# if ($file_attributes[$_]) { print ', ' . $_ . '.' . $file_attributes[$_] ; }
|
|
# }
|
|
}
|
|
}
|
|
|
|
closedir(DIR2) ;
|
|
|
|
} #--------------------------------------------------------------------------------------------
|
|
|
|
sub process_uploads {
|
|
|
|
&db_min_ro('uploads_backup','*','','','') ;
|
|
|
|
foreach my $id (sort {$db{uploads_backup}{$a}{year} cmp $db{uploads_backup}{$b}{year}} keys %{$db{uploads_backup}}) {
|
|
my $send_date = $db{uploads_backup}{$id}{send_date} ;
|
|
my $sent_to = $db{uploads_backup}{$id}{sent_to} ;
|
|
my $bak_count = $db{uploads_backup}{$id}{count} ;
|
|
my $bak_year = $db{uploads_backup}{$id}{year} ;
|
|
my $bak_month = $db{uploads_backup}{$id}{month} ;
|
|
my $bak_type = $db{uploads_backup}{$id}{type} ; my $ucf_bak_type = ucfirst $bak_type ;
|
|
$db_entry_exists{$bak_year}{$bak_month}{$bak_type} = $bak_count ;
|
|
$sent{$bak_year}{$bak_month}{$bak_type} = $sent_to ;
|
|
|
|
my $print_sent_to = '' ; if ($sent_to) { $print_sent_to = qq(sent to $sent_to ($send_date)) ; }
|
|
|
|
my $selected = '' ; if ($izip eq "$bak_type-$bak_month-$bak_year") { $selected = 'SELECTED' ; }
|
|
|
|
if ($bak_type eq 'pod') { next ; }
|
|
if ($bak_type eq 'vat') { next ; }
|
|
|
|
$opts{zip} .= qq(<option value="$bak_type-$bak_month-$bak_year" $selected>$ucf_bak_type $bak_month $bak_year [$bak_count] $print_sent_to</option>) ;
|
|
}
|
|
|
|
foreach my $type (keys %files_to_zip_hash) {
|
|
foreach my $year (keys %{$files_to_zip_hash{$type}}) {
|
|
foreach my $month (keys %{$files_to_zip_hash{$type}{$year}}) {
|
|
# print "$type $month $year [$files_to_zip_hash{$type}{$year}{$month}] \n" ;
|
|
|
|
%i = () ;
|
|
|
|
if ($db_entry_exists{$year}{$month}{$type}) {
|
|
unless ($db_entry_exists{$year}{$month}{$type} == $files_to_zip_hash{$type}{$year}{$month}) {
|
|
$i{count} = "$files_to_zip_hash{$type}{$year}{$month}" ;
|
|
$i{sent_to} = '' ;
|
|
&db_min_upd('uploads_backup',"`month`='$month' AND `year`='$year' AND `type`='$type'") ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$i{month} = "$month" ;
|
|
$i{type} = "$type" ;
|
|
$i{year} = "$year" ;
|
|
$i{count} = "$files_to_zip_hash{$type}{$year}{$month}" ;
|
|
$i{sent_to} = '' ;
|
|
&db_min_insert('uploads_backup') ;
|
|
my $ucf_type = ucfirst $type ;
|
|
$opts{zip} .= qq(<option value="$type-$month-$year">$ucf_type $month $year [$files_to_zip_hash{$type}{$year}{$month}]</option>) ;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
$archivezip = "$htmlpath/archives/$izip.zip" ;
|
|
|
|
our $g_archiveziplink = $archivezip ; $g_archiveziplink =~ s/\/var\/www\/html/https:\/\/www.ffwaybill.co.za/gi ;
|
|
our $g_archivezipname = $archivezip ; $g_archivezipname =~ s/\/var\/www\/html//gi ;
|
|
our $g_zip_link = qq(<b>DOWNLOAD NOW as it will be deleted if older than a week : <a href="$g_archiveziplink" target="_blank">$g_archivezipname</a></b><br>);
|
|
|
|
} #--------------------------------------------------------------------------------------------
|
|
|
|
sub delete_uploads {
|
|
|
|
# CHECK ZIP EXISTS THEN OPEN DOWNLOAD LINK AFTER DELETE
|
|
|
|
unless (-e $archivezip) {
|
|
$alert = qq(<div class="alert alert-danger" role="alert"><i class="glyphicon glyphicon-warning-sign"></i> No zipped file in existance, please zip and download first!</div>) ;
|
|
return ;
|
|
}
|
|
|
|
# our $download_zip_after_delete = qq(
|
|
# \$(function () {
|
|
# window.open("$archiveziplink")
|
|
# });
|
|
# );
|
|
|
|
our $download_zip_after_delete = qq(
|
|
\$(document).ready(function(){ \$('#open-zip').submit(); })
|
|
);
|
|
|
|
my $sent_to = $sent{$zyear}{$zmonth}{$ztype} ;
|
|
|
|
unless ($sent_to) {
|
|
$alert = qq(<div class="alert alert-danger" role="alert"><i class="glyphicon glyphicon-warning-sign"></i> Files have not been zipped and emailed, do this before deleting the uploads!</div>) ;
|
|
return ;
|
|
}
|
|
|
|
my $deleted = '' ;
|
|
|
|
foreach my $filepath (@zip_file_arr) {
|
|
# print "unlink $filepath \n" ;
|
|
$files_affected .= qq(delete $filepath<br>) ;
|
|
unlink ($filepath) ; $deleted = 1 ;
|
|
}
|
|
|
|
if ($deleted) {
|
|
$i{delete_date} = "$now_ccyy_mm_dd $now_hour:$now_min:$now_sec" ;
|
|
&db_min_upd('uploads_backup',"`month`='$zmonth' AND `year`='$zyear' AND `type`='$ztype'") ;
|
|
}
|
|
|
|
$alert = qq(<div class="alert alert-success" role="alert"><i class="glyphicon glyphicon-ok-circle"></i> Files deleted!</div>) ;
|
|
|
|
} #--------------------------------------------------------------------------------------------
|
|
|
|
sub archive_zip {
|
|
|
|
use Archive::Zip;
|
|
use Archive::Zip::Tree ;
|
|
|
|
$archivezip = "$htmlpath/archives/$izip.zip" ;
|
|
|
|
if (-e $archivezip) { unlink $archivezip ; }
|
|
|
|
my $zip = Archive::Zip->new() ;
|
|
|
|
foreach my $filepath (@zip_file_arr) {
|
|
# print "$filepath \n" ;
|
|
$zip->addTree($filepath,'');
|
|
|
|
# my $link = $filepath ; $link =~ s/\\var\\www\\html/https:\/\/www.ffwaybill.co.za/gi ; $link =~ s/\\/\//gi ;
|
|
my $name = $filepath ; $name =~ s/\/var\/www\/html//gi ;
|
|
my $link = $filepath ; $link =~ s/\/var\/www\/html/https:\/\/www.ffwaybill.co.za/gi ;
|
|
$c++;
|
|
$emsg .= qq(<tr><td> $c </td><td> <a href="$link" target="_blank">$name</a> </td></tr>
|
|
) ;
|
|
$files_affected .= qq(zipped <a href="$link" target="_blank">$name</a> <br>) ;
|
|
}
|
|
|
|
my $archivezipname = $archivezip ; $archivezipname =~ s/\/var\/www\/html//gi ;
|
|
my $archiveziplink = $archivezip ; $archiveziplink =~ s/\/var\/www\/html/https:\/\/www.ffwaybill.co.za/gi ;
|
|
|
|
$zip_link = qq(<tr><td> </td><td> <b>Download ZIP now as it will be deleted : <a href="$archiveziplink" target="_blank">$archivezipname</a></b> </td></tr>);
|
|
|
|
$zip->writeToFileNamed($archivezip) ; # or die "could not execute : $!" ;
|
|
|
|
if (-e $archivezip) {
|
|
$alert = qq(<div class="alert alert-success" role="alert"><i class="glyphicon glyphicon-ok-circle"></i> Zipped & Sent to $to!</div>) ;
|
|
}
|
|
else
|
|
{
|
|
$alert = qq(<div class="alert alert-danger" role="alert"><i class="glyphicon glyphicon-warning-sign"></i> ERROR!</div>) ;
|
|
}
|
|
|
|
} #--------------------------------------------------------------------------------------------
|
|
|
|
sub delete_previous_zips {
|
|
|
|
opendir(DIR, "$archivezipdir") or die "cant open Directory $archivezipdir: $!\n";
|
|
|
|
while(defined($folder = readdir(DIR))) {
|
|
if (length $folder > 2) {
|
|
my ($file,$type) = split(/\./,$folder) ;
|
|
#only delete if more than a week old
|
|
|
|
my ($chk_year,$chk_month,$chk_day,$chk_hour,$chk_min,$chk_sec) = Add_Delta_DHMS($now_year,$now_mm,$now_dd,$now_hour,$now_min,$now_sec,-7,0,0,0); # check n days back
|
|
|
|
$chk_month = sprintf("%02s", $chk_month) ;
|
|
$chk_day = sprintf("%02s", $chk_day) ;
|
|
|
|
my @file_attributes = stat ("$archivezipdir/$file.zip") ;
|
|
# my $file_modified_time_readable = localtime ($file_attributes[9]) ;
|
|
|
|
($file_sec,$file_min,$file_hour,$file_dd,$file_mm,$file_year,$file_wday,$file_yday,$isdst)=localtime($file_attributes[9]);
|
|
|
|
$file_year += 1900;
|
|
|
|
$file_dd = sprintf("%02s", $file_dd) ;
|
|
$file_mm = sprintf("%02s", $file_mm + 1) ;
|
|
|
|
$file_ccyymmdd = $file_year . $file_mm . $file_dd ;
|
|
|
|
if ("$file_ccyymmdd" < "$chk_year$chk_month$chk_day") {
|
|
unlink ("$archivezipdir/$file.zip") or print "unable to unlink - $archivezipdir/$folder : $!";
|
|
# print "unlink - $archivezipdir/$folder";
|
|
}
|
|
}
|
|
}
|
|
|
|
closedir(DIR) ;
|
|
|
|
} #------------------------------------------------------------------------------------
|
|
|
|
sub archive_unzip {
|
|
|
|
# my ($uploadpath,$uploadfile) = @_ ;
|
|
|
|
# use Archive::Extract;
|
|
|
|
# $ae = Archive::Extract->new(archive => "$uploadpath/$uploadfile.zip") ;
|
|
# $ae->extract( to => "$uploadpath");
|
|
|
|
} #--------------------------------------------------------------------------------------------
|
|
|
|
sub server_usage {
|
|
|
|
my $size = 0;
|
|
find( sub { $size += -f $_ ? -s _ : 0 }, "$htmlpath" );
|
|
|
|
$size = $size / 1000000 ; # convert to MB
|
|
$serverspace = 19000 ; # MB (19.00 GB)
|
|
$usage = sprintf("%.2f",($size / $serverspace * 100)) ; # %
|
|
|
|
if ($alert) { return ; }
|
|
|
|
if ($usage > 90) {
|
|
$alert = qq(<div class="alert alert-danger" role="alert"><i class="glyphicon glyphicon-warning-sign"></i> DANGER, YOU ARE RUNNING OUT OF SPACE ON THE SERVER, ARCHIVE NOW!</div>) ;
|
|
}
|
|
elsif ($usage > 80) {
|
|
$alert = qq(<div class="alert alert-warning" role="alert"><i class="glyphicon glyphicon-info-sign"></i> WARNING, YOU ARE RUNNING OUT OF SPACE ON THE SERVER, ARCHIVE SOON!</div>) ;
|
|
}
|
|
else
|
|
{
|
|
$alert = qq(<div class="alert alert-success" role="alert"><i class="glyphicon glyphicon-ok-circle"></i> YOU HAVE SUFFICIENT SPACE ON THE SERVER!</div>) ;
|
|
}
|
|
|
|
} #--------------------------------------------------------------------------------------------
|
|
|
|
sub display_screen1 {
|
|
|
|
if ($files_affected) {
|
|
$print_files_affected = qq(<div class="row">
|
|
<div class="box col-md-12">
|
|
<div class="box-inner">
|
|
<div class="box-header well" data-original-title="">
|
|
<h2><i class="glyphicon glyphicon-file"></i> Files</h2>
|
|
</div>
|
|
<div class="box-content">
|
|
<div class="row"><div class="col-md-12"> </div></div>
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
$g_zip_link
|
|
$files_affected
|
|
</div>
|
|
</div>
|
|
<div class="row"><div class="col-md-12"> </div></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div><!--/row--> );
|
|
}
|
|
|
|
$print_usage = qq(<div class="row">
|
|
<div class="box col-md-12">
|
|
<div class="box-inner">
|
|
<div class="box-header well" data-original-title="">
|
|
<h2><i class="glyphicon glyphicon-film"></i> Server Usage</h2>
|
|
</div>
|
|
<div class="box-content">
|
|
<div class="row"><div class="col-md-12"> </div></div>
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="progress">
|
|
<div class="progress-bar" role="progressbar" aria-valuenow="$usage" aria-valuemin="0" aria-valuemax="100" style="width: $usage\%;">
|
|
$usage\%
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div><!--/row-->
|
|
<div class="row"><div class="col-md-12"> </div></div>
|
|
<div class="row">
|
|
<div class="box col-md-12">
|
|
<div class="box-inner">
|
|
<div class="box-header well" data-original-title="">
|
|
<h2><i class="glyphicon glyphicon-film"></i> Backup Option</h2>
|
|
</div>
|
|
<div class="box-content">
|
|
<div class="row"><div class="col-md-12"> </div></div>
|
|
<div class="row">
|
|
<div class="col-md-5">
|
|
<div class="control-group">
|
|
<div class="controls">
|
|
<select class="form-control" style="margin:2px 0 2px 0;" name="zip" id="selectZip" data-placeholder="Select Zip" data-rel="chosen" tabindex="1">
|
|
$opts{zip}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row"><div class="col-md-12"> </div></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div><!--/row-->
|
|
<div class="row"><div class="col-md-12"> </div></div>
|
|
$print_files_affected) ;
|
|
|
|
$print_buttons = qq(
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<a href="javascript:zipUploads();" class="btn btn-success"><i class="glyphicon glyphicon-envelope"></i> ZIP & SEND SELECTED UPLOADS</a>
|
|
<a href="javascript:zipDelete();" class="btn btn-danger"><i class="glyphicon glyphicon-trash"></i> DELETE SELECTED UPLOADS</a>
|
|
<button type="button" class="btn btn-default" onclick="history.go(-1);">Back</button>
|
|
</div>
|
|
</div>) ;
|
|
|
|
&screen1 ;
|
|
|
|
} #------------------------------------------------------------------------------------------
|
|
|
|
sub screen1 {
|
|
|
|
require archive ;
|
|
|
|
exit;
|
|
|
|
} #------------------------------------------------------------------------------------------
|
|
|
|
sub send_email {
|
|
|
|
$msg = MIME::Lite -> new(
|
|
From => 'Film Freight <info@filmfreight.co.za>',
|
|
To => $to,
|
|
Subject => "FF Backup : $izip : $now_year-$now_mm-$now_dd",
|
|
Type => 'multipart/mixed'
|
|
);
|
|
|
|
# my $boundary = "====" . time() . "====";
|
|
|
|
my $email_body = <<END_OF_BODY;
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
|
|
<title></title>
|
|
|
|
<style type="text/css">
|
|
body { background-color:#ffffff; color:#222222; }
|
|
tbody tr td { font-size: 11px; }
|
|
.table th{background-color:#fff !important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}
|
|
.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#EEEEEE; color:#222222; }
|
|
.table-striped>tbody>tr:nth-child(even)>td,.table-striped>tbody>tr:nth-child(even)>th{ background-color:#A4A2A2; color:#ffffff; }
|
|
.table-striped>tbody>tr:nth-child(odd)>td a:not(.btn) { text-decoration: none; color: #375A7F; font-weight: bold; }
|
|
.table-striped>tbody>tr:nth-child(even)>td a:not(.btn) { text-decoration: none; color: #BCCEE2; font-weight: bold; }
|
|
.table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td { height: 8px; vertical-align: middle; }
|
|
</style>
|
|
|
|
</head>
|
|
<body style="background-color: #FFFFFF; font-family: Arial, Helvetica, sans-serif; font-size: 13px">
|
|
|
|
<div align="center">
|
|
|
|
<img alt="Film Freight" src="https://www.ffwaybill.co.za/img/filmfreight_logo.jpg" border="0"></a>
|
|
<br><br>
|
|
|
|
<table id="ff-table" class="table table-striped table-bordered bootstrap-datatable datatable responsive">
|
|
<thead><tr><th> </th><th>Link</th></tr></thead>
|
|
<tbody>
|
|
$zip_link
|
|
$emsg
|
|
</tbody>
|
|
</table>
|
|
|
|
</p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
END_OF_BODY
|
|
|
|
$msg -> attach(
|
|
Type => 'text/html',
|
|
Data => $email_body
|
|
);
|
|
|
|
# $msg -> attach (
|
|
# Type => 'AUTO',
|
|
# Path => "$archivezip",
|
|
# Filename => "$izip.zip",
|
|
# Disposition => 'attachment'
|
|
# ) or die "Error adding $path : $attach $!\n";
|
|
|
|
$msg -> send ('smtp','localhost', Debug=>0 );
|
|
|
|
} #-------------------------------------------------------------------------------
|
|
|
|
use today ;
|
|
use common ;
|
|
|
|
1; |