From ccffe251fcf2b6528f938c79de6331af7bb9d418 Mon Sep 17 00:00:00 2001 From: b Date: Mon, 28 Dec 2015 20:09:31 +0000 Subject: [PATCH] moved data file functions to library fixed bot bug - entity encoding of hyperlinks interface shows thread lists and images git-svn-id: svn://botcastle1b/yplom/facebug1@11 7dec801f-c475-4e67-ba99-809552d69c55 --- bot.1.pl | 125 +-------------- configure.pl | 4 + facebug_lib.1.pm | 119 ++++++++++++++- if.css | 208 ++++++++++++++++--------- interface.1.pl | 385 ++++++++++++++++++++++++++++++++++++++++++++--- settings | 5 +- 6 files changed, 626 insertions(+), 220 deletions(-) diff --git a/bot.1.pl b/bot.1.pl index 04a9288..4cbab6b 100644 --- a/bot.1.pl +++ b/bot.1.pl @@ -11,8 +11,8 @@ use Fcntl; use File::Copy; ###PROXY_LIB; ###FACEBUG_LIB; -use proxy_lib qw(url2path urldiv2path path2urldiv getcgi divideurl joinurl readconfigfile entitydecode urldecode readheaderfile); -use facebug_lib qw(key); +use proxy_lib qw(url2path urldiv2path path2urldiv getcgi divideurl joinurl readconfigfile entitydecode entityencode urldecode readheaderfile); +use facebug_lib qw(key readdatafile writedatafile); use POSIX qw(strftime); ###ARCH_PATH; @@ -619,7 +619,7 @@ sub processfile { elsif ($tag{'<'} eq 'a') { # a link to an external page if ($tag{'href'} =~ /^https?:\/\/([a-z0-9\.\-]+)?facebook\.com\/l\.php\?(.*&)?u=([^&]+)(&.*)?$/) { - $thread{'postcontent'}.=''; + $thread{'postcontent'}.=''; $link=1; } # a link to a user @@ -983,7 +983,7 @@ sub processfile { elsif ($tag{'<'} eq 'a') { # a link to an external page if ($tag{'href'} =~ /^https?:\/\/([a-z0-9\.\-]+)?facebook\.com\/l\.php\?(.*&)?u=([^&]+)(&.*)?$/) { - $post{'content'}.=''; + $post{'content'}.=''; $link=1; } # a link to a user @@ -1091,123 +1091,6 @@ sub processfile { close ($contentfile); } -# Function to read data from datafiles. -# Very similar to http header file reading. (function readheaderfile() in proxy -# library) -# -# Differences: -# -# 1. After field name and colon there must be exactly one whitespace (space or -# tab). Any other leading or trailing whitespace (but not the newline character -# at the end of the line) is treated as part of the field value. -# -# 2. When header field is split into multiple lines the next lines must start -# with exactly one whitespace (tab or space) Any other leading or trailing -# whitespace (but not the newline character at the end of the line) is treated -# as part of the field value. the lines will be joined with a newline between -# them. -# -# 3. When the same field name appears it replaces the previous one. -# -# 4. Line separator is LF and not CR LF. The CR character is treated as part of -# the field value. -# -# Returns a hash containing the values. -# Names are case sensitive and are converted to lowercase -# -# Argument can be a path or a file handle. In case of a file handle it will just -# read the file. In case of path it opens the file before reading and closes -# after. On failure (file not open) returns empty hash. -# -sub readdatafile { - (my $datapath) = @_; - my $datafile; - my %data; - - # check if $datapath is actually a path or maybe a filehandle - # filehandles are references. - if(ref($datapath)) { - $datafile=$datapath; - } - else { - unless (open ($datafile, "<", $datapath)) { - return %data; - } - } - - # The name of header field in previous line. Required for header fields that - # occupy multiple lines. - my $lastname=''; - - while (defined(my $line = <$datafile>)) { - $line =~ s/[\n]$//g; - my $name=''; - my $value=''; - - # Line starts with whitespace. It's a continuation of the previous line. - # Concatenate the field value, separated by newline. - if($line =~ /^[ \t](.*)$/){ - if($lastname ne '') { - $data{$lastname}.="\n".$1; - } - } - # Line starts with a name followed by colon. Save the value - elsif ($line =~ /^([^:]+):[ \t](.*)$/) { - $name = lc($1); - $value = $2; - - $data{$name}=$value; - - $lastname = $name; - } - } - - # If argument was a path the file must be closed. - unless (ref($datapath)) { - close ($datafile); - } - - return %data; -} - -# the function to write data to datafiles (see readdatafile() description) -# -# First argument can be a path or a file handle. In case of a file handle it -# will just read the file. In case of path it opens the file before writing and -# closes after. -# -# On failure (file not open) returns 0. -# On success returns 1. -# -sub writedatafile { - (my $headerpath, my %header) = @_; - my $headerfile; - - if(ref($headerpath)) { - $headerfile=$headerpath; - } - else { - unless (open ($headerfile, ">", $headerpath)) { - return 0; - } - } - - foreach my $ind (keys %header) { - my $headname = $ind; - my $headval = $header{$ind}; - $headval =~ s/\r//g; - $headval =~ s/\n/\n /g; - print $headerfile "$headname: $headval\n"; - } - print $headerfile "\n"; - - unless (ref($headerpath)) { - close ($headerfile); - } - - return 1; -} - # Function to get a timenumber from a "date" http header field value. # It's a 14 digit number: 4 - year, 2 - month, 2 - day, 2 - hour, 2 - minute, # 2 - second. diff --git a/configure.pl b/configure.pl index 3d3abaf..43c96c5 100644 --- a/configure.pl +++ b/configure.pl @@ -36,12 +36,16 @@ $def{'PROXY_ARCH_PATH'} = "use constant PROXY_ARCH_PATH => '".$set{'proxy $def{'ARCH_PATH'} = "use constant ARCH_PATH => '".$set{'data_path'}."group/';"; $def{'GROUPSETTINGS_PATH'} = "use constant GROUPSETTINGS_PATH => '".$set{'data_path'}."groupsettings/';"; $def{'KEY_BITS'} = "use constant KEY_BITS => ".$set{'key_bits'}.";"; +$def{'THREADS_IN_PAGE'} = "use constant THREADS_IN_PAGE => ".$set{'threads_in_page'}.";"; +$def{'POSTS_IN_PAGE'} = "use constant POSTS_IN_PAGE => ".$set{'postss_in_page'}.";"; $def{'MAX_REDIRECTIONS'} = "use constant MAX_REDIRECTIONS => ".$set{'max_redirections'}.";"; $def{'IF_CSS_PATH'} = "use constant IF_CSS_PATH => '".$set{'interface_path'}."/if.css';"; $def{'INTERFACE_PATH'} = "use constant INTERFACE_PATH => '".$set{'interface_path'}."/view';"; $def{'LOGIN_PATH'} = "use constant LOGIN_PATH => '".$set{'interface_path'}."/view/login';"; $def{'LIST_PATH'} = "use constant LIST_PATH => '".$set{'interface_path'}."/view/list';"; $def{'GROUP_PATH'} = "use constant GROUP_PATH => '".$set{'interface_path'}."/view/group';"; +$def{'THREAD_PATH'} = "use constant THREAD_PATH => '".$set{'interface_path'}."/view/thread';"; +$def{'IMAGE_PATH'} = "use constant IMAGE_PATH => '".$set{'interface_path'}."/view/image';"; $def{'PASS_PATH'} = "use constant PASS_PATH => '".$set{'data_path'}."pass/';"; $def{'ACCESS_PATH'} = "use constant ACCESS_PATH => '".$set{'data_path'}."access/';"; $def{'TIMEOUT_UNLOCK'} = "use constant TIMEOUT_UNLOCK => ".$set{'timeout_unlock'}.";"; diff --git a/facebug_lib.1.pm b/facebug_lib.1.pm index 360cb4f..d7a6e95 100644 --- a/facebug_lib.1.pm +++ b/facebug_lib.1.pm @@ -10,7 +10,7 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); $VERSION = 0.000000; @ISA = qw(Exporter); @EXPORT = (); -@EXPORT_OK = qw(key); +@EXPORT_OK = qw(key readdatafile writedatafile); %EXPORT_TAGS = (); # Function to generate a random hexadecimal number (key) with a defined number @@ -31,4 +31,121 @@ sub key { return $keytext; } +# Function to read data from datafiles. +# Very similar to http header file reading. (function readheaderfile() in proxy +# library) +# +# Differences: +# +# 1. After field name and colon there must be exactly one whitespace (space or +# tab). Any other leading or trailing whitespace (but not the newline character +# at the end of the line) is treated as part of the field value. +# +# 2. When header field is split into multiple lines the next lines must start +# with exactly one whitespace (tab or space) Any other leading or trailing +# whitespace (but not the newline character at the end of the line) is treated +# as part of the field value. the lines will be joined with a newline between +# them. +# +# 3. When the same field name appears it replaces the previous one. +# +# 4. Line separator is LF and not CR LF. The CR character is treated as part of +# the field value. +# +# Returns a hash containing the values. +# Names are case sensitive and are converted to lowercase +# +# Argument can be a path or a file handle. In case of a file handle it will just +# read the file. In case of path it opens the file before reading and closes +# after. On failure (file not open) returns empty hash. +# +sub readdatafile { + (my $datapath) = @_; + my $datafile; + my %data; + + # check if $datapath is actually a path or maybe a filehandle + # filehandles are references. + if(ref($datapath)) { + $datafile=$datapath; + } + else { + unless (open ($datafile, "<", $datapath)) { + return %data; + } + } + + # The name of header field in previous line. Required for header fields that + # occupy multiple lines. + my $lastname=''; + + while (defined(my $line = <$datafile>)) { + $line =~ s/[\n]$//g; + my $name=''; + my $value=''; + + # Line starts with whitespace. It's a continuation of the previous line. + # Concatenate the field value, separated by newline. + if($line =~ /^[ \t](.*)$/){ + if($lastname ne '') { + $data{$lastname}.="\n".$1; + } + } + # Line starts with a name followed by colon. Save the value + elsif ($line =~ /^([^:]+):[ \t](.*)$/) { + $name = lc($1); + $value = $2; + + $data{$name}=$value; + + $lastname = $name; + } + } + + # If argument was a path the file must be closed. + unless (ref($datapath)) { + close ($datafile); + } + + return %data; +} + +# the function to write data to datafiles (see readdatafile() description) +# +# First argument can be a path or a file handle. In case of a file handle it +# will just read the file. In case of path it opens the file before writing and +# closes after. +# +# On failure (file not open) returns 0. +# On success returns 1. +# +sub writedatafile { + (my $headerpath, my %header) = @_; + my $headerfile; + + if(ref($headerpath)) { + $headerfile=$headerpath; + } + else { + unless (open ($headerfile, ">", $headerpath)) { + return 0; + } + } + + foreach my $ind (keys %header) { + my $headname = $ind; + my $headval = $header{$ind}; + $headval =~ s/\r//g; + $headval =~ s/\n/\n /g; + print $headerfile "$headname: $headval\n"; + } + print $headerfile "\n"; + + unless (ref($headerpath)) { + close ($headerfile); + } + + return 1; +} + 1; diff --git a/if.css b/if.css index 45f55e7..b617f7a 100644 --- a/if.css +++ b/if.css @@ -1,5 +1,5 @@ -/* Currently, it's identical to botm.css, the default style of - 1190.bicyclesonthemoon.info. May be changed in the future. */ +/* It's derived from botm.css, the default style of + 1190.bicyclesonthemoon.info. */ html { @@ -49,142 +49,200 @@ a:hover:visited color: #ffffff!important; } -form.hl { +form.inline { display: inline; } - -table.pl -{ +input.hl { + background:none!important; + border:none!important; + padding:0!important; +/* font-family:inherit; + font-size:inherit; */ + font: inherit; + text-decoration:underline; border-color: #0057af; - border-width: 4px 16px 16px 16px; - border-style: solid; - border-spacing: 0px; + color: #0057af; +} +input.hl:hover { + border-color: #bb6622; + color: #bb6622; } -div.pl +input.textfield { border-color: #0057af; - border-width: 4px 16px 16px 16px; + color: #000000; + background-color: #ffffff; + border-width: 2px; border-style: solid; - /* border-spacing: 0px; */ + margin: 2px; } -div.in +input.textfield:focus { - display: inline-block; + border-color: #bb6622; } -div.le +select.pk { - float: left; + border-color: #0057af; + color: #000000; + background-color: #ffffff; + border-width: 2px; + border-style: solid; + margin: 2px; } -div.pr +select.pk:focus { - float: right; + border-color: #bb6622; } -.tp +input.button { - text-align: right; + border-color: #0057af; + color: #000000; + background-color: #ffffff; + border-width: 2px; + border-style: solid; + margin: 2px; } -div.pls -{ - text-align: center; - font-weight: bold; +input.pagebutton { + border-color: #0057af; + color: #000000; + background-color: #ffffff; + border-width: 2px; + border-style: solid; + margin: 2px; + padding: 0px; + font-size: 70%; +} +input.samepagebutton { + border-color: #0057af; color: #ffffff; background-color: #0057af; - width: 100%; + border-width: 2px; + border-style: solid; + margin: 2px; + padding: 0px; + font-size: 70%; } -div.plt +input.button:focus { - color: #ffffff; - background-color: #0057af; - width: 100%; - clear: both; + border-color: #bb6622; } -div.plw +input.pagebutton:focus { - background-color: #ffffff; - color: #000000; - padding: 4px; - clear: both; + border-color: #bb6622; } -tr.plw +input.samepagebutton:focus +{ + border-color: #bb6622; + background-color: #bb6622; +} + +table.list +{ + border-color: #0057af; + border-width: 4px 16px 16px 16px; + border-style: solid; + border-spacing: 0px; +} +tr.list-entry-0 { background-color: #ffffff; color: #000000; } -tr.plv +tr.list-entry-1 { background-color: #D9ECFF; color: #000000; } -tr.plt +tr.list-name { color: #ffffff; background-color: #0057af; } -tr.pls +tr.list-name-b { text-align: center; font-weight: bold; color: #ffffff; background-color: #0057af; } -td.plk +td.list-cell { padding: 4px 8px; } -input.hl { - background:none!important; - border:none!important; - padding:0!important; -/* font-family:inherit; - font-size:inherit; */ - font: inherit; - text-decoration:underline; + + +div.post +{ border-color: #0057af; - color: #0057af; + border-width: 4px 16px 16px 16px; + border-style: solid; + margin: 1em 0em 1em 0em; + /* border-spacing: 0px; */ } -input.hl:hover { - border-color: #bb6622; - color: #bb6622; +div.in +{ + display: inline-block; } -input.pt +div.left { - border-color: #0057af; - color: #000000; - background-color: #ffffff; - border-width: 2px; - border-style: solid; - margin: 2px; + float: left; } -input.pt:focus +div.right { - border-color: #bb6622; + float: right; } -select.pk +.tp +{ + text-align: right; +} +div.post-name-b +{ + text-align: center; + font-weight: bold; + color: #ffffff; + background-color: #0057af; + width: 100%; +} +div.post-name +{ + color: #ffffff; + background-color: #0057af; + width: 100%; + clear: both; +} +div.post-content-0 { - border-color: #0057af; - color: #000000; background-color: #ffffff; - border-width: 2px; - border-style: solid; - margin: 2px; + color: #000000; + padding: 4px; + clear: both; } -select.pk:focus +div.post-content-1 { - border-color: #bb6622; + background-color: #D9ECFF; + color: #000000; + padding: 4px; + clear: both; } -input.pk +div.post-attachment { - border-color: #0057af; color: #000000; background-color: #ffffff; - border-width: 2px; + border-color: #bb6622; + border-width: 4px; border-style: solid; - margin: 2px; + padding: 2px; + clear: both; + overflow: hidden; } -input.pk:focus -{ + +img.post-attachment { + border-width: 4px; border-color: #bb6622; + border-style: solid; + margin: 2px; } + textarea.pt { border-color: #0057af; diff --git a/interface.1.pl b/interface.1.pl index 7f8c512..bed208d 100644 --- a/interface.1.pl +++ b/interface.1.pl @@ -9,7 +9,7 @@ use strict; ###PROXY_LIB; ###FACEBUG_LIB; use proxy_lib qw(entityencode getcgi urldecode readconfigfile); -use facebug_lib qw(key); +use facebug_lib qw(key readdatafile); ###IF_CSS_PATH; ###LOGIN_PATH; @@ -18,10 +18,15 @@ use facebug_lib qw(key); ###INTERFACE_PATH; ###LIST_PATH; ###GROUP_PATH; +###THREAD_PATH; +###IMAGE_PATH; ###KEY_BITS; ###TIMEOUT_UNLOCK; ###TIMEOUT_INACT; ###GROUPSETTINGS_PATH; +###ARCH_PATH; +###POSTS_IN_PAGE; +###THREADS_IN_PAGE; my %http; my %cgi; @@ -31,6 +36,9 @@ my $method; my $IP; my $id; my $skey; +my $key; + +my @idt; my $time = time(); srand ($time-$$); @@ -93,11 +101,24 @@ if ($mode !~ /^(login|logout)$/) { unless ($skey=access($time,$IP,$cgi{'skey'})) { exit loginpage ("You must log in to access this $mode.","Status: 403 Forbidden\n"); } - if($id =~ /^([0-9\/]*)$/) { - $id = $1; + if ($mode eq 'image') { + if($id =~ /^(([0-9]*)\/([a-zA-Z]_([A-Za-z0-9\-\._\/]|(\@[A-Fa-f0-9]{2}))+))$/) { + $id = $1; + $idt[0]=$2; + $idt[1]=$3; + } + else { + exit failpage("Status: 404 Not Found\n","404 Not Found\n"," \"$id\" is not a valid image ID."); + } } - elsif ($mode !~ /^(list)$/) { - exit failpage("Status: 404 Not Found\n","404 Not Found\n"," \"$id\" is not a valid $mode ID."); + else { + if($id =~ /^([0-9\/]*)$/) { + $id = $1; + @idt = split('/',$id) + } + elsif ($mode !~ /^(list)$/) { + exit failpage("Status: 404 Not Found\n","404 Not Found\n"," \"$id\" is not a valid $mode ID."); + } } } @@ -105,12 +126,329 @@ if ($mode !~ /^(login|logout)$/) { if($mode eq 'login') { exit login(); } -elsif ($mode eq 'list') { +#if($mode eq 'logout') { +# exit logout(); +#} +if ($mode eq 'list') { exit list(); } - +if ($idt[0]eq '') { + exit failpage("Status: 404 Not Found\n","404 Not Found\n"," No $mode ID."); +} +if ($mode eq 'group') { + exit group(); +} +if ($idt[1]eq '') { + exit failpage("Status: 404 Not Found\n","404 Not Found\n"," Incomplete $mode ID."); +} +if ($cgi{'key'} =~ /^([A-Fa-f0-9]+)$/) { + $key=$1; +} +if ($mode eq 'image') { + exit image(); +} exit loginpage ("$mode --- $id"); +sub showthread { + (my $threadid, my $even) = @_; + my $threadpath; + my %thread; + my $first; + + if($threadid =~ /^([0-9]+)$/) { + $threadid=$1; + } + else { + return 0; + } + $threadpath=ARCH_PATH.$idt[0].'/thread/'.$threadid; + %thread=readdatafile($threadpath); + if($thread{'id'} =~ /^([0-9]+)$/) { + $threadid=$1; + } + else{ + return 0; + } + + $thread{'postcontent'} =~ s/&img([^;]+);/insertimg($1)/ge; + + print '
'; + #'
e:e:e
'."\n". + print '
'.entityencode($thread{'name'}).(($thread{'timetext'} ne '')?(' • '.$thread{'timetext'}):'').(($thread{'replies'} ne '')?(' • replies: '.$thread{'replies'}):'').'
'."\n"; + print '
'.$thread{'postcontent'}.'
'."\n"; + + $first=1; + for(my $ind=1;;++$ind) { + if($thread{'link-'.$ind} ne ''){ + if($first){ + print '
'."\n"; + $first=0; + } + print '
'; + if($thread{'img-'.$ind} ne ''){ + print '
image '.$ind.'
'; + } + print '
'.$thread{'linktitle-'.$ind}.'
'.$thread{'linktext-'.$ind}.'
'."\n"; + } + elsif($thread{'img-'.$ind} ne ''){ + if($first){ + print '
'."\n"; + $first=0; + } + print 'image '.$ind.''; + } + else{ + last; + } + } + unless($first) { + print '
'."\n"; + } + + print '
'."\n"; + print '
'."\n"; + + return 1; +} + +sub image { + my $headerpath; + my $imagepath; + my $imagefile; + my %header; + my $buffer; + + $imagepath=ARCH_PATH.$idt[0].'/image/'.$idt[1]; + $headerpath=$imagepath.'@h'; + $imagepath.='@v'; + %header = readdatafile($headerpath); + + ### 304 !!! !!! !!! + + if($header{'id'}!~/^[a-zA-Z]_([A-Za-z0-9\-\._\/]|(\@[A-Fa-f0-9]{2}))+$/) { + return failpage("Status: 404 Not Found\n","404 Not Found","Image \"$id\" not found."); + } + open($imagefile,'<',$imagepath) or return failpage("Status: 500 Internal Server Error\n","500 Internal Server Error"," Can't open image file."); + unless(binmode($imagefile)) { + close($imagefile); + return failpage("Status: 500 Internal Server Error\n","500 Internal Server Error"," Can't switch to binary mode."); + } + + if(($header{'key'} ne'') and ($key ne $header{'key'})) { + exit loginpage ("You must log in to access this image.","Status: 403 Forbidden\n"); + } + + foreach my $ind (keys %header) { + if ($ind =~ /^content-/) { + print "$ind: $header{$ind}\n"; + } + } + print "\n"; + + if ($method eq 'HEAD'){ + close($imagefile); + return; + } + + while (read ($imagefile,$buffer,1024)) { + print (STDOUT $buffer); + } + close($imagefile); +} + +sub group { + my $dir; + my $grouppath; + my %group; + my $groupid; + my $threadspath; + my @threads; + my $threadid; + my $page; + my $pagesq; + my $threadsq; + my $even; + + $grouppath=GROUPSETTINGS_PATH.$idt[0]; + %group=readconfigfile($grouppath); + if($group{'id'} =~ /^([0-9]+)$/) { + $groupid=$1; + } + else { + return failpage("Status: 404 Not Found\n","404 Not Found","Group \"$id\" not found."); + } + + if ($cgi{'p'} ne '') { + $page=int($cgi{'p'}); + } + elsif ($idt[1] ne '') { + $page=int($idt[1]); + } + else { + $page=1; + } + + $threadspath=ARCH_PATH.$groupid.'/thread/'; + opendir ($dir, $threadspath) or return failpage("Status: 500 Internal Server Error\n","500 Internal Server Error","Can't access thread list."); + while (defined ($threadid = readdir $dir)) { + if ($threadid =~ /^([0-9]+)$/) { + push @threads, $1; + } + } + closedir($dir); + if($cgi{'rev'} ne ''){ + @threads=sort { $b <=> $a } @threads; + } + else { + @threads=sort { $a <=> $b } @threads; + } + + $threadsq=scalar @threads; + $pagesq= int(($threadsq-1)/THREADS_IN_PAGE)+1; + if($pagesq<=0) { + $pagesq=1; + } + if ($page > $pagesq) { + $page=$pagesq; + } + elsif ($page<=0) { + $page=1; + } + + if ($method eq 'HEAD') { + print "Status: 200 Ok\n\n"; + return; + } + print "Content-type: text/html\n\n"; + print ''."\n"; + print ''."\n"; + print 'List of threads'.(($pagesq>1)?(', page '.$page.' of '.$pagesq):'').' - the redundant facebook copy'."\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print '

'.(($group{'name'}ne'')?(entityencode($group{'name'})):$groupid).' - the redundant facebook copy

'."\n"; + print '

List of threads'.(($pagesq>1)?(', page '.$page.' of '.$pagesq):'').'

'."\n"; + + print '
'; + print ''; + print '
'."\n"; + + print '
'; + if($cgi{'rev'} ne ''){ + print ''; + } + else { + print ''; + } + print '
'."\n"; + + if($pagesq > 1){ + print ' Page: '; + if($page>1){ + grouppagebutton($groupid,1,($cgi{'rev'} ne '')); + if ($page > 6) { + print ' ... '; + } + } + for(my $ind=(($page>6)?(($page<$pagesq)?($page-3):($page-4)):2);$ind<$page;++$ind) { + grouppagebutton($groupid,$ind,($cgi{'rev'} ne '')); + } + grouppagebutton($groupid,$page,($cgi{'rev'} ne ''),1); + for(my $ind=$page+1;$ind<=(($page+6<=$pagesq)?(($page==1)?($page+4):($page+3)):($pagesq-1));++$ind) { + grouppagebutton($groupid,$ind,($cgi{'rev'} ne '')); + } + if ($page<$pagesq) { + if ($page+6<=$pagesq){ + print ' ... '; + } + grouppagebutton($groupid,$pagesq,($cgi{'rev'} ne '')); + } + print ' Go to page:
'; + if($cgi{'rev'} ne ''){ + print ''; + } + print '
'."\n"; + + } + + $even = 1; + for(my $ind = ($page-1)*THREADS_IN_PAGE; ($ind < $page*THREADS_IN_PAGE) and ($ind < $threadsq); ++$ind) { + if (showthread($threads[$ind],$even)) { + $even = !$even; + } + } + + print '
'; + print ''; + print '
'."\n"; + + print '
'; + if($cgi{'rev'} ne ''){ + print ''; + } + else { + print ''; + } + print '
'."\n"; + + if($pagesq > 1){ + print ' Page: '; + if($page>1){ + grouppagebutton($groupid,1,($cgi{'rev'} ne '')); + if ($page > 6) { + print ' ... '; + } + } + for(my $ind=(($page>6)?(($page<$pagesq)?($page-3):($page-4)):2);$ind<$page;++$ind) { + grouppagebutton($groupid,$ind,($cgi{'rev'} ne '')); + } + grouppagebutton($groupid,$page,($cgi{'rev'} ne ''),1); + for(my $ind=$page+1;$ind<=(($page+6<=$pagesq)?(($page==1)?($page+4):($page+3)):($pagesq-1));++$ind) { + grouppagebutton($groupid,$ind,($cgi{'rev'} ne '')); + } + if ($page<$pagesq) { + if ($page+6<=$pagesq){ + print ' ... '; + } + grouppagebutton($groupid,$pagesq,($cgi{'rev'} ne '')); + } + print ' Go to page:
'; + if($cgi{'rev'} ne ''){ + print ''; + } + print '
'."\n"; + + } + + print ''."\n"; + +} + +sub insertimg { + (my $imgtext) = @_; + my $imgid; + my $imgkey; + # &img@ir_v2@2Fyo@2Fr@2FX8YPpi6kcyo.png@k47793b703215f9410a43c96202872683a25c8e9fc474fd9822d39ee677f98281; + + if ($imgtext=~ /^\@i([a-zA-Z]_([A-Za-z0-9\-\._\/]|(\@[A-Fa-f0-9]{2}))+)\@k([A-Fa-f0-9]+)$/) { + return IMAGE_PATH.'/'.$idt[0].'/'.$1.'?key='.$4.'&skey='.$skey; + } + else { + return $imgtext; + } + +} + +sub grouppagebutton { + (my $groupid, my $page, my $reversed, my $samepage) = @_; + print '
'; + print ''; + if($reversed){ + print ''; + } + print ''; + print '
'."\n"; +} sub list { my $dir; @@ -129,13 +467,14 @@ sub list { print "Content-type: text/html\n\n"; print ''."\n"; print ''."\n"; - print 'List of facebook groups'."\n"; + print 'List of groups - the redundant facebook copy'."\n"; print ''."\n"; print ''."\n"; print ''."\n"; - print '

List of facebook groups

'."\n"; - print ''."\n"; - print ''."\n"; + print '

The redundant facebook copy

'."\n"; + print '

List of groups

'."\n"; + print '
Available groups
nameaction
'."\n"; + print ''."\n"; $even=0; @@ -154,7 +493,7 @@ sub list { next; } $even = !$even; - print ''."\n"; + print ''."\n"; } print '
Available groups
nameaction
'.entityencode($group{'name'}).'
'.(($group{'name'}ne'')?(entityencode($group{'name'})):$groupid).'
'."\n"; @@ -300,14 +639,15 @@ sub login { print "Content-type: text/html\n\n"; print ''."\n"; print ''."\n"; - print 'Login successful'."\n"; + print 'Login successful - the redundant facebook copy'."\n"; print ''."\n"; print ''."\n"; print ''."\n"; - print '

Login successful

'."\n"; + print '

The redundant facebook copy

'."\n"; + print '

Login successful

'."\n"; print '

You have successfully logged in.

'."\n"; print '
'."\n"; - print '
'."\n"; + print '
'."\n"; print ''."\n"; print '
'."\n"; } @@ -360,18 +700,19 @@ sub loginpage { print "Content-type: text/html\n\n"; print ''."\n"; print ''."\n"; - print 'Log in to the facebook interface'."\n"; + print 'Log in - the redundant facebook copy'."\n"; print ''."\n"; print ''."\n"; print ''."\n"; - print '

Log in to the facebook interface

'."\n"; + print '

The redundant facebook copy

'."\n"; + print '

Log in

'."\n"; if($message ne ''){ print '

'.entityencode($message).'

'."\n"; } print '
'."\n"; - print ''."\n"; - print ''."\n"; - print '
Username:
Password:
'."\n"; + print 'Username: '."\n"; + print 'Password: '."\n"; + print ''."\n"; print ''."\n"; } @@ -394,7 +735,7 @@ sub failpage { print ''."\n"; print ''."\n"; if($title ne ''){ - print "

$title

"."\n"; + print "

$title - the redundant facebook copy

"."\n"; } if($message ne ''){ print '

'.entityencode($message).'

'."\n"; @@ -403,6 +744,6 @@ sub failpage { if($cgi{'skey'} =~ /^([A-Fa-f0-9]+)$/){ print ''; } - print ''."\n"; + print ''."\n"; print ''."\n"; } diff --git a/settings b/settings index 3bb3b7b..6e60937 100644 --- a/settings +++ b/settings @@ -35,9 +35,12 @@ gcc = /usr/bin/gcc gzip = /bin/gzip c_flags = -g -Wall -key_bits = 512 +key_bits = 256 max_redirections = 16 +posts_in_page = 40 +threads_in_page = 20 + log_size_limit = 65536 # How big can a log file be logs_uncompressed = 2 # How many uncompressed old logs to keep logs_total = 10 # How many old logs to keep -- 2.30.2