]> bicyclesonthemoon.info Git - yplom/facebug1/commitdiff
moved data file functions to library
authorb <b@7dec801f-c475-4e67-ba99-809552d69c55>
Mon, 28 Dec 2015 20:09:31 +0000 (20:09 +0000)
committerb <b@7dec801f-c475-4e67-ba99-809552d69c55>
Mon, 28 Dec 2015 20:09:31 +0000 (20:09 +0000)
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
configure.pl
facebug_lib.1.pm
if.css
interface.1.pl
settings

index 04a92885a2c7ebb5c1a4312f7bb10bc864143cc3..4cbab6b78c745146a5a676730c7a5ea626574c29 100644 (file)
--- 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'}.='<a href="'.urldecode($3).'">';
+                                               $thread{'postcontent'}.='<a href="'.entityencode(urldecode($3)).'">';
                                                $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'}.='<a href="'.urldecode($3).'">';
+                                               $post{'content'}.='<a href="'.entityencode(urldecode($3)).'">';
                                                $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.
index 3d3abaf99919fa4b8e7fd98ac9634389e9e01d5e..43c96c5517110ad83c48794040793a6e3f599c4c 100644 (file)
@@ -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'}.";";
index 360cb4fab960ed3091ca10d4a3e6eae2161f6cb9..d7a6e9583cd632112a2b40a087c29173cf7992f1 100644 (file)
@@ -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 45f55e7fa5905019eb9f3c081fd3edfbd67deb1a..b617f7ad8f0a973791bea05e5b5c5aaedfa97918 100644 (file)
--- a/if.css
+++ b/if.css
@@ -1,5 +1,5 @@
-/* Currently, it's identical to botm.css, the default style of\r
-   1190.bicyclesonthemoon.info. May be changed in the future. */\r
+/* It's derived from botm.css, the default style of\r
+   1190.bicyclesonthemoon.info. */\r
 \r
 html\r
 {\r
@@ -49,142 +49,200 @@ a:hover:visited
        color: #ffffff!important;\r
 }\r
 \r
-form.hl {\r
+form.inline {\r
        display: inline;\r
 }\r
-\r
-table.pl\r
-{\r
+input.hl {\r
+       background:none!important;\r
+       border:none!important; \r
+       padding:0!important;\r
+/*     font-family:inherit;\r
+       font-size:inherit; */\r
+       font: inherit;\r
+       text-decoration:underline;\r
        border-color: #0057af;\r
-       border-width: 4px 16px 16px 16px;\r
-       border-style: solid;\r
-       border-spacing: 0px;\r
+       color: #0057af;\r
+}\r
+input.hl:hover {\r
+       border-color: #bb6622;\r
+       color: #bb6622;\r
 }\r
-div.pl\r
+input.textfield\r
 {\r
        border-color: #0057af;\r
-       border-width: 4px 16px 16px 16px;\r
+       color: #000000;\r
+       background-color: #ffffff;\r
+       border-width: 2px;\r
        border-style: solid;\r
-       /* border-spacing: 0px; */\r
+       margin: 2px;\r
 }\r
-div.in\r
+input.textfield:focus\r
 {\r
-       display: inline-block;\r
+       border-color: #bb6622;\r
 }\r
-div.le\r
+select.pk\r
 {\r
-       float: left;\r
+       border-color: #0057af;\r
+       color: #000000;\r
+       background-color: #ffffff;\r
+       border-width: 2px;\r
+       border-style: solid;\r
+       margin: 2px;\r
 }\r
-div.pr\r
+select.pk:focus\r
 {\r
-       float: right;\r
+       border-color: #bb6622;\r
 }\r
-.tp\r
+input.button\r
 {\r
-       text-align: right;\r
+       border-color: #0057af;\r
+       color: #000000;\r
+       background-color: #ffffff;\r
+       border-width: 2px;\r
+       border-style: solid;\r
+       margin: 2px;\r
 }\r
-div.pls\r
-{\r
-       text-align: center;\r
-       font-weight: bold;\r
+input.pagebutton {\r
+       border-color: #0057af;\r
+       color: #000000;\r
+       background-color: #ffffff;\r
+       border-width: 2px;\r
+       border-style: solid;\r
+       margin: 2px;\r
+       padding: 0px;\r
+       font-size: 70%;\r
+}\r
+input.samepagebutton {\r
+       border-color: #0057af;\r
        color: #ffffff;\r
        background-color: #0057af;\r
-       width: 100%;\r
+       border-width: 2px;\r
+       border-style: solid;\r
+       margin: 2px;\r
+       padding: 0px;\r
+       font-size: 70%;\r
 }\r
-div.plt\r
+input.button:focus\r
 {\r
-       color: #ffffff;\r
-       background-color: #0057af;\r
-       width: 100%;\r
-       clear: both;\r
+       border-color: #bb6622;\r
 }\r
-div.plw\r
+input.pagebutton:focus\r
 {\r
-       background-color: #ffffff;\r
-       color: #000000;\r
-       padding: 4px;\r
-       clear: both;\r
+       border-color: #bb6622;\r
 }\r
-tr.plw\r
+input.samepagebutton:focus\r
+{\r
+       border-color: #bb6622;\r
+       background-color: #bb6622;\r
+}\r
+\r
+table.list\r
+{\r
+       border-color: #0057af;\r
+       border-width: 4px 16px 16px 16px;\r
+       border-style: solid;\r
+       border-spacing: 0px;\r
+}\r
+tr.list-entry-0\r
 {\r
        background-color: #ffffff;\r
        color: #000000;\r
 }\r
-tr.plv\r
+tr.list-entry-1\r
 {\r
        background-color: #D9ECFF;\r
        color: #000000;\r
 }\r
-tr.plt\r
+tr.list-name\r
 {\r
        color: #ffffff;\r
        background-color: #0057af;\r
 }\r
-tr.pls\r
+tr.list-name-b\r
 {\r
        text-align: center;\r
        font-weight: bold;\r
        color: #ffffff;\r
        background-color: #0057af;\r
 }\r
-td.plk\r
+td.list-cell\r
 {\r
        padding: 4px 8px;\r
 }\r
-input.hl {\r
-       background:none!important;\r
-       border:none!important; \r
-       padding:0!important;\r
-/*     font-family:inherit;\r
-       font-size:inherit; */\r
-       font: inherit;\r
-       text-decoration:underline;\r
+\r
+\r
+div.post\r
+{\r
        border-color: #0057af;\r
-       color: #0057af;\r
+       border-width: 4px 16px 16px 16px;\r
+       border-style: solid;\r
+       margin: 1em 0em 1em 0em;\r
+       /* border-spacing: 0px; */\r
 }\r
-input.hl:hover {\r
-       border-color: #bb6622;\r
-       color: #bb6622;\r
+div.in\r
+{\r
+       display: inline-block;\r
 }\r
-input.pt\r
+div.left\r
 {\r
-       border-color: #0057af;\r
-       color: #000000;\r
-       background-color: #ffffff;\r
-       border-width: 2px;\r
-       border-style: solid;\r
-       margin: 2px;\r
+       float: left;\r
 }\r
-input.pt:focus\r
+div.right\r
 {\r
-       border-color: #bb6622;\r
+       float: right;\r
 }\r
-select.pk\r
+.tp\r
+{\r
+       text-align: right;\r
+}\r
+div.post-name-b\r
+{\r
+       text-align: center;\r
+       font-weight: bold;\r
+       color: #ffffff;\r
+       background-color: #0057af;\r
+       width: 100%;\r
+}\r
+div.post-name\r
+{\r
+       color: #ffffff;\r
+       background-color: #0057af;\r
+       width: 100%;\r
+       clear: both;\r
+}\r
+div.post-content-0\r
 {\r
-       border-color: #0057af;\r
-       color: #000000;\r
        background-color: #ffffff;\r
-       border-width: 2px;\r
-       border-style: solid;\r
-       margin: 2px;\r
+       color: #000000;\r
+       padding: 4px;\r
+       clear: both;\r
 }\r
-select.pk:focus\r
+div.post-content-1\r
 {\r
-       border-color: #bb6622;\r
+       background-color: #D9ECFF;\r
+       color: #000000;\r
+       padding: 4px;\r
+       clear: both;\r
 }\r
-input.pk\r
+div.post-attachment\r
 {\r
-       border-color: #0057af;\r
        color: #000000;\r
        background-color: #ffffff;\r
-       border-width: 2px;\r
+       border-color: #bb6622;\r
+       border-width: 4px;\r
        border-style: solid;\r
-       margin: 2px;\r
+       padding: 2px;\r
+       clear: both;\r
+       overflow: hidden;\r
 }\r
-input.pk:focus\r
-{\r
+\r
+img.post-attachment {\r
+       border-width: 4px;\r
        border-color: #bb6622;\r
+       border-style: solid;\r
+       margin: 2px;\r
 }\r
+\r
 textarea.pt\r
 {\r
        border-color: #0057af;\r
index 7f8c51292928e11131ef43712470ab7565000f44..bed208d832c56d0a88901465e43181e9f8298f59 100644 (file)
@@ -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 '<div class="post" id="'.$threadid.'">';
+       #'<div class="post-name-b">e:e:e</div>'."\n".
+       print '<div class="post-name">'.entityencode($thread{'name'}).(($thread{'timetext'} ne '')?(' &bull; '.$thread{'timetext'}):'').(($thread{'replies'} ne '')?(' &bull; replies: '.$thread{'replies'}):'').'</div>'."\n";
+       print '<div class="'.($even?'post-content-0':'post-content-1').'">'.$thread{'postcontent'}.'</div>'."\n";
+       
+       $first=1;
+       for(my $ind=1;;++$ind) {
+               if($thread{'link-'.$ind} ne ''){
+                       if($first){
+                               print '<div class="'.($even?'post-content-0':'post-content-1').'">'."\n";
+                               $first=0;
+                       }
+                       print '<div class="post-attachment">';
+                       if($thread{'img-'.$ind} ne ''){
+                               print '<div class="left"><a href="'.entityencode($thread{'link-'.$ind}).'"><img class="post-attachment" src="'.IMAGE_PATH.'/'.$idt[0].'/'.$thread{'img-'.$ind}.'?key='.$thread{'imgkey-'.$ind}.'&amp;skey='.$skey.'" alt="image '.$ind.'"></a></div>';
+                       }
+                       print '<div class="left"><a href="'.entityencode($thread{'link-'.$ind}).'" class="br"><b>'.$thread{'linktitle-'.$ind}.'</b></a><br>'.$thread{'linktext-'.$ind}.'</div></div>'."\n";
+               }
+               elsif($thread{'img-'.$ind} ne ''){
+                       if($first){
+                               print '<div class="'.($even?'post-content-0':'post-content-1').'">'."\n";
+                               $first=0;
+                       }
+                       print '<img class="post-attachment" src="'.IMAGE_PATH.'/'.$idt[0].'/'.$thread{'img-'.$ind}.'?key='.$thread{'imgkey-'.$ind}.'&amp;skey='.$skey.'" alt="image '.$ind.'">';
+               }
+               else{
+                       last;
+               }
+       }
+       unless($first) {
+               print '</div>'."\n";
+       }
+       
+       print '<div class="'.($even?'post-content-0':'post-content-1').'"><form class="inline" method="post" action="'.THREAD_PATH.'/'.$idt[0].'/'.$threadid.'"><input type="submit" class="button" value="show thread"><input type="hidden" name="skey" value="'.$skey.'"><input type="hidden" name="key" value="'.$thread{'key'}.'"></form></div>'."\n";
+       print '</div>'."\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 '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">'."\n";
+       print '<html lang="en"><head>'."\n";
+       print '<title>List of threads'.(($pagesq>1)?(', page '.$page.' of '.$pagesq):'').' - the redundant facebook copy</title>'."\n";
+       print '<meta http-equiv="Content-type" content="text/html; charset=UTF-8">'."\n";
+       print '<link rel="stylesheet" href="'.IF_CSS_PATH.'">'."\n";
+       print '</head><body>'."\n";
+       print '<h1>'.(($group{'name'}ne'')?(entityencode($group{'name'})):$groupid).' - the redundant facebook copy</h1>'."\n";
+       print '<h2>List of threads'.(($pagesq>1)?(', page '.$page.' of '.$pagesq):'').'</h2>'."\n";
+       
+       print '<form class="inline" method="post" action="'.LIST_PATH.'">';
+       print '<input type="submit" value="back to the group list" class="button"><input type="hidden" name="skey" value="'.$skey.'">';
+       print '</form>'."\n";
+       
+       print '<form class="inline" method="post" action="'.GROUP_PATH.'/'.$groupid.'" ><input type="hidden" name="skey" value="'.$skey.'">';
+       if($cgi{'rev'} ne ''){
+               print '<input type="submit" value="show chronological" class="button">';
+       }
+       else {
+               print '<input type="submit" value="show antichronological" class="button"><input type="hidden" name="rev" value="1">';
+       }
+       print '</form>'."\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: <form class="inline" method="post" action="'.GROUP_PATH.'/'.$groupid.'" ><input type="hidden" name="skey" value="'.$skey.'">';
+               if($cgi{'rev'} ne ''){
+               print '<input type="hidden" name="rev" value="1">';
+               }
+               print '<input type="text" class="textfield" name="p" size="4"><input type="submit" value="go" class="button"></form>'."\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 '<form class="inline" method="post" action="'.LIST_PATH.'">';
+       print '<input type="submit" value="back to the group list" class="button"><input type="hidden" name="skey" value="'.$skey.'">';
+       print '</form>'."\n";
+       
+       print '<form class="inline" method="post" action="'.GROUP_PATH.'/'.$groupid.'" ><input type="hidden" name="skey" value="'.$skey.'">';
+       if($cgi{'rev'} ne ''){
+               print '<input type="submit" value="show chronological" class="button">';
+       }
+       else {
+               print '<input type="submit" value="show antichronological" class="button"><input type="hidden" name="rev" value="1">';
+       }
+       print '</form>'."\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: <form class="inline" method="post" action="'.GROUP_PATH.'/'.$groupid.'" ><input type="hidden" name="skey" value="'.$skey.'">';
+               if($cgi{'rev'} ne ''){
+               print '<input type="hidden" name="rev" value="1">';
+               }
+               print '<input type="text" class="textfield" name="p" size="4"><input type="submit" value="go" class="button"></form>'."\n";
+               
+       }
+       
+       print '</body></html>'."\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.'&amp;skey='.$skey;
+       }
+       else {
+               return $imgtext;
+       }
+       
+}
+
+sub grouppagebutton {
+       (my $groupid, my $page, my $reversed, my $samepage) = @_;
+       print '<form class="inline" method="post" action="'.GROUP_PATH.'/'.$groupid.'/'.$page.'">';
+       print '<input type="hidden" name="skey" value="'.$skey.'">';
+       if($reversed){
+               print '<input type="hidden" name="rev" value="1">';
+       }
+       print '<input type="submit" class="'.($samepage?'samepagebutton':'pagebutton').'" value="'.$page.'">';
+       print '</form>'."\n";
+}
 
 sub list {
        my $dir;
@@ -129,13 +467,14 @@ sub list {
        print "Content-type: text/html\n\n";
        print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">'."\n";
        print '<html lang="en"><head>'."\n";
-       print '<title>List of facebook groups</title>'."\n";
+       print '<title>List of groups - the redundant facebook copy</title>'."\n";
        print '<meta http-equiv="Content-type" content="text/html; charset=UTF-8">'."\n";
        print '<link rel="stylesheet" href="'.IF_CSS_PATH.'">'."\n";
        print '</head><body>'."\n";
-       print '<h1>List of facebook groups</h1>'."\n";
-       print '<table class="pl"><tr class="pls"><td colspan="2">Available groups</td></tr>'."\n";
-       print '<tr class="plt"><td class="plk">name</td><td class="plk">action</td></tr>'."\n";
+       print '<h1>The redundant facebook copy</h1>'."\n";
+       print '<h2>List of groups</h2>'."\n";
+       print '<table class="list"><tr class="list-name-b"><td colspan="2">Available groups</td></tr>'."\n";
+       print '<tr class="list-name"><td class="list-cell">name</td><td class="list-cell">action</td></tr>'."\n";
 
        $even=0;
        
@@ -154,7 +493,7 @@ sub list {
                        next;
                }
                $even = !$even;
-               print '<tr class="'.($even?'plw':'plv').'"><td class="plk">'.entityencode($group{'name'}).'</td><td class="plk"><form method="post" action="'.GROUP_PATH.'/'.$groupid.'" class="hl"><input type="hidden" name="skey" value="'.$skey.'"><input type="submit" value="show chronological" class="pk"></form> <form method="post" action="'.GROUP_PATH.'/'.$groupid.'" class="hl"><input type="hidden" name="skey" value="'.$skey.'"><input type="hidden" name="rev" value="1"><input type="submit" value="show antichronological" class="pk"></form></td></tr>'."\n";
+               print '<tr class="'.($even?'list-entry-0':'list-entry-1').'"><td class="list-cell">'.(($group{'name'}ne'')?(entityencode($group{'name'})):$groupid).'</td><td class="list-cell"><form method="post" action="'.GROUP_PATH.'/'.$groupid.'" class="inline"><input type="hidden" name="skey" value="'.$skey.'"><input type="submit" value="show chronological" class="button"></form> <form method="post" action="'.GROUP_PATH.'/'.$groupid.'" class="inline"><input type="hidden" name="skey" value="'.$skey.'"><input type="hidden" name="rev" value="1"><input type="submit" value="show antichronological" class="button"></form></td></tr>'."\n";
        }
        
        print '</table></body></html>'."\n";
@@ -300,14 +639,15 @@ sub login {
        print "Content-type: text/html\n\n";
        print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">'."\n";
        print '<html lang="en"><head>'."\n";
-       print '<title>Login successful</title>'."\n";
+       print '<title>Login successful - the redundant facebook copy</title>'."\n";
        print '<meta http-equiv="Content-type" content="text/html; charset=UTF-8">'."\n";
        print '<link rel="stylesheet" href="'.IF_CSS_PATH.'">'."\n";
        print '</head><body>'."\n";
-       print '<h1>Login successful</h1>'."\n";
+       print '<h1>The redundant facebook copy</h1>'."\n";
+       print '<h2>Login successful</h2>'."\n";
        print '<p><b class="ni">You have successfully logged in.</b></p>'."\n";
        print '<form method="post" action="'.LIST_PATH.'">'."\n";
-       print '<input type="submit" value="show the list" class="pk"><br>'."\n";
+       print '<input type="submit" value="show the list" class="button"><br>'."\n";
        print '<input type="hidden" name="skey" value="'.entityencode($key).'">'."\n";
        print '</form></body></html>'."\n";
 }
@@ -360,18 +700,19 @@ sub loginpage {
        print "Content-type: text/html\n\n";
        print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">'."\n";
        print '<html lang="en"><head>'."\n";
-       print '<title>Log in to the facebook interface</title>'."\n";
+       print '<title>Log in - the redundant facebook copy</title>'."\n";
        print '<meta http-equiv="Content-type" content="text/html; charset=UTF-8">'."\n";
        print '<link rel="stylesheet" href="'.IF_CSS_PATH.'">'."\n";
        print '</head><body>'."\n";
-       print '<h1>Log in to the facebook interface</h1>'."\n";
+       print '<h1>The redundant facebook copy</h1>'."\n";
+       print '<h2>Log in</h2>'."\n";
        if($message ne ''){
                print '<p><b class="br">'.entityencode($message).'</b></p>'."\n";
        }
        print '<form method="post" action="'.LOGIN_PATH.'"><table>'."\n";
-       print '<tr><td><b>Username: <b></td><td><input type="text" name="username" class="pt"></td></tr>'."\n";
-       print '<tr><td><b>Password: <b></td><td><input type="password" name="password" class="pt"></td></tr>'."\n";
-       print '</table><input type="submit" value="log in" class="pk">'."\n";
+       print '<tr><td><b>Username: <b></td><td><input type="text" name="username" class="textfield"></td></tr>'."\n";
+       print '<tr><td><b>Password: <b></td><td><input type="password" name="password" class="textfield"></td></tr>'."\n";
+       print '</table><input type="submit" value="log in" class="button">'."\n";
        print '</form></body></html>'."\n";
 }
 
@@ -394,7 +735,7 @@ sub failpage {
        print '<link rel="stylesheet" href="'.IF_CSS_PATH.'">'."\n";
        print '</head><body>'."\n";
        if($title ne ''){
-               print "<h1>$title</h1>"."\n";
+               print "<h1>$title - the redundant facebook copy</h1>"."\n";
        }
        if($message ne ''){
                print '<p><b class="br">'.entityencode($message).'</b></p>'."\n";
@@ -403,6 +744,6 @@ sub failpage {
        if($cgi{'skey'} =~ /^([A-Fa-f0-9]+)$/){
                print '<input type="hidden" name="skey" value="'.$1.'">';
        }
-       print '<input type="submit" value="back to the interface" class="pk"></form>'."\n";
+       print '<input type="submit" value="back to the interface" class="button"></form>'."\n";
        print '</body></html>'."\n";
 }
index 3bb3b7be7126800ef5c9a0b67af53ee6b86c3eda..6e60937c7dce980288bdd6dd25352aaad271369a 100644 (file)
--- 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