From 9442d4d260b55e7acd9f804d281dce62455fc01c Mon Sep 17 00:00:00 2001
From: b <rowerynaksiezycu@gmail.com>
Date: Tue, 9 Jan 2024 21:22:56 +0000
Subject: [PATCH] Improvements to comment interface: - show post time seconds -
 check duplicate - check access to particular frame - generate index in case
 of page 0 comment - log "spam" attempts

---
 bsta_lib.1.pm |  5 ++--
 opomba.1.pl   | 73 ++++++++++++++++++++++++++++++++++++++++++++++-----
 reset.1.pl    |  4 +--
 settings.txt  |  8 +++---
 4 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/bsta_lib.1.pm b/bsta_lib.1.pm
index 935bc26..b5301f0 100644
--- a/bsta_lib.1.pm
+++ b/bsta_lib.1.pm
@@ -1372,12 +1372,13 @@ sub print_comments {
 			if ($post_time != 0) {
 				my @time_tab = gmtime($post_time);
 				$post_time_text = sprintf(
-					'%04d.%02d.%02d %02d:%02d UTC',
+					'%04d.%02d.%02d %02d:%02d:%02d UTC',
 					$time_tab[5]+1900,
 					$time_tab[4]+1,
 					$time_tab[3],
 					$time_tab[2],
-					$time_tab[1]
+					$time_tab[1],
+					$time_tab[0]
 				);
 			}
 			if (($edit_time !=0) && ($edit_time != $post_time)) {
diff --git a/opomba.1.pl b/opomba.1.pl
index 2ae8adc..e35aa0b 100644
--- a/opomba.1.pl
+++ b/opomba.1.pl
@@ -36,7 +36,7 @@ use botm_common (
 	'make_id'
 );
 use bsta_lib (
-	'TEXT_MODE',
+	'TEXT_MODE', 'STATE',
 	'get_password',
 	'fail_method', 'fail_content_type',
 	'redirect',
@@ -44,7 +44,8 @@ use bsta_lib (
 	'print_html_head_start', 'print_html_head_end',
 	'print_html_body_start', 'print_html_body_end',
 	'bb_to_html', 'eval_bb',
-	'merge_settings'
+	'merge_settings',
+	'write_index'
 );
 
 ###PERL_PATH_SEPARATOR:     PATH_SEPARATOR     = /
@@ -53,8 +54,10 @@ use bsta_lib (
 ###PERL_CGI_WORDS_PATH:     CGI_WORDS_PATH     = /bsta/w
 
 ###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings
+###PERL_DATA_STATE_PATH:    DATA_STATE_PATH    = /botm/data/bsta/state
 ###PERL_DATA_WORDS_PATH:    DATA_WORDS_PATH    = /botm/data/bsta/words/
 
+###PERL_LOG_SPAM_PATH:      LOG_SPAM_PATH      = /botm/log/bsta/words_spam.log
 ###PERL_LOG_WORDS_PATH:     LOG_WORDS_PATH     = /botm/log/bsta/words.log
 
 ###PERL_WEBSITE_NAME:       WEBSITE_NAME       = Bicycles on the Moon
@@ -71,25 +74,32 @@ srand ($time-$$);
 
 my %http;
 my %cgi;
+my %state;
 my %settings;
 my %words_data;
 my %post_data;
+my %last_post_data;
 
 my @post_list;
 
 my $method;
 my $frame;
 my $ID;
+my $last_ID;
 my $password;
 my $password_ok;
+my $access;
 my $edit = 0;
 my $remove = 0;
 my $post = 0;
 my $quote;
 my $words_data_path;
 my $post_data_path;
+my $last_post_data_path;
 my $index;
 my $page;
+my $ong_state;
+my $last_frame;
 my $fh;
 my $r;
 
@@ -132,7 +142,10 @@ if ($cgi{'i'} =~ /^.+$/) {
 }
 $password = get_password(\%cgi);
 
-%settings   = read_data_file(DATA_SETTINGS_PATH());
+%settings = read_data_file(DATA_SETTINGS_PATH());
+%state    = read_data_file(DATA_STATE_PATH());
+$ong_state = int($state{'state'});
+$last_frame = int($state{'last'});
 
 $password_ok = ($password eq $settings{'password'});
 
@@ -166,9 +179,18 @@ if ($ID ne '') {
 	}
 }
 
-if ($frame eq '') {
+unless ($frame ne '') {
 	exit output(0, '400 Bad Request', 'Frame ID not specified.');
 }
+$access = (
+	$password_ok || (
+		($ong_state >= STATE->{'waiting'}) &&
+		($frame <= $last_frame)
+	)
+);
+unless ($access) {
+	exit output(0, '403 Forbidden', 'Not allowed to post this here now');
+}
 
 $words_data_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $frame);
 
@@ -256,8 +278,24 @@ if ($remove || ($ID ne '')) {
 }
 unless ($cgi{'password2'} eq '') {
 	close($fh);
-	exit output(0, '', 'Please don\'t write anything in the place which should remain empty.', 1);
 	# no error code to confuse spambot :)
+	output(0, '', 'Please don\'t write anything in the place which should remain empty.', 1);
+	if (open_encoded($fh, ">>:encoding(UTF-8)", LOG_SPAM_PATH())) {
+		$cgi{'content'} = $cgi{'words'};
+		$cgi{'empty'} = $cgi{'password2'};
+		delete($cgi{'words'});
+		delete ($cgi{'password'});
+		delete ($cgi{'password2'});
+		print $fh "$time SPAM $ID\n";
+		write_data_file(
+			$fh, \%cgi, '',
+			0, 0, 0,
+			'>>', 1
+		);
+		print $fh "\n\n";
+		close ($fh);
+	}
+	exit;
 }
 
 # all conditions fulfilled
@@ -304,6 +342,21 @@ if ($ID eq '') {
 if ($index eq '') {
 	$index = scalar(@post_list);
 	$page = int($index / COMMENT_PAGE_LENGTH());
+	if ($index > 0) {
+		$last_ID = $post_list[-1];
+		$last_post_data_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $last_ID);
+		%last_post_data = read_data_file($last_post_data_path);
+		if (
+			($cgi{'username'} eq $last_post_data{'name'   }) &&
+			($cgi{'words'   } eq $last_post_data{'content'})
+		) { # duplicate post
+			$index -= 1;
+			$page = int($index / COMMENT_PAGE_LENGTH());
+			$ID = $last_ID;
+			close ($fh);
+			exit output(1);
+		}
+	}
 	push @post_list, $ID;
 }
 $words_data{'posts'} = scalar(@post_list);
@@ -350,6 +403,10 @@ unless ($r) {
 
 close($fh);
 
+if (($frame == 0) && ($ong_state > STATE->{'inactive'})) {
+	write_index(\%state, \%settings);
+}
+
 if (open_encoded($fh, ">>:encoding(UTF-8)", LOG_WORDS_PATH())) {
 	delete ($post_data{'password'});
 	print $fh "$time POST $ID\n";
@@ -368,7 +425,6 @@ exit output(1);
 sub output {
 	(my $done, my $status, my $message, my $show_content) = @_;
 	
-	
 	my $return_url = merge_url(
 		{'path' => CGI_VIEWER_PATH()},
 		{
@@ -407,6 +463,9 @@ sub output {
 	else {
 		$title = 'Words';
 	}
+	if ($frame ne '') {
+		$title = $frame.'. '.$title;
+	}
 	
 	if ($cgi{'username'} ne '') {
 		$name = $cgi{'username'}
@@ -530,6 +589,6 @@ sub output {
 		print '   </div>'."\n";
 	}
 	
-	print_html_body_end(\*STDOUT); # , $ong_state == STATE->{'inactive'}
+	print_html_body_end(\*STDOUT, $ong_state == STATE->{'inactive'});
 	print_html_end(\*STDOUT);
 }
diff --git a/reset.1.pl b/reset.1.pl
index 00f6129..bfe5dda 100644
--- a/reset.1.pl
+++ b/reset.1.pl
@@ -112,12 +112,10 @@ write_index(
 if (opendir_encoded(my $dir, DATA_WORDS_PATH())) {
 	print DATA_WORDS_PATH()."\n";
 	while (my $file_name = readdir_decoded($dir)) {
-		print $file_name."\n";
 		if ($file_name !~ /^[0-9]+$/) {
 			next;
 		}
 		my $full_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $file_name);
-		print $full_path."\n";
 		unlink_encoded ($full_path);
 	}
-}
\ No newline at end of file
+}
diff --git a/settings.txt b/settings.txt
index 520664d..ea00785 100644
--- a/settings.txt
+++ b/settings.txt
@@ -67,9 +67,10 @@ _data_state_path    = @_PATH( $data_path, state      )
 _data_story_path    = @_PATH( $data_path, story      )
 _data_words_path    = @_PATH( $data_path, words      )
 
-_log_path           = @_PATH( $log_path,          )
-_log_ong_path       = @_PATH( $log_path, ong.log  )
-_log_words_path     = @_PATH( $log_path, words.log)
+_log_path           = @_PATH( $log_path,               )
+_log_ong_path       = @_PATH( $log_path, ong.log       )
+_log_spam_path      = @_PATH( $log_path, words_spam.log)
+_log_words_path     = @_PATH( $log_path, words.log     )
 
 _www_path           = @_PATH( $www_path,          )
 _www_index_path     = @_PATH( $www_path, index.htm)
@@ -178,6 +179,7 @@ PERL_DATA_STORY_PATH    = @_PERL_CONSTANT_STR( DATA_STORY_PATH   , $_data_story_
 PERL_DATA_WORDS_PATH    = @_PERL_CONSTANT_STR( DATA_WORDS_PATH   , $_data_words_path   )
 
 PERL_LOG_PATH           = @_PERL_CONSTANT_STR( LOG_PATH      , $_log_path      )
+PERL_LOG_SPAM_PATH      = @_PERL_CONSTANT_STR( LOG_SPAM_PATH , $_log_spam_path )
 PERL_LOG_WORDS_PATH     = @_PERL_CONSTANT_STR( LOG_WORDS_PATH, $_log_words_path)
 
 PERL_WWW_PATH           = @_PERL_CONSTANT_STR( WWW_PATH      , $_www_path      )
-- 
2.30.2